All the tests for compilers (AC_PROG_CC, AC_PROG_CXX, AC_PROG_F77) define the output variable EXEEXT based on the output of the compiler, typically to the empty string if Unix and .exe if Win32 or OS/2.
They also define the output variable OBJEXT based on the output of the compiler, after .c files have been excluded, typically to o if Unix, obj if Win32.
If the compiler being used does not produce executables, they fail. If the executables can't be run, and cross-compilation is not enabled, they fail too. Chapter 12, for more on support for cross compiling.
Some compilers exhibit different behaviors.
Autoconf relies on a trick to extract one bit of information from the C compiler: using negative array sizes. For instance the following excerpt of a C source demonstrates how to test whether ints are 4 bytes long:
int main (void) { static int test_array [sizeof (int) == 4 ? 1 : -1]; test_array [0] = 0 return 0; }
To our knowledge, there is a single compiler that does not support this trick: the HP C compilers (the real one, not only the "bundled") on HP-UX 11.00:
$ cc -c -Ae +O2 +Onolimit conftest.c cc: "conftest.c": error 1879: Variable-length arrays cannot \ have static storage.
Autoconf works around this problem by casting sizeof (int) to long before comparing it.
function>AC_CHECK_SIZEOF/function> (type, [unused], [includes = default-includes]) Define SIZEOF_type (the section called “Standard Symbols”) to be the size in bytes of type. If type is unknown, it gets a size of 0. If no includes are specified, the default includes are used (the section called “Default Includes ”). If you provide include, make sure to include stdio.h which is required for this macro to run.
This macro now works even when cross-compiling. The unused argument was used when cross-compiling.
For example, the call
AC_CHECK_SIZEOF(int *)
defines SIZEOF_INT_P to be 8 on DEC Alpha AXP systems.
function>AC_PROG_CC/function> ([compiler-search-list]) Determine a C compiler to use. If CC is not already set in the environment, check for gcc and cc, then for other C compilers. Set output variable CC to the name of the compiler found.
This macro may, however, be invoked with an optional first argument which, if specified, must be a space separated list of C compilers to search for. This just gives the user an opportunity to specify an alternative search list for the C compiler. For example, if you didn't like the default order, then you could invoke AC_PROG_CC like this:
AC_PROG_CC(cl egcs gcc cc)
If the C compiler is not in ansi C mode by default, try to add an option to output variable CC to make it so. This macro tries various options that select ansi C on some system or another. It considers the compiler to be in ansi C mode if it handles function prototypes correctly.
After calling this macro you can check whether the C compiler has been set to accept ansi C; if not, the shell variable ac_cv_prog_cc_stdc is set to no. If you wrote your source code in ansi C, you can make an un-ansified copy of it by using the program ansi2knr, which comes with Automake. See also under AC_C_PROTOTYPES below.
If using the gnu C compiler, set shell variable GCC to yes. If output variable CFLAGS was not already set, set it to -g -O2 for the gnu C compiler (-O2 on systems where GCC does not accept -g), or -g for other compilers.
function>AC_PROG_CC_C_O/function> If the C compiler does not accept the -c and -o options simultaneously, define NO_MINUS_C_MINUS_O. This macro actually tests both the compiler found by AC_PROG_CC, and, if different, the first cc in the path. The test fails if one fails. This macro was created for gnu Make to choose the default C compilation rule.
function>AC_PROG_CPP/function> Set output variable CPP to a command that runs the C preprocessor. If $CC -E doesn't work, /lib/cpp is used. It is only portable to run CPP on files with a .c extension.
If the current language is C (the section called “Language Choice”), many of the specific test macros use the value of CPP indirectly by calling AC_TRY_CPP, AC_CHECK_HEADER, AC_EGREP_HEADER, or AC_EGREP_CPP.
Some preprocessors don't indicate missing include files by the error status. For such preprocessors an internal variable is set that causes other macros to check the standard error from the preprocessor and consider the test failed if any warnings have been reported.
The following macros check for C compiler or machine architecture features. To check for characteristics not listed here, use AC_TRY_COMPILE (the section called “Examining Syntax”) or AC_TRY_RUN (the section called “Checking Run Time Behavior”)
function>AC_C_BIGENDIAN/function> ([action-if-true], [action-if-false], [action-if-unknown]) If words are stored with the most significant byte first (like Motorola and SPARC CPUs), execute action-if-true. If words are stored with the less significant byte first (like Intel and VAX CPUs), execute action-if-false.
This macro runs a test-case if endianness cannot be determined from the system header files. When cross-compiling the test-case is not run but grep'ed for some magic values. action-if-unknown is executed if the latter case fails to determine the byte sex of the host system.
The default for action-if-true is to define WORDS_BIGENDIAN. The default for action-if-false is to do nothing. And finally, the default for action-if-unknown is to abort configure and tell the installer which variable he should preset to bypass this test.
function>AC_C_CONST/function> If the C compiler does not fully support the ansi C qualifier const, define const to be empty. Some C compilers that do not define __STDC__ do support const; some compilers that define __STDC__ do not completely support const. Programs can simply use const as if every C compiler supported it; for those that don't, the Makefile or configuration header file will define it as empty.
Occasionally installers use a C++ compiler to compile C code, typically because they lack a C compiler. This causes problems with const, because C and C++ treat const differently. For example:
const int foo;
is valid in C but not in C++. These differences unfortunately cannot be papered over by defining const to be empty.
If autoconf detects this situation, it leaves const alone, as this generally yields better results in practice. However, using a C++ compiler to compile C code is not recommended or supported, and installers who run into trouble in this area should get a C compiler like GCC to compile their C code.
function>AC_C_VOLATILE/function> If the C compiler does not understand the keyword volatile, define volatile to be empty. Programs can simply use volatile as if every C compiler supported it; for those that do not, the Makefile or configuration header will define it as empty.
If the correctness of your program depends on the semantics of volatile, simply defining it to be empty does, in a sense, break your code. However, given that the compiler does not support volatile, you are at its mercy anyway. At least your program will compile, when it wouldn't before.
In general, the volatile keyword is a feature of ansi C, so you might expect that volatile is available only when __STDC__ is defined. However, Ultrix 4.3's native compiler does support volatile, but does not defined __STDC__.
function>AC_C_INLINE/function> If the C compiler supports the keyword inline, do nothing. Otherwise define inline to __inline__ or __inline if it accepts one of those, otherwise define inline to be empty.
function>AC_C_CHAR_UNSIGNED/function> If the C type char is unsigned, define __CHAR_UNSIGNED__, unless the C compiler predefines it.
function>AC_C_LONG_DOUBLE/function> If the C compiler supports a working long double type with more range or precision than the double type, define HAVE_LONG_DOUBLE.
function>AC_C_STRINGIZE/function> If the C preprocessor supports the stringizing operator, define HAVE_STRINGIZE. The stringizing operator is # and is found in macros such as this:
#define x(y) #y
function>AC_C_PROTOTYPES/function> If function prototypes are understood by the compiler (as determined by AC_PROG_CC), define PROTOTYPES and __PROTOTYPES. In the case the compiler does not handle prototypes, you should use ansi2knr, which comes with the Automake distribution, to unprotoize function definitions. For function prototypes, you should first define PARAMS:
#ifndef PARAMS # if PROTOTYPES # define PARAMS(protos) protos # else /* no PROTOTYPES */ # define PARAMS(protos) () # endif /* no PROTOTYPES */ #endif
then use it this way:
size_t my_strlen PARAMS ((const char *));
This macro also defines __PROTOTYPES; this is for the benefit of header files that cannot use macros that infringe on user name space.
function>AC_PROG_GCC_TRADITIONAL/function> Add -traditional to output variable CC if using the gnu C compiler and ioctl does not work properly without -traditional. That usually happens when the fixed header files have not been installed on an old system. Since recent versions of the gnu C compiler fix the header files automatically when installed, this is becoming a less prevalent problem.
function>AC_PROG_CXX/function> ([compiler-search-list]) Determine a C++ compiler to use. Check if the environment variable CXX or CCC (in that order) is set; if so, then set output variable CXX to its value.
Otherwise, if the macro is invoked without an argument, then search for a C++ compiler under the likely names (first g++ and c++ then other names). If none of those checks succeed, then as a last resort set CXX to g++.
This macro may, however, be invoked with an optional first argument which, if specified, must be a space separated list of C++ compilers to search for. This just gives the user an opportunity to specify an alternative search list for the C++ compiler. For example, if you didn't like the default order, then you could invoke AC_PROG_CXX like this:
AC_PROG_CXX(cl KCC CC cxx cc++ xlC aCC c++ g++ egcs gcc)
If using the gnu C++ compiler, set shell variable GXX to yes. If output variable CXXFLAGS was not already set, set it to -g -O2 for the gnu C++ compiler (-O2 on systems where G++ does not accept -g), or -g for other compilers.
function>AC_PROG_CXXCPP/function> Set output variable CXXCPP to a command that runs the C++ preprocessor. If $CXX -E doesn't work, /lib/cpp is used. It is only portable to run CXXCPP on files with a .c, .C, or .cc extension.
If the current language is C++ (the section called “Language Choice”), many of the specific test macros use the value of CXXCPP indirectly by calling AC_TRY_CPP, AC_CHECK_HEADER, AC_EGREP_HEADER, or AC_EGREP_CPP.
Some preprocessors don't indicate missing include files by the error status. For such preprocessors an internal variable is set that causes other macros to check the standard error from the preprocessor and consider the test failed if any warnings have been reported. However, it is not known whether such broken preprocessors exist for C++.
function>AC_PROG_F77/function> ([compiler-search-list]) Determine a Fortran 77 compiler to use. If F77 is not already set in the environment, then check for g77 and f77, and then some other names. Set the output variable F77 to the name of the compiler found.
This macro may, however, be invoked with an optional first argument which, if specified, must be a space separated list of Fortran 77 compilers to search for. This just gives the user an opportunity to specify an alternative search list for the Fortran 77 compiler. For example, if you didn't like the default order, then you could invoke AC_PROG_F77 like this:
AC_PROG_F77(fl32 f77 fort77 xlf cf77 g77 f90 xlf90)
If using g77 (the gnu Fortran 77 compiler), then AC_PROG_F77 will set the shell variable G77 to yes. If the output variable FFLAGS was not already set in the environment, then set it to -g -02 for g77 (or -O2 where g77 does not accept -g). Otherwise, set FFLAGS to -g for all other Fortran 77 compilers.
function>AC_PROG_F77_C_O/function> Test if the Fortran 77 compiler accepts the options -c and -o simultaneously, and define F77_NO_MINUS_C_MINUS_O if it does not.
The following macros check for Fortran 77 compiler characteristics. To check for characteristics not listed here, use AC_TRY_COMPILE (the section called “Examining Syntax”) or AC_TRY_RUN (the section called “Checking Run Time Behavior”), making sure to first set the current language to Fortran 77 AC_LANG(Fortran 77) (the section called “Language Choice”).
function>AC_F77_LIBRARY_LDFLAGS/function> Determine the linker flags (e.g. -L and -l) for the Fortran 77 intrinsic and run-time libraries that are required to successfully link a Fortran 77 program or shared library. The output variable FLIBS is set to these flags.
This macro is intended to be used in those situations when it is necessary to mix, e.g. C++ and Fortran 77 source code into a single program or shared library ().
For example, if object files from a C++ and Fortran 77 compiler must be linked together, then the C++ compiler/linker must be used for linking (since special C++-ish things need to happen at link time like calling global constructors, instantiating templates, enabling exception support, etc.).
However, the Fortran 77 intrinsic and run-time libraries must be linked in as well, but the C++ compiler/linker doesn't know by default how to add these Fortran 77 libraries. Hence, the macro AC_F77_LIBRARY_LDFLAGS was created to determine these Fortran 77 libraries.
The macro AC_F77_DUMMY_MAIN or AC_F77_MAIN will probably also be necessary to link C/C++ with Fortran; see below.
function>AC_F77_DUMMY_MAIN/function> ([action-if-found], [action-if-not-found]) With many compilers, the Fortran libraries detected by AC_F77_LIBRARY_LDFLAGS provide their own main entry function that initializes things like Fortran I/O, and which then calls a user-provided entry function named e.g. MAIN__ to run the user's program. The AC_F77_DUMMY_MAIN or AC_F77_MAIN macro figures out how to deal with this interaction.
When using Fortran for purely numerical functions (no I/O, etcetera), users often prefer to provide their own main and skip the Fortran library initializations. In this case, however, one may still need to provide a dummy MAIN__ routine in order to prevent linking errors on some systems. AC_F77_DUMMY_MAIN detects whether any such routine is required for linking, and what its name is; the shell variable F77_DUMMY_MAIN holds this name, unknown when no solution was found, and none when no such dummy main is needed.
By default, action-if-found defines F77_DUMMY_MAIN to the name of this routine (e.g. MAIN__) if it is required. [action-if-not-found] defaults to exiting with an error.
In order to link with Fortran routines, the user's C/C++ program should then include the following code to define the dummy main if it is needed:
#ifdef F77_DUMMY_MAIN # ifdef __cplusplus extern "C" # endif int F77_DUMMY_MAIN() { return 1; } #endif
Note that AC_F77_DUMMY_MAIN is called automatically from AC_F77_WRAPPERS; there is generally no need to call it explicitly unless one wants to change the default actions.
function>AC_F77_MAIN/function> As discussed above for AC_F77_DUMMY_MAIN, many Fortran libraries allow you to provide an entry point called e.g. MAIN__ instead of the usual main, which is then called by a main function in the Fortran libraries that initializes things like Fortran I/O. The AC_F77_MAIN macro detects whether it is possible to utilize such an alternate main function, and defines F77_MAIN to the name of the function. (If no alternate main function name is found, F77_MAIN is simply defined to main.)
Thus, when calling Fortran routines from C that perform things like I/O, one should use this macro and name the "main" function F77_MAIN instead of main.
function>AC_F77_WRAPPERS/function> Defines C macros F77_FUNC(name,NAME) and F77_FUNC_(name,NAME) to properly mangle the names of C/C++ identifiers, and identifiers with underscores, respectively, so that they match the name-mangling scheme used by the Fortran 77 compiler.
Fortran 77 is case-insensitive, and in order to achieve this the Fortran 77 compiler converts all identifiers into a canonical case and format. To call a Fortran 77 subroutine from C or to write a C function that is callable from Fortran 77, the C program must explicitly use identifiers in the format expected by the Fortran 77 compiler. In order to do this, one simply wraps all C identifiers in one of the macros provided by AC_F77_WRAPPERS. For example, suppose you have the following Fortran 77 subroutine:
subroutine foobar(x,y) double precision x, y y = 3.14159 * x return end
You would then declare its prototype in C or C++ as:
#define FOOBAR_F77 F77_FUNC(foobar,FOOBAR) #ifdef __cplusplus extern "C" /* prevent C++ name mangling */ #endif void FOOBAR_F77(double *x, double *y);
Note that we pass both the lowercase and uppercase versions of the function name to F77_FUNC so that it can select the right one. Note also that all parameters to Fortran 77 routines are passed as pointers ().
Although Autoconf tries to be intelligent about detecting the name-mangling scheme of the Fortran 77 compiler, there may be Fortran 77 compilers that it doesn't support yet. In this case, the above code will generate a compile-time error, but some other behavior (e.g. disabling Fortran-related features) can be induced by checking whether the F77_FUNC macro is defined.
Now, to call that routine from a C program, we would do something like:
{ double x = 2.7183, y; FOOBAR_F77(x, y); }
If the Fortran 77 identifier contains an underscore (e.g. foo_bar), you should use F77_FUNC_ instead of F77_FUNC (with the same arguments). This is because some Fortran 77 compilers mangle names differently if they contain an underscore.
function>AC_F77_FUNC/function> (name, [shellvar]) Given an identifier name, set the shell variable shellvar to hold the mangled version name according to the rules of the Fortran 77 linker (see also AC_F77_WRAPPERS). shellvar is optional; if it is not supplied, the shell variable will be simply name. The purpose of this macro is to give the caller a way to access the name-mangling information other than through the C preprocessor as above; for example, to call Fortran routines from some language other than C/C++.