如何配置SCONS以正确编译C、CPP及.S汇编文件?
问题描述
我有一个包含.c和.cpp文件的ARM项目,使用SCONS作为构建系统,此前一切运行正常。现需为项目添加SEGGER SystemView,其中包含SEGGER_RTT_ASM_ARMv7M.S汇编文件。当我按如下方式添加该文件时:
src = Glob('somepath/*.c') + \ Glob('someotherpath/*.c') + \ Glob('resources/segger/*.c') + \ Glob('resources/segger/*.S') program = env.Program("my-binary.elf", src)
SCONS未将该.S文件编译为目标文件,而是直接将其加入链接阶段:
arm-none-eabi-g++ -o build\my-binary.elf ...linker-options... object-file1.o object-file2.o resources\segger\SEGGER_RTT_ASM_ARMv7M.S
如何配置SCONS,使其像处理.c和.cpp文件一样将该汇编文件编译为目标文件?我的环境配置选项(为简洁起见省略了部分标志和路径):
env_options_arm_gcc = { "CC" : arch_arm_gcc + "gcc", "CXX" : arch_arm_gcc + "g++", "LD" : arch_arm_gcc + "g++", "AR" : arch_arm_gcc + "ar", "STRIP" : arch_arm_gcc + "strip", "TARGET_ARCH" : "arm", "PROGSUFFIX" : ".elf", "OBJSUFFIX" : ".o", "LIBPATH" : ["#src\\Device_Startup", "#build\\resources"], "LINKFLAGS" : ...linker_flags..., "CCFLAGS" : ...c/cpp compile flags... "CFLAGS" : '-std=gnu99', "CXXFLAGS" : '-std=c++11', "LIBS" : 'stdc++', "CPPPATH" : [ ...Include path... ] }
解决方法
SCONS默认未将大写.S后缀的文件关联到汇编构建器,且缺少ARM架构下的汇编器配置,可通过以下步骤修复:
1. 配置汇编器与汇编选项
在环境配置中添加AS(指定ARM汇编器)和ASFLAGS(匹配项目ARM内核的架构参数):
env_options_arm_gcc = { # ... 原有配置 ... "AS" : arch_arm_gcc + "as", # 也可使用gcc:arch_arm_gcc + "gcc",支持预处理汇编文件 "ASFLAGS" : "-mthumb -mcpu=cortex-m4", # 根据实际内核调整,比如cortex-m3 # ... 原有配置 ... }
若汇编文件包含C预处理器指令(如
#include、宏定义),建议用gcc作为汇编器,并在ASFLAGS中添加-x assembler-with-cpp,确保预处理正常执行。
2. 注册.S后缀到汇编构建器
SCONS默认处理小写.s后缀,需手动将大写.S关联到汇编构建器。创建环境后添加以下代码:
env = Environment(**env_options_arm_gcc) # 注册.S后缀的处理规则 env.Append(SUFFIXES = ['.S']) env['BUILDERS']['AS'].add_emitter('.S', env['BUILDERS']['AS'].emitters['.s'])
或更简洁的写法:
env['BUILDERS']['AS'].suffixes.append('.S') env['SUFFIXES'].append('.S')
3. 验证构建流程
修改后重新运行scons,SCONS会先将.S文件编译为.o目标文件,再参与链接。示例执行流程:
arm-none-eabi-as -o build/resources/segger/SEGGER_RTT_ASM_ARMv7M.o resources/segger/SEGGER_RTT_ASM_ARMv7M.S # 后续链接步骤 arm-none-eabi-g++ -o build/my-binary.elf ... object-files ... build/resources/segger/SEGGER_RTT_ASM_ARMv7M.o
额外注意事项
- 确保ASFLAGS中的架构参数与CCFLAGS保持一致,避免因架构不匹配导致链接错误。
- 若使用gcc作为汇编器,ASFLAGS可复用CCFLAGS中的部分参数(如
-mthumb、-mcpu),减少重复配置。
内容的提问来源于stack exchange,提问作者Staszek
相关产品推荐
相关产品推荐

