3 回答

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超8個(gè)贊
一、概述
scons是一個(gè)Python寫(xiě)的自動(dòng)化構(gòu)建工具,和GNU make相比優(yōu)點(diǎn)明顯:1、 移植性:python能運(yùn)行的地方,就能運(yùn)行scons2、 擴(kuò)展性:理論上scons只是提供了python的類(lèi),scons使用者可以在這個(gè)類(lèi)的基礎(chǔ)上做所有python能做的事情。比如想把一個(gè)已經(jīng)使用了Makefile大型工程切換到scons,就可以保留原來(lái)的Makefile,并用python解析Makefile中的編譯選項(xiàng)、源/目標(biāo)文件等,作為參數(shù)傳遞給scons,完成編譯。3、 智能:Scons繼承了autoconf/automake的功能,自動(dòng)解析系統(tǒng)的include路徑、typedef等;“以全局的觀點(diǎn)來(lái)看所有的依賴(lài)關(guān)系”
二、scons文件
scons中可能出現(xiàn)的文件:SConstruct,Sconstruct,sconstruct,SConscript
scons將在當(dāng)前目錄以下次序 SConstruct,Sconstruct,sconstruct 來(lái)搜索配置文件,從讀取的第一個(gè)文件中讀取相關(guān)配置。在配置文件SConstruct中可以使用函數(shù)SConscript()函數(shù)來(lái)定附屬的配置文件。按慣例,這些附屬配置文件被命名為”SConscript”,當(dāng)然也可以使用任意其它名字。
三、scons的命令行參數(shù)scons: 執(zhí)行SConstruct中腳本scons -c cleanscons -Q 只顯示編譯信息,去除多余的打印信息scons -Q --implicit-cache hello 保存依賴(lài)關(guān)系--implicit-deps-changed 強(qiáng)制更新依賴(lài)關(guān)系--implicit-deps-unchanged 強(qiáng)制使用原先的依賴(lài)關(guān)系,即使已經(jīng)改變
四、SConstruct提供的方法
1、Program:生成可執(zhí)行文件
Program('hello.c') 編譯hello.c可執(zhí)行文件,根據(jù)系統(tǒng)自動(dòng)生成(hello.exe on Windows; hello on POSIX)Program('hello','hello.c') 指定Output文件名(hello.exe on Windows; hello on POSIX)Program(['hello.c', 'file1.c', 'file2.c']) 編譯多個(gè)文件,Output文件名以第一個(gè)文件命名Program(source = "hello.c",target = "hello")Program(target = "hello" , source = "hello.c")Program('hello', Split('hello.c file1.c file2.c')) 編譯多個(gè)文件
Program(Glob("*.c"))src = ["hello.c","foo.c"];Program(src)2、Object:生成目標(biāo)文件
Object('hello.c') 編譯hello.c目標(biāo)文件,根據(jù)系統(tǒng)自動(dòng)生成(hello.obj on Windows; hello.o on POSIX)3、Library:生成靜態(tài)/動(dòng)態(tài)庫(kù)文件
Library('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯librarySharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯 shared libraryStaticLibrary('bar', ['f4.c', 'f5.c', 'f6.c']) 編譯 static library
庫(kù)的使用:
Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.') 連接庫(kù),不需加后綴或是前綴
4、SourceSignatures:判斷源文件是否修改SourceSignatures('MD5') 根據(jù)內(nèi)容是否改變,默認(rèn)方式SourceSignatures('timestamp') 根據(jù)修改時(shí)間
5、TargetSignatures:判斷目標(biāo)文件是否改變TargetSignatures('build') 根據(jù)編譯結(jié)果TargetSignatures('content') 根據(jù)文件內(nèi)容,如果只是加了句注釋?zhuān)瑢⒉粫?huì)被重新編譯6、Ignore:忽略依賴(lài)關(guān)系
Ignore(hello, 'hello.h') 忽略某個(gè)依賴(lài)關(guān)系
7、Depends:明確依賴(lài)關(guān)系
Depends(hello, 'other_file') 明確依賴(lài)關(guān)系
8、SConscript:scons的配置文件。
源文件的目錄結(jié)構(gòu)如下:src:| SConstruct| test.cpp| mA(目錄):| SConscript| func.cpp其中test.cpp為主文件,中調(diào)用func.cpp中定義的函數(shù)SConstruct內(nèi)容如下:
[cpp] view plaincopy
subobj = SConscript(['mA/SConscript'])
obj = subobj + Object(Glob("*.cpp"))
Program("test",list(obj))
SConscript內(nèi)容 :
obj = Object(Glob("*.cpp"))
Return("obj")
上例中,在主目錄中執(zhí)行 scons就可以編譯整個(gè)"工程"。SConstruct編譯主目錄中的test.cpp,并通過(guò)SConscript編譯mA目錄下的源文件,并最終生成可執(zhí)行文件;SConscript用于編譯mA中的func.cpp并把生成的func.o傳遞給主目錄的SConstruct。
env = Environment()
dict = env.Dictionary()
keys = dict.keys()
keys.sort()
for key in keys:
print "construction variable = '%s', value = '%s'" % (key, dict[key])
環(huán)境變量的使用:
env = Environment() #創(chuàng)建默認(rèn)的環(huán)境變量,默認(rèn)scons會(huì)按編譯器的默認(rèn)選項(xiàng)來(lái)進(jìn)行編譯
import os
env = Environment(CC = 'gcc',CCFLAGS = '-O2') #創(chuàng)建并設(shè)置環(huán)境 變量
env.Program('foo.c')
env = Environment()
flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])
env.MergeFlags(class_flags)
subobj = SConscript(['mA/SConscript'])
obj = subobj + env.Object(Glob("*.cpp"))
env.Program("test",list(obj),LIBS = ['libstlport.a'])
obj = Object(Glob("*.cpp"))
Return("obj")
env = Environment()
flags = env.ParseFlags(['-pthread -I/usr/include/stlport ',' -L .'])
env.MergeFlags(class_flags)
Export('env')
subobj = SConscript(['mA/SConscript'],exports = 'env')
obj = subobj + env.Object(Glob("*.cpp"))
env.Program("test",list(obj),LIBS = ['libstlport.a'])
mA/SConscript:
[cpp] view plaincopy
10.env:環(huán)境變量環(huán)境變量用于設(shè)置在編譯過(guò)程中的各種參數(shù),可以用下面的SConstruct打印環(huán)境變量的所有信息(實(shí)際上env就是一個(gè)python字典)可以使用如下的SConstruct查看環(huán)境變量的內(nèi)容:
[cpp] view plaincopy
環(huán)境變量的復(fù)制:env = Environment(CC = 'gcc')opt = env.Clone(CCFLAGS = '-O2')dbg = env.Clone(CCFLAGS = '-g')
環(huán)境變量的替換:env = Environment(CCFLAGS = '-DDEFINE1')env.Replace(CCFLAGS = '-DDEFINE2')env.Program('foo.c')環(huán)境變量的輸入輸出:用于統(tǒng)一多目錄源文件的編譯選項(xiàng),如:src:| SConstruct| libstlport.a| test.cpp| include(目錄):| foo.h| mA(目錄):| SConscript| func.cpp
test.cpp和mA/func.cpp都引用了include/foo.h,test.cpp調(diào)用了mA/func.cpp的功能函數(shù),其中include/foo.h中定義了一個(gè)包含string類(lèi)型的類(lèi)。
SConstruct如下:
[cpp] view plaincopy
mA/SConscrip如下:
[cpp] view plaincopy
不出意外的話上邊的工程編譯可以通過(guò),但是運(yùn)行的時(shí)候會(huì)Aborted。因?yàn)閠est.cpp,mA/func.cpp都使用了包含string類(lèi)型的那個(gè)類(lèi),但是由于編譯環(huán)境的不同,test.cpp認(rèn)為string變量的大小是24字節(jié), mA/func.cpp認(rèn)為string變量的大小是4個(gè)字節(jié)(libstlport.a搗的鬼)。
解決問(wèn)題的辦法就是環(huán)境變量輸出,修改SConstruct和mA/SConscript如下:SConstruct:
[cpp] view plaincopy

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊
class a:
def fun(self):
print(11111111)
實(shí)例化類(lèi)a
b=a()
然后調(diào)用
b.fun()
結(jié)果輸出就是print的結(jié)果11111111
- 3 回答
- 0 關(guān)注
- 835 瀏覽
添加回答
舉報(bào)