只计算一次 automake 变量

Posted

技术标签:

【中文标题】只计算一次 automake 变量【英文标题】:Evaluate automake variable only once 【发布时间】:2012-03-11 20:37:22 【问题描述】:

我们正在使用automakeautoconf 来构建我们的多包软件。我想知道如何用例如的输出填充变量shell脚本一次并重用它,例如对于需要的包含目录

INCLUDES := -I`some-ext-config --incdir`

在这里使用:= 而不是= 会使这个变量填充一次,所以some-ext-config 只会被调用一次(AFAIK 这来自普通的make)。当然INCLUDESAM_CPPFLAGS 的表亲,但如果我改用那个,每次编译都会调用shell 脚本。

使用INCLUDES 而不是AM_CPPFLAGS 对我来说是一个可以接受的解决方案(尽管我认为可能存在可移植性问题),但我没有解决方案,例如用于 libtool 库的 LDFLAGS

libmylib_la_LDFLAGS := `some-ext-config --ldflags` # will always be evaluated

如果我想确保这些外部工具不会被多次调用,automake 内部的一般解决方案是什么?我想避免在configure.ac 中使用明显的AC_SUBST,因为我们必须确保我们的包可以从子目录(其中一些configure.ac)以及从顶层和configure.ac 那里不需要对不同的子项目了解太多。

【问题讨论】:

【参考方案1】:

:= 是 GNU-make 特定的,因此建议您在 automake 中只使用 =。如果您不想每次都运行 shell 脚本 INCLUDES(或 AM_CPPFLAGS,没关系,两者都会发生),然后在 configure.ac 中运行脚本并通过 AC_SUBST 使用变量替换。这基本上就是 pkg-config 会做的事情——说到它,如果有一个 .pc 文件,你可以使用它而不是 some-ext-config。

# configure.ac
libfoo_CPPFLAGS=$(some-ext-config --incdir);
libfoo_LIBS=$(some-ext-config --libs);
AC_SUBST([libfoo_CPPFLAGS])
AC_SUBST([libfoo_LIBS])

# Makefile.am
AM_CPPFLAGS = -Iwhatever $libfoo_CPPFLAGS
bin_PROGRAMS = foo
foo_LDADD = $libfoo_LIBS

【讨论】:

嗯,我写道,出于某些外部原因,我不想将其放入configure.ac @honk:那么你将不得不解决这些外部原因(例如使用AC_CONFIG_SUBDIRS)或者放弃编写可移植的Makefile。 外部原因是我们希望能够在顶层Makefile.am 中为子目录Makefiles 添加AC_OUTPUTs,而不是在每个子目录中调用configure (这需要我们构建的 5 倍)。我们只需要移植到 GNU make,我是否正确理解没有办法只填充这些 automake 变量一次? @honk:我不知道。另一种选择是从configure.acsubproject/configure.ac 共享的autoconf 宏中AC_SUBST 你的变量。***configure.ac 已经知道子项目的Makefile,因此您可以安排将AC_OUTPUT 和所需的AC_SUBST 保留在同一个文件中。 我的意思是 AC_CONFIG_FILES 而不是 AC_OUTPUT,请参阅我更长的答案。【参考方案2】:

这是对我在对 jørgensen 的回答的评论中建议的更冗长的解释。

我了解您的***configure.ac 必须生成多个子项目的makefile,并执行所需的测试,这样您就不必在任何子项目中运行configure(子configure仅在您想要处理此特定子项目时提供服务)。

在这种情况下,您希望避免从各种configure.ac 中复制尽可能多的内容。我建议您考虑子configure 的所有代码,这些代码也必须由***configurem4 宏中执行。这包括测试、AC_SUBSTSMakefile 声明。

例如只使用一个子项目。这是***./configure.ac

AC_INIT([toplevel], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
SUB1_COMMON([sub1/])  dnl Stuff from the subproject
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

./Makefile.am:

ACLOCAL_AMFLAGS = -I sub1/m4
SUBDIRS = sub1

现在这里是子项目的sub1/configure.ac

AC_INIT([sub1], [1.0])
AM_INIT_AUTOMAKE([foreign -Werror])
AC_CONFIG_MACRO_DIR([m4])
SUB1_COMMON
AC_OUTPUT

m4/common.m4 中定义SUB1_COMMON

AC_DEFUN([SUB1_COMMON],
  [AC_SUBST([PYTHON3LIB], [`pkg-config --libs python3`])
   AC_CONFIG_FILES([$1Makefile])])

最后sub1/Makefile.am 只是:

ACLOCAL_AMFLAGS = -I m4
# Build something.
...

SUB1_COMMON 包含您希望在两个configure.ac 文件之间共享的所有代码,并使用参数$1 适当地重新定位配置文件。在此示例中,无论运行了哪个 configure,都将定义变量 PYTHON3LIB

【讨论】:

以上是关于只计算一次 automake 变量的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法在 Automake 中引用库?

sh 脚本只显示工具的版本,如果它们安装在系统中。 (clang make automake autoconf cmake)

使用 automake 并通过工具链进行配置

可移植地在 autoconf/automake 中包含 GLib 标头

使用 Automake 为 bin_SCRIPTS 中的每个文件应用一个命令

使用 automake 在 CentOS 上将 pkg-config 文件安装到正确的路径