如何使用自动工具设置包含路径
Posted
技术标签:
【中文标题】如何使用自动工具设置包含路径【英文标题】:how to set include paths with autotools 【发布时间】:2013-12-12 09:47:06 【问题描述】:我正在开发一个使用autoconf
和automake
的C++ 项目,并且我正在努力正确设置*CPPFLAGS
中的包含路径。我已经阅读了大约 3 个小时的文件,但我还无法弄清楚。我不是在寻找黑客,而是在寻找正确的方法。这是我的难题。
在我看来,包含路径有 3 个完全不同的来源:
-
必须与我的包一起安装的外部库,由
configure --with-XXX=<PATH>
配置。
在我的包中,一些源文件使用#include <file.h>
,即使file.h
是包的一部分,所以要编译它们,我必须正确设置包含路径。 (请注意,不能编辑所有这些文件。)
异想天开(或非)标准指定必须允许用户指定他们自己的(额外)包含路径。也就是说,我根本不应该设置CPPFLAGS
。
在我当前的设置中:
类型 1 路径由AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>")
在 configure.ac
内设置。
Type 2 路径由test_CPPFLAGS = -I<path>
在Makefile.am
中设置。
无法设置类型 3。更准确地说,如果用户在运行make
之前设置了CPPFLAGS
,这会覆盖Type 1 设置,导致编译失败。当然,用户可以尝试改用CXXFLAGS
,但那个有不同的用途(请记住,我要求的是正确的方法,而不是hack)。
我尝试通过在configure.ac
中使用AM_CPPFLAGS
设置Type 1 路径来解决此问题。 (供参考:如果您设置了AM_CPPFLAGS
而不是CPPFLAGS
,但仍需要运行一些检查,例如AC_CHECK_HEADERS
,则需要临时设置CPPFLAGS
,然后将其恢复为检查工作;这是解释了here。)这为Type 3路径释放了CPPFLAGS
,但不幸的是编译失败,因为configure
生成的Makefile
-s将只使用AM_CPPFLAGS
,如果没有专门的<target>_CPPFLAGS
存在。因此,如果 test_CPPFLAGS
存在类型 2 路径,则编译 test
将失败,因为它没有获得类型 1 路径。
解决方法是在Makefile.am
中指定始终使用AM_CPPFLAGS
。但这是“书本”吗?我可以以全局方式执行此操作,还是必须编辑每个target_CPPFLAGS
?还有其他“正确”的解决方案吗?
【问题讨论】:
通过“异想天开”,您是否包含官方的 autoconf 文档,其中明确指出 CPPFLAGS 是一个用户变量,维护者不应修改? (见第 4.8.1 节gnu.org/software/autoconf/manual/autoconf.html) 虽然官方 automake 文档中的一个不那么模棱两可的例子可能更清楚,它指出“您永远不应该在 Makefile.am 中重新定义用户变量,例如 CPPFLAGS。”在第 27.6 节中gnu.org/software/automake/manual/html_node/… 【参考方案1】:我知道很难从 autotools 手册中得到直接的答案。有几个很好的从头到尾的教程here 和 here。
autoconf 中没有特定于包的*CPPFLAGS
的标准变量。 configure
可以用CPPFLAGS=...
调用,automake 会将此CPPFLAGS
添加到相关的makefile 规则中——在Makefile.in
文件中搜索CPPFLAGS
以获取示例。因此,我建议您不要将此变量用于其他任何用途。
将Makefile.am
中的标志添加到AM_CPPFLAGS
变量(所有预处理器调用的默认值)或用target_CPPFLAGS
覆盖各个预处理器标志。在第 3 方库的示例中,最好使用如下名称:FOO_CPPFLAGS
来保存预处理器选项,例如,
FOO_CPPFLAGS="-I$FOO_DIR/include -DFOO_BAR=1"
...
AC_SUBST(FOO_CPPFLAGS)
在Makefile.am
:
AM_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)
# or:
target_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)
top_srcdir
变量由configure
定义——我用它来说明第二种情况。假设您在***目录下的另一个目录other
中有file.h
。 -I$(top_srcdir)
允许您将其包含为<other/file.h>
。或者,-I$(top_srcdir)/other
将允许您将其包含为 <file.h>
。
另一个有用的preset variable 是srcdir
- 当前目录。 -I$(srcdir)
添加到 AM_CPPFLAGS
默认情况下。因此,如果file.h
在当前目录中,您可以将其包含在<file.h>
甚至"file.h"
中。如果other
是一个“兄弟”目录,-I$(srcdir)/..
将允许您包含<other/file.h>
,而-I$(srcdir)/../other
将允许<file.h>
。
我还要补充一点,一些软件包安装了 pkg-config .pc
文件。如果 pkg-config 的安装设置为搜索正确的目录,您可能会发现 PKG_CHECK_MODULES
宏非常有用。
【讨论】:
另一个是$(builddir)
或$(top_builddir)
,这显然是用于在构建期间生成的任何文件。以上是关于如何使用自动工具设置包含路径的主要内容,如果未能解决你的问题,请参考以下文章