[英]A generated C file and autotools
在基于autoools的构建中,我想用生成的C文件替换版本控制的C文件。
这个虚拟的hello世界示例排序工作:
#!/bin/sh -ex
cat > configure.ac <<EOF
AC_INIT([hello], [0.01])
AC_PREREQ([2.68])
AC_CONFIG_SRCDIR([hello.c])
AC_CONFIG_AUX_DIR([build-aux])
AM_INIT_AUTOMAKE([1.11])
AC_CONFIG_FILES([Makefile])
AC_PROG_CC
AC_OUTPUT
EOF
cat > autogen.sh <<EOF
touch NEWS README AUTHORS ChangeLog COPYING
autoreconf -i
EOF
chmod +x autogen.sh
printf "
bin_PROGRAMS = hello
hello_SOURCES = hello.c
hello.c: generate
\t./generate
" > Makefile.am
cat > hello.c <<EOF
#include <stdio.h>
int main()
{
puts("hello world");
return 0;
}
EOF
cat > generate <<EOF0
#!/bin/sh
cat > hello.c <<EOF
#include <stdio.h>
int main()
{
puts("HELLO WORLD");
return 0;
}
EOF
EOF0
chmod +x generate
./autogen.sh
./configure
make -j$(nproc)
除了它阻止我进行树外构建,例如:
mkdir B
cd B
../configure
make
我通常可以在基于autotools的程序包中执行此操作。 如何生成C文件,以便树外构建继续工作?
重要的是要记住, make
对目录的了解并不多。 在大多数情况下,一切都是字符串。 这并不总是那么明显,但是当您试图编写可以处理源代码外构建的构建系统时,它往往会给您带来极大的困扰。
您提供了一个构建规则,其中hello.c
取决于您的generate
脚本,原则上很好。 Make
甚至可以在源外构建中正确处理依赖项处理,在源目录中找到generate
脚本。 但是构建规则中的配方显式运行./generate
,当您执行源外构建时不存在。 此外,在依赖项和构建规则之间存在脱节:'generate'与'./generate'是不同的东西。
有两种主要选择:
在你的构建规则,只有依靠自动make
变量(如$<
)指的依赖。 当make
执行源外构建时,它将使用可行路径初始化自动变量。
通过显式路径引用源目录中的文件。
要单独使用选项(1),您需要解决(大概)不在路径中时如何运行generate
脚本的问题。 您可以通过外壳间接运行它来实现。 在这种情况下,您想要的制造规则是
hello.c: generate
$(SHELL) $<
这对于源内或源外构建均适用。 $(SHELL)
make变量应由Autotools提供。
另一方面,要使用选项(2),您可能会依赖$(srcdir)
或$(top_srcdir)
:
# Note that the dependency name will always contain a '/':
hello.c: $(srcdir)/generate
$<
(您也可以在构建配方中使用路径命名生成脚本,但是通常最好避免重复。)Autotools也提供$(srcdir)
和$(top_srcdir)
变量。 前者是指源树中与我们当前正在构建的build-tree目录相对应的目录; 后者是指包含configure
脚本的源树目录。
在这两个代码中,我本着外包资源的精神对(1)进行了更多评价,但实际上并没有太大区别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.