You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

CMake交叉编译ARM时如何为汇编器设置独立编译标志?

解决CMake交叉编译时汇编器收到无效编译器选项/宏的问题

这个问题在ARM交叉编译场景里挺常见——CMake默认会把目标级的编译选项和宏定义传递给所有编译语言(包括汇编),但ARM汇编器arm-none-eabi-as并不支持GCC编译器专属的选项(比如-specs-ffunction-sections),对宏定义的处理逻辑也和C/C++编译器有差异。下面给你几个实用的解决方法:

方法1:用Generator Expression精准区分编译语言

这是现代CMake最推荐的做法,能让选项只作用于特定语言(C/C++),完全不会波及汇编编译流程:

1.1 过滤编译选项

把原来的target_compile_options()改成带语言判断的形式:

target_compile_options(fsfw_example PRIVATE
  $<$<COMPILE_LANGUAGE:C,CXX>:
    -mcpu=cortex-m7
    -mfpu=fpv5-d16
    -mfloat-abi=hard
    -mthumb
    -ffunction-sections
    -fdata-sections
    -specs=nosys.specs
    -specs=nano.specs
    -g
  >
)

$<$<COMPILE_LANGUAGE:C,CXX>:...>这个生成器表达式会让括号内的选项仅在编译C/C++文件时生效,汇编文件编译时会自动跳过这些不兼容的参数。

1.2 控制宏定义的作用范围

同样用生成器表达式限制宏只传给C/C++编译器:

target_compile_definitions(fsfw_example PRIVATE
  $<$<COMPILE_LANGUAGE:C,CXX>:
    STM32H743xx
    USE_HAL_DRIVER
  >
)

如果你的汇编代码确实需要某些宏,可以单独为ASM语言添加适配的定义:

target_compile_definitions(fsfw_example PRIVATE
  $<$<COMPILE_LANGUAGE:ASM>:
    # 这里放汇编器支持的宏定义
  >
)

方法2:全局配置汇编器专属选项

如果你更习惯全局配置的方式,可以分别设置C/C++和汇编器的全局编译参数:

# 为C/C++编译器设置专属选项
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -specs=nosys.specs -specs=nano.specs -g")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}")

# 为汇编器设置仅它支持的选项(移除-specs、-ffunction-sections等无效参数)
set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -g")

注意:全局配置的优先级低于目标级配置,所以要确保你没有在目标级重复添加那些汇编器不兼容的选项。

方法3:为单个汇编文件单独设置属性

如果只有少数汇编文件出问题,可以针对性地调整这些文件的编译属性:

# 指定需要特殊处理的汇编文件
set(ASM_TARGET_FILE bsp_stm32/startup_stm32h743xx.s)

# 清除该文件继承的目标级宏定义
set_source_files_properties(${ASM_TARGET_FILE} PROPERTIES
  COMPILE_DEFINITIONS ""
)

# 为该文件设置汇编器专属的编译选项
set_source_files_properties(${ASM_TARGET_FILE} PROPERTIES
  COMPILE_FLAGS "-mcpu=cortex-m7 -mfpu=fpv5-d16 -mfloat-abi=hard -mthumb -g"
)

这种方式灵活性高,适合零散的特殊汇编文件,但维护起来相对麻烦一些。

验证效果

修改后重新生成CMake构建文件并编译,你会看到汇编器的命令行里不再包含-DSTM32H743xx-specs=nosys.specs-ffunction-sections这些无效选项,只会保留汇编器支持的-mcpu-mfpu等参数。

内容的提问来源于stack exchange,提问作者Spacefish

火山引擎 最新活动