SConstruct
使用 SConstruct 实现自动化构建。 SConstruct 是一种使用 Python 编写且经过改进可跨平台使用的 gnu make 替代工具。SConstruct 是一种更简便,更可靠,更高效的编译系统解决方案,一般简称 SCons。
SCons 是一种更现代的自动化构建解决方案,相比传统的 gnu make, 其特点更明显:
-
使用 Python 脚本做为配置文件,良好的夸平台性
-
内建可靠的自动依赖分析
-
支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex, 扩展性好,支持用户自扩展编程语言
-
支持 make -j 风格的并行构建,可以同时运行 N 个工作,而 不用担心代码的层次结构
-
使用 Autoconf 风格查找头文件,函数库,函数和类型定义
-
基于 MD5 识别构建文件的改变,更精准和安全
的 SConstruct 在 SDK 根目录下,主要用来配置编译逻辑和一些全局环境变量的设置,用户可以添加自己的私有的
ENV。
import os import sys # root directory AIC_ROOT = os.path.normpath(os.getcwd()) # custom scripts aic_script_path = os.path.join(AIC_ROOT, 'tools/scripts/') sys.path.append(aic_script_path) from aic_build import * chk_prj_config(AIC_ROOT) PRJ_CHIP,PRJ_BOARD,PRJ_KERNEL,PRJ_APP,PRJ_DEFCONFIG_NAME,PRJ_CUSTOM_LDS,MKIMAGE_POST_ACTION = get_prj_config(AIC_ROOT) PRJ_NAME = PRJ_DEFCONFIG_NAME.replace('_defconfig','') PRJ_OUT_DIR = 'output/' + PRJ_NAME + '/images/' AIC_SCRIPT_DIR = aic_script_path AIC_COMMON_DIR = os.path.join(AIC_ROOT, 'bsp/artinchip/sys/' + PRJ_CHIP) AIC_PACK_DIR = os.path.join(AIC_ROOT, 'target/' + PRJ_CHIP + '/' + PRJ_BOARD + '/pack/') # Var tranfer to SConscript Export('AIC_ROOT') Export('AIC_SCRIPT_DIR') Export('AIC_COMMON_DIR') Export('AIC_PACK_DIR') Export('PRJ_CHIP') Export('PRJ_BOARD') Export('PRJ_KERNEL') Export('PRJ_APP') Export('PRJ_NAME') Export('PRJ_DEFCONFIG_NAME') Export('PRJ_OUT_DIR') # Var tranfer to Kconfig 'option env=xxx' os.environ["AIC_ROOT"] = AIC_ROOT os.environ["AIC_SCRIPT_DIR"] = AIC_SCRIPT_DIR os.environ["AIC_COMMON_DIR"] = AIC_COMMON_DIR os.environ["AIC_PACK_DIR"] = AIC_PACK_DIR os.environ["PRJ_CHIP"] = PRJ_CHIP os.environ["PRJ_BOARD"] = PRJ_BOARD os.environ["PRJ_KERNEL"] = PRJ_KERNEL os.environ["PRJ_APP"] = PRJ_APP os.environ["PRJ_NAME"] = PRJ_NAME os.environ["PRJ_DEFCONFIG_NAME"] = PRJ_DEFCONFIG_NAME os.environ["PRJ_OUT_DIR"] = PRJ_OUT_DIR # rtconfig chip_path = os.path.join(AIC_ROOT, 'bsp/artinchip/sys/' + PRJ_CHIP) sys.path.append(chip_path) import rtconfig # RTT_ROOT if os.getenv('RTT_ROOT'): RTT_ROOT = os.getenv('RTT_ROOT') else: RTT_ROOT = os.path.join(AIC_ROOT, 'kernel/rt-thread/') os.environ["RTT_ROOT"] = RTT_ROOT sys.path.append(os.path.join(RTT_ROOT, 'tools')) from building import * # ENV_ROOT if os.getenv('ENV_ROOT') is None: ENV_ROOT = RTT_ROOT + '/../../tools/env' os.environ["ENV_ROOT"] = ENV_ROOT # TARGET TARGET = PRJ_OUT_DIR + rtconfig.SOC + '.' + rtconfig.TARGET_EXT rtconfig.LFLAGS += ' -T ' + ld # add post action rtconfig.POST_ACTION += MKIMAGE_POST_ACTION # create env env = Environment(tools = ['mingw'], AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS, CC = rtconfig.CC, CFLAGS = rtconfig.CFLAGS, CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS, AR = rtconfig.AR, ARFLAGS = '-rc', LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH) # add --start-group and --end-group for GNU GCC env['LINKCOM'] = '$LINK -o $TARGET $LINKFLAGS $__RPATH $SOURCES $_LIBDIRFLAGS -Wl,--start-group $_LIBFLAGS -Wl,--end-group' env['ASCOM'] = env['ASPPCOM'] # signature database env.SConsignFile(PRJ_OUT_DIR + ".sconsign.dblite") Export('RTT_ROOT') Export('rtconfig') # Var tranfer to building.py env['AIC_ROOT'] = AIC_ROOT env['AIC_SCRIPT_DIR'] = AIC_SCRIPT_DIR env['AIC_COMMON_DIR'] = AIC_COMMON_DIR env['AIC_PACK_DIR'] = AIC_PACK_DIR env['PRJ_CHIP'] = PRJ_CHIP env['PRJ_BOARD'] = PRJ_BOARD env['PRJ_KERNEL'] = PRJ_KERNEL env['PRJ_NAME'] = PRJ_NAME env['PRJ_APP'] = PRJ_APP env['PRJ_DEFCONFIG_NAME'] = PRJ_DEFCONFIG_NAME env['PRJ_OUT_DIR'] = PRJ_OUT_DIR # prepare building environment objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) # make a building DoBuilding(TARGET, objs)