c++ - automake第三方库

标签 c++ gnu autotools 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

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行只是告诉 Automakeprogram依赖于首先构建的lib/libYOURLIB.a,而_LDADD行只是将库添加到链接器命令中。


上面假设您已经有构建库的规则。由于您使用的是SUBDIRS,因此您收到了“没有规则来创建目标 XXXXXX”构建失败,这表明您没有(至少从src子目录中的 Makefile 的角度来看)。要解决此问题,您可以在 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.hppprogram/include中。我不确定当另一个项目将整个$(top_srcdir)源目录包含在其自己的program变量中时SUBDIRS是否正确,但是$(srcdir)将始终引用顶级program目录一个非递归的 automake,这使得它在包含此包作为组件的大型项目中可能更有用。

关于c++ - automake第三方库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30677198/

相关文章:

c++ - 函数填充 vector ,但它在某个时候变成空的。

c++ - 在 vs2008 中升级后检测到堆损坏

c++ - Linux 中是否有等同于 _set_pure call handler() 的函数?

c++ - 指示 Automake 对 *.S 文件使用 C++ 编译器?

c++ - 不理解-c -o的Unix C++编译器

c++ - 链接到 libresolv 时 undefined reference

C++:如何阻止 .msc 和 .cpl 类型的应用程序?

C++ 用户定义 vector

c - "if"的 gnu C 条件

linux - 如何识别文件中以 5 结尾的行