如何使用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
lib/Makefile.am的内容应该是什么?

最佳答案

(不知道为什么您似乎自己可以控制库代码时​​为什么说“第三方”。有关使用Automake创建和使用库的更多信息,请引用GNU Automake manual's section on libraries)

lib / Makefile.am

lib_LIBRARIES = libYOURLIB.a
libYOURLIB_a_SOURCES = library.cpp

如果您不想安装库本身,则可以使用noinst_lib_LIBRARIES。请注意,我假设您只想构建一个静态库。有关与Libtool集成以生成共享库的信息,请参见GNU Automake手册的Building A Shared Library部分。当然,您可以手动执行此操作,但是使用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 Angular 而言)。为了解决这个问题,您可以在 src / Makefile.am 中尝试以下操作(从GNU Automake邮件列表文件中的"Re: library dependency"中获取):
FORCE:

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

当然,您也可以简单地将lib作为src的子目录,作为注释的指示,并使其更简单。

另外,您可以停止使用递归构 build 置,而可以使用更简单的非递归构 build 置。有关此信息,请参见GNU Automake Manual §7.3: An Alternative Approach to SubdirectoriesNon-recursive Automake,但是通常的想法是更改内容以允许:

configure.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"AM_CPPFLAGS = -I $(top_srcdir)/include都放在另一个目录中,那么您可能还希望对obj_program_CPPFLAGS = -I include中使用的所有文件使用bin/program或对所有用于构建library.hpp的源文件使用program/include。当另一个项目在其自己的$(top_srcdir)变量中包含整个program源目录时,我不确定SUBDIRS是否正确,但是在非递归自动制作的情况下,$(srcdir)将始终引用顶级program目录,这可能会使它更多在将此程序包作为组件的大型项目中很有用。

09-04 07:32
查看更多