如何向BSD系统GCC传递自定义编译标志设置编译期MACRO
解答
完全可以实现,不需要给GCC加什么自定义的特殊编译开关,用GCC原生支持的标准参数就能满足你编译期确定逻辑、裁剪二进制适配ELF分发环境的需求,全程没有运行时判断开销。
- 你要的「传对应编译标志就自动在代码里生效对应宏」的效果,直接用GCC的
-D参数即可,这个参数是所有类Unix环境(包括你用的BSD环境)下GCC的通用标准参数,和你之前查到的Visual Studio编译器的自定义flag逻辑不通用,不要套MSVC的使用规则。
实际用法非常简单:如果你要启用你说的flagset对应的逻辑,编译时直接加参数-DFLAGSET即可,GCC会在预处理阶段自动定义名为FLAGSET的宏,不需要你在代码文件里额外写#define语句。 - 代码端直接用标准条件编译语法写就行,未被选中的分支会在预处理阶段被完全剔除,不会出现在最终生成的ELF二进制里,示例写法:
// 业务逻辑片段 #ifdef FLAGSET // 传入-DFLAGSET参数时才会被编译进二进制的函数集 void target_func_group() { // 对应专属逻辑 } #else // 默认编译(不带-DFLAGSET参数)时启用的函数集 void target_func_group() { // 默认分支逻辑 } #endif
- 如果你一定要用
-flagset这种不带前缀D的参数形式,自己写个10行以内的shell包装脚本,把传入的-flagset参数自动替换为-DFLAGSET再调用真实gcc二进制就行,不过实际完全没必要:-D是GCC、Clang等所有类Unix编译器通用的标准参数,make、cmake、autotools等所有常见构建工具都原生支持,没有任何兼容性问题。
补充说明:如果需要给宏指定具体值,直接写成
-D宏名=值即可,比如-DFLAGSET=2,和你在代码里写#define FLAGSET 2效果完全一致;如果只写-D宏名,该宏会被默认定义为1。不要用运行时变量加if判断的方式做逻辑选择,这种方式下未触发分支的代码大概率会被保留在最终二进制里,达不到你编译期裁剪的目的。
内容的提问来源于stack exchange,提问作者Noah
相关产品推荐
相关产品推荐

