简体   繁体   English

自动制作第三方库

[英]automake third party libraries

How to compile and link third party libraries with automake? 如何使用automake编译和链接第三方库?

My file structure is: 我的文件结构是:

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

Contents of automake files are pretty generic: 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

What should be the contents of lib/Makefile.am ? lib/Makefile.am的内容应该是什么?

(Not sure why you said "third-party" when you appear to have control of the library code yourself... For more info related to creating and working with libraries using Automake, I refer you to the GNU Automake manual's section on libraries ) (不知道为什么您似乎自己可以控制库代码时​​为什么说“第三方”。有关与使用Automake创建和使用库有关的更多信息,请参考GNU Automake手册的库部分

lib/Makefile.am lib / Makefile.am

lib_LIBRARIES = libYOURLIB.a
libYOURLIB_a_SOURCES = library.cpp

You can use noinst_lib_LIBRARIES if you don't want to install the library itself. 如果您不想安装库本身,则可以使用noinst_lib_LIBRARIES Note that I'm assuming you want to build a static library only. 请注意,我假设您只想构建一个静态库。 See the Building A Shared Library section of the GNU Automake manual for integrating with Libtool to produce a shared library. 请参阅GNU Automake手册的“ 构建共享库”部分,以与Libtool集成以生成共享库。 You can do it manually of course, but it's a lot easier with Libtool as it takes care of various platform differences. 当然,您可以手动执行此操作,但是使用Libtool可以解决各种平台差异,因此要容易得多。

To link your library to program , you'd add the following lines in 要将库链接到program ,请在中添加以下行
src/Makefile.am : src / Makefile.am

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

The _DEPENDENCIES line simply tells Automake that program relies on lib/libYOURLIB.a being built first, and the _LDADD line simply adds the library to the linker command. _DEPENDENCIES线只是告诉Automake该program依靠lib/libYOURLIB.a正在初建,与_LDADD线只是添加库到链接器命令。


The above assumes that you have a rule to build the library already. 上面假设您已经有一个规则来构建库。 Since you're using SUBDIRS , you received a "no rule to make target XXXXXX" build failure, which indicates that you don't (at least from the perspective of the Makefile in the src subdirectory). 由于您使用的是SUBDIRS ,因此收到“没有规则使目标XXXXXX生成”失败,这表明您没有这样做(至少从src子目录中的Makefile角度而言)。 To remedy this, you can try the following in src/Makefile.am (taken from "Re: library dependency" on the GNU Automake mailing list archives): 为了解决这个问题,您可以在src / Makefile.am中尝试以下操作(取自GNU Automake邮件列表档案中的“ Re:库依赖项” ):

FORCE:

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

You can also simply make lib a subdirectory of src as your comment indicated of course and make it simpler. 当然,也可以按照您的注释将lib设为src的子目录,并使之更简单。

Alternatively, you can stop using a recursive build setup and use what is perhaps a simpler non-recursive build setup. 另外,您可以停止使用递归构建设置,而可以使用更简单的非递归构建设置。 See GNU Automake Manual §7.3: An Alternative Approach to Subdirectories and Non-recursive Automake for some information on that, but the general idea would be to alter things to allow for : 有关此方面的一些信息,请参见GNU Automake手册§7.3:子目录非递归Automake 的替代方法 ,但是一般的想法是更改内容以允许:

configure.ac configure.ac

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

Makefile.am 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 renamed to lib/Makefile.am.inc 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 renamed to src/Makefile.am.inc 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

Renaming the files is optional (you could always just include src/Makefile.am ), but it helps to denote that it isn't meant to be a standalone Automake source file. 重命名文件是可选的(您始终可以只include src/Makefile.am ),但这有助于表明它并非独立的Automake源文件。

Also, supposing that lib/library.cpp and src/main.cpp both #include "library.hpp" , and it's in another directory, you might also want to use AM_CPPFLAGS = -I $(top_srcdir)/include for all files or obj_program_CPPFLAGS = -I include for all source files that are used in building bin/program , assuming library.hpp is in program/include . 另外,假设lib/library.cppsrc/main.cpp都包含#include "library.hpp" ,并且位于另一个目录中,那么您可能还想对所有文件使用AM_CPPFLAGS = -I $(top_srcdir)/includeobj_program_CPPFLAGS = -I includeobj_program_CPPFLAGS = -I include bin/program中使用的所有源文件,假定library.hppprogram/include I'm not sure if $(top_srcdir) is right when another project includes your entire program source directory in its own SUBDIRS variable, but $(srcdir) will always refer to the top-level program directory in the case of a non-recursive automake, making it perhaps more useful in larger projects that include this package as a component. 当另一个项目在其自己的SUBDIRS变量中包含整个program源目录时,我不确定$(top_srcdir)是否正确,但是在非递归的情况下, $(srcdir)将始终引用顶级program目录自动制作,使其在包含此软件包作为组件的大型项目中可能更有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM