scons笔记
scons筆記
一、SConstruct File {{{1 ? ? 1. Sconstruct 文件 是scons用來控制編譯的文件 ? ? 2. Sconstruct 文件 是一個python腳本 ? ? 3. SConstruct 文件 是一個類似于makefile一樣的東西, 告訴 scons做什么,而不是嚴(yán)格的規(guī)定soncs做這件事的步驟二、scons選項 {{{1 ? ? -c ? ? ?Cleaning up After a Build ? ? -Q ? ? ?Making the scons output less verbose
三、SConstruct 腳本的編寫基礎(chǔ) {{{1 ? ?? 1. builder method {{{2 ? ? Program ? ? ?: generate executable file ? ? Object ? ? ? : generate Object file ? ? Java ? ? ? ? : 編譯java程序, User Guide 2.3, Chapter 25 ? ? Library ? ? ?: 靜態(tài)庫, ? 也可以使用 StaticLibrary替代 ? ? SharedLibrary: 動態(tài)庫
2. 指定目標(biāo)名 {{{2 ? ? Program('hello.c') ? ? ? ? ? ? ? ?# 生成 hello.exe ? ? Program('new_hello', 'hello.c') ? # 生成 new_hello.exe
3. 編譯多個文件 {{{2 ? ? Program(['prog.c', 'file1.c', 'file2.c']) ? ? ? ? ? ? # 生成 prog.exe ? ? Program('program', ['prog.c', 'file1.c', 'file2.c']) ?# 生成program.exe ? ? Program('program', ['prog.c', 'file1.obj', 'file2.obj']) ?# 可以在文件列表中指定.obj文件
? ? 3.1 使用Glob 編譯所有匹配的文件 ? ? ? ? Program('program', Glob('*.c') )
? ? ? ? Glob原型為:Glob(self, pattern, ondisk=True, source=False, strings=False) ? ? ? ? ? ? 其中pattern 支持unix系統(tǒng)下的文件名匹配: *(任意多個字符), ?(單個字符) 和 [](括號中的任一字符) ? ? 3.2 使用Split ? ? ? ? Program('program', Split('main.c file1.c file2.c'))
? ? ? ? Split以空白字符為分隔符,將字符串分割,因此,你也可以這樣寫: ? ? ? ? Program('program', Split(""" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? main.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? file1.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? file2.c ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?""") ) ? ? 3.3 使用關(guān)鍵字參數(shù) ? ? ? ? Program(target = 'program', source = 'hello.c') ? ? ? ??
4. 指定編譯選項 {{{2 ? ? $CPPFLAGS ?指定編譯選項 ? ? $LINKFLAGS 指定鏈接選項, 如 /DEBUG ? ? $CPPDEFINES指定預(yù)編譯器
? ? $LIBS ? ? ?指定所需要鏈接的庫文件 ? ? $LIBPATH ? 指定庫文件(.lib)的搜索目錄 ? ? $CPPPATH ? 指定[.h, .c, .cpp]等文件搜索路徑
? ? 例如: ? ? ? ? Library('foo', Split('f1.c f2.c f3.c') ) ? ? ? ? Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.')
? ? ? ? 注:LIBS和LIBPATH若為一個可以使用字符串,若為多個則使用列表
四、使用Environments {{{1 ? ? 一個environment是一個影響程序執(zhí)行的值得集合。 ? ? (1) 外部環(huán)境 External Environment ? ? ? ? 外部環(huán)境是運(yùn)行Scons時 用戶的環(huán)境變量。它們可以通過os.environ獲取
? ? (2) 構(gòu)建環(huán)境 Construction Environment ? ? ? ? 它包含一些變量,這些變量會影響Scons構(gòu)建目標(biāo)的行為 ? ? (3) 執(zhí)行環(huán)境 Execution Environment ? ? ? ? 執(zhí)行環(huán)境用于Scons執(zhí)行外部命令(external command), 以構(gòu)建一個或多個目標(biāo)。 ? ? ? ? 注意:它與外部環(huán)境不相同
1. Construction Environment {{{2 ? ? > 創(chuàng)建 construction Environment ? ? ? ? env = Environment() ? ? ? ? 一個Environment是一個 (name,value)的集合,可以這樣查看它的內(nèi)容: ? ? ? ? ? ? for item in env.Dictionary(): ? ? ? ? ? ? ? ? print '(%s:%s)' % (item, env[item])
? ? > 查看變量 ? ? ? ? env['CC'] #查看 CC ,即C語言編譯器 ? ? ? ? env.subst('$CC') # 功能同上 ? ? ? ? ? ? 它的優(yōu)勢在于,它會將出現(xiàn)在結(jié)果中的環(huán)境變量轉(zhuǎn)換成最終的值 ? ? ? ? ? ? 使用AllowSubstException()函數(shù),使得當(dāng)subst中的變量不存在時報告錯誤, ? ? ? ? ? ? ? ? AllowSubstException() ? ? ? ? ? ? ? ? env.subst('$missing') # 出現(xiàn)異常,NameError ? ? > 修改環(huán)境變量 ? ? ? ? 拷貝一個環(huán)境變量 ? ? ? ? ? ? 使用env.Clone #詳見user guide 7.2.7 ? ? ? ? 替換一個已經(jīng)存在的環(huán)境變量 ? ? ? ? ? ? env.Replace ? ? ? ? 為一個沒有被定義的變量設(shè)置默認(rèn)值 ? ? ? ? ? ? env.SetDefault ? ? ? ? 為一個已存在的環(huán)境變量增加一個值 ? ? ? ? ? ? env.Append, 例如: ? ? ? ? ? ? env.Append(CCFLAGS = '-option -O3 -O1') ? ? ? ? ? ? env.Append(CCFLAGS = ['-option', 'O3']) ? ? ? ? 為一個環(huán)境變量增加一個唯一的值 ? ? ? ? ? ? env.AppendUnique ? ? ? ? 在最前邊添加一個值 ? ? ? ? ? ? env.Prepend ? ? ? ? 在最前邊添加一個唯一的值 ? ? ? ? ? ? env.PrependUnique ? ? ? ? 合并環(huán)境變量 ? ? ? ? ? ? env.MergeFlags, 例如: ? ? ? ? ? ? flags = {'CCFLAGS':'-option -O3 -O1'} ? ? ? ? ? ? env.MergeFlags(flags) ? ? ? ? ? ? flags = {'CPPPATH' : ['/user/opt/include', 'user/local/include']} ? ? ? ? ? ? env.MergeFlags(flags)
? ? ? ? ? ? #若參數(shù)不是Dictionary, 內(nèi)部調(diào)用ParseFlags將其轉(zhuǎn)化為Dictionary ? ? ? ? ? ? env.MergeFlags('-whatever -I/usr/opt/include -O3 -I/usr/local/include')
? ? > 一些實(shí)用的變量 ? ? ? ? 判斷是否是windows:? ? ? ? ? ? ? env['PLATFORM'] == 'win32'
2. Execution Environment {{{2 ? ? 當(dāng)scons構(gòu)建一個目標(biāo)文件時,它所使用的外部環(huán)境和執(zhí)行scons時的環(huán)境變量是不同的。 ? ? scons使用$ENV 構(gòu)建變量 中 存儲的目錄 作為它執(zhí)行命令的外部環(huán)境變量
? ? > PATH? ? ? ? ? POSIX 系統(tǒng)中默認(rèn)的PATH是 /user/local/bin:/user/bin ? ? ? ? Window系統(tǒng)中默認(rèn)的PATH是 command interpreter在注冊表中的值
? ? ? ? 1. 在構(gòu)建環(huán)境中顯示初始化PATH ? ? ? ? ? ? path = ['/user/local/bin', '/bin', '/user/bin'] ? ? ? ? ? ? env = Environment(ENV = {'PATH':path}) ? ? ? ? 上面這種方式,只設(shè)置了ENV,如果你想保留其他的變量,可以這么做: ? ? ? ? ? ? env['ENV']['PATH'] = ['/user/local/bin', '/bin', '/user/bin'] ? ? ? ? 2. 從 外部環(huán)境 初始化 PATH ? ? ? ? ? ? import os ? ? ? ? ? ? env = Environment(ENV = {'path' : os.environ['PATH']})
? ? ? ? ? ? 你也可以將完整的外部變量傳遞給執(zhí)行環(huán)境變量: ? ? ? ? ? ? import os ? ? ? ? ? ? env = Environment(ENV = os.environ) ? ? ? ? ? ? 這樣做的缺點(diǎn)是:如果環(huán)境變量目錄中,有多個目錄包含編譯器如gcc,那么, ? ? ? ? ? ? ? ? ? ? ? ? ? ? scons將執(zhí)行第一個被找到的gcc
? ? ? ? 3. 使用env.PrependENVPath 和 env.AppendENVPath ? ? ? ? ? ? 例如:將'/user/local/bin' 插入 $PATH中第一個位置 ? ? ? ? ? ? ? ? env.PrependENVPath('PATH', '/user/local/bin') ? ? ? ? ? ? 例如:將'/user/local/bin' 插入 $LIB中最后一個位置 ? ? ? ? ? ? ? ? env.AppendENVPath('lib', '/user/local/lib')
五、Controlling Build Output {{{1 1. 使用Help 函數(shù) 來說明SConstruct腳本 ? ? 例如: ? ? Help('this is a debug version')
? ? 在控制臺上使用 scons -h 命令查看此幫助信息
? ? 你可以在腳本中多次使用Help,幫助信息會被連接到一起
六、scons 命令行參數(shù) {{{1 ? ? 用戶可以為scons指定三種類型的參數(shù): ? ? > Options ? ?: 以 一個或兩個(-) 開頭 , 詳細(xì)參考 User Guide 10.1 ? ? > Variables ?: 形式為:variable=value, 詳細(xì)參考 ? ? ? ? ? ?10.2 ? ? > Target ? ? : 如果不是一個 Option 或 Variable ,那么就是一個Target , 詳細(xì)參考 User Guide 10.3
1. 讀取命令行的Variable參數(shù) ? ? 命令行:scons debug=1 ? ? SConstruct腳本如下: ? ? debug = ARGUMENTS.get('debug', 0) ? ? if int(debug) : ? ? ? ? pass # do something
2. Command-Line Targets ? ? scons提供 COMMAND_LINE_TARGETS 供用戶訪問命令行參數(shù)中的 Targets列表,例如: ? ? if 'bar' in COMMAND_LINE_TARGETS: ? ? ? ? print "Don't forget to copy 'bar' to the archivel" ? ? Default(Program('foo.c')) ? ? Program('bar.c')
? ? > 使用 Default函數(shù) 定義 默認(rèn)目標(biāo) ? ? ? ? 當(dāng)你沒有在命令行參數(shù)中指定目標(biāo)時,scons會編譯每一個目標(biāo) ? ? ? ? 例子: ? ? ? ? env = Environment() ? ? ? ? hello = env.Program('hello.c') ? ? ? ? env.Program('goodbye.c') ? ? ? ? Default(hello) ? ? ?#如果沒有在命令行指定Target,則會編譯hello
? ? ? ? 使用DEFAULT_TARGETS獲取 默認(rèn)目標(biāo), 例如: ? ? ? ? ? ? prog1 = Program('prog1.c') ? ? ? ? ? ? Default(prog1) ? ? ? ? ? ? print "DEFAULT_TARGETS is", map(str, DEFAULT_TARGETS)
? ? ? ? 使用 BUILD_TARGETS 獲取要編譯的目標(biāo)
七、控制目標(biāo)文件的路徑 {{{1 1. BINDIR {{{2 ? >使用Install:如, ? ? ? test = env.Program('test.cpp') ? ? ? env.Install('bin', 'test.exe') #表示要將test.exe 放到bin目錄下 ? ? ? 或 ? ? ? env.Install('bin', test)
? >在指定目標(biāo)名的時候指定其目錄,如: ? ? ? env.Program('bin/test', 'test.cpp')
? >將目標(biāo)放到其他目錄下,并修改名字 ? ? ? test = env.Program('test.cpp') ? ? ? env.InstallAs('bin/testapp.exe', 'test.exe') #表示將test.exe 拷貝到 bin/testapp.exe ? ? ? 或 這樣寫 ? ? ? env.InstallAs('bin/testapp', test) ? ? ?? ? ? ? 當(dāng) 需要對多個目標(biāo)做此操作時,可以這樣做: ? ? ? ? ? ?env = Environment() ? ? ? ? ? ?hello = env.Program('hello.c') ? ? ? ? ? ?goodbye = env.Program('goodbye.c') ? ? ? ? ? ?env.InstallAs(['/usr/bin/hello-new', '/usr/bin/goodbye-new'], [hello, goodbye]) #多個目標(biāo) ? ? ? ? ? ?env.Alias('install', '/usr/bin') ? ? ??
2. obj文件路徑 {{{2 ? ? 使用VariantDir函數(shù)指定 3. 一份代碼構(gòu)建多個版本的Target {{{2 ? ? 通常會有這樣的需求,一份源碼,既要構(gòu)建它的debug版本,又要構(gòu)建它的release版本,這種情況下,
? ? >我們需要為不同版本指定不能的obj名字,否則就會產(chǎn)生沖突,導(dǎo)致scons不能工作。簡單的示例如下: ? ? ? ? opt = Environment(CCFLAGS = '-O2') ? ? ? ? ?dbg = Environment(CCFLAGS = '-g')
? ? ? ? ?o = opt.Object('foo-opt', 'foo.c') ?// 生成 foo-opt.o ? ? ? ? ?opt.Program(o)
? ? ? ? ?d = dbg.Object('foo-dbg', 'foo.c') ?// 生成 foo-dbg.o ? ? ? ? ?dbg.Program(d)
? ? ?>或者將不同版本的obj放到不同的路徑下: ? ? ? ? ?o = opt.Object('opt/foo', 'foo.c') ?// 生成 foo-opt.o ? ? ? ? ?opt.Program(o)
? ? ? ? ?d = dbg.Object('dbg/foo', 'foo.c') ?// 生成 foo-dbg.o ? ? ? ? ?dbg.Program(d) ? ?
總結(jié)
- 上一篇: 机器学习 | EM 算法原理
- 下一篇: madagascar 软件安装方法