我有一个使用自动工具套件的大型软件项目。当我需要调试复杂的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使事情复杂化了吗?
答案 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.s
与foo.c
一起保存,
后者已编译。
由于这些文件不在make
已知的目标之中,因此make clean
不会
自动删除它们(尽管它们的新鲜程度无关紧要,因为它们
总是clo不休)。如果要make clean
删除它们,请添加:
clean-local:
$(RM) *.i *.s
访问相关的Makefile.am
作为像这样对configure.ac
进行硬编码的替代方法,您可以
考虑使用{p> 1随时配置-save-temps
,
./configure CFLAGS=-save-temps