2013-11-27 36 views
8

我正在使用autoconf & automake的C++项目,我正在努力正确设置*CPPFLAGS中的包含路径。我已经阅读了大约3小时的文档,我还没有弄明白。我不是在寻找黑客,而是寻找正确的方法来做到这一点。这是我的难题。如何使用自动工具设置包含路径

在我看来,有3个完全不同的用于源包括路径:它必须与我的包,这是由configure --with-XXX=<PATH>配置一起安装

  1. 外部库。
  2. 在我的软件包中,有些源文件使用#include <file.h>,即使file.h是软件包的一部分,为了编译它们,我必须正确设置include路径。 (注意,这不是编辑所有这些文件的选项。)
  3. 异想天开(或不)标准指定用户必须被允许指定他们自己的(额外的)包含路径。也就是说,我不应该设置CPPFLAGS

在我的当前设置:

  • 类型1路径由AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>")设置内部configure.ac
  • 类型2路径设置在Makefile.am之内test_CPPFLAGS = -I<path>
  • 无法设置类型3。更确切地说,如果用户在运行make之前设置了CPPFLAGS,则会覆盖类型1设置,导致编译失败。当然,用户可以尝试使用CXXFLAGS来代替,但该用户有不同的用途(请记住,我正在寻求正确的方式来执行此操作,而不是黑客)。

我试图通过在configure.ac内使用AM_CPPFLAGS设置类型1路径来解决此问题。 (仅供参考:如果您设置了AM_CPPFLAGS而不是CPPFLAGS,但仍需要执行一些检查,例如AC_CHECK_HEADERS,则需要暂时​​设置CPPFLAGS,然后将其恢复以便检查生效;这是here的解释。)这样可以释放CPPFLAGS对于类型3路径,但不幸的是,编译失败,因为configure产生的Makefile-s将只使用AM_CPPFLAGS,如果没有专门的<target>_CPPFLAGS存在。因此,如果test_CPPFLAGS与类型2路径一起存在,则编译test将失败,因为它不会获得类型1路径。

修复方法是在Makefile.am之内指定始终使用AM_CPPFLAGS。但这是“靠书”吗?我能以全局方式做到这一点,还是必须编辑每一个target_CPPFLAGS?有没有另一种“正确的”解决方案?

+0

通过“异想天开”,你是否包含官方autoconf文档,明确指出CPPFLAGS是一个用户变量,不应该由维护者修​​改? (见http://www.gnu.org/software/autoconf/manual/autoconf.html上的第4.8.1节) –

+0

尽管官方automake文档中一个较不明确的例子可能会更清晰,其中指出:“你永远不应该重新定义用户变量,如Makefile.am中的CPPFLAGS“。在第27.6节的http://www.gnu.org/software/automake/manual/html_node/Flag-Variables-Ordering.html#Flag-Variables-Ordering –

回答

18

我知道很难从autotools手册中得到直接的答案。有几个很好的开始到结束教程herehere

autoconf中没有针对特定软件包*CPPFLAGS的标准变量。 configure可以用CPPFLAGS=...调用,automake会将这个CPPFLAGS添加到相关的生成文件规则中 - 例如在Makefile.in文件中搜索CPPFLAGS。出于这个原因,我建议你而不是使用这个变量的任何其他。

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 - 我用它来说明第二种情况。假设您在顶级目录下的另一个目录other中有file.h-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宏非常有用。

+2

另一个是'$(builddir)'或'$(top_builddir) '这显然意味着用于构建期间生成的任何文件。 – CMCDragonkai

相关问题