在 autotool 中包含不同 bin_Programs 的不同库

Including different libraries for different bin_Programs in autotool

我们正在使用 Autotools 构建我们的 c++ 应用程序。我们正在 Makefile.am 中创建两个 bin_Programs,如下所示:

bin_PROGRAMS = \ applications/A/a \ applications/B/b

目前,我们为这两个程序添加了相同的库,如下所示:

INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @MYLIB_CFLAGS@ @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@

这是@MYLIB_CFLAGS@的定义:

MYLIB_CFLAGS=-I${mylib_include_dir}

Makefile.am中的变量为空如下:

applications_A_a_SOURCES = 

applications_A_a_LDADD =

applications_A_a_LDFLAGS =

我们正在为程序 b 定义相同的变量。

我注意到 b 程序不需要 @MYLIB_CFLAGS@include 并且在尝试更新 Glibc 时这会导致问题。我的问题是是否有办法为 "a" 应用程序包含 @MYLIB_CFLAGS@ 而不是 "b" 应用程序。 `

Currently, we are including the same libraries to both of these programs as below:

INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @MYLIB_CFLAGS@ @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@

弄清楚术语对您有好处,因为这将使您更容易就此类问题与他人交流并解释文档,例如 the Automake manual。为此,INCLUDES 变量的目的是保存编译器标志,这些标志指示应出现在 C 和 C++ #include 指令的搜索路径中的位置,或用于类似目的的编译器标志其他语言的编译器。它只是间接地与库有关,并且当按预期使用时,它肯定不会导致任何地方都包含任何内容。

此外,与您的问题更直接相关的是,这使得 INCLUDES 变量成为各种 *_CPPFLAGS 变量的附属物,这些变量通常用于传达旨在调制的标志预处理器的行为。这与旨在调整编译器行为的标志不同,后者指定了 *_CFLAGS (C)、*_CXXFLAGS (C++) 和其他一些标志。人们通常可以通过使用错误的变量来传达标志而侥幸逃脱,但这确实会有所不同。当然,project-specific 变量不需要遵守这些命名约定,但我更愿意这样做以保持清晰。

因此,考虑...

This is the definition of @MYLIB_CFLAGS@:

MYLIB_CFLAGS=-I${mylib_include_dir}

... 该变量传递的唯一标志是 -I 标志,因此如果我进行命名,该变量将是 MYLIB_CPPFLAGS。但这是一个project-specific变量,所以它的名字的意义是你决定的。

The variables in Makefile.am are empty as below:

嗯,这不是很有用,我怀疑它实际上误导了您。不必为 Automake 指定空变量。这样做对 Automake 的意义与完全省略变量没有什么不同,但我怀疑它可能给您的印象是 Makefile.am 中给出的变量是唯一可用的 per-target 变量。他们不是。事实上,还有 许多,如所列 in the manual

特别是,有(名义上的)变量 applications_A_a_CPPFLAGSapplications_B_b_CPPFLAGS,您可以在其中列出特定于一个目标或另一个目标的预处理器标志。这些是 global-effect 变量的累积值,例如 INCLUDES,因此解决所描述问题的一种方法是更改​​ INCLUDES 并添加 applications_A_a_CPPFLAGS,如下所示:

INCLUDES = -I@NE_ROOT@ -I@CORE_ROOT@/include @BOOST_CFLAGS@ @LOG4CPP_CFLAGS@

applications_A_a_CPPFLAGS = @MYLIB_CFLAGS@

现在 @MYLIB_CFLAGS@ 中的标志将仅用于建筑 applications_A_a

我还注意到,您说 all Makefile.am 文件中列出的 target-specific 变量是空的,这很可疑。这不一定是错误的,但请注意,不是 header-only 的库也需要以某种方式在链接器变量中表示。也许你有一个 LDADD 变量,通过它为所有目标指定相同的库(或者你可能用 AM_LDFLAGS 来做,这在某些情况下可能有效但不正确,或者你可能使用 LDFLAGS,这会更糟)。如果您需要这样做,那么指定特定于一个程序目标或另一个程序目标的二进制库的正确方法是通过变量 applications_A_a_LDADDapplications_B_b_LDADD.