CMake中为混合C/C++目标分别设置C/C++编译标志的方法
解决混合C/C项目中针对C单独设置
-fno-rtti的CMake方案 针对你遇到的这个混合C/C嵌入式项目的编译标志问题——需要给C单独加-fno-rtti,但又不能用全局FLAGS或直接给整个target加标志(会影响C文件触发警告),我有几个完全符合《Effective CMake》推荐的target-centric风格的解决方案:
方案一:使用Generator Expressions(最推荐)
CMake的生成器表达式可以精准地针对特定编译语言应用编译选项,完全不需要拆分库或者修改全局变量。你只需要把原来的target_compile_options改成带语言过滤的形式:
target_compile_options(my_target PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti> )
原理说明
$<$<COMPILE_LANGUAGE:CXX>:-fno-rtti>这个表达式的核心逻辑是:仅当编译C++源文件时,才应用-fno-rtti标志。CMake会自动识别目标中每个源文件的语言类型,给C文件跳过这个标志,完美避免了给C代码加-fno-rtti导致的警告(毕竟你的项目开启了-Werror没法忽略这些警告)。
这种方式完全符合《Effective CMake》中推荐的“针对目标而非全局设置选项”的原则,不会污染其他目标的编译环境,也不需要拆分你的代码到不同库中(解决了你之前拆分库后二进制异常的问题)。
备选方案:按语言分组管理源文件(适合复杂场景)
如果你的项目中C和C++源文件的分组很清晰,也可以通过分批次添加源文件并针对性设置选项:
# 先添加C源文件,不设置C++专属标志 target_sources(my_target PRIVATE src/file1.c src/file2.c ) # 添加C++源文件,并配合生成器表达式设置专属标志 target_sources(my_target PRIVATE src/file1.cpp src/file2.cpp ) target_compile_options(my_target PRIVATE $<$<COMPILE_LANGUAGE:CXX>:-fno-rtti> )
不过这个方案本质上还是依赖生成器表达式,只是把源文件分组更明确了,实际效果和方案一一致,通常方案一已经足够解决问题。
内容的提问来源于stack exchange,提问作者Daan Timmer
相关产品推荐
相关产品推荐

