简体   繁体   English

如何使用autotools设置包含路径

[英]how to set include paths with autotools

I'm working on a C++ project that uses autoconf & automake , and I'm struggling to correctly set up the include paths in *CPPFLAGS . 我正在开发一个使用autoconfautomake的C ++项目,我正在努力在*CPPFLAGS正确设置包含路径。 I've read about 3 hours worth of documents, and I can't figure it out yet. 我已经阅读了大约3个小时的文件,我还想不通。 I'm not looking for a hack, but for the correct way to do this. 我不是在寻找黑客,而是寻找正确的方法。 Here is my conundrum. 这是我的难题。

As I see it, there are 3 completely different sources for include paths: 在我看来,包含路径有3个完全不同的来源:

  1. External libraries that must be installed along with my package, which are configured by configure --with-XXX=<PATH> . 必须与我的包一起安装的外部库,由configure --with-XXX=<PATH>
  2. Within my package, some source files use #include <file.h> even when file.h is part of the package, so to compile them, I must set the include path correctly. 在我的包中,一些源文件使用#include <file.h>即使file.h是包的一部分,因此要编译它们,我必须正确设置包含路径。 (Note, it's not an option to edit all these files.) (注意,它不是编辑所有这些文件的选项。)
  3. Whimsical (or not) standards specify the user must be allowed to specify their own (extra) include paths. 异想天开(或不是)标准指定必须允许用户指定自己的(额外)包含路径。 That is, I shouldn't be setting CPPFLAGS at all. 也就是说,我根本不应该设置CPPFLAGS

In my current setup: 在我目前的设置中:

  • Type 1 paths are set inside configure.ac by AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>") . 通过AC_SUBST(CPPFLAGS, "$CPPFLAGS -I<path>")configure.ac中设置类型1路径。
  • Type 2 paths are set inside Makefile.am by test_CPPFLAGS = -I<path> . 通过test_CPPFLAGS = -I<path>Makefile.am中设置类型2路径。
  • Type 3 cannot be set. 无法设置类型3。 More exactly, if the user sets CPPFLAGS before running make , this overrides Type 1 settings, causing compilation to fail. 更确切地说,如果用户在运行make之前设置CPPFLAGS ,则会覆盖Type 1设置,从而导致编译失败。 Of course, the user could try to use CXXFLAGS instead, but that one has a different use (remember, I'm asking for the correct way to do this, not a hack). 当然,用户可能会尝试使用CXXFLAGS ,但是那个用户有不同的用途(记住,我要求正确的方法来做到这一点,而不是黑客攻击)。

I tried to fix this by setting Type 1 paths using AM_CPPFLAGS inside configure.ac . 我尝试通过在configure.ac使用AM_CPPFLAGS设置类型1路径来解决此问题。 (For reference: if you set AM_CPPFLAGS instead of CPPFLAGS , but you still need to run some checks such as AC_CHECK_HEADERS , you need to temporarily set CPPFLAGS and then revert it for the checks to work; this is explained here .) This frees up CPPFLAGS for Type 3 paths, but unfortunately the compilation fails because the Makefile -s that gets produced by configure will only use AM_CPPFLAGS if no specialized <target>_CPPFLAGS exists. (供参考:如果您设置AM_CPPFLAGS而不是CPPFLAGS ,但仍需要运行某些检查,例如AC_CHECK_HEADERS ,则需要临时设置CPPFLAGS然后还原它以使检查AC_CHECK_HEADERS ; 此处将对此进行说明。)这样可以释放CPPFLAGS对于类型3路径,但遗憾的是编译失败,因为如果不存在专门的<target>_CPPFLAGS ,则configure生成的Makefile -s将仅使用AM_CPPFLAGS So, if test_CPPFLAGS exists with a Type 2 path, compiling test will fail because it doesn't get the Type 1 path. 因此,如果test_CPPFLAGS存在类型2路径,则编译test将失败,因为它不会获得类型1路径。

A fix would be to specify inside Makefile.am to always use AM_CPPFLAGS . 修复方法是在Makefile.am指定始终使用AM_CPPFLAGS But is this "by the book"? 但这是“按书”吗? Can I do this in a global way, or do I have to edit every single target_CPPFLAGS ? 我可以以全局方式执行此操作,还是必须编辑每个target_CPPFLAGS Is there another "correct" solution? 还有其他“正确”的解决方案吗?

I know it's difficult to get a straight answer from the autotools manuals. 我知道很难从autotools手册中得到一个直接的答案。 There are a couple of good start-to-finish tutorials here and here . 这里这里有几个很好的从头到尾的教程。

There isn't a standard variable for package-specific *CPPFLAGS in autoconf. autoconf中没有特定于包的*CPPFLAGS的标准变量。 configure can be invoked with CPPFLAGS=... , and automake will add this CPPFLAGS to the relevant makefile rules - search for CPPFLAGS in a Makefile.in file for examples. 可以使用CPPFLAGS=...调用configure ,并且automake会将此CPPFLAGS添加到相关的makefile规则中 - 例如,在Makefile.in文件中搜索CPPFLAGS For that reason, I suggest that you not use this variable for anything else. 出于这个原因,我建议您不要将此变量用于其他任何事情。

Add flags in Makefile.am to the AM_CPPFLAGS variable (the default for all preprocessor calls) or override individual preprocessor flags with target_CPPFLAGS . Makefile.am中的标志添加到AM_CPPFLAGS变量(所有预处理程序调用的默认值)或使用target_CPPFLAGS覆盖单个预处理程序标志。 In the example of a 3rd party library, it's best to use a name like: FOO_CPPFLAGS to hold preprocessor options, eg, 在第三方库的示例中,最好使用如下名称: FOO_CPPFLAGS来保存预处理器选项,例如,

FOO_CPPFLAGS="-I${FOO_DIR}/include -DFOO_BAR=1"
...
AC_SUBST(FOO_CPPFLAGS)

and in the Makefile.am : 并在Makefile.am

AM_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)
# or:
target_CPPFLAGS = -I$(top_srcdir) $(FOO_CPPFLAGS)

