C++ 如何使用gcc/g+去除非活动的#if指令+;预处理器?

C++ 如何使用gcc/g+去除非活动的#if指令+;预处理器?,c++,c,gcc,C++,C,Gcc,我正在使用第三方开源项目,需要去掉不活动的ifs、ifdef等,以便更好地理解代码流 有没有一种方法可以使用make来生成没有这些指令的源文件版本?我希望避免扩展宏,只是删除指令 我在看 而且似乎只有-dD和-fdirectives才是开始的好选择 这些预处理文件将显示在哪里?在何处添加这些命令以与Makefile和“make”一起使用? 我试着运行“make-n”来生成一个脚本,并在-Wformat之后的脚本中为g++和gcc调用添加选项,但是我没有注意到任何事情 我不确定这是否会使事情复杂

我正在使用第三方开源项目,需要去掉不活动的ifs、ifdef等,以便更好地理解代码流

有没有一种方法可以使用make来生成没有这些指令的源文件版本?我希望避免扩展宏,只是删除指令

我在看

而且似乎只有-dD和-fdirectives才是开始的好选择

这些预处理文件将显示在哪里?在何处添加这些命令以与Makefile和“make”一起使用? 我试着运行“make-n”来生成一个脚本,并在-Wformat之后的脚本中为g++和gcc调用添加选项,但是我没有注意到任何事情

我不确定这是否会使事情复杂化,但我也在使用AVRCC和avr-g++


我看过coan,它不支持#include#defines,因此无法用于此目的,我无法让sunifdef工作。是否有一种方法可以通过预处理器实现这一点


定义分散在当前文件、包含的文件和包含的makefiles中,这些文件指定了-Dfoo=opt选项。

您的预处理器选项正确-D将定义一个值为1的宏,-U将取消以前的任何定义(它将变为未定义),而-fdirectives仅将抑制宏扩展。除此之外,您还可以在gcc中使用-E标志,告诉它将预处理器输出作为单独的文件提供,以供检查。然而,我不认为他们会像你期望的那样。CPP(C预处理器)输出可能添加了其他内容,如所建议的,您应该检查gnu。这就是你将从CPP得到的

听起来您希望能够一次性剥离这些无关的代码,并从中进行开发。为此,我鼓励您再试一次。这就是unifdef的设计目的,而CPP的设计目的是为编译准备代码。它们是不同的任务,因此您应该为它们使用正确的工具。它作为一个独立的应用程序在上提供,并内置于某些应用程序中

<>它允许您指定要考虑定义或未定义的宏,并移除有条件指令将其估计为false的代码块。例如,您可以这样运行它:

unifdef-I-DMACRO1-UMACRO2

它将通过C/C++源文件搜索指定的目录,查找
\if
\ifdef
\ifndef
等。当遇到它们时,它将计算条件表达式并有选择地删除由该表达式控制的代码。考虑一个带有此代码的输入文件:

int i = 0;
#ifdef MACRO1
int j = 0;
#endif /* ifdef MACRO1 */
int k = 0;

int m = 0;
#if (MACRO1 && MACRO2)
int n = 0;
#endif /* if (MACRO1 && MACRO2) */
int p = 0;

int q = 0;
#ifdef MACRO3
int r = 0;
#endif /* ifdef MACRO3 */
int t = 0;
如果我们像上面的示例那样调用unifdef,则输出如下:

int i = 0;
int j = 0;
int k = 0;

int m = 0;
int p = 0;

int q = 0;
#ifdef MACRO3
int r = 0;
#endif /* ifdef MACRO3 */
int t = 0;

注意,N的声明已被删除,因为它包含在预处理器<代码>中,如果/Cux> Enff块,其控制表达式被评估为false(我们告诉UNIFDEF考虑宏2未定义)。j的声明仍然存在,但是由于已知控制表达式为true,因此删除了

#ifdef
#endif
语句

依赖于MACRO3的块保持不变,因为其状态未知

对于如何运行,也有很大的灵活性和控制

如果您决定希望它成为构建过程的一部分,您可以随时将其添加到makefile中

如果没有应定义或未定义宏的列表,可以使用unifdef提供的“unifdefall”脚本,它将使用CPP自行发现源代码中的宏定义,并根据源代码中包含的定义删除/保留代码块

TL;博士 是的,你可以(某种程度上)用预处理器来做。但是unifdef和sunifdef是专门为实现这一点而设计的工具,因此您应该使用它们。

  • 本练习的目的是生成一个C/C++源代码体,其中大部分条件编译被删除,并编译为相同的二进制文件
  • 这是第三方源代码,您知道合并后续更新的问题
  • 这是开源的,但您不打算分发修改过的源代码
  • 这些程序是任意复杂的,由任意复杂的makefile或类似工具构建,带有命令行符号定义和/或配置include文件
  • 我的策略是使用像unifdef这样的程序。第一次这样做时,我自己编写了一个程序,您可能需要修改程序以产生所需的结果

    核心战略是:

  • 识别一个可能定义的符号(需要实验或试验和错误)
  • 通过unifdef运行代码
  • 或者,直观地比较源代码之前和之后,以发现明显的问题
  • 生成后版本以确保其正确生成
  • 编译before和after版本,以使用相同的makefile生成预处理的输出
  • 比较预处理前后的源代码对。它们应该是相同的,给或取一些空白
  • 根据需要在版本之前或之后进行编辑,以解决问题
  • (可选)从所有生成文件中删除对符号的所有引用。[这应该没有什么区别。]
  • 重复此操作,使用后一版本和其他符号
  • 每次一个符号,每次都要彻底测试。有些符号可能太难了,如果你有超过一百万行的源代码和上百个左右的符号,这些符号都会失控


    最后一步:如果您修改了unifdef,那么可以将您的更改贡献给社区。这是一项非常具有挑战性的任务,需要做好

    使用make-n创建