我目前正在开发一个依赖于递归automake进行构建的C ++项目。
我想构建一个共享库,库的Makefile.am
目录中的src
看起来像
# ...
# Library name
lib_LTLIBRARIES = libadapter-@MY_API_VERSION@.la
# Sources
libadapter_@MY_API_VERSION@_la_SOURCES = \
$(top_builddir)/src/sourceA.cpp \
$(top_builddir)/src/sourceB.cpp
# ...
自版本1.14起,当subdir-objects
中的AM_INIT_AUTOMAKE
未指定configure.ac
选项时,automake会发出警告。但是,添加subdir-objects
选项似乎打破了构建过程,make
抱怨缺少.Plo
个文件。我已经在网上搜索了遇到类似问题的人,但没有找到任何合理的提示,如何在不将项目更改为非递归项的情况下解决问题。非常感谢任何帮助。
修改
深入研究问题,我注意到./configure
在库的当前源目录下创建了一个名为$(top_builddir)
的目录,其中包含构建库所需的所有.Plo
文件。但是,在Makefile
中,我发现我的图书馆来源的.Plo
等效项(示例中为sourceA.cpp
和sourceB.cpp
)的前缀为include $(top_builddir)/src/$(DEPDIR)/
和{ {1}}是定义为 relative 路径的变量(即$(top_builddir)
)。现在很清楚为什么../../../src/.deps/
无法找到make
文件,因为它会搜索错误的目录。这看起来像是错误#16375的可能重复。任何解决方法?
编辑2:
在网络上进一步挖掘后,又发现了另外两个线程来解决这个问题:#1327和automake-bug。已知的解决方法似乎是将.Plo
选项传递给--disable-dependency-tracking
。至少对我来说它是有效的。
答案 0 :(得分:5)
来自automake-1.14.1
NEWS
文件:
The next major Automake version (2.0) will unconditionally activate
the 'subdir-objects' option. In order to smooth out the transition,
we now give a warning (in the category 'unsupported') whenever a
source file is present in a subdirectory but the 'subdir-object' is
not enabled. For example, the following usage will trigger such a
warning:
bin_PROGRAMS = sub/foo
sub_foo_SOURCES = sub/main.c sub/bar.c
因此,如果您使用上述'对象'名称中的子目录,则需要subdir-objects
作为AM_INIT_AUTOMAKE
中的一个选项。默认情况下,此选项将在2.0中“打开”。
如果您可以为失败的目录提供Makefile.am
,则可能会提供相关目录未匹配的原因。
好的,有关于Makefile.am
的一些事情。首先,有一些方法可以正确地对libtool库进行版本化,并且@MY_API_VERSION@
替换不是可行的方法。您可以在configure.ac
中形成数字字符串,然后是 AC_SUBST(MY_API_VERSION)
。
在Makefile.am
中: libadapter_la_LDFLAGS = -release $(MY_API_VERSION)
会将此信息放入libadapter.la
libtool元文件中。
对于严重版本控制,需要接口兼容性,修订版,二进制兼容性等,您可以查看versioning上的libtool参考。重要的系统库,特别是GNOME / GTK(查看他们的configure.ac
文件!),全力以赴。我当然不这样做,除非我考虑在野外发布一些东西。我仍觉得很困惑。
省略@MY_API_VERSION@
,您还可以坚持使用 libadapter_la_SOURCES
。但是,找不到相对于任何builddir
路径的源文件,这可能是您.Plo
文件问题的来源。 builddir
变量描述了构建的组件的位置 - 您还可以构建树外,这是一个很好的测试,可以确定您的automake设置是否健壮。有些软件包会提升这一点,例如,转到软件包的顶部,创建一个名为build
或my_build
的目录或任何适合的目录:
cd my_build; ../configure <options>; make
包,它的源代码树和递归目录将保持不变,所有内容都将在my_build
目录下构建,子目录将镜像源树的子目录,只有它们将充满构建的对象,库,可执行文件等make install
也应该使用生成的my_build/Makefile
完美地工作。
但回到这一点 - 那些源文件是相对于$(srcdir)
目录的,它对应于当前(递归)Makefile.am
的目录。各种builddir
和srcdir
变量的描述均为here。
如果您的src
目录位于顶级目录下,则可以使用:"$(top_srcdir)/src/sourceA.cpp"
- 请注意"$(srcdir)/src/sourceA.cpp"
错误,因为它就像在这种情况下指定"$(top_srcdir)/src/src/sourceA.cpp"
一样。
你可以使用"$(srcdir)/sourceA.cpp"
,但无论如何这个目录都是隐含的。您所需要的只是:
<强> libadapter_la_SOURCES = sourceA.cpp sourceB.cpp
强>
将任何头文件放在src
列表中libadapter
使用的SOURCES
目录中也是完全可以接受的。更改标题将重建所需的内容。
无论如何,我并不是故意写这么多,但我知道获得关于autotools的清晰信息是多么令人沮丧。 Autotools Mythbuster提供了出色的“漫游”教程,并保持最新状态。