CMake配置clang-tidy+GCC8.2编译嵌入式目标时armv6-m报错
我太懂你这个困扰了——想在嵌入式C项目里用clang-tidy提前揪bug,再用GCC 8.2编译armv6-m目标,结果CMake把GCC的架构参数直接传给了clang-tidy,导致它报错。核心问题其实是**CMake会把全局的CMAKE_CXX_FLAGS传递给所有C相关工具,包括clang-tidy**,但Clang(clang-tidy依赖的编译器)对ARM架构的参数格式和GCC完全不一样。
问题根源
GCC用-march=armv6-m指定架构,但Clang根本不认识这个写法——它需要用--target=armv6m-none-eabi这种完整的交叉编译目标字符串来识别ARM架构。当clang-tidy拿到GCC的-march参数时,自然会懵圈报错"unknown target CPU"。
解决方案
我们要做两件事:给clang-tidy指定正确的ARM目标参数,同时不让它继承GCC的专属编译选项。
1. 修改ClangTidy.cmake,给clang-tidy添加正确的目标参数
在设置CMAKE_CXX_CLANG_TIDY时,加上--target=armv6m-none-eabi,让clang-tidy明确知道要分析的是armv6-m架构的代码:
set(ENABLE_CLANG_TIDY ON CACHE BOOL "Add clang-tidy automatically to builds") if (ENABLE_CLANG_TIDY) find_program(CLANG_TIDY_EXE NAMES "C:\\Program Files\\LLVM\\bin\\clang-tidy.exe") if (CLANG_TIDY_EXE) message(STATUS "clang-tidy found: ${CLANG_TIDY_EXE}") set(CLANG_TIDY_CHECKS "-*,modernize-*") # 新增--target参数,指定armv6m的交叉编译目标格式 set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE};--target=armv6m-none-eabi;-checks=${CLANG_TIDY_CHECKS};-header-filter='${CMAKE_SOURCE_DIR}/*'" CACHE STRING "" FORCE) else() message(AUTHOR_WARNING "clang-tidy not found!") set(CMAKE_CXX_CLANG_TIDY "" CACHE STRING "" FORCE) # 清空无效配置 endif() endif()
2. 把GCC的架构参数从全局移到目标专属选项
别再用全局的CMAKE_CXX_FLAGS设置GCC的-march等参数了,改用target_compile_options给你的可执行目标单独添加,这样clang-tidy就不会拿到这些GCC专属参数:
set(TARGET STM32F070x6) set(ARCH armv6-m) set(CORE cortex-m0) # 移除全局CMAKE_CXX_FLAGS设置,改为给目标单独配置编译选项 add_executable(${TARGET}.elf ${MAIN_SOURCE}) # 用PRIVATE确保这些参数只传给GCC编译,不会被其他工具继承 target_compile_options(${TARGET}.elf PRIVATE -march=${ARCH} -mcpu=${CORE} -D${TARGET}) add_custom_target(size ALL arm-none-eabi-size ${TARGET}.elf DEPENDS ${TARGET}.elf) add_custom_target(${TARGET}.bin ALL DEPENDS ${TARGET}.elf COMMAND ${CMAKE_OBJCOPY} -Obinary ${TARGET}.elf ${TARGET}.bin)
额外提示
- 如果你用的LLVM版本偏旧,记得确认它支持
armv6m-none-eabi目标,一般LLVM 8及以上版本都没问题。 --target参数的格式是{arch}-{vendor}-{os}-{abi},这里armv6m-none-eabi是嵌入式ARM的标准格式,对应armv6-m架构、无特定厂商、无操作系统、EABI接口。
这样修改后,clang-tidy会用正确的ARM目标参数分析代码,GCC编译时也能拿到它需要的-march等参数,两者就不会再冲突啦。
内容的提问来源于stack exchange,提问作者David Ledger

