【发布时间】:2010-11-14 01:27:09
【问题描述】:
我有一个 perl 脚本,我想在 gcc 正常处理它们之前过滤我的 cpp/h 文件——基本上作为一个额外的预处理步骤。是否有捷径可寻?我意识到我可以将 cpp 文件提供给脚本并让 gcc 从 stdin 读取输出,但这对头文件没有帮助。
【问题讨论】:
标签: c++ perl gcc preprocessor
我有一个 perl 脚本,我想在 gcc 正常处理它们之前过滤我的 cpp/h 文件——基本上作为一个额外的预处理步骤。是否有捷径可寻?我意识到我可以将 cpp 文件提供给脚本并让 gcc 从 stdin 读取输出,但这对头文件没有帮助。
【问题讨论】:
标签: c++ perl gcc preprocessor
处理此类过程的经典方法是将源代码(Perl 过滤器的输入)视为一种新语言,并带有新的文件后缀。然后告诉make,从这种新文件类型编译 C++ 源文件的方法是使用 Perl 脚本。
例如:
.ccp
新规则(假设.cc后缀):
.ccp.cc:
${FILTERSCRIPT} $<
将新后缀添加到后缀列表中 - 优先于普通 C++ 规则。
最后一点是最棘手的。如果只是将.ccp 后缀添加到列表中,那么当.cc 文件存在时,make 将不会真正关注.ccp 文件的变化。您要么必须删除中间 .cc 文件,要么确保 .ccp 在后缀列表中出现在 .cc 之前。 (注意:如果你写了一个没有'.ccp.cc'规则的'.ccp.o'规则并且不确保'.cc'中间被清理,那么编译失败后的重建可能意味着@ 987654335@ 只编译 '.cc' 文件,这可能会令人沮丧和困惑。)
如果更改后缀不是一个选项,则编写一个编译脚本进行过滤并直接调用 C++ 编译器。
【讨论】:
C 和 C++ 预处理器不支持这种东西。处理此问题的唯一方法是让您的 makefile(或其他)在调用编译器之前通过 perl 脚本处理所有文件。这显然非常困难,并且是不设计需要这样一步的架构的一个很好的理由。你在做什么让你认为你需要这样的设施?您可能不知道有更好的解决方案。
【讨论】:
运行 Perl 脚本然后调用 gcc 的 gcc 包装器怎么样?将其命名为 plgcc 并在您的 makefile 中设置 CC=plgcc。你的脚本必须足够聪明才能处理包含指令——除非你的脚本只调用预处理器来引入包含,做它的事情,然后调用 gcc。
【讨论】:
GCC 允许您使用自己的预处理器。您可以将脚本设置为预处理器,然后通过 cpp(普通的 gcc 预处理器)运行输出。查看 gcc 手册中的 -B 和 -no-integrated-cpp 命令行选项。
警告 - 我自己从未尝试过,所以不知道它可能会有多混乱(请记住,尽管多年来很多语言,包括 C++,都被实现为 ac 编译器的预处理器,所以不应该支持太糟糕了)。
【讨论】:
我过去曾通过以下方式处理过此类案例。这种方法假设可以通过某种命名方案来区分未处理的源代码,在这种情况下,用_pp 为基本名称添加后缀。
# These are your source files to be preprocessed
SRC_RAW = mysrc_pp.cpp
# These are the source files after preprocessing
SRC_PP = $(patsubst %_pp.cpp, %.cpp, $(SRC_RAW))
ALL_SRC = $(SRC) main.cpp other.cpp
OBJ = $(patsubst %.cpp, %.o, $(ALL_SRC))
$(SRC): %.cpp: %_pp.cpp
$(PERL) $< > $@
$(OBJ): %.o: %.cpp
$(CXX) ...
但是,这并不能处理您有需要预处理的头文件的情况。在这种情况下,您将需要类似的规则来创建它们。
【讨论】: