CMake中target_compile_options设PRIVATE仍影响链接库编译选项问题
问题描述
我用target_compile_options给可执行文件main_full设置了PRIVATE编译选项,配置如下:
target_compile_options( main_full PRIVATE ### Gnu/Clang C Options $<$<COMPILE_LANG_AND_ID:C,GNU>:-fdiagnostics-color=always> $<$<COMPILE_LANG_AND_ID:C,Clang>:-fcolor-diagnostics> $<$<COMPILE_LANG_AND_ID:C,Clang,GNU>:-Wall> $<$<COMPILE_LANG_AND_ID:C,Clang,GNU>:-Wextra> $<$<COMPILE_LANG_AND_ID:C,Clang,GNU>:-Werror> $<$<COMPILE_LANG_AND_ID:C,Clang>:-Weverything> )
但发现这些编译选项(尤其是-Werror)被应用到了和该可执行文件链接的库(pico_stdlib、FreeRTOS-Kernel等)上,链接配置如下:
target_link_libraries( main_full pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 pico_cyw43_arch_none )
移除target_compile_options中的-Werror选项后,项目才能正常构建。想问下是不是遗漏了某些配置?或者有其他设置导致这个问题?
原因分析与解决办法
CMake中
PRIVATE编译选项理论上仅作用于目标本身(即main_full的编译过程),不会传递给依赖库。出现这个问题,大概率是以下几种情况:- 依赖库是当前项目的子模块(需要本地编译):如果这些库不是预编译好的二进制库,而是作为子项目在当前CMake工程中构建,Pico SDK的特殊配置可能会让可执行文件的部分编译属性传递给依赖库。
- 存在全局编译选项设置:检查CMakeLists.txt中是否有通过
CMAKE_C_FLAGS或CMAKE_CXX_FLAGS全局添加-Werror的代码,全局设置会作用于所有编译目标,包括依赖库。 - CMake版本bug:部分旧版本CMake对
PRIVATE选项的处理存在缺陷,升级到3.20以上的稳定版本可能解决问题。
针对问题的解决办法:
- 如果是依赖库被强制继承了编译选项,可以给这些库单独禁用
-Werror:
或者用循环批量处理:# 逐个给依赖库禁用Werror target_compile_options(pico_stdlib PRIVATE -Wno-error) target_compile_options(FreeRTOS-Kernel PRIVATE -Wno-error) target_compile_options(FreeRTOS-Kernel-Heap4 PRIVATE -Wno-error) target_compile_options(pico_cyw43_arch_none PRIVATE -Wno-error)foreach(lib IN ITEMS pico_stdlib FreeRTOS-Kernel FreeRTOS-Kernel-Heap4 pico_cyw43_arch_none) target_compile_options(${lib} PRIVATE -Wno-error) endforeach() - 排查全局编译选项,确保没有通过
CMAKE_C_FLAGS等全局变量添加-Werror,如果有,改成仅针对main_full用target_compile_options设置。
- 如果是依赖库被强制继承了编译选项,可以给这些库单独禁用
内容的提问来源于stack exchange,提问作者tonyjosi
相关产品推荐
相关产品推荐

