自动工具添加规则以生成预处理文件

时间:2018-09-10 21:50:20

标签: autotools

我有一个使用自动工具套件的大型软件项目。当我需要调试复杂的C宏时,有时我会查询预处理后的文件。

虽然我可以通过“ make V = 1”手动完成此操作,然后剪切并粘贴输出并添加-E标志,但是看来我应该能够在某处添加正确的规则来为我执行此操作

例如我已经可以做make src/driver/foo/some_object.o,但我也想做make src/driver/foo/some_object.i

这是一个简单的Makefile吗,我可以添加

.%i : %c
    $(CC) $(CPPFLAGS) -E -o $@

但是将该行添加到Makefile.am会导致

  make: *** No rule to make target src/driver/foo/some_object.i

libtool使事情复杂化了吗?

2 个答案:

答案 0 :(得分:2)

  

例如我已经可以做make src/driver/foo/some_object.o,但我也想做make src/driver/foo/some_object.i

很显然,如果不向Makefile添加适当的规则(通过Makefile.am),就不能做到后者。 Autotools不会自动提供用于构建.i文件的规则,GNU也不具有用于构建它们的隐式规则。 但是,如果确实要调用通常用于构建foo.o的相同配方,但是将-E标志传递给编译器,那么您应该能够通过在CFLAGS命令行上为make变量指定一个值来实现此目的。例如,

make src/driver/foo/some_object.o CFLAGS=-E

符合GNU政策和约定的Autotools构建系统本身不会在CFLAGS(或CPPFLAGS)中设置选项,这是所谓的“用户变量”,即项目构建器应该可以自由使用来指定选项。因此,以这种方式使用它不应掩盖任何其他选择(或者,如果这样做,那应该解决)。

这仍然应该将输出放在src/driver/foo/some_object.o中,尽管那是由于配方的(预期)形式,而不是目标名称。此外,如果.o文件已经存在并且是最新的,它将不执行任何操作。您可以通过将它们全部包装在一个小脚本中来解决这两个问题,也许是这样的:

preprocess.sh

#!/bin/bash

if [ $# -lt 1 ]; then
  echo Specify at least one file name 1>&2
  exit 1
fi

for path; do
  stem="${path%.[ioc]}"
  rm -f "${stem}.o"
  make "${stem}.o" CFLAGS=-E
  mv "${stem}.o" "${stem}.i"
done

您可以通过以下任何形式调用它:

./preprocess.sh src/driver/foo/some_object.i
./preprocess.sh src/driver/foo/some_object.o
./preprocess.sh src/driver/foo/some_object.c
./preprocess.sh src/foo.i src/bar.i src/driver/baz.o src/main/frobozz.c

但是也许您认为那是一个大错特错。您还说了话,

  

这是一个简单的Makefile吗,我可以添加

.%i : %c
    $(CC) $(CPPFLAGS) -E -o $@
     

但是将该行添加到Makefile.am中导致

  make: *** No rule to make target src/driver/foo/some_object.i

好吧,如果您准确地添加了 规则,那就不足为奇了。正确的GNU Make模式规则符合以下要求:

%.i : %.c
    $(CC) $(AM_CPPFLAGS) $(CPPFLAGS) -E -o $@ $<

请注意目标名称和先决条件名称的差异,但也不要忽略规则中的差异。 AM_CPPFLAGS部分是可选的,但末尾附加的$<是必填项。

另一方面,Autotools专注于生成跨平台,跨工具链的构建系统,并且诸如上述的模式规则特定于GNU make。因此,您实际上应该使用传统的后缀规则:

.c.i:
    $(CC) $(AM_CPPFLAGS) $(CPPFLAGS) -E -o $@ $<

此外,您必须以任何一种方式告诉Automake您正在提供默认情况下无法识别的后缀规则:

SUFFIXES = .i

Automake manual谈到了这个一般用例。

  

libtool使事情复杂化了吗?

在这种情况下不太可能。

答案 1 :(得分:0)

似乎您想静态配置生成以生成 每次C编译都经过预处理的.i文件。

您可以添加以下内容:

AC_SUBST(AM_CFLAGS,[-save-temps])

您的configure.ac。 (然后再次autoreconf./configure。)

-save-temps编译选项 使预处理的源foo.i和程序集foo.sfoo.c一起保存, 后者已编译。

由于这些文件不在make已知的目标之中,因此make clean不会 自动删除它们(尽管它们的新鲜程度无关紧要,因为它们 总是clo不休)。如果要make clean删除它们,请添加:

clean-local:
    $(RM) *.i *.s

访问相关的Makefile.am

作为像这样对configure.ac进行硬编码的替代方法,您可以 考虑使用{p> 1随时配置-save-temps

./configure CFLAGS=-save-temps