使用SCONS+KEIL ARMCLANG编译代码

wangbing · 16次点击 · 1天前

本帖旨在提供命令行方式使用 scons +keil armclang工具链对代码进行编译,keil还是必须要安装的。只是换一种方式,不用打开keil并且不再维护uvprojx文件(uvprojx删除)


如何从keil工程切换成这种方式进行编译,请下载后阅读ReadMe.txt中的步骤进行。


这里介绍几个关键点

  • keil路径自动检测。首次使用时,需要运行get_prj_files_from_uvprojx.bat,以检测keil安装路径、版本。如果检测失败,在prj_files.sconscript文件中(文本文件),就无法看到KEIL_INSTALL_DIR和KEIL_VERSION。此时需要开发者手动对这两个变量进行赋值。 KEIL的版本,可以从Keil IDE Help->uVision Help中获取,如下截图中取前版本号前两个数字即可。

image.png

这两个变量位于prj_files.sconscript文件末尾

KEIL_INSTALL_DIR = "C:/Keil_v5/ARM"

KEIL_VERSION = "533"


  • 运行get_prj_files_from_uvprojx.bat以得到prj_files.sconscript文件。

非首次运行,则手动维护prj_files.sconscript文件了,uvprojx文件可以不再需要了。


  • prj_files.sconscript 主要有DEFINS/SOURCES/INCLUDES/LIBRARYIES/EXIST_OBJS/KEIL_INSTALL_DIR/KEIL_VERSION


其中 DEFINES 用来定义全局宏定义, 可以插入多行,使用逗号结尾,最后一行不需要逗号

DEFINES = [
    "CONFIG_AUTOCONF_PRESET",
    "CONFIG_LIB_PRESET_BLE_1PERIPHERAL",
    "CONFIG_OM6626A=1",
    "_start=main",
]

SOURCES用来定义要编译的代码, 可以插入多行,使用逗号结尾,最后一行不需要逗号

SOURCES = [
    "../../../bsp/OM662X_EVB/board_om6626a_evb.c",
    "../../../common/call_tree_dump.c",
    "../../../common/hardfault_debug.c",
    "../../../common/om_fifo.c",
    "../../../common/om_libc_retarget.c",
    "../../../common/om_list.c",
    "../../../common/om_log.c",
    ...
]

INCLUDES用来引入要包含的路径, 可以插入多行,使用逗号结尾,最后一行不需要逗号

INCLUDES = [
    "../../../bsp/OM662X_EVB",
    "../../../bsp/include",
    "../../../common",
    "../../../components/ble/controller/include",
    ...
]


LIBRARYIES用来引入用户库文件, 可以插入多行,使用逗号结尾,最后一行不需要逗号

LIBRARIES = [
    "../../../third_party/xui/lib/keil_xui_cm4.lib"
]

EXIST_OBJS 用来引入已经存在的obj文件, 可以插入多行,使用逗号结尾,最后一行不需要逗号

EXIST_OBJS = [
    "../src/main/algo_motion.o"
]

 

  • 如何指定编译器前,编译后要执行的动作:

编译前(注意:只要scons检测到需要执行编译动作,这里才会执行,比如头文件源文件发生改变):

def pre_build_hook(target, source, env):
    print(">>> [PRE-BUILD HOOK] 开始构建项目!")
    print(f">>> 项目名称: {PROJECT}")
    print(f">>> 源文件数量: {len(SOURCES)}")
    print(f">>> 包含路径数量: {len(INCLUDES)}")
    if len(LIBRARIES) > 0:
        print(f">>> 库文件数量: {len(LIBRARIES)}")
    if len(EXIST_OBJS) > 0:
        print(f">>> 预编译对象文件数量: {len(EXIST_OBJS)}")
    return 0

可在该函数中添加os.system("before_build.bat")调用批处理。批处理中加入想要做的事情。


编译后(编译成功后会执行,注意:如果编译后发现axf, bin, hex等文件没以后发生变化,则不会执行):

def after_link_hook(target, source, env):
    print(">>> [POST-LINK HOOK] 链接已完成!")
    print(f">>> 生成文件: {target[0]}")
    return 0

同样可以在这个函数中添加os.system("after_build.bat")运行自定义批处理。


改变链接脚本SCT文件

修改SConstruct文件,如下变量定义,实际上就是一个相当于SConstruct文件的路径。

LDSCRIPT = f"{CUR_ROMLIB_DIR}ARM/linker_flash.sct"


改变“scons -c” 命令清理文件列表, 在SConstruct文件中改变CLEAN_FILES列表中内容。添加或删除都可以,可以是文件夹也可以是文件:

CLEAN_FILES = [
    PROJECT + ".dep",
    PROJECT + ".objs",
    PROJECT + ".map",
    PROJECT + ".bin",
    PROJECT + ".hex",
    PROJECT + ".dis",
    PROJECT + ".htm",
    ".sconsign.dblite",
    "user_lib.via",
    "__pycache__"
]


  • 如何改变编译器/ 连接器、汇编器的命令行参数

    打开SConstruct文件,修改其中的“CCFLAGS”、“ASFLAGS”、“LDFLAGS”即可。


后续改进点

自动识别uvprojx中定义的sct文件、编译前后动作、C/ASM Misc Control选项、Linker的Misc Control选项,敬请关注。

keil_scons_V7-202509226542.zip
被收藏 0  ∙  0 赞  
加入收藏
点赞
0 回复  
善言善语 (您需要 登录 后才能回复 没有账号 ?)

请先登录网站