The top_srcdir variable is defined by configure - I use it to illustrate the 2nd case. top_srcdir变量由configure定义 - 我用它来说明top_srcdir情况。 Let's say you have file.h in another directory other , under the top-level directory. 比方说,你已经file.h在其他目录other ,顶级目录下。 -I$(top_srcdir) allows you to include it as <other/file.h> . -I$(top_srcdir)允许您将其包含为<other/file.h> Alternatively, -I$(top_srcdir)/other would allow you to include it as <file.h> . 或者, -I$(top_srcdir)/other允许您将其包含为<file.h>

Another useful preset variable is srcdir - the current directory. 另一个有用的预设变量srcdir - 当前目录。 -I$(srcdir) is added to AM_CPPFLAGS by default . -I$(srcdir) 默认添加到AM_CPPFLAGS So if file.h is in the current directory you can include it with <file.h> or even "file.h" . 因此,如果file.h位于当前目录中,则可以将其包含在<file.h>甚至"file.h" If other was a 'sibling' directory, -I$(srcdir)/.. would allow you to include <other/file.h> , and -I$(srcdir)/../other would allow <file.h> . 如果other是'sibling'目录, -I$(srcdir)/..将允许你包含<other/file.h> ,并且-I$(srcdir)/../other允许<file.h>


I'd also add that some packages install a pkg-config .pc file. 我还要补充一些软件包安装pkg-config .pc文件。 Provided the installation of pkg-config is set up to search the right directories, you might find the PKG_CHECK_MODULES macro very useful. 如果设置pkg-config的安装来搜索正确的目录,您可能会发现PKG_CHECK_MODULES宏非常有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM