如何使用自动工具设置包含路径

Posted

技术标签:

【中文标题】如何使用自动工具设置包含路径【英文标题】:how to set include paths with autotools 【发布时间】:2013-12-12 09:47:06 【问题描述】:

我正在开发一个使用autoconfautomake 的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),这显然是用于在构建期间生成的任何文件。

以上是关于如何使用自动工具设置包含路径的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ScrollView 中为 ImageView 设置自动布局约束?

vs2018 设置了包含路径还是提示说打不开头文件

mysql自动备份怎么设置计划

mysql怎样设置定期自动导入本地文件

IAR和Keil文件包含路径设置

如何设置REPORTVIEWER控件工具条显示中文