2015-06-05 173 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現在看來很明顯,爲什麼會發生這種情況,但當時我並沒有意識到會發生這種情況。我編輯了我的評論以解釋您擁有的其他選項。 –