由于 AM_INIT_AUTOMAKE 中的 subdir-objects 选项,Autotools 构建失败
Posted
技术标签:
【中文标题】由于 AM_INIT_AUTOMAKE 中的 subdir-objects 选项,Autotools 构建失败【英文标题】:Autotools build fails due to subdir-objects option in AM_INIT_AUTOMAKE 【发布时间】:2014-03-03 19:01:06 【问题描述】:我目前正在开发一个依赖递归 automake 进行构建的 C++ 项目。
我想建立一个共享库,库的src
目录中的Makefile.am
看起来像
# ...
# 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 版开始,当 configure.ac
中的 AM_INIT_AUTOMAKE
中未指定 subdir-objects
选项时,automake 会发出警告。但是,添加subdir-objects
选项似乎会中断构建过程,make
抱怨缺少.Plo
文件。我已经在网上搜索了遇到类似问题的人,但没有找到任何关于如何在不将项目更改为非递归项目的情况下解决问题的明智提示。非常感谢任何帮助。
编辑:
更深入地研究这个问题,我注意到./configure
在库的当前源目录下创建了一个字面上命名为$(top_builddir)
的目录,其中包含构建库所需的所有.Plo
文件。但是,在Makefile
中,我发现我的库源的.Plo
等效项(示例中为sourceA.cpp
和sourceB.cpp
)以include $(top_builddir)/src/$(DEPDIR)/
为前缀,$(top_builddir)
是一个定义为相对路径(即../../../src/.deps/
)。现在很清楚为什么make
找不到.Plo
文件,因为它搜索了错误的目录。这看起来可能是错误#16375 的重复。有什么解决方法吗?
编辑 2:
在网络上进一步挖掘发现了另外两个解决该问题的线程:#1327 和automake-bug。一个已知的解决方法似乎是将--disable-dependency-tracking
选项传递给./configure
。至少对我来说它有效。
【问题讨论】:
您是否使用relative paths 作为源? FWIW,我在 automake 1.14 中也收到了这条消息(非递归构建,没有相对路径)。目前,我的策略是忽略警告,直到我找到不搞砸构建的方法。似乎可以构建(现在......)。 @ldav1s - 有趣。您在*** Makefile.am 中使用 ACLOCAL_AMFLAGS 吗? AM_INIT_AUTOMAKE 选项呢? 我使用ACLOCAL_AMFLAGS
只是为了设置宏路径(-I ...
)。 AM_INIT_AUTOMAKE
选项由 AUTOMAKE_OPTIONS
: 1.11 foreign
设置。就是这样。
OTOH,也许我不使用相对路径。也许我必须将top_srcdir
切换到abs_top_srcdir
和top_builddir
到abs_top_builddir
。嗯……
【参考方案1】:
来自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"
将是错误,就像指定@987654356 @ 在这种情况下。
你可以使用"$(srcdir)/sourceA.cpp"
,但无论如何这个目录是隐含的。你只需要:
libadapter_la_SOURCES = sourceA.cpp sourceB.cpp
将任何头文件放在SOURCES
列表中libadapter
使用的src
目录中也是完全可以接受的。更改标头将重建所需的内容。
无论如何,我不是故意写这么多,但我知道获得有关自动工具的清晰信息是多么令人沮丧。 Autotools Mythbuster 提供了出色的“演练”教程,并且始终保持最新状态。
【讨论】:
我已经从automake
NEWS
文件中知道了这个sn-p,但据我了解,如果将subdir-objects
选项简单地添加到@987654366,automake
应该可以顺利工作@ in configure.ac
- 无论在Makefile.am
中使用的是相对路径还是绝对路径。如果我错了,请纠正我。
@Marcel - 我已尝试解决您的Makefile.am
中的问题。希望对您有所帮助。
非常感谢您的详尽回答。我看到top_srcdir
和top_builddir
之间的区别,但我不明白为什么用前者交换后者会对树内构建产生任何影响,这就是我目前所做的。此外,省略 MY_API_VERSION
不应有助于解决问题。与此同时,我想我已经找到了构建失败的原因,请参阅我更新的问题。
是的,我做到了,但没有任何效果 - 错误仍然存在。
将“subdir-objects”添加到我的 AM_INIT_AUTOMAKE 解决了我的问题。谢谢。以上是关于由于 AM_INIT_AUTOMAKE 中的 subdir-objects 选项,Autotools 构建失败的主要内容,如果未能解决你的问题,请参考以下文章
使用 AM_INIT_AUTOMAKE 参数并配置脚本命令行参数