构建系统

构建流程

玄武OS的构建是从xwbd/电路板名称/目录下执行命令make开始的, 以$XWOS_BRD_DIR代表此目录。生成的文件全部位于$XWOS_BRD_DIR/wkspc中。

img

生成配置

  • 构建系统会调用脚本xwbs/util/el/mkcfg.el处理$XWOS_BRD_DIR/cfg下的 所有配置文件,将它们转化成$XWOS_BRD_DIR/wkspc/XuanWuOS.cfg, 这个配置文件之后会被构建系统引入。
## ******** ******** ******** basic info ******** ******** ******** ##
XuanWuOS_CFG_HOSTOS := gnu/linux # 编译主机的操作系统
XuanWuOS_CFG_ARCH := arm # 架构
XuanWuOS_CFG_SUBARCH := v7m # 子架构
XuanWuOS_CFG_COMPILER := gcc # 编译器
XuanWuOS_CFG_LDSCRIPT := cfg/XuanWuOS.lds # 连接脚本在$(XuanWuOS_CFG_BRD)中的路径
XuanWuOS_CFG_CPU := m4 # CPU子集名称
XuanWuOS_CFG_SOC := stm32f4x # SOC芯片名称
XuanWuOS_CFG_PERPHERAL := y # 是否启用外设库
XuanWuOS_CFG_BRD := fk429m # 电路板名称
XuanWuOS_CFG_CORE := smp # 内核是SMP还是UP
XuanWuOS_CFG_XWMD := y # 是否启用中间件
XuanWuOS_CFG_XWEM := y # 是否启用第三方模块
XuanWuOS_CFG_XWAM := y # 是否启用应用模块
XuanWuOS_CFG_MK_RULE := arm-cortex-m.gcc.rule # 选择xwbs目录下的编译规则文件
XuanWuOS_CFG_ELF_MK := arm-cortex-m.gcc.mk # 编译ELF的makefile文件
XuanWuOS_CFG_XWMO_MK := arm-cortex-m.gcc.xwmo.mk # 编译模块的makefile文件
## ******** ******** ******** ******** build Script info ******** ******** ******** ******** ##
XWBS_UTIL_MK_XWMO := xwbs/util/mk/xwmo.mk # 定义了编译玄武模块的一些辅助功能
## ******** ******** ******** directory info ******** ******** ******** ##
XWOS_PATH := /path/to/XuanWuOS # 玄武OS源代码的绝对路径
XWOS_KN_DIR := xwos # 内核文件夹
XWOS_MD_DIR := xwmd # 中间件文件夹
XWOS_EM_DIR := xwem # 第三方软件包模块文件夹
XWOS_AM_DIR := xwam # 应用模块文件夹
XWOS_ARCH_DIR := xwcd/soc/arm/v7m/gcc # 架构相关代码的路径
XWOS_CPU_DIR := xwcd/soc/arm/v7m/gcc/m4 # CPU相关代码的路径
XWOS_SOC_DIR := xwcd/soc/arm/v7m/gcc/m4/stm32f4x # SOC芯片相关代码的路径
XWOS_PP_DIR := xwcd/perpheral # 外设库文件夹
XWOS_BRD_DIR := xwbd/fk429m # 电路板目录
XWOS_BDL_DIR := xwbd/fk429m/bdl # 电路板相关代码的路径
XWOS_BM_DIR := xwbd/fk429m/bm # 电路板软件包模块文件夹
XWOS_OEM_DIR := xwbd/s32k144evb/oem # OEM模块文件夹
XWOS_WKSPC_DIR := xwbd/fk429m/wkspc # 生成文件的输出文件夹
  • 脚本xwbs/util/el/mkcfg.el会生成$XWOS_BRD_DIR/wkspc/autogen.h, 此文件会被自动包含在顶级头文件xwos/standard.h中。

  • 脚本xwbs/util/el/mkcfg.el最后会生成$XWOS_BRD_DIR/wkspc/env.rc, 在bashsource这个文件,可在终端环境中引入一些辅助功能

编译ADL

编译系统会根据编译规则$XWOS_ARCH_DIR/arch.mk, 编译架构描述层(Arch Description Layer)的源码, 并输出静态库arch.a$XWOS_WKSPC_DIR/obj目录下。

编译CDL

编译系统会根据编译规则$XWOS_CPU_DIR/arch.mk, 编译架构描述层(CPU Description Layer)的源码, 并输出静态库cpu.a$XWOS_WKSPC_DIR/obj目录下。

编译SDL

编译系统会根据编译规则$XWOS_SOC_DIR/soc.mk, 编译架构描述层(SOC Description Layer)的源码, 并输出静态库soc.a$XWOS_WKSPC_DIR/obj目录下。

编译BDL

编译系统会根据编译规则$XWOS_BDL_DIR/bdl.mk, 编译架构描述层(Arch Description Layer)的源码, 并输出静态库bdl.a$XWOS_WKSPC_DIR/obj目录下。

