Subject: bug#53240: Compiler stderr messages cause -fPIC detection to fail

From: Rodrigo Arias <[email-masked]>
Date: Thu, 13 Jan 2022 22:02:59 +0100

Hi,

When using a compiler that produces dynamic messages via stderr when 
invoked, the configure code of libtool assumes the -fPIC is not working. 
This originally happened to me when using a gcc wrapper in nix with 
verbose messages enabled, which prints the arguments, but it can be 
reproduced more easily with gcc and `CFLAGS=-v` in the configure.

Related: https://lists.gnu.org/archive/html/bug-autoconf/2012-07/msg00046.html

$ ./configure CFLAGS=-v
...
checking if gcc supports -fno-rtti -fno-exceptions... no
checking for gcc option to produce PIC... -fPIC -DPIC
checking if gcc PIC flag -fPIC -DPIC works... no       <-- see here
checking if gcc static flag -static works... no
checking if gcc supports -c -o file.o... no
checking if gcc supports -c -o file.o... (cached) no

Here is the part of the config.log:

...
configure:9683: checking for gcc option to produce PIC
configure:9691: result: -fPIC -DPIC
configure:9699: checking if gcc PIC flag -fPIC -DPIC works
configure:9718: gcc -c -std=c11 -v  -fPIC -DPIC -DPIC conftest.c >&5
Using built-in specs.
COLLECT_GCC=/nix/store/h6d0c7lnxx65i925xmnxgwdfdvc7hc2p-gcc-10.3.0/bin/gcc
Target: x86_64-unknown-linux-gnu
Configured with: 
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 10.3.0 (GCC)
[ more lines removed ]
configure:9722: $? = 0
configure:9735: result: no  <--- here it assumes it doesn't work
configure:9764: checking if gcc static flag -static works
configure:9793: result: no

Here is the offending code in the configure:

   lt_cv_prog_compiler_pic_works=no
    ac_outfile=conftest.$ac_objext
    echo "$lt_simple_compile_test_code" > conftest.$ac_ext
    lt_compiler_flag="$lt_prog_compiler_pic -DPIC"  ## exclude from sc_useless_quotes_in_assignment
    # Insert the option either (1) after the last *FLAGS variable, or
    # (2) before a word containing "conftest.", or (3) at the end.
    # Note that $ac_compile itself does not contain backslashes and begins
    # with a dollar sign (not a hyphen), so the echo should work correctly.
    # The option is referenced via a variable to avoid confusing sed.
    lt_compile=`echo "$ac_compile" | $SED \
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
    (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
    echo "$as_me:$LINENO: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
      $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp
      $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2
      if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then
        lt_cv_prog_compiler_pic_works=yes
      fi
    fi
    $RM conftest*

It looks like the diff command fails because the gcc output has multiple 
lines which have now changed to include the -fPIC option, causing it to 
return 1.

The same problem would happen with other checks that use 
_LT_COMPILER_OPTION, but I only see the -fno-rtti check using it. 
However, this problem will likely happen to any other detection checks 
that rely on the diff over the output being the same.

I don't know if there is a good solution to this problem, but at least I 
believe it can be tested if the output is a reliable source to look for 
errors by using two flags without side effects and testing that the log 
stays the same, say gcc -E vs gcc -E -E. If that causes the output to 
differ, then diffing the output alone is not a reliable way to test if 
-fPIC has caused an error. Example:

% echo | gcc -E - 2>&1 | md5sum
23f8c0306cc1ad862a3a5a6cb2a6747b  -
% echo | gcc -E -E - 2>&1 | md5sum
23f8c0306cc1ad862a3a5a6cb2a6747b  -

Output seems reliable.

% echo | gcc -v -E - 2>&1 | md5sum
be68c813b36efa7b72a69a31c6ddfc06  -
% echo | gcc -v -E -E - 2>&1 | md5sum
a814600ad051ee786c38498d6298a1bb  -

Output changes with the args and is not reliable.

Best,
Rodrigo.