只计算一次 automake 变量
Posted
技术标签:
【中文标题】只计算一次 automake 变量【英文标题】:Evaluate automake variable only once 【发布时间】:2012-03-11 20:37:22 【问题描述】:我们正在使用automake
和autoconf
来构建我们的多包软件。我想知道如何用例如的输出填充变量shell脚本一次并重用它,例如对于需要的包含目录
INCLUDES := -I`some-ext-config --incdir`
在这里使用:=
而不是=
会使这个变量填充一次,所以some-ext-config
只会被调用一次(AFAIK 这来自普通的make
)。当然INCLUDES
是AM_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
中为子目录Makefile
s 添加AC_OUTPUT
s,而不是在每个子目录中调用configure
(这需要我们构建的 5 倍)。我们只需要移植到 GNU make,我是否正确理解没有办法只填充这些 automake 变量一次?
@honk:我不知道。另一种选择是从configure.ac
和subproject/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
的所有代码,这些代码也必须由***configure
在m4
宏中执行。这包括测试、AC_SUBSTS
和 Makefile
声明。
例如只使用一个子项目。这是***./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 变量的主要内容,如果未能解决你的问题,请参考以下文章
sh 脚本只显示工具的版本,如果它们安装在系统中。 (clang make automake autoconf cmake)
可移植地在 autoconf/automake 中包含 GLib 标头