简体   繁体   English

生成的C文件和自动工具

[英]A generated C file and autotools

In an autoools-based build, I'd like to replace a version-controlled C file with a generated C file. 在基于autoools的构建中,我想用生成的C文件替换版本控制的C文件。

This dummy, hello world example sort-of works: 这个虚拟的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)

except it prevents me from doing an out-of-tree build such as: 除了它阻止我进行树外构建,例如:

mkdir B
cd B
../configure
make

which I can normally do in an autotools-based package. 我通常可以在基于autotools的程序包中执行此操作。 How can I generated the C file so that out-of-tree builds continue to work? 如何生成C文件,以便树外构建继续工作?

It is important to remember that make doesn't really know much about directories; 重要的是要记住, make对目录的了解并不多。 for the most part, everything is a string to it. 在大多数情况下,一切都是字符串。 That's not always so obvious, but it tends to really bite you when you are trying to write a build system that can handle out-of-source builds. 这并不总是那么明显,但是当您试图编写可以处理源代码外构建的构建系统时,它往往会给您带来极大的困扰。

You provide a build rule wherein hello.c depends on your generate script, which is fine in principle. 您提供了一个构建规则,其中hello.c取决于您的generate脚本,原则上很好。 Make will even handle the dependency processing correctly in an out-of-source build, finding the generate script in the source directory. Make甚至可以在源外构建中正确处理依赖项处理,在源目录中找到generate脚本。 But the recipe in the build rule explicitly runs ./generate , which does not exist when you're performing an out-of-source build. 但是构建规则中的配方显式运行./generate ,当您执行源外构建时不存在。 Furthermore, you have a disconnect between the dependency and the build rule: 'generate' is not the same thing as './generate'. 此外,在依赖项和构建规则之间存在脱节:'generate'与'./generate'是不同的东西。

There are two main alternatives: 有两种主要选择:

  1. In your build rules, rely only on automatic make variables (eg $< ) to refer to dependencies. 在你的构建规则,只有依靠自动make变量(如$< )指的依赖。 When make is performing an out-of-source build, it initializes automatic variables with viable paths. make执行源外构建时,它将使用可行路径初始化自动变量。

  2. Refer to files in the source directory via explicit paths. 通过显式路径引用源目录中的文件。

To use option (1) by itself, you would need to work around the problem of how to run the generate script when it is (presumably) not in the path. 要单独使用选项(1),您需要解决(大概)不在路径中时如何运行generate脚本的问题。 You can do that by running it indirectly, via the shell. 您可以通过外壳间接运行它来实现。 The make rule you would want in that case would be 在这种情况下,您想要的制造规则是

hello.c: generate
    $(SHELL) $<

That should work for either in-source or out-of-source building. 这对于源内或源外构建均适用。 The $(SHELL) make variable should be provided by the Autotools. $(SHELL) make变量应由Autotools提供。

To use option (2), on the other hand, you would probably rely on $(srcdir) or $(top_srcdir) : 另一方面,要使用选项(2),您可能会依赖$(srcdir)$(top_srcdir)

# Note that the dependency name will always contain a '/':
hello.c: $(srcdir)/generate
    $<

(You can also name the generate script, with path, in the build recipe, but it's usually best to avoid repeating yourself.) The $(srcdir) and $(top_srcdir) variables are also provided by the Autotools. (您也可以在构建配方中使用路径命名生成脚本,但是通常最好避免重复。)Autotools也提供$(srcdir)$(top_srcdir)变量。 The former refers to the directory in the source tree that corresponds to the build-tree directory we are currently building; 前者是指源树中与我们当前正在构建的build-tree目录相对应的目录; the latter refers to the source-tree directory containing the configure script. 后者是指包含configure脚本的源树目录。

Of those two, I'd rate (1) a bit more in the spirit of out-of-source building, but there isn't really that much difference. 在这两个代码中,我本着外包资源的精神对(1)进行了更多评价,但实际上并没有太大区别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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