我开始学习autotools,以便首先了解并扩展现有项目的构建系统。目前,该项目根据其输出构建了一个程序。构建系统非常复杂,由几个子目录和Makefile.am
组成,其中文件以维护者模式生成,依此类推。我希望能够使用大部分相同的源代码创建一个库,重用大部分现有的构建系统。
我想象的是一个新的make目标,以便在运行configure之后,我可以运行make
来制作程序,或者说,make library
来构建库。执行此操作或具有类似效果的正确方法是什么?
当我运行普通make
(只是以前的程序)时,我不想同时构建库和程序,我不想在运行make library
时构建程序(I只想要图书馆。)
如果有人可以提供一个简单的例子,例如由main.c
,foo.c
和bar.c
组成的程序以及由foo.c
和bar.c
组成的图书馆,该图书馆也非常有用。
编辑
为了澄清,我原本以为程序和lib可以完全分开构建。该库只包含主程序代码的一部分,我相信这两个是独立的实体。然而,事情更复杂。程序本身被构建并用于输出一些代码,然后在第二步中编译到程序中(我认为)。通过以下步骤,我已经有效地得到了我想要的东西。
首先添加一个条件到configure.ac
dnl Adds LIBRARY conditional for --enable-foolib mode to
dnl build foo as a library
AC_ARG_ENABLE(foolib,
AS_HELP_STRING([--enable-foolib],
[enable qucslib build, default: no]),
[case "${enableval}" in
yes) foolib=true ;;
no) foolib=false ;;
*) AC_MSG_ERROR([bad value ${enableval} for --enable-foolib]) ;;
esac],
[foolib=false])
AM_CONDITIONAL(FOOLIB, test x"$foolib" = x"true")
然后在适当的Makefile.am中我做了类似于以下的事情:
if FOOLIB
noinst_LIBRARIES = libbar.a libfoo.a
else
noinst_LIBRARIES = libbar.a
endif
bin_PROGRAMS = barprog
barprog_SOURCES = main.cpp src1.cpp src2.cpp etc.cpp
barprog_LDADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
... other stuff
if FOOLIB
libfoo_a_LIBADD = libbar.a \
subdir1/libsubdir1.a \
subdir2/libsubdir2.a \
etcdir/libetc.a
libfoo_a_SOURCES = src1.cpp src2.cpp etc.cpp
endif
然后当我想创建库时
configure --enable-foolib
make
这暂时有用,但看起来很糟糕。我不确定如何在构建系统中实现提供的答案。
答案 0 :(得分:0)
如果程序依赖于库,那么在不构建库的情况下将无法构建程序。您已经能够构建单个库:configure && make libfoo.a
应该可以正常工作(或make libfoo.la
)。如果您希望名为library
的目标,只需将以下内容添加到任何Makefile.am:
library:
libfoo.a
(或者您可能需要libfoo.la
。基本上,如果在Makefile.am
主要内容LIBRARIES
下指定了库,那么您将使用libfoo.a
,但如果指定LTLIBRARIES
主要版本,您将使用libfoo.la
。)这将仅在包含Makefile.am的每个目录中创建library
目标。如果你有一个复杂的递归构建(你应该真的简化它,但这是另一个问题),你可以在你的顶级Makefile.am
中放置类似下面的内容来在整个树中构建库:
library:
cd subdir && $(MAKE) $(AM_MAKEFLAGS) library
这假设您已经如上所述向subdir / Makefile.am添加了library
目标。
要迂腐,您可能希望使用$(am__cd)
代替cd
,但这并非绝对必要。