如何在常见的Autoconf宏中包含宏?

时间:2019-02-04 00:14:25

标签: autotools autoconf

背景

我设法为大约六个使用相同嵌入式处理器的不同板构建固件和库。由于所有板均使用同一处理器,因此存在重要的通用配置(CCCXXCPPFLAGSCFLAGSCXXFLAGS,{{1} }等)和食谱。对于固件,我使用自定义makefile,这些自定义makefile包含定义所有通用配置和配方的通用配置文件。为了简化在开发人员计算机上安装库和标头的过程,我对库使用了GNU Autotools。但是,自定义makefile和GNU Autotools文件之间存在大量重复的配置,因此我将固件迁移到GNU Autotools。

客观

我想尽可能减少样板。董事会的LDFLAGS可能如下所示:

configure.ac

库的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 可能如下所示:

configure.ac

这些文件之间有很多通用配置。我想在本地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 目录中有一个文件,该文件定义了具有常见Autoconf宏的宏:

include

然后,我想将第一个示例简化为以下内容:

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])])

除了简单之外,它还有许多优点。例如,如果MPPT开发人员将C ++引入当前完全用C语言编写的固件中,那么他们(或我)就不必更新其AC_INIT([mppt], [0.1.0]) TIVASDK AC_OUTPUT 。如果要对工具链进行更改,则只需将更新推送到一个存储库即可,而无需进行将近10个更新。

问题

Autoconf无法像我期望的那样理解宏。有两种不同的故障机制。

configure.ac

请参见this answer

我有一个用于测试的骨架项目。非常简单的expanded before it was required指定Makefile.am

ACLOCAL_AMFLAGS

ACLOCAL_AMFLAGS = -I "$TIVASDK_HOME"/include noinst_PROGRAMS = skel.axf skel_axf_SOURCES = \ src/main.cpp \ src/abort.cpp TIVASDK_HOME中定义。

请参见this question。其~/.profile使用宏:

configure.ac

它的AC_INIT([skel], [0.1.0]) m4_define([TIVASDK_HOME], [esyscmd([printf "$TIVASDK_HOME"])]) AC_CONFIG_MACRO_DIR(TIVASDK_HOME[/include]) TIVASDK AC_OUTPUT autogen.sh中树外构建:

build

运行#!/bin/sh autoreconf -vfi .. && \ ../configure --prefix="$TIVASDK_HOME" --host=arm-none-eabi 得到以下结果:

autogen.sh

$ ./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由于某种原因扩展了一些Autoconf宏。我将AC_DEFUN替换为AC_DEFUN

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])]) 得到以下结果:

autogen.sh

$ ./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 似乎根本没有扩展。我尝试将TIVASDK替换为m4_define无济于事。

最小的工作示例

仅将宏定义放在define中即可解决此问题:

configure.ac

运行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 得到以下结果:

autogen.sh

TL; DR

  • 为什么$ ./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 会尝试扩展AC_DEFUN
  • 为什么AC_PROG_CC定义的宏似乎无法扩展?
  • 为什么m4_define中定义的宏的行为与另一个文件中定义并包含的宏的行为不同?

1 个答案:

答案 0 :(得分:0)

  
      
  • 为什么AC_DEFUN尝试扩展AC_PROG_CC?
  •   

我无法解释您的错误原因。我确实用您的代码复制了它,但是用我最初尝试的类似代码 not 进行了复制。似乎涉及多种因素,其中AC_PROG_CCAC_PROG_CXX并存。

但是,从您的初次尝试开始,出现在“问题”标题上方的问题中,并根据错误消息所指向的在线Autoconf手册页上的信息,我可以简单地通过调用{ {1}}通过AC_PROG_CC间接而非直接:

AC_REQUIRE

顺便说一句,我发现,至少在骨架项目中,没有理由定义或使用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 # ... 宏。 TIVASDK_HOME中定义的ACLOCAL_AMFLAGS显然足够。

我不太喜欢使用环境变量来定义所需宏include目录的位置,并且该示例并未向我说明为什么这样做很有用,但是如果您继续使用它,那么我会鼓励您

  • 使用Makefile.in记录该变量并将其变贵,并且
  • 确实会删除相同名称的宏。
  
      
  • 为什么m4_define定义的宏似乎不扩展?
  •   

我认为这是因为外部宏文件未直接使用,而是由AC_ARG_VAR处理以生成文件aclocal,而该文件已包含在内。我想您会发现出现在任何Autoconf宏定义范围之外的直接aclocal.m4并没有被复制。

  
      
  • 为什么configure.ac中定义的宏的行为与另一个文件中定义并包含的宏的行为不同?
  •   

我认为没有。但是m4_define中定义的M4宏的行为的确不同于其他地方定义的(包括)。