编译XWOS内核

编译系统会加载位于xwos/xwos.mk的编译规则,最后输出静态库 xwos.a$XWOS_WKSPC_DIR/obj目录下。

编译中间件

  • 编译系统会扫描xwmd/文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个中间件模块在$XWOS_BRD_DIR/cfg/xwmd.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

编译外设库

  • 编译系统会扫描xwcd/perpheral文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个外设库模块在$XWOS_BRD_DIR/cfg/perpheral.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

编译电路板软件模块

  • 编译系统会扫描$XWOS_BM_DIR文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个电路板软件模块在$XWOS_BRD_DIR/cfg/board.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

编译第三方软件模块

  • 编译系统会扫描xwem文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个外设库模块在$XWOS_BRD_DIR/cfg/xwem.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

编译应用模块

  • 编译系统会扫描xwam文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个外设库模块在$XWOS_BRD_DIR/cfg/xwam.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

编译OEM模块

  • OEM模块文件夹路径由配置XuanWuOS_CFG_OEMPATH指定,此配置位于 cfg/XuanWuOS.h中:
    • 如果配置为相对路径,则相对于玄武OS的根目录;
    • 可以配置为绝对路径;
    • 路径可以在玄武OS根目录之外。
  • 编译系统会扫描OEM模块文件夹下的xwmo.mk文件,生成模块列表, 依次将它们编译成.a静态库,输出到$XWOS_WKSPC_DIR/obj/oem目录下。
  • 每个xwmo.mk文件代表了一个模块,其中定义了模块相关的参数:源代码列表、 附加编译选项、头文件路径等。
  • 每个外设库模块在$XWOS_BRD_DIR/cfg/oem.h中都有一个编译开关的宏定义, 编译开关定义为1时表示包含这个模块,0未定义表示排除这个模块。
  • 编译开关的命名规则参考模块编译开关的命名规则

连接ELF文件

编译系统最终会将以上生成的所有.a静态库连接成XuanWuOS.elf文件, 连接脚本由$XWOS_BRD_DIR/$XuanWuOS_CFG_LDSCRIPT定义。

生成其他文件

编译系统会将XuanWuOS.elf文件转换成.bin文件以及.hex文件, 也会生成调试脚本等其他文件。

编译选项

  • ~V
    • 取值:
      • 1: 开启选项
      • 0: 关闭选项(默认值)
    • 用法:
make ~V=1
  • 作用:输出完整的编译过程

  • ~D

    • 取值:
      • 1: 开启选项(默认值)
      • 0: 关闭选项
    • 用法:
make ~D=0
  • 作用:优化编译,输出体积较小的二进制,但不利于调试。

玄武模块

玄武OS的外设驱动模块、电路板软件模块、中间件模块、第三方软件模块以及OEM模块, 都是使用xwmo.mk来描述编译规则的,将它们统一称为玄武模块xwmo.mk的设计原理类似于Android系统中的Android.mk。每个玄武模块都是 独立编译的,其中定义的编译参数、头文件只对自己有效,这可解决多个第三方软件集成 在一起时的头文件、符号冲突等问题。

示例,xwbd/fk429m/bm/cxxxwmo.mk

include $(XWOS_WKSPC_DIR)/XuanWuOS.cfg                 # 包含默认配置
include $(XWBS_UTIL_MK_XWMO)                           # 包含一些Makefile函数

XWMO_CSRCS := init.c                                   # 指定C源文件
XWMO_CFLAGS :=                                         # 指定附加的C编译规则

XWMO_CXXSRCS := task.cxx                               # 指定C++源文件
XWMO_CXXSRCS += operator/allocator.cxx                 # 增加C++源文件
XWMO_CXXSRCS += test/literal.cxx test/vector.cxx       # 增加C++源文件
XWMO_CXXFLAGS := -Wno-unused-value -Wno-literal-suffix # 指定附加的C++编译规则

XWMO_INCDIRS := $(call getXwmoDir)                     # 指定附加的头文件搜索路径
include xwbs/$(XuanWuOS_CFG_XWMO_MK)                   # 引用编译Makefile执行编译

模块路径命名规则

  • 由于模块路径需要对应于C语言中的一个宏定义作为编译开关, 因此模块路径需要符合C语言标识符的规则,但可以包含几个特殊符号:
    • 路径不能以数字开头;
    • 路径中每级目录以"/"隔开;
    • 路径中可包含".",但不能出现"../"和"./";
    • 路径中可包含"-";

