2015-06-05 138 views
1

如何使用automake编译和链接第三方库?automake第三方库

我的文件结构是:

program/ 
    | 
    +--src/ 
    | | 
    | +--Makefile.am 
    | +--main.cpp 
    | 
    +--lib/ 
    | | 
    | +--Makefile.am 
    | +--library.cpp 
    | 
    +--Makefile.am 
    +--configure.ac 
    +--README 

的automake的文件的内容非常通用:

# src/Makefile.am 
bin_PROGRAMS = program 
program_SOURCES = main.cpp 

# Makefile.am 
SUBDIRS = src lib 
dist_doc_DATA = README 

# configure.ac 
AC_INIT([program], [1.0]) 
AM_INIT_AUTOMAKE([-Wall]) 
AC_PROG_CXX 
AC_CONFIG_HEADERS([config.h]) 
AC_CONFIG_FILES([Makefile src/Makefile lib/Makefile]) 
AC_OUTPUT 

守什么ld是lib/Makefile.am的内容吗?

+0

只需添加到@ chrono的答案,'SUBDIRS'列出深度优先下降的目录。由于'src'依赖于'lib'版本,因此考虑设置:'SUBDIRS = lib src'。您甚至可以添加'.'目录来指示相对于当前目录的处理顺序。 –

回答

2

(不知道为什么当你自己控制库代码时​​,你说的是“第三方”...有关使用Automake创建和使用库的更多信息,请参考GNU Automake manual's section on libraries

的lib/Makefile.am

lib_LIBRARIES = libYOURLIB.a 
libYOURLIB_a_SOURCES = library.cpp 

您可以使用noinst_lib_LIBRARIES,如果你不想安装库本身。请注意,我假设你只想建立一个静态库。请参阅GNU Automake手册的Building A Shared Library部分,以便与Libtool集成以生成共享库。当然,你可以手动完成,但Libtool更容易处理各种平台差异。

到库链接到program,你会添加以下行
的src/Makefile.am

program_DEPENDENCIES = $(top_builddir)/lib/libYOURLIB.a 
program_LDADD = $(top_builddir)/lib/libYOURLIB.a 

_DEPENDENCIES线只是告诉Automake是program依靠lib/libYOURLIB.a正在初建时,而_LDADD行简单地将库添加到链接器命令。


上面假设您已经有了一个规则来构建库。由于您使用的是SUBDIRS,您收到了“没有规则使目标XXXXXX”构建失败,这表明您没有(至少从子目录src的Makefile的角度看)。为了解决这个问题,你可以试试下面的的src/Makefile.am(从"Re: library dependency"在GNU Automake的邮件列表存档占用):

FORCE: 

$(top_builddir)/lib/libYOURLIB.a: FORCE 
<TAB>(cd $(top_builddir)/lib && $(MAKE) $(AM_MAKEFLAGS) libYOURLIB.a) 

你也可以简单地使libsrc子目录作为您的评论当然要指出并简化。

或者,您可以停止使用递归构建设置并使用可能更简单的非递归构建设置。有关这方面的一些信息,请参阅GNU Automake Manual §7.3: An Alternative Approach to SubdirectoriesNon-recursive Automake,但总体思路是改变允许的内容:

配置。AC

AM_INIT_AUTOMAKE([-Wall subdir-objects]) 
... 
AC_CONFIG_FILES([Makefile]) 

Makefile.am

# Instead of using the SUBDIRS variable. 
include src/Makefile.am.inc 
include lib/Makefile.am.inc 
dist_doc_DATA = README 

的lib/Makefile.am更名为的lib/Makefile.am.inc

# Full path relative to the top directory. 
lib_LIBRARIES = lib/libYOURLIB.a 
lib_libYOURLIB_a_SOURCES = lib/library.cpp 

的src/Makefile文件.am更名为的src/Makefile.am.inc

# Full path relative to the top directory. 
bin_PROGRAMS = bin/program 
bin_program_SOURCES = src/main.cpp 
bin_program_DEPENDENCIES = lib/libYOURLIB.a 
bin_program_LDADD = lib/libYOURLIB.a 

重命名文件是可选的(你总是可以只include src/Makefile.am),但它有助于表示,这并不意味着是一个独立的Automake的源文件。

此外,假设lib/library.cppsrc/main.cpp#include "library.hpp",它的其他目录下,你可能还需要使用对于在建bin/program使用的所有源文件AM_CPPFLAGS = -I $(top_srcdir)/include的所有文件或obj_program_CPPFLAGS = -I include,假设library.hppprogram/include。我不知道是否$(top_srcdir)是正确的,当另一个项目包含您的整个program源目录在其自己的SUBDIRS变量,但$(srcdir)将永远指在非递归automake的情况下,顶级program目录,使其可能更多在包含此软件包作为组件的大型项目中很有用。

+0

我已经对'lib/Makefile.am'和'src/Makefile.am'进行了相应的修改,但在添加'AC_PROG_RANLIB'到'configure.ac'后,又收到了一个有关RANLIB的投诉,我又遇到了另一个错误'No rule to make target ../../ src /../ lib/libtest.a' – Daveel

+0

到目前为止,我的解决方法是将'lib'移动到'src/lib',然后修改'src/Makefile.am' =>'program_SOURCES = main.cpp lib/library.cpp' – Daveel

+0

@Daveel现在看来很明显,为什么会发生这种情况,但当时我并没有意识到会发生这种情况。我编辑了我的评论以解释您拥有的其他选项。 –