ARM交叉编译中CMake为汇编器配置独立编译标志的问题
解决ARM交叉编译中汇编器接收无效宏定义和编译选项的问题
这个问题非常典型——CMake默认会把目标级的编译选项和宏定义传递给所有类型的源文件编译器,包括汇编器,但arm-none-eabi-as并不支持-D宏定义参数,也不需要C/C++专属的编译标志(比如-std=gnu++11、-ffunction-sections)。下面是几种可靠的解决方法:
方法1:按语言类型拆分编译选项和宏定义
最清晰的方式是给C/C++和汇编分别指定专属配置,利用CMake的编译语言条件生成器表达式来区分,确保不同语言的编译器只拿到自己需要的参数:
# 针对C/C++源文件设置专属选项和宏定义 target_compile_options(fsfw_example PRIVATE $<COMPILE_LANGUAGE:C,CXX>: -g -specs=nosys.specs -specs=nano.specs $<COMPILE_LANGUAGE:C,CXX>: -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb $<COMPILE_LANGUAGE:C,CXX>: -ffunction-sections -fdata-sections -std=gnu++11 ) target_compile_definitions(fsfw_example PRIVATE $<COMPILE_LANGUAGE:C,CXX>: STM32H743xx $<COMPILE_LANGUAGE:C,CXX>: USE_HAL_DRIVER ) # 单独给汇编源文件设置适配的选项 target_compile_options(fsfw_example PRIVATE $<COMPILE_LANGUAGE:ASM>: -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -g )
这样CMake只会把对应语言的选项传递给对应的编译器,汇编器就不会收到-D宏定义和C/C++专属标志了。
方法2:覆盖汇编器的编译命令模板
如果你的项目已经有大量目标级配置,不想逐个拆分,可以直接修改CMake的汇编器编译命令模板,手动过滤掉无效参数:
# 获取默认的汇编编译命令模板 get_property(CMAKE_ASM_COMPILE_OBJECT_DEFAULT GLOBAL PROPERTY CMAKE_ASM_COMPILE_OBJECT) # 移除模板中的-D宏定义部分(正则匹配所有-D开头的参数) string(REGEX REPLACE "(-D[^ ]+ )" "" CMAKE_ASM_COMPILE_OBJECT "${CMAKE_ASM_COMPILE_OBJECT_DEFAULT}") # 同时移除不需要的C/C++标志,比如-specs、-ffunction-sections等 string(REPLACE " -specs=nosys.specs -specs=nano.specs" "" CMAKE_ASM_COMPILE_OBJECT "${CMAKE_ASM_COMPILE_OBJECT}") string(REPLACE " -ffunction-sections -fdata-sections" "" CMAKE_ASM_COMPILE_OBJECT "${CMAKE_ASM_COMPILE_OBJECT}")
这个方法会直接修改汇编器的调用命令,剔除掉所有-D开头的宏定义参数和无效的C/C++标志,仅保留汇编器需要的架构相关选项。
方法3:单独设置CMAKE_ASM_FLAGS
CMake有专门针对汇编器的全局变量CMAKE_ASM_FLAGS,你可以直接配置它,同时确保目标级的选项不会覆盖它:
# 清空默认的ASM_FLAGS,避免继承无效选项 set(CMAKE_ASM_FLAGS "") # 添加汇编器需要的架构标志 set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -g") # 确保目标级的C/C++选项只传给C/C++编译器 target_compile_options(fsfw_example PRIVATE $<$<COMPILE_LANGUAGE:CXX>: -std=gnu++11 -ffunction-sections -fdata-sections> $<$<COMPILE_LANGUAGE:C>: -ffunction-sections -fdata-sections> -g -specs=nosys.specs -specs=nano.specs -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb )
注意架构相关的选项(比如-mcpu)可以同时给C/C和汇编器,所以可以放在公共部分,而宏定义和C/C专属标志必须用条件表达式限定。
内容的提问来源于stack exchange,提问作者Spacefish
相关产品推荐
相关产品推荐

