预处理C / C ++元程序

时间:2014-02-07 09:05:53

标签: c++ c metaprogramming

我们有一个大型C ++项目,并且只希望发布客户要求的代码,从而删除了所有不需要的代码。即如果我们有一些元程序,如:

/** File: calc.c */
#ifdef ENABLE_SOME_ADVANCED_FEATURE
/** Advanced calculations */
void AdvancedCalc(int a, int b) {
   // ...
}
#else
/** Basic calculations */
void BasicCalc(int a, int b) {
   // ...
}
#endif

我想要一些预处理C ++元程序的脚本,因此如果我只想在运行脚本后进行基本计算,那么文件将如下所示:

/** File: calc.min.c */
/** Basic calculations */
void BasicCalc(int a, int b) {
   // ...
}

因此,我们不想发布的所有代码都被删除了。

我确信那里肯定会有这样的事情。

更新

我认为How to get rid of ifdef's in a large c project有我正在寻找的解决方案。

5 个答案:

答案 0 :(得分:1)

Clang或G ++

g++ -E source.cpp
  

-E在预处理阶段后停止;不要运行编译器   正确。输出采用预处理源代码的形式   被发送到标准输出。

     

忽略不需要预处理的输入文件。

Visual Studio

预处理器输出到stdout

cl /E source.cpp

预处理器输出到文件

cl /P source.cpp

如何减少不需要的输出的示例(ignore-header.pl)

#!/usr/bin/perl

use warnings;
use strict;

while (my $line = <>) {

    if ($line !~ /^#include/) {
        print $line
    }
}

<强>执行

  

cat source.cpp | perl ignore-headers.pl | g ++ -E -nostdinc -nostdinc ++ -x c ++ -

<强>资源

G++ Manual

Visual Stuido Manual

GCC preprocessor

答案 1 :(得分:0)

您可以使用GCC预处理器

gcc -E

请参阅GCC preprocessor

答案 2 :(得分:0)

gcc -E filename应该做到这一点 GCC Options

答案 3 :(得分:0)

有几个选择:

  1. 您可以像其他人一样使用gcc -E建议,但您也可以添加-H标记来获取文件列表。

    2。您可以使用-MD进行编译,并生成.d个文件。您可以使用脚本或更好的方式处理.d文件,但您可以创建一个规则来压缩所有依赖项,作为编译的一部分。

  2. 我还想看看如何在/ usr / src / debug中删除源代码时生成debuginfo包(至少在RPM生态系统中)

答案 4 :(得分:0)

我准备了一个脚本:

  • 注释掉所有包含和不得触及的定义,使用一些“魔术通配符”,如//@TAKE_ME_BACK@并将其保存到临时文件中;
  • 运行cpp -C或临时文件上的任何预处理器(cpp -C的优点是文件不需要以.c终止)。重要提示:它不得删除评论(即-C)!
  • 取消注释 - 之前已注释掉的所有行,还原您的包含

如果你需要处理递归#ifdef,我认为awk范围语法(pattern1,pattern2)可能会有很大的帮助。

另一方面,如果你只需要忽略包含,那么这样的事情就可以完成:

sed 's|^#include|//@TAKE_ME_BACK@#include|' $file > $file.tmp
cpp -C $file.tmp > $file.tmp2
sed -e '/^#/d' -e 's|//@TAKE_ME_BACK@||' < $file.tmp2 > $file

(您还需要注意上一个sed中预处理器丢弃的#开头的行。)

注1:在示例中我提议原始文件被覆盖:谨慎处理:)

注意2:工作但未经过测试 - 只是一个要精心设计/定制的建议。