Reputation: 65
AC_DEFUN
try to expand AC_PROG_CC
?m4_define
seem not to expand?configure.ac
behave differently than a macro defined in another file and included?I manage building the firmware and libraries for about half a dozen different boards that all use the same embedded processor. Because all of the boards use the same processor, there is significant common configuration (CC
, CXX
, CPPFLAGS
, CFLAGS
, CXXFLAGS
, LDFLAGS
, etc.) and recipes. For the firmware, I use custom makefiles that include a common configuration file that defines all of the common configuration and recipes. To simplify installing libraries and headers on developers' computers, I use use the GNU Autotools for the libraries. However, there is significant duplicate configuration between the custom makefiles and the GNU Autotools files, so I am migrating the firmware to the GNU Autotools.
I want to have as little boilerplate as possible. A configure.ac
for a board might look like the following:
AC_INIT([mppt], [0.1.0])
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
AC_PROG_CC
AM_PROG_CC_C_O
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
A configure.ac
for a library might look like the following:
AC_INIT([gcc-arm-none-eabi-samples], [4.7+])
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CXX='arm-none-eabi-g++ -specs=nosys.specs'}
AC_PROG_CXX
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
AM_PROG_AS
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_RANLIB
AC_PROG_CXX_C_O
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
There is a lot of common configuration between these files. I would like to have a single file in a local include
directory that defines a macro with common Autoconf macros:
AC_DEFUN([TIVASDK],
[AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
AC_PROG_CC
: ${CXX='arm-none-eabi-g++ -specs=nosys.specs'}
AC_PROG_CXX
AM_PROG_AS
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_RANLIB
AM_PROG_CC_C_O
AC_PROG_CXX_C_O
AC_CONFIG_FILES([Makefile])])
Then, I would like to be able to simplify the first example to the following:
AC_INIT([mppt], [0.1.0])
TIVASDK
AC_OUTPUT
This has a number of advantages besides simplicity. If, for example, the MPPT developers were to introduce C++ into firmware currently written entirely in C, then they or I would not have to update their configure.ac
. If I were to make a change to the toolchain, I would only have to push an update to one repository, not to almost ten.
Autoconf does not understand the macro as I would expect. There are a couple different failure mechanisms.
expanded before it was required
See this answer.
I have a skeleton project that I am using for testing. Its very simple Makefile.am
specifies ACLOCAL_AMFLAGS
:
ACLOCAL_AMFLAGS = -I "$TIVASDK_HOME"/include
noinst_PROGRAMS = skel.axf
skel_axf_SOURCES = \
src/main.cpp \
src/abort.cpp
TIVASDK_HOME
is defined in ~/.profile
.
See this question. Its configure.ac
uses the macro:
AC_INIT([skel], [0.1.0])
m4_define([TIVASDK_HOME], [esyscmd([printf "$TIVASDK_HOME"])])
AC_CONFIG_MACRO_DIR(TIVASDK_HOME[/include])
TIVASDK
AC_OUTPUT
Its autogen.sh
builds out-of-tree in build
:
#!/bin/sh
autoreconf -vfi .. && \
../configure --prefix="$TIVASDK_HOME" --host=arm-none-eabi
Running autogen.sh
yields the following:
$ ./autogen.sh
autoreconf: Entering directory `..'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I /home/matthew/github.gatech.edu/GTSR/tiva-sdk/include
configure.ac:4: warning: AC_REQUIRE: `AC_PROG_CC' was expanded before it was required
configure.ac:4: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
/home/matthew/github.gatech.edu/GTSR/tiva-sdk/include/tivasdk.m4:1: TIVASDK is expanded from...
configure.ac:4: the top level
configure.ac:4: warning: AC_REQUIRE: `AC_PROG_CC' was expanded before it was required
configure.ac:4: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
/home/matthew/github.gatech.edu/GTSR/tiva-sdk/include/tivasdk.m4:1: TIVASDK is expanded from...
configure.ac:4: the top level
autoreconf: configure.ac: tracing
configure.ac:4: warning: AC_REQUIRE: `AC_PROG_CC' was expanded before it was required
configure.ac:4: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
aclocal.m4:1173: TIVASDK is expanded from...
configure.ac:4: the top level
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
configure.ac:4: warning: AC_REQUIRE: `AC_PROG_CC' was expanded before it was required
configure.ac:4: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
aclocal.m4:1173: TIVASDK is expanded from...
configure.ac:4: the top level
autoreconf: configure.ac: not using Autoheader
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:4: warning: AC_REQUIRE: `AC_PROG_CC' was expanded before it was required
configure.ac:4: http://www.gnu.org/software/autoconf/manual/autoconf.html#Expanded-Before-Required
aclocal.m4:1173: TIVASDK is expanded from...
configure.ac:4: the top level
configure.ac:4: installing './compile'
configure.ac:4: installing './install-sh'
configure.ac:4: installing './missing'
Makefile.am: installing './depcomp'
autoreconf: Leaving directory `..'
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-none-eabi-strip... arm-none-eabi-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for style of include used by make... GNU
checking for arm-none-eabi-gcc... arm-none-eabi-gcc
checking whether we are using the GNU C compiler... no
checking whether arm-none-eabi-gcc accepts -g... no
checking for arm-none-eabi-gcc option to accept ISO C89... unsupported
checking whether arm-none-eabi-gcc understands -c and -o together... yes
checking dependency style of arm-none-eabi-gcc... gcc3
checking for arm-none-eabi-gcc... (cached) arm-none-eabi-gcc
checking whether the C compiler works... no
configure: error: in `/home/matthew/gatech.edu/sp2019/vip4602/tmp/skel/build':
configure: error: C compiler cannot create executables
See `config.log' for more details
command not found
I had a hunch that AC_DEFUN
expands some Autoconf macros for some reason. I replaced the AC_DEFUN
with m4_define
:
m4_define([TIVASDK],
[AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
AC_PROG_CC
: ${CXX='arm-none-eabi-g++ -specs=nosys.specs'}
AC_PROG_CXX
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_CXX_C_O
AC_CONFIG_FILES([Makefile])])
Running autogen.sh
yields the following:
$ ./autogen.sh
autoreconf: Entering directory `..'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I /home/matthew/github.gatech.edu/GTSR/tiva-sdk/include
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
autoreconf: configure.ac: not using Autoheader
autoreconf: configure.ac: not using Automake
autoreconf: Leaving directory `..'
../configure: line 1678: TIVASDK: command not found
configure: creating ./config.status
It seems that TIVASDK
is not expanding at all. I tried replacing m4_define
with define
to no avail.
Simply placing the macro definition in configure.ac
fixes the issue:
m4_define([TIVASDK],
[AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
AC_PROG_CC
: ${CXX='arm-none-eabi-g++ -specs=nosys.specs'}
AC_PROG_CXX
AM_PROG_AS
AM_PROG_CC_C_O
AC_PROG_CXX_C_O
AC_CONFIG_FILES([Makefile])])
AC_INIT([skel], [0.1.0])
TIVASDK
AC_OUTPUT
Running autogen.sh
yields the following:
$ ./autogen.sh
autoreconf: Entering directory `..'
autoreconf: configure.ac: not using Gettext
autoreconf: running: aclocal --force -I /home/matthew/github.gatech.edu/GTSR/tiva-sdk/include
autoreconf: configure.ac: tracing
autoreconf: configure.ac: not using Libtool
autoreconf: running: /usr/bin/autoconf --force
autoreconf: configure.ac: not using Autoheader
autoreconf: running: automake --add-missing --copy --force-missing
configure.ac:12: installing './compile'
configure.ac:12: installing './install-sh'
configure.ac:12: installing './missing'
Makefile.am: installing './depcomp'
autoreconf: Leaving directory `..'
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for arm-none-eabi-strip... arm-none-eabi-strip
checking for a thread-safe mkdir -p... /bin/mkdir -p
checking for gawk... gawk
checking whether make sets $(MAKE)... yes
checking whether make supports nested variables... yes
checking for arm-none-eabi-gcc... arm-none-eabi-gcc -specs=nosys.specs
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... yes
checking for suffix of object files... o
checking whether we are using the GNU C compiler... yes
checking whether arm-none-eabi-gcc -specs=nosys.specs accepts -g... yes
checking for arm-none-eabi-gcc -specs=nosys.specs option to accept ISO C89... none needed
checking whether arm-none-eabi-gcc -specs=nosys.specs understands -c and -o together... yes
checking for style of include used by make... GNU
checking dependency style of arm-none-eabi-gcc -specs=nosys.specs... gcc3
checking whether we are using the GNU C++ compiler... yes
checking whether arm-none-eabi-g++ -specs=nosys.specs accepts -g... yes
checking dependency style of arm-none-eabi-g++ -specs=nosys.specs... gcc3
checking dependency style of arm-none-eabi-gcc -specs=nosys.specs... gcc3
checking whether arm-none-eabi-g++ -specs=nosys.specs understands -c and -o together... yes
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: executing depfiles commands
Upvotes: 2
Views: 1207
Reputation: 181724
- Why does AC_DEFUN try to expand AC_PROG_CC?
I cannot explain the reason for your error. I did replicate it with your code, but not with similar code that I initially tried. There seems to be a combination of factors involved, among them the presence of both AC_PROG_CC
and AC_PROG_CXX
together.
However, starting with your initial attempt, presented in the question above the "Problem" heading, and based on information from the online Autoconf manual page to which the error message refers, I was able to solve the problem simply by calling AC_PROG_CC
indirectly through AC_REQUIRE
instead of directly:
AC_DEFUN([TIVASDK], [
AM_INIT_AUTOMAKE([foreign subdir-objects -Wall -Werror])
: ${CC='arm-none-eabi-gcc -specs=nosys.specs'}
# HERE:
AC_REQUIRE([AC_PROG_CC])
: ${CXX='arm-none-eabi-g++ -specs=nosys.specs'}
AC_PROG_CXX
# ...
I find, by the way, that there is no reason, at least in the skeleton project, to define or use the TIVASDK_HOME
macro. The ACLOCAL_AMFLAGS
defined in Makefile.in
apparently suffice.
I'm not much enamored by the idea of using an environment variable to define the location of the wanted macro include directory, and the example does not make it clear to me why that's useful, but if you continue with that then I encourage you to
AC_ARG_VAR
to document that variable and make it precious, AND
- Why does a macro defined by m4_define seem not to expand?
I presume that this would be because external macro files are not used directly, but rather processed by aclocal
to generate file aclocal.m4
, which is what gets included. I think you'll find that the direct m4_define
, appearing outside the scope of any Autoconf macro definition, did not get copied over.
- Why does a macro defined in configure.ac behave differently than a macro defined in another file and included?
I don't think it does. But an M4 macro defined in configure.ac
certainly does behave differently than one defined elsewhere and not included.
Upvotes: 1