SCons的使用
SCons的使用
分類: python 2011-05-07 19:34 10712人閱讀 評論(2) 收藏 舉報 makefilelibrarypythonobjectconstructionstring一、概述
??? scons是一個Python寫的自動化構建工具,和GNU make相比優點明顯:
??? 1、?移植性:python能運行的地方,就能運行scons
??? 2、?擴展性:理論上scons只是提供了python的類,scons使用者可以在這個類的基礎上做所有python能做的事情。比如想把一個已經使用了Makefile大型工程切換到scons,就可以保留原來的Makefile,并用python解析Makefile中的編譯選項、源/目標文件等,作為參數傳遞給scons,完成編譯。
??? 3、?智能:Scons繼承了autoconf/automake的功能,自動解析系統的include路徑、typedef等;“以全局的觀點來看所有的依賴關系”
?
二、scons文件
??? scons中可能出現的文件:
??????? SConstruct,Sconstruct,sconstruct,SConscript
??
??? scons將在當前目錄以下次序 SConstruct,Sconstruct,sconstruct 來搜索配置文件,從讀取的第一個文件中讀取相關配置。
??? 在配置文件SConstruct中可以使用函數SConscript()函數來定附屬的配置文件。按慣例,這些附屬配置文件被命名為”SConscript”,當然也可以使用任意其它名字。
?
三、scons的命令行參數
??? scons: 執行SConstruct中腳本
??? scons -c?? clean
??? scons -Q? 只顯示編譯信息,去除多余的打印信息
??? scons -Q?? --implicit-cache hello 保存依賴關系
?????????????????? --implicit-deps-changed?? 強制更新依賴關系
?????????????????? --implicit-deps-unchanged? 強制使用原先的依賴關系,即使已經改變
?
四、SConstruct提供的方法
1、Program:生成可執行文件
??? Program('hello.c')? 編譯hello.c可執行文件,根據系統自動生成(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']) 編譯多個文件,Output文件名以第一個文件命名
??? Program(source = "hello.c",target = "hello")
??? Program(target = "hello" , source = "hello.c")
??? Program('hello', Split('hello.c file1.c file2.c')) 編譯多個文件
??? Program(Glob("*.c"))
??? src = ["hello.c","foo.c"];Program(src)
?
2、Object:生成目標文件
??? Object('hello.c') 編譯hello.c目標文件,根據系統自動生成(hello.obj on Windows; hello.o on POSIX)
?
3、Library:生成靜態/動態庫文件
??? Library('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯library
??? SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯 shared library
??? StaticLibrary('bar', ['f4.c', 'f5.c', 'f6.c']) 編譯 static library
??? 庫的使用:
??? Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.') 連接庫,不需加后綴或是前綴
?
4、SourceSignatures:判斷源文件是否修改
??? SourceSignatures('MD5')???? 根據內容是否改變,默認方式
??? SourceSignatures('timestamp') 根據修改時間
?
5、TargetSignatures:判斷目標文件是否改變
????TargetSignatures('build')?? 根據編譯結果
????TargetSignatures('content')? 根據文件內容,如果只是加了句注釋,將不會被重新編譯
?
6、Ignore:忽略依賴關系
????Ignore(hello, 'hello.h')? 忽略某個依賴關系
?
7、Depends:明確依賴關系
????Depends(hello, 'other_file') 明確依賴關系?
?
8、SConscript:scons的配置文件。
??? 源文件的目錄結構如下:
??? src:
????|??? SConstruct
? ??|????test.cpp
? ? |??? mA(目錄):
? ?????? |???? SConscript
? ?????? |???? func.cpp
??? 其中test.cpp為主文件,中調用func.cpp中定義的函數
?
??? SConstruct內容如下:
???????
[cpp] view plaincopy??? SConscript內容 :
??????? [cpp] view plaincopy
??? 上例中,在主目錄中執行 scons就可以編譯整個"工程"。SConstruct編譯主目錄中的test.cpp,并通過SConscript編譯mA目錄下的源文件,并最終生成可執行文件;SConscript用于編譯mA中的func.cpp并把生成的func.o傳遞給主目錄的SConstruct。
?
10.env:環境變量
???? 環境變量用于設置在編譯過程中的各種參數,可以用下面的SConstruct打印環境變量的所有信息(實際上env就是一個python字典)
???? 可以使用如下的SConstruct查看環境變量的內容:
???????
???? 環境變量的使用:
? ?????? env = Environment()?? #創建默認的環境變量,默認scons會按編譯器的默認選項來進行編譯
???????? import os
???????? env = Environment(CC = 'gcc',CCFLAGS = '-O2') #創建并設置環境 變量
???????? env.Program('foo.c')
???? 環境變量的復制:
? ?????? env = Environment(CC = 'gcc')
???????? opt = env.Clone(CCFLAGS = '-O2')
???????? dbg = env.Clone(CCFLAGS = '-g')
???? 環境變量的替換:
???????? env = Environment(CCFLAGS = '-DDEFINE1')
???????? env.Replace(CCFLAGS = '-DDEFINE2')
???????? env.Program('foo.c')?
???? 環境變量的輸入輸出:用于統一多目錄源文件的編譯選項,如:
???? src:
? ?? |??? SConstruct
? ?? |??? libstlport.a
? ?? |??? test.cpp
? ?? |???? include(目錄):
? ??????? |??? foo.h
???? |??? mA(目錄):
????????? |??? SConscript
????????? |????func.cpp
???
???? test.cpp和mA/func.cpp都引用了include/foo.h,test.cpp調用了mA/func.cpp的功能函數,其中include/foo.h中定義了一個包含string類型的類。
???? SConstruct如下:
??????
??? mA/SConscrip如下:
??????
????? 不出意外的話上邊的工程編譯可以通過,但是運行的時候會Aborted。因為test.cpp,mA/func.cpp都使用了包含string類型的那個類,但是由于編譯環境的不同,test.cpp認為string變量的大小是24字節, mA/func.cpp認為string變量的大小是4個字節(libstlport.a搗的鬼)。
?????
?????解決問題的辦法就是環境變量輸出,修改SConstruct和mA/SConscript如下:
????SConstruct:
???????
????mA/SConscript:
?????? [cpp] view plaincopy
總結
- 上一篇: 导师推荐,本周开课 | 第 5 期临床基
- 下一篇: 这些21个不太好搜索其含义的特殊符号你都