我没有看到任何与GNU autoconf/automake构建有关的问题,但我希望至少有一些人熟悉它.开始:
我有一个项目(我称之为myproject),包括另一个项目(供应商).供应商项目是由其他人维护的独立项目.包含这样的项目是相当简单的,但在这种情况下有一个小问题:每个项目都生成自己的config.h文件,每个文件定义标准宏,如PACKAGE,VERSION等.这意味着,在构建期间,当供应商正在构建中,我收到很多这样的错误:
... warning: "VERSION" redefined
... warning: this is the location of the previous definition
... warning: "PACKAGE" redefined
... warning: this is the location of the previous definition
Run Code Online (Sandbox Code Playgroud)
这些只是警告,暂时至少,但我想摆脱它们.我已经能够通过Google搜索获得的唯一相关信息是automake邮件列表中的这个主题,这不是很多帮助.还有其他人有更好的想法吗?
是否可以在使用automake/libtool的项目中使用gcc预编译头文件?
添加新的make规则来构建预编译头文件并不困难.问题是你还必须添加由libtool和AFAIK引入的编译标志,它无法处理标头输入文件.
你怎么能这样做?
我有一个大型的autoconf/automake项目,使用AC_CONFIG_SUBDIRS分解成组件.有没有办法让autoconf/configure运行得更快?也许并行进行子目录,或缓存可重用的结果?
我可以轻松地编写一个可以并行构建组件的构建脚本,但更愿意不添加构建结构维护的辅助点.
在Makefile.in我看到变量定义,其中外部变量名称包含在两个@符号之间
# @configure_input@
package = @PACKAGE_NAME@
Run Code Online (Sandbox Code Playgroud)
那些外部变量来自哪里?另外,我在GNU手册中找不到两个@符号之间完全包含变量的含义是什么意思?它是Makefile.in特有的东西吗?
谢谢.
我有一个autotools项目,可以在Mac上编译得很好,但在Linux(Ubuntu 12.04.1 LTS)下,命令行传递给gcc库相对于目标文件乱序.例如,autotools生成以下命令来编译我的代码,一个名为test.c二进制文件的文件命名为test:
gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -lglib-2.0 -o test test-test.o
Run Code Online (Sandbox Code Playgroud)
此命令行失败:
/home/user/glib-test/test.c:4: undefined reference to `g_malloc`
/home/user/glib-test/test.c:5: undefined reference to `g_free`
Run Code Online (Sandbox Code Playgroud)
但是,如果我从命令行编译并将其切换,以便库引用位于目标文件之后,它可以正常工作:
gcc -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -g -O2 -o test test-test.o -lglib-2.0
Run Code Online (Sandbox Code Playgroud)
挑战在于我无法弄清楚如何强制Autotools以正确的顺序生成命令行.为了清楚起见,我在这里重现了简单的测试用例.首先是configure.ac:
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
AC_INIT(glib-test, 1.0)
AC_CANONICAL_SYSTEM
AM_INIT_AUTOMAKE()
AC_PROG_CC
AM_PROG_CC_C_O
PKG_CHECK_MODULES(GLIB, glib-2.0 > 2.0)
AC_CONFIG_FILES(Makefile)
AC_OUTPUT
Run Code Online (Sandbox Code Playgroud)
接下来很简单Makefile.am:
CFLAGS=-Wall
bin_PROGRAMS=test
test_CFLAGS=$(GLIB_CFLAGS)
test_LDFLAGS=$(GLIB_LIBS)
test_SOURCES=test.c
Run Code Online (Sandbox Code Playgroud)
最后,这个最小测试用例的源代码,test.c:
#include <glib.h>
int …Run Code Online (Sandbox Code Playgroud) 我正在尝试为hello world示例C程序创建安装包.
我已经完成了以下工作.
自动扫描
mv configure.scan configure.ac编辑configure.ac以添加一些宏.
aclocal会
在其中创建Makefile.am
bin_PROGRAMS = hello
hello_SOURCES = hello.c
Run Code Online (Sandbox Code Playgroud)
最后我做了automake.
然后我收到了消息..
configure.ac:12: error: required file './compile' not found
configure.ac:12: 'automake --add-missing' can install 'compile'
configure.ac:6: error: required file './missing' not found
configure.ac:6: 'automake --add-missing' can install 'missing'
Makefile.am: error: required file './INSTALL' not found
Makefile.am: 'automake --add-missing' can install 'INSTALL'
Makefile.am: error: required file './NEWS' not found
Makefile.am: error: required file './README' not found
Makefile.am: error: required file './AUTHORS' not found
Makefile.am: error: required …Run Code Online (Sandbox Code Playgroud) 我在使用automake时遇到了以下错误.我知道你可以把AUTOMAKE_OPTIONS = subdir-objects"放在Makefile.am的顶部.但是如何为所有文件设置这种行为,所以我不需要逐个进行呢?
Makefile.am:454: warning: source file 'libs/esl/src/esl_threadmutex.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/ivrd.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/src/esl_json.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
Makefile.am:454: warning: source file 'libs/esl/src/esl_buffer.c' is in a subdirectory,
Makefile.am:454: but option 'subdir-objects' is disabled
tests/unit/unit.mk:6: warning: source file 'tests/unit/switch_event.c' is in a subdirectory,
tests/unit/unit.mk:6: but option 'subdir-objects' is disabled
Makefile.am:854: 'tests/unit/unit.mk' …Run Code Online (Sandbox Code Playgroud) 我正在使用Autoconf来构建我的c ++项目.它使用第三方代码,也是在Autoconf/Automake的帮助下构建的.所以在我的configure.ac我有以下几行:
AC_CONFIG_SUBDIRS([subdirectoryname])
Run Code Online (Sandbox Code Playgroud)
一切正常,但我也使用该功能让测试自动make check执行 - 这也是由第三方代码完成的.因为这些测试需要一段时间,所以每次我想测试自己的代码时执行它们都很烦人.那么有什么方法可以避免将check选项传递给子目录Makefile?
更新:覆盖check-recursive似乎不是一个选项,因为我的顶级Makefile.am看起来(或多或少)像这样:
SUBDIRS=library src
Run Code Online (Sandbox Code Playgroud)
因此禁用此级别的检查也会禁用我的src文件夹内的检查.这不是我想要实现的目标.我只是想禁用library目录中的检查.
我想在安装之前使用automake来处理/修改二进制文件.例如,我想将二进制文件中的符号提取到一个单独的文件和位置(如下所示).另一个例子是收集md5sums的关键资产以发布报告.
这是一个简化的(但有代表性的)Makefile.am,我有:
abc_PROGRAMS = foo
foo_SOURCES = foo.cpp
pqr_PROGRAMS = bar
bar_SOURCES = bar.cpp
ALL_SYMS := $(PROGRAMS:%=%.sym)
sym_DATA = $(ALL_SYMS)
# A convenient target such as "make foo.sym" will trigger this rule:
$(ALL_SYMS): %.sym : %
...
objcopy --preserve-dates --only-keep-debug $< $@
objcopy --preserve-dates --strip-all --add-gnu-debuglink=$@ $<
...
Run Code Online (Sandbox Code Playgroud)
我在安装过程中尝试了几种方法来挂钩我的脚本,但成功有限.
一种可能的方法是使用install-exec-local:
install-exec-local: $(ALL_SYMS)
Run Code Online (Sandbox Code Playgroud)
install-exec-local的问题是,当我使用:"make install -j"时,install-exec-local目标与安装并行运行,因此二进制文件foo和bar安装到各自的目标dirs,甚至当他们正在被%.sym规则修改时,从而可能会破坏已安装的文件.但是,如果不使用-j,则此解决方案有效.我想如果我可以利用使用-j的优点.
另一种可能的方法是使用install-exec-hook:
install-exec-hook: $(ALL_SYMS)
Run Code Online (Sandbox Code Playgroud)
install-exec-hook的问题是在我有机会使用%.sym规则修改它们之前已经安装了程序foo和bar.除了foo和bar安装在不同的位置,我没有一个通用的方法来获取他们的目标位置,同时编写一个合适的install-exec-hook规则.
另一种可能的方法是定义STRIP_PROGRAM或类似的东西,但这不能很好地工作,因为我认为它不适用于"make install"目标,而只能使用"make install-strip -j".我没有走这条路,因为我们的构建脚本使用"make install -j".
另一种方法是通过创建在构建时间而不是安装时间运行的构建规则来实现.但是这个真的很麻烦,它在build目录中创建了很多文件,我想避免它.此外,项目中的新人在添加新程序时可以轻松绕过这些精心调整的精心安排.
abc_PROGRAMS = foo
foo : foo.tmp
foo.sym : foo
noinst_PROGRAMS = foo.tmp …Run Code Online (Sandbox Code Playgroud)我在Autoconf Archive中找到了几个有用的宏,还有一个有用的m4文件,它有助于测试Boost库的支持.Autoconf Archive由GNU托管,Boost m4帮助器作为GitHub仓库托管.我想在一个使用Autotools并由git管理的C++项目中使用它们.
显然,可以手动下载它们并插入我的项目的git仓库.但有更推荐的方法吗?
例如,通过使构建过程自动下载它们而不是手动更新它们,可以确保第三方文件是最新版本.它还有助于将源与外部文件分开,因为第三方文件实际上不是纯源代码的一部分,而是外部下载的文件.
如果这是一件好事,应该通过autogen.sh手动完成吗?或者使用automake.am?或两者兼而有之(例如在autogen.sh下载文件和在automake中测试版本+更新)?
我想将它们保存在git repo中并不是一场灾难(就像COPYING,git.mk和其他人一样),但是让构建过程从Web更新到最新版本仍然很有用.