We use GNUmakefile as our primary build system. The makefile performs feature tests using test programs in source files:
$ ls TestPrograms/
dump2def.cxx test_arm_sm4.cxx test_x86_avx.cxx
test_32bit.cxx test_cxx.cxx test_x86_avx2.cxx
test_64bit.cxx test_mixed_asm.cxx test_x86_avx512.cxx
...
A test program is what one would expect:
$ cat test_cxx.cxx
#include <string>
int main(int argc, char* argv[])
{
unsigned int x=0;
return x;
}
We support Autotools for distros like Debian and Fedora. We want Autotools to use the test programs like GNUmakefile and CMake. Autools documentation on AC_COMPILE_IFELSE
is here, but it is pathetic as usual. It does not discuss the topic or provide examples.
Taking stabs in the dark:
CXXFLAGS="-msse2"
AC_MSG_CHECKING([if $CXXNAME supports $CXXFLAGS and Foo Bar])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([TestPrograms/test_x86_sse2.cxx])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
Results in:
checking if g++ supports -msse2 and Foo Bar... no
And the same result with cat
'ing the file into a string:
CXXFLAGS="-msse2"
AC_MSG_CHECKING([if $CXXNAME supports $CXXFLAGS and Foo Bar])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM(`cat TestPrograms/test_x86_sse2.cxx`)],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
The result is incorrect on a Skylake machine. SSE2 is part of the core instruction set and always available:
$ g++ -msse2 TestPrograms/test_x86_sse2.cxx
$
How do we tell Autoconf to compile the test file?
Autools documentation on
AC_COMPILE_IFELSE
[...] is pathetic as usual. It does not discuss the topic or provide examples.
Although that individual page does not provide full details, it is part of a larger manual that provides more detail and some relevant examples in nearby sections. Even that page itself suggests AC_LANG_PROGRAM
as an appropriate means to produce the input
parameter for that macro, however, and the documentation for that macro gives a reasonable idea of the general form it produces -- actual source code for a program, not a file name.
When it comes to taking stabs at an answer, I suggest not being willfully in the dark. Even if you do not find the documentation adequate, at least configure
's log file (config.log
) should contain a lot of information about what, exactly, failed, and how. In the event of a failure, it will show you the complete source of the test program it used, the commands it executed to actually perform the test, and any diagnostics emitted.
For example, using a configure script derived from this configure.ac
inspired by your examples ...
AC_INIT([test_test], [0.0.1])
AC_CONFIG_SRCDIR([test_src/test_cxx.cxx])
AC_PROG_CXX
CXXFLAGS="-msse2"
AC_MSG_CHECKING([if $CXXNAME supports $CXXFLAGS and Foo Bar])
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([`cat test_src/test_cxx.cxx`])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
AC_OUTPUT
... I get a failure result with this relevant output in the log:
configure:2891: gcc -o conftest -g -O2 conftest.c >&5 conftest.c:9:18: fatal error: string: No such file or directory #include <string> ^ compilation terminated. configure:2891: $? = 1 configure: failed program was: | /* confdefs.h */ | #define PACKAGE_NAME "test_test" | #define PACKAGE_TARNAME "test_test" | #define PACKAGE_VERSION "0.0.1" | #define PACKAGE_STRING "test_test 0.0.1" | #define PACKAGE_BUGREPORT "" | #define PACKAGE_URL "" | /* end confdefs.h. */ | #include <string> | int main(int argc, char* argv[]) | { | unsigned int x=0; | return x; | } | int | main () | { | | ; | return 0; | } configure:2895: result: no
This shows that source code is indeed being read from the external file, and it also reveals two key problems:
AC_LANG_PROGRAM
is providing more than you want in this case (consistent with its documentation). In fact, you don't need it at all if you are providing complete source for the test program.
The test program is being compiled and linked as a C program, but its source is C++. This default is documented in the manual.
Issue (1) can be resolved by just feeding the source directly to AC_LINK_IFELSE
, without wrapping it via AC_LANG_PROGRAM
, but Autoconf will warn in that case about not seeing AC_LANG_SOURCE
. A reasonably comfortable solution to that is to use AC_LANG_SOURCE
directly, instead of AC_LANG_PROGRAM
. That will add some additional #defines
to the provided source, however, which might not suit you. If you don't want that, then I think it will be safe to ignore the warnings in this case.
Issue (2) can be resolved by using the AC_LANG
macro to tell Autoconf that test should be performed using the C++ compiler and the relevant Autotools variables for C++ flags.
Thus, if I update my configure.ac
to
AC_INIT([test_test], [0.0.1])
AC_CONFIG_SRCDIR([test_src/test_cxx.cxx])
AC_PROG_CXX
AC_LANG([C++])
CXXFLAGS="-msse2"
AC_MSG_CHECKING([if $CXXNAME supports $CXXFLAGS and Foo Bar])
AC_LINK_IFELSE(
[AC_LANG_SOURCE([`cat test_src/test_cxx.cxx`])],
[AC_MSG_RESULT([yes])],
[AC_MSG_RESULT([no])]
)
AC_OUTPUT
then my configure run succeeds, and I see in the log that the compilation command it executed, successfully, was
configure:2296: g++ -o conftest -msse2 conftest.cpp >&5
. That is, it compiled using the selected C++ compiler, using flags as specified in CXXFLAGS
, and naming the test source file appropriately for compilation as C++.