模块编译开关的命名规则

  • 模块路径只需要转换相对路径部分:
    • 中间件模块:取xwmd(不含)之后的路径;
    • 外设驱动模块:取xwcd/perpheral(不含)之后的路径;
    • 电路板软件模块:取$XWOS_BM_DIR(不含)之后的路径;
    • 第三方软件模块:取xwem(不含)之后的路径;
    • 应用模块:取xwam(不含)之后的路径;
    • OEM模块:取oem目录(不含)之后的路径。
  • 路径中的"_",需要两个"_"来表示;
  • 路径中的"/"被转换成"_";
  • 路径中的"."被转换成"_";
  • 路径中的"-"被转换成"_";
  • 增加前缀:
    • 中间件模块:XWMDCFG
    • 外设驱动模块:PPCFG
    • 电路板软件模块:BMCFG
    • 第三方软件模块:XWEMCFG
    • 应用模块:XWAMCFG
    • OEM模块:OEMCFG
  • 示例:
    • 中间件模块:xwmd/isc/xwpcp –> XWMDCFG_isc_xwpcp
    • 外设驱动模块:xwcd/perpheral/ds/i2c/eeprom –> PPCFG_ds_i2c_eeprom
    • 电路板软件模块:xwbd/fk429m/bm/stm32_cube –> BMCFG_stm32__cube
    • 第三方软件模块:xwem/vm/l__u_a-5.4.0 –> XWEMCFG_vm_l____u__a_5_4_0
    • 应用模块:xwam/example/cxx –> XWAMCFG_example_cxx
    • OEM模块:oem/s32ksdk –> OEMCFG_s32ksdk
  • 可以借助辅助功能中的xwmc命令生成编译开关的宏标识符。

增加模块

  1. 中间件模块
    • 模块位于xwmd目录中;
    • 编译开关以XWMDCFG为前缀,位于文件$XWOS_BRD_DIR/cfg/xwmd.h, 定义为1表示编译模块。
  2. 外设驱动模块
    • 模块位于 xwcd/perpheral/ 目录中;
    • 编译开关以 PPCFG 为前缀,位于文件 $XWOS_BRD_DIR/cfg/perpheral.h , 定义为1表示编译模块。
  3. 电路板软件模块
    • 模块位于$XWOS_BRD_DIR/bm/目录中;
    • 编译开关以BMCFG为前缀,位于文件$XWOS_BRD_DIR/cfg/board.h, 定义为1表示编译模块。
  4. 第三方软件模块
    • 模块位于xwem/目录中;
    • 编译开关以XWEMCFG为前缀,位于文件$XWOS_BRD_DIR/cfg/xwem.h, 定义为1表示编译模块。
  5. 应用模块
    • 模块位于xwam/目录中;
    • 编译开关以XWAMCFG为前缀,位于文件$XWOS_BRD_DIR/cfg/xwam.h, 定义为1表示编译模块。
  6. OEM模块
    • 模块位于配置XuanWuOS_CFG_OEMPATH指定的目录中;
    • 编译开关以OEMCFG 为前缀,位于文件$XWOS_BRD_DIR/cfg/oem.h, 定义为1表示编译模块。
  7. xwmo.mk模板
include $(XWOS_WKSPC_DIR)/XuanWuOS.cfg # 包含配置文件
include $(XWBS_UTIL_MK_XWMO) # 包含一些Makefile函数,例如下面调用的getXwmoDir
XWMO_CSRCS :=             # C源文件
XWMO_CFLAGS :=            # 增加C编译选项
XWMO_CXXSRCS :=           # C++源文件
XWMO_CXXFLAGS :=          # 增加C++编译选项
XWMO_INCDIRS := $(call getXwmoDir)    # 获取模块路径并附加到头文件搜索路径
XWMO_LUASRCS :=           # 增加Lua源文件
include xwbs/$(XuanWuOS_CFG_XWMO_MK)  # 引用编译Makefile执行编译

辅助功能

为了方便开发,玄武OS定义了一些与模块编译相关的辅助命令。

初始化环境

source xwbd/fk429m/env.sh # 假设电路板名称是fk429m

命令

  • xwmc
    • 功能:获取模块编译开关的C语言宏标识符。
    • 用法举例:
cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmc
> XWEMCFG_vm_lua # 输出结果
  • xwmn
    • 功能:获取模块的 .a 文件名。
    • 用法举例:
cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmn
> xwem_vm_lua.a # 输出
  • xwm
    • 功能:编译整个玄武OS工程,类似Android的m命令。
    • 用法:xwm [选项] [目标]
    • 选项 -B:全部重新编译一次
    • 目标:make的目标
    • 用法举例:
xwm # 编译整个工程
xwm c # 清理
xwm d # 侧底清理
  • xwmm
    • 功能:单独编译模块,类似Android的mm命令,使用当前路径作为模块的路径。
    • 选项 -B:全部重新编译一次
    • 用法举例:
cd ${XWOS_PATH}/xwem/vm/lua # 进入到vm/lua模块中
xwmm
  • xwmmm
    • 功能:单独编译模块,类似Android的mmm命令,需要指定模块的路径。
    • 选项 -B:全部重新编译一次
    • 用法举例:
xwmmm xwem/vm/lua
  • xwcroot

    • 功能:切换到玄武OS的根目录,类似Android的croot命令。
  • xwcbd

    • 功能:切换到电路板目录。