繁体   English   中英

生成的C文件和自动工具

[英]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'是不同的东西。

有两种主要选择:

  1. 在你的构建规则,只有依靠自动make变量(如$< )指的依赖。 make执行源外构建时,它将使用可行路径初始化自动变量。

  2. 通过显式路径引用源目录中的文件。

要单独使用选项(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.

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