我设法为大约六个使用相同嵌入式处理器的不同板构建固件和库。由于所有板均使用同一处理器,因此存在重要的通用配置(CC
,CXX
,CPPFLAGS
,CFLAGS
,CXXFLAGS
,{{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
$ ./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
中定义的宏的行为与另一个文件中定义并包含的宏的行为不同?答案 0 :(得分:0)
- 为什么AC_DEFUN尝试扩展AC_PROG_CC?
我无法解释您的错误原因。我确实用您的代码复制了它,但是用我最初尝试的类似代码 not 进行了复制。似乎涉及多种因素,其中AC_PROG_CC
和AC_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宏的行为的确不同于其他地方定义的(不包括)。