mainAutoconf - Support: sr #110294, AC_LANG_PUSH/AC_LANG_POP...

 
 

sr #110294: AC_LANG_PUSH/AC_LANG_POP malfunction inside AC_DEFUN

Submitter:  Bruno Haible <haible>
Submitted:  Tue 18 Aug 2020 04:38:28 PM UTC
   
 
Priority:  * 5 - Unprioritized Severity:  3 - Normal
Status:  Invalid Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Operating System:  GNU/Linux
* Mandatory Fields

Add a New Comment Rich Markup
   

Mon 07 Dec 2020 01:12:42 PM UTC, comment #5: 

Your workaround works perfectly! I'm using it in gnulib now:
https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=commitdiff;h=a0654cff8f1cbb705fbcba80841c58747b993440
Many many thanks!!

> After a bunch of head-scratching I have figured out what's going on.

Are there debugging tools or debugging tips available for this situation (that could be documented in the manual)? I also tried head-scratching, and for me it was enough to resolve the issue.

Bruno Haible <haible>
Mon 07 Dec 2020 01:34:29 AM UTC, comment #4: 

It looks like that happened because I typoed the verbatim markup. Thanks for copying over the full text.

Zack Weinberg <zackw>
Group administrator
Mon 07 Dec 2020 12:21:13 AM UTC, comment #3: 

Comment #2 was truncated. It was meant to read:

After a bunch of head-scratching I have figured out what's going on. This code


    AC_LANG_PUSH([C++])
    AC_CACHE_CHECK([whether the C++ compiler has <cuchar>],
      [gl_cv_cxxheader_cuchar],
      [
       AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM(
            [[#include <cuchar>]],
            [[]])
         ],
         [gl_cv_cxxheader_cuchar=yes],
         [gl_cv_cxxheader_cuchar=no])
      ])
    AC_LANG_POP([C++])


invokes AC_COMPILE_IFELSE with the current language set to C++.
AC_COMPILE_IFELSE calls AC_LANG_COMPILER_REQUIRE, which AC_REQUIREs AC_LANG_COMPILER(C++), which AC_REQUIREs AC_PROG_CXX.  Because of your earlier "kind of an optional AC_PROG_CXX" code, this causes the AC_LANG machinery to get confused about what the correct setting for $ac_compile is, for checks in between the top of the AC_DEFUN and the AC_LANG_PUSH.

We can't support your code as-is in Autoconf 2.70.  However, I can offer you a simple workaround.  Move all of the "optional AC_PROG_CXX" code into a new AC_DEFUN.  Make the last line of that AC_DEFUN be


m4_provide([AC_PROG_CXX])


(right after the "Determine a good default for CXXFLAGS" if-block).

In my testing, those modifications make your sample configure script work correctly.  They should be harmless with 2.69.

Bruno Haible <haible>
Sun 06 Dec 2020 10:18:42 PM UTC, comment #2: 

