SCons简单入门(一)
你曾經為繁瑣的makefile語法糾結過嗎?你有想要擺脫VS的束縛,自己構建工程卻又苦于無從下手嗎?你有為同一個工程要在不同操作系統或不同平臺下構建編譯環境而苦惱過嗎? 本文有我的選擇,你的答案。
最近小試了一把用scons來構建編譯環境,感覺很不錯,跟大家分享一下。
先說明下什么是scons,scons是一個Python寫的自動化構建工具,就比如老牌的cmake,或者如果經常跟google一些開源項目打交道的話,那肯定知道新近開始流行的gyp(google內部用的構建工具),scons實現跟它們有類似的功能。而scons又有區別于其他構建工具的特點,不得不承認,這些特點讓我喜歡上了這個工具。
先簡單總結下吸引我的幾點:
1. 自動依賴分析
2. 工具本身由python實現,跨平臺
3. 基于MD5識別構建文件的改變,并且可以自定義和擴展
4. 構建文件邏輯用python來寫,功能強大,擴展性超強,跨平臺
5. 簡單易用(半小時內可以學會如何構建中小規模編譯環境)
6. 官方提供的文檔詳細易理解(如果看過google的gyp的文檔,那叫一個坑爹)
好了,進入正題,就讓我們來循序漸進的來領略下scons的魅力吧。
首先是安裝環境,
第一步當然是要保證系統中安裝了python,貌似2.6和2.7下scons都沒有問題,其他的自己嘗試下吧。
第二步,安裝scons。windows環境的話直接去官網下載exe直接安裝即可。linux Debian系統下則更方便,可以直接用如下命令來安裝:sudo apt-get install scons
安裝完成后,在命令行驗證一下,輸入scons -v, 如果沒有提示scons命令不存在則說明安裝成功。不幸的是,windows下還真提示不存在了,怎么辦?其實在python安裝路徑C:\Python27\Scripts下(我的python安裝在C:\Python27)有個scons.bat,以后運行這個命令就可以(/scons.bat -v),為了方便可以把該路徑追加到環境變量PATH中。
ok,環境搞定。
接著,一起來細細品味下scons吧。
1. 假設有如下【helloScons.c】文件:
#include <stdio.h> #include <stdlib.h> int main(int argc, char* argv[]) {printf("Hello, SCons!\n");return 0; }用scons怎么編譯它呢?首先在helloScons.c相同路徑下新建【SConstruct】文件,內容如下:
Program('helloScons.c')
命令行,進入該文件相同路徑,運行‘scons’(windows下運行scons.bat)。可以看到如下運行結果:
scons: Reading SConscript files ... scons: done reading SConscript files. scons: Building targets ... gcc -o helloScons.o -c helloScons.c gcc -o helloScons helloScons.o scons: done building targets.編譯完成,得到helloScons可執行文件。
如果我們希望生成其他名字的可執行文件呢?很簡單,把【SConstruct】改成如下內容就可:
Program('newName', 'helloScons.c')2. 我們稍微改動下,比如相同路徑下再新建個文件extScons.c, extScons.h:
【extScons.h】
int add(int x, int y);?【extScons.c】
int add(int x, int y) {return x + y; }?然后修改下【helloScons.c】:
#include <stdio.h> #include <stdlib.h> #include “extScons.h” int main(int argc, char* argv[]) { printf("Hello, SCons %d!\n", add(1, 2)); return 0; }【SConstruct】文件怎么改呢?
Program(['helloScons.c', 'extScons.c'])
那如果你整個工程中有上百個.c,難道都要在SConstruct中一個一個寫出來嗎?當然不需要,下面這樣也能達到跟上面一樣的功能:
Program(Glob('*.c'))?3. 假設我們再變化一下,在當前路徑下創建ext文件夾,把extScons.h和extScons.c移到ext文件夾里,【SConstruct】怎么寫:
Program(['helloScons.c', 'ext/extScons.c'])類似如果希望設置為文件夾下所有文件,也可以寫成:
Program([Glob('*.c'), Glob('ext/*.c')])4. 那么如果要把extScons.c編譯成動態鏈接庫.so,怎么做?
【SConstruct】文件如下:
SharedLibrary('ext/extScons.c') Program(['helloScons.c'], LIBS=['extScons'], LIBPATH='./ext')解釋一下,SharedLibrary()指定把ext/extScons.c編譯成動態鏈接庫,如果想編譯為靜態鏈接庫則使用StaticLibrary()。Program方法中,LIBS指定的是主程序helloScons.c需要使用的動態鏈接庫libextScons.so,LIBPATH則指定的是libextScons.so的路徑。
運行scons后,可以看到ext文件夾下生成了libextScons.so,主文件夾下生成了可執行程序helloScons。
5. 如果要把編譯和鏈接兩個步驟分開呢?沒問題,scons提供了Object方法來編譯生成.o(windows下為.obj)文件。
【SConstruct】文件如下:
?
Object方法用來編譯生成.o文件,Library和Program則用來鏈接.o生成靜態鏈接庫和可執行文件。
還可以再改善下如上構建代碼:
import os ext = Object('ext/extScons.c') Library(ext) main = Object('helloScons.c') Program(main, LIBS=['extScons'], LIBPATH='./ext')Object會返回編譯產生的.o文件列表,可以直接把這個返回值傳給Library和Program方法。在需要編譯許多代碼文件時,這點還是很有用的。
6. 如果需要在不同操作系統下編譯鏈接不同的代碼文件呢?scons可以很簡單就實現。
我們再創建一個文件【helloSconsForWin.c】,作為windows環境下使用的主程序:
?
同時,假設我們又希望在Linux下以動態鏈接的形式,而在windows下以靜態鏈接的形式使用extScons。【SConstruct】文件如下:
import os if os.name == "posix":SharedLibrary('ext/extScons.c')Program(['helloScons.c'], LIBS=['extScons'], LIBPATH='./ext') elif os.name == "nt":StaticLibrary('ext/extScons.c')Program(['helloSconsForWin.c'], LIBS=['extScons'], LIBPATH='./ext')純粹的python語法,使用了os模塊,如果你熟悉python的話,編譯和鏈接的邏輯你可以隨心所欲的寫。其實這一點是最吸引我的,因為我算是個python的fan,呵呵。
本文其實只是一些關于scons的最基本的說明,在這里我也只是拋磚引玉,scons還有很多很好的特性,大家可以參考官方的文檔:
http://www.scons.org/doc/production/HTML/scons-user/index.html
?
原文鏈接:https://blog.csdn.net/my_business/article/details/7816736
總結
以上是生活随笔為你收集整理的SCons简单入门(一)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机专业常用英语(转)
- 下一篇: VS2010中使用zxing识别图片二维