如何使用autotools设置包含路径

时间:2013-11-27 00:35:18

标签: autotools autoconf automake include-path

我正在开发一个使用autoconf&的C ++项目。 automake,我正在努力在*CPPFLAGS中正确设置包含路径。我已经阅读了大约3个小时的文件,我还想不通。我不是在寻找黑客,而是寻找正确的方法。这是我的难题。

在我看来,包含路径有3个完全不同的来源:

  1. 必须与我的包一起安装的外部库,由configure --with-XXX=<PATH>
  2. 配置
  3. 在我的包中,一些源文件使用#include <file.h>即使file.h是包的一部分,因此要编译它们,我必须正确设置包含路径。 (注意,它不是编辑所有这些文件的选项。)
  4. 异想天开(或不是)标准指定必须允许用户指定自己的(额外)包含路径。也就是说,我不应该设置CPPFLAGS
  5. 在我目前的设置中:

    • 类型1路径在configure.ac AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>")内设置。
    • 类型2路径在Makefile.am test_CPPFLAGS = -I<path>内设置。
    • 无法设置类型3。更准确地说,如果用户在运行CPPFLAGS之前设置make,则会覆盖类型1设置,从而导致编译失败。当然,用户可以尝试使用CXXFLAGS,但是那个有不同的用途(请记住,我要求正确的方法来做到这一点,而不是黑客)。

    我尝试通过在AM_CPPFLAGS内使用configure.ac设置类型1路径来解决此问题。 (供参考:如果您设置AM_CPPFLAGS而不是CPPFLAGS,但仍需要运行某些检查,例如AC_CHECK_HEADERS,则需要暂时​​设置CPPFLAGS,然后还原它使检查工作;解释为here。)这为类型3路径释放CPPFLAGS,但遗憾的是编译失败,因为Makefile - 由{{1}生成如果不存在专门的configure,则只会使用AM_CPPFLAGS。因此,如果<target>_CPPFLAGS存在类型2路径,则编译test_CPPFLAGS将失败,因为它不会获得类型1路径。

    修复方法是在test内指定始终使用Makefile.am。但这是“按书”吗?我可以以全局方式执行此操作,还是必须编辑每个AM_CPPFLAGS?还有其他“正确”的解决方案吗?

1 个答案:

答案 0 :(得分:23)

我知道很难从autotools手册中得到一个直接的答案。有一些很好的从头到尾的教程herehere

autoconf中没有特定于包的*CPPFLAGS的标准变量。可以使用configure调用CPPFLAGS=...,并且automake会将此CPPFLAGS添加到相关的makefile规则中 - 例如,在CPPFLAGS文件中搜索Makefile.in。出于这个原因,我建议您将此变量用于其他任何内容。

Makefile.am中的标志添加到AM_CPPFLAGS变量(所有预处理器调用的默认值)或使用target_CPPFLAGS覆盖单个预处理器标志。在第三方库的示例中,最好使用如下名称: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定义 - 我用它来说明第二种情况。假设您在顶级目录下的另一个目录file.h中有other-I$(top_srcdir)允许您将其包含为<other/file.h>。或者,-I$(top_srcdir)/other允许您将其包含为<file.h>

另一个有用的preset variablesrcdir - 当前目录。默认情况下,-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宏非常有用。