After a bunch of head-scratching I have figured out what's going on. This code


    AC_LANG_PUSH([C++])
    AC_CACHE_CHECK([whether the C++ compiler has <cuchar>],
      [gl_cv_cxxheader_cuchar],
      [
       AC_COMPILE_IFELSE(
         [AC_LANG_PROGRAM(
            [[#include <cuchar>]],
            [[]])
         ],
         [gl_cv_cxxheader_cuchar=yes],
         [gl_cv_cxxheader_cuchar=no])
      ])
    AC_LANG_POP([C++])
-verbatim+

invokes AC_COMPILE_IFELSE with the current language set to C++.  AC_COMPILE_IFELSE calls AC_LANG_COMPILER_REQUIRE, which AC_REQUIREs AC_LANG_COMPILER(C++), which AC_REQUIREs AC_PROG_CXX.  Because of your earlier "kind of an optional AC_PROG_CXX" code, this causes the AC_LANG machinery to get confused about what the correct setting for $ac_compile is, for checks in between the top of the AC_DEFUN and the AC_LANG_PUSH.

We can't support your code as-is in Autoconf 2.70.  However, I can offer you a simple workaround.  Move all of the "optional AC_PROG_CXX" code into a new AC_DEFUN.  Make the last line of that AC_DEFUN be

+verbatim+
m4_provide([AC_PROG_CXX])


(right after the "Determine a good default for CXXFLAGS" if-block).

In my testing, those modifications make your sample configure script work correctly.  They should be harmless with 2.69.

Zack Weinberg <zackw>
Group administrator
Tue 18 Aug 2020 04:43:50 PM UTC, comment #1: 

The comment at _AC_LANG_SET in lang.m4 says "... it can introduce differences between the sh-current language and the m4-current-language when m4_require is used."

Maybe there are other situations where the sh-current language and the m4-current-language disagree, and I happened to hit one of them?

Bruno Haible <haible>
Tue 18 Aug 2020 04:38:28 PM UTC, original submission:  

With Autoconf 2.69, a wrong configure file is generated when the configure.ac file (attached) contains
  - an AC_DEFUN,
  - an AC_LANG_PUSH([C++]) / AC_LANG_POP([C++]) pair inside the AC_DEFUN,
  - no AC_LANG_CXX invocation (because my package has optional C++ support; invoking AC_LANG_CXX would make configure abort if no C++ compiler is found, which is not what I want).

How to reproduce:
1. In an empty directory, save the attached configure.ac file.
2. aclocal
3. autoconf
4. touch install-sh
5. configure

The output contains:

checking for library needed for log()...
checking whether the C++ compiler has <cuchar>... no
checking for library needed for pow()... -lm


So, autoconfiguration has correctly determined that use of pow() needs linking with -lm. But it has incorrectly determined that use of log() does not need linking with -lm. Why? The config.log shows it:

configure:4398: checking for library needed for log()
configure:4416: g++ -o conftest -g -O2   conftest.cpp  >&5
configure:4416: $? = 0
...
configure:4480: checking for library needed for pow()
configure:4498: gcc -o conftest -g -O2   conftest.c  >&5
/tmp/ccYm3cJH.o: In function `main':
/tmp/1/conftest.c:19: undefined reference to `log'
collect2: error: ld returned 1 exit status
configure:4498: $? = 1

You can see that it has executed the log() test with the C++ compiler! And since libstdc++ is linked with libm (use 'ldd' to confirm this), the "g++ -o conftest -g -O2   conftest.cpp" command succeeded.

The configure script uses a variable 'ac_compile'. See where it is being set:

$ grep -n '\(ac_compile=\|<math.h>\)' configure
1882:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
2498:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3281:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3287:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3339:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3695:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3719:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3870:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3991:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4012:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4263:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4406:         #include <math.h>
4430:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4464:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4488:         #include <math.h>

You can clearly see that the last assignment to ac_compile before the first <math.h> test is in line 4263 and that it prepares for use of the C++ compiler, not of the C compiler.

The bizarre thing is that when adding an invocation of AC_PROG_CXX (at one of the two places indicated by a comment "This fixes it!") makes the bug disappear. Then we see

$ grep -n '\(ac_compile=\|<math.h>\)' configure
1882:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
2498:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3281:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3287:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3339:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3695:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3719:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3870:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
3991:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4008:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4259:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4406:         #include <math.h>
4430:ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4464:ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
4488:         #include <math.h>

Here the last assignment to ac_compile before the first <math.h> test activates the C compiler. This is good. But as I said above, I do not want to use AC_PROG_CXX.

Bruno Haible <haible>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #49686:  configure.ac added by haible (3KiB - application/octet-stream)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by zackw (Posted a comment)
  • -email is unavailable- added by haible (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2020-12-06 zackw StatusNone Invalid
        Open/ClosedOpen Closed
    2020-08-18 haible Attached File- Added configure.ac, #49686

    Back to the top

    Powered by Savane 3.13-3230.
    Corresponding source code