[英]How do I strip out inactive #if directives with the gcc/g++ preprocessor?
我正在使用第三方开源项目,需要删除不活动的#ifs,#ifdefs等,以便更好地理解代码流。
有没有办法使用make来生成没有这些指令的源文件版本? 我想避免扩展宏,只需删除指令。
我在看https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html
似乎-dD和-fdirectives只是开始的好选择。
这些预处理文件将出现在哪里? 我在哪里添加这些命令以用于Makefile和“make”? 我尝试运行“make -n”来生成脚本并在-Wformat之后在脚本中添加g ++和gcc调用选项,但我没有注意到任何事情。
我不确定这是否复杂,但我也使用avr-gcc和avr-g ++。
我看过coan,它不支持#included #defines所以它不能用于此目的,我无法让sunifdef工作。 是否有一种方法可以使用预处理器执行此操作。
定义分散在当前文件,包含的文件和包含指定-Dfoo = opt选项的makefile之间。
您可以使用预处理器选项走上正轨。 -D将定义一个值为1的宏,-U将取消任何先前的定义(它将变为未定义),-fdirectives-only将禁止宏扩展。 除此之外,您可以将-E标志与gcc一起使用,以告诉它将预处理器输出作为单独的文件提供给您进行检查。 但是,我认为它们不会像你期望的那样。 CPP(C预处理器)输出可能会添加其他内容, 如此SO问题所示 ,您应该检查gnu CPP输出手册页 。 这就是你从CPP得到的东西。
听起来你想要能够剥离这个无关的代码并从那里开发。 要做到这一点,我会鼓励你再试一次unifdef。 这就是unifdef的目的,而CPP旨在为编译准备代码。 它们是不同的任务,因此您应该使用正确的工具。 它可以作为http://dotat.at/prog/unifdef/上的独立应用程序使用,并且内置于一些Linux Shell中 。
它允许您指定希望它定义或未定义的宏,并删除条件指令评估为false的代码块。 例如,您可以像这样运行它:
unifdef -I <path> -DMACRO1 -UMACRO2
它将通过C / C ++源文件搜索<path>指定的目录,查找#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的声明已被删除,因为它包含在预处理器#if
/ #endif
块中,其控制表达式的计算结果为false(我们告诉unifdef将MACRO2视为未定义)。 j的声明仍然存在,但#ifdef
和#endif
语句被删除,因为已知控制表达式为真。
取决于MACRO3的块保持不变,因为其状态未知。
对于其运行方式,还有很大的灵活性和控制力。
如果你决定你希望它是构建过程的一部分,你可以随时把它添加到你的makefile。
如果您没有可定义或未定义的宏的列表,您可以使用unifdef提供的“unifdefall”脚本,它将使用CPP自己发现源代码中的宏定义,并删除/保留代码块根据源代码中包含的定义。
是的,你可以(有点)用预处理器来做。 但unifdef和sunifdef是完成这个的工具,所以你应该使用它们。
假设
我的策略是使用像unifdef这样的程序。 我第一次这样做,我自己编写,你可能需要修改程序以产生所需的结果。
核心战略是:
一次一个符号,每次都要彻底测试。 有些符号可能会变得太难,如果你有超过一百万行的源代码和一百多个符号,它们都会失控。
最后一步:如果您修改unifdef,请随时将您的更改贡献给社区。 做得好是一项非常具有挑战性的任务!
使用make -n创建makefile生成的shell脚本。 转到运行avr-g ++的行并在所有其他选项之前添加-dM -E。 转到-o之后的文件,#define的列表就在那里(它应该是something.o)使用unifdef -f defineFile.o filename
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.