gcc -save-temps选项

在很多开源项目中,作者喜欢用宏定义以及预处理中的拼接技术来生成一些函数。比如,在QEMU的源码中就使用这种方式来定义函数

//  file1
#define
xglue(x, y) x ## y #define glue(x, y) xglue(x, y)
// file2 #define HELPER(name) glue(helper_, name)
// file3
uint32_t HELPER(clz)(uint32_t x) { return clz32(x); }

其实最终的效果就是定义了

uint32_t helper_clz(uint32_t x)
{
    return clz32(x);
}

这种办法给项目的作者减少了一些重复书写的过程,但是却给阅读代码的人带来了很大的障碍。

为了解决这个问题,可以输出预处理之后的源码,方便阅读的过程中进行分析。gcc提供了一个选项-save-temps,可以保存编译过程中的中间文件,这里面就包括了预处理之后的源码。

在阅读QEMU代码的时候,可以在configure的过程中加入这个选项,比如

./configure --target-list=arm-softmmu --extra-cflags=-save-temps

由于QEMU支持的平台很多,target-list指定多个目标可能会多次编译,后生成的中间文件可能会覆盖之前生成的,所以建议每次只添加一个目标。