rtthread_scons简介
env工具基本構成
打開ENV工具進入具體工程目錄
C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer
menuconfig工作機制
Kconfig文件:
(目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer)
用戶退出交互界面并保存配置,menuconfig根據內部數據庫內容,生成新的.config文件。
.config文件:
將.config文件翻譯成c語言能夠識別的rtconfig.h文件,位于當前工作目錄下。
通過上面的步驟,menuconfig根據用戶的配置,最終生成了rtconfig.h文件,用戶便可以直接引用rtconfig.h文件來使用系統宏。從下面截取的示例可以看到rtconfig.h文件和.config文件是一 一對應的關系
rtconfig.h文件:
SCons基本命令
scons
編譯指令,根據scons腳本(SConstruct, SConscript)的配置,組織編譯代碼。scons命令必須在工程路徑下執行,因為scons默認會在當前路徑下尋找SConstruct文件作為第一個解析的腳本。
scons支持增量編譯,對已經編譯過的文件,且編譯后沒有進行過修改,那scons不會重新編譯這些文件,從而達到提高編譯效率的目的。
scons --verbose
直接使用scons編譯時,默認是不會輸出編譯選項等信息的。使用scons --verbose進行編譯時,將會打印編譯器選項等輔助信息。
scons -c
清除上一次編譯的臨時文件。執行該命令后,下一次編譯將能保證所有源文件都會被重新編譯。
scons --help
幫助命令,該命令會例舉出scons支持的所有操作選項,包括原生scons自帶的選項與OneOS擴展的操作選項。scons支持的操作選項很豐富,推薦讀者都去了解一下。
scons --ide=xxx
生成第三方IDE工程命令,其中“XXX”對應想要生成的工程類型。具體支持的工程類型可以通過scons --help查看。舉例生成keil5工程的命令如下:
scons --ide=mdk5
需要注意的是,要生產指定的IDE工程文件,一般需要提供一個空的工程文件作為模版,用戶應該在相應的模版文件中配置好硬件相關的編譯選項。具體可以參考示例開發板的工程目錄中的文件。
SCons編譯構造概述
Scons是構造工具,通過讀取SConstruct/Sconstruct/sconstruct和SConscript腳本來組織管理源碼,并調用指定的編譯鏈接器來對源文件進行編譯。
scons目前支持的編譯器包括 ARM GCC、MDK、IAR、VisualStudio、Visual DSP。對流行的ARM Cortex M0、M3、M4 等架構,一般都同時支持ARM GCC、MDK、IAR 等編譯器。用戶可以通過 project 目錄下的osconfig.py 里的 CROSS_TOOL 選項查看相關的編譯器配置。
使用SCons工具時,會使用到SConstruct/Sconstruct/sconstruct和SConscript 2種類型的文件。這2種類型的文件是Scons工具必備的,是編譯的配置腳本文件,相當于make中的makefile文件。
Scons將在當前目錄下按SConstruct、Sconstruct、sconstruct次序來搜索配置文件,從讀取的第1個文件中讀取相關配置。
在配置文件SConstruct中,可以使用SConscript()函數來讀取附屬的配置文件。按慣例,這些附屬配置文件被命名為“SConscript”。
SCons的擴展性
scons的配置文件都是基于python腳本語法的。因此可以在SConstruct文件中使用python語言很方便的調用自定義的python腳本與模塊。
同時,scons自身也是python實現的,在自己的python腳本文件中通過添加語句:
from SCons.Script import *
可以很方便的直接使用scons內置類與操作。正因為scons與python腳本可以方便的互相調用,我們可以對scons方便的進行自定義與擴展。
SCons常用函數
腳本涉及到的函數分為兩部分:標準函數,自定義函數。
Import()、Export()函數
Import(vars)
導入其它腳本定義的變量
‘vars’變量名,變量名是字符串,可以是一個變量或一個變量列表
Export(vars)
導出變量,供其它腳本使用
‘vars’變量名,變量名是字符串,可以是一個變量或一個變量列表
SConscript()函數
SConscript(scripts, [exports, variant_dir, duplicate])
讀取一個或多個sconscript腳本,返回一個node列表,node是指一個編譯對象
‘scripts’:指定要加載的sconscript腳本名稱與路徑
‘exports’:可選參數,導出一個變量,此變量比一般Export()導出的變量有更高優先權
‘variant_dir’:可選參數,指定一個目錄,編譯動作都在該目錄中進行,不影響源碼路徑
‘duplicate’:可選參數,指定編譯目錄中是否拷貝源碼
PresentDir()函數
PresentDir()
獲取當前腳本所在路徑
Glob()函數
Glob(pattern)
返回滿足pattern指定條件的Node(編譯對象)
‘pattern’:指定匹配條件,支持unix shell的通配符替換。支持當前腳本所在路徑進行相對路徑索引
IsDefined()函數
IsDefined(depend)
判斷依賴的宏或宏列表是否被定義,被定義返回True,如果存在未被定義的宏返回False
‘depend’:指定依賴的宏,或宏列表
DeleteSrcFile()函數
DeleteSrcFile(src, remove)
將指定的文件從編譯列表中移除
‘src’:編譯node列表
‘remove’:指定被移除的文件
AddCodeGroup()函數
AddCodeGroup(name, src, depend, **parameters)
將編譯對象添加到一個代碼組中進行編譯管理,返回編譯對象列表
‘name’:指定代碼組名稱,如果該名稱已經存在,則將添加到已經存在的組中。在keil工程中以該名稱呈現一個工作組
‘src’:指定要被添加的編譯對象列表
‘depend’:關鍵字參數,指定創建該組依賴的宏,如果條件宏不滿足,則直接返回空列表
‘parameters’:可變關鍵字參數,指定相應的編譯行為,支持的關鍵字如下:
CPPPATH指定頭文件路徑,對應gcc的-I
CCFLAGS對應gcc的–include選項
CPPDEFINES定義編譯宏,對應gcc的-D
LINKFLAGS定義鏈接選項
LOCAL_CPPPATH
定義僅對當前組有效的頭文件路徑選項
SCons的編譯環境類
scons中的一個基本類是構造環境Environment,scons對編譯源碼的管理,以及對編譯行為的控制都是通過配置構造環境(Env)來管理的。通過調用Environment()可以創建一個構造環境對象(Env)
配置Env對象中的各個變量,我們可以方便的定義需要的編譯行為。簡單舉例:
通過CPPPATH變量可以添加gcc編譯的-I選項
通過CPPDEFINES變量可以添加gcc的-D選項
通過CC變量可以指定C語言的交叉編譯器
通過RESULT_SUFFIX變量可以指定生成目標文件的類型
通過env[‘ENV’][‘PATH’]變量可以指定交叉編譯工具鏈的路徑
python基礎知識
os函數
- os.system() #運行shell命令
- os.name #返回當前使用平臺的代表字符,Windows用’nt’表示,Linux用’posix’表示
- os.sep #返回當前操作系統特定的路徑分隔符,window和Linux通常不一樣
- os.path.split(path) #將path的目錄和文件名分開為元組
- os.path.join(path1,path2,…) #將path1,path2,…進行組合,若path2為絕對路徑,則會將path1刪除
- os.path.dirname(path) #返回path中的目錄(文件夾部分),結果不包含’’
- os.path.basename(path) #返回path中的文件名
scons內置函數
每一個 RT-Thread BSP 目錄下都會存在下面三個文件:rtconfig.py、SConstruct 和 SConscript,它們控制 BSP 的編譯。SConstruct文件是SCons默認解析的第一個腳本,因此scons命令必須在它所在的路徑下執行。一般建議將SConstruct腳本與rtconfig.py腳本置于用戶工程目錄中。下面以一個SConstruct為例進行簡單分析:
SConstruct文件(SCons環境配置類腳本):
import os //加載python庫os,os是python自帶的系統模塊,需要import使用os 源于英文Operating System(操作系統)的縮寫 import sys //加載python庫sys import rtconfig //加載編譯選項配置腳本rtconfig.pyif os.getenv('RTT_ROOT'):RTT_ROOT = os.getenv('RTT_ROOT') else:RTT_ROOT = os.path.normpath(os.getcwd() + '/../../..') //cwd(Current Working Directory),含義為當前工作目錄,os.getcwd() 指獲取當前工作目錄。定義從SConstruct所在目錄到rtthread源碼根目錄的相對路徑sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')] try:from building import * except:print('Cannot found RT-Thread root directory, please check RTT_ROOT')print(RTT_ROOT)exit(-1)TARGET = 'rt-thread.' + rtconfig.TARGET_EXT //指定編譯生成二進制文件的名字//將rtconfig.py中配置的編譯選項信息傳遞到scons內置編譯對象env中 DefaultEnvironment(tools=[]) env = Environment(tools = ['mingw'],AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,AR = rtconfig.AR, ARFLAGS = '-rc',CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS) env.PrependENVPath('PATH', rtconfig.EXEC_PATH)if rtconfig.PLATFORM == 'iar':env.Replace(CCCOM = ['$CC $CCFLAGS $CPPFLAGS $_CPPDEFFLAGS $_CPPINCFLAGS -o $TARGET $SOURCES'])env.Replace(ARFLAGS = [''])env.Replace(LINKCOM = env["LINKCOM"] + ' --map rt-thread.map')Export('RTT_ROOT') //導出 RTT_ROOT 變量,供其他腳本使用 Export('rtconfig') //導出 rtconfig 變量,供其他腳本使用SDK_ROOT = os.path.abspath('./')if os.path.exists(SDK_ROOT + '/libraries'):libraries_path_prefix = SDK_ROOT + '/libraries' else:libraries_path_prefix = os.path.dirname(SDK_ROOT) + '/libraries'SDK_LIB = libraries_path_prefix Export('SDK_LIB')# prepare building environment objs = PrepareBuilding(env, RTT_ROOT, has_libcpu=False) //調用(某腳本文件).py中的工具函數,其中會對scons選項,以及相應的編譯選項適配進行處理,通過sconscript()調用sconscript腳本文件stm32_library = 'STM32F4xx_HAL' rtconfig.BSP_LIBRARY_TYPE = stm32_library# include libraries objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SConscript')))# include drivers objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript')))# make a building DoBuilding(TARGET, objs)由上示例可以看出,SConstruct與rtconfig.py與用戶的具體應用環境和編譯配置緊密相關
SConscript文件(SCons中間加載類腳本):
(目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer)
SConscript文件(SCons代碼組織類腳本):
此SConscript腳本位于子目錄
(目錄:C:\Users\Admin\Desktop\data\rt-thread\bsp\stm32\stm32f407-atk-explorer\applications)
DefineGroup()中的名字參數必須指定,如果該名字的組已經存在,則會進行追加合并。鍵值參數不是必選的,可以缺省。
import rtconfig from building import *cwd = GetCurrentDir() CPPPATH = [cwd, str(Dir('#'))] #添加搜尋頭文件路徑 src = Split(""" main.c """) #定義要添加的源文件group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH) #創建代碼管理組Return('group') #將定義的組返回給上一級調用腳本rtconfig.py文件:
rtconfig.py文件,主要用于指定編譯器以及安裝路徑。除此之外,該文件中定義了大量的變量,這些變量包括編譯選項,匯編選項,鏈接選項。
總結
以上是生活随笔為你收集整理的rtthread_scons简介的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java程序验证五子棋先手必胜_五子棋的
- 下一篇: html 三种插入css样式的方式