成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Waf - a Python based build system

sunnyxd / 1608人閱讀

摘要:以上便是所有的內(nèi)容,可以看到涉及到的文件不算多。用也一樣,一般是再等機(jī)器的轟鳴停止后繼續(xù)工作流。這個(gè)抽象幾乎相互獨(dú)立,個(gè)人認(rèn)為是很好的一個(gè)抽象。從聲明式表達(dá)到生成的這項(xiàng)任務(wù),由完成。

前言

看懂這篇文章需要一點(diǎn)使用waf的經(jīng)驗(yàn),不過(guò)也不費(fèi)事,看看例子也夠了。

構(gòu)建系統(tǒng)簡(jiǎn)談

軟件構(gòu)建系統(tǒng)不像是個(gè)很多人在研究的東西,所以在網(wǎng)絡(luò)上很少能找到剖析某個(gè)構(gòu)建系統(tǒng)原理、或者闡述構(gòu)建系統(tǒng)principle的文章??磏s3的過(guò)程中接觸到了waf,發(fā)現(xiàn)其文檔waf book[https://waf.io/book/]很好的闡述了構(gòu)建系統(tǒng)的一些基礎(chǔ)知識(shí),個(gè)人認(rèn)為比cmake的文檔好一些。因?yàn)槠浜诵闹挥惺畮讉€(gè)文件,這個(gè)構(gòu)建系統(tǒng)只需要一個(gè)10k+的waf文件,所以可以放到版本庫(kù)里(像對(duì)python的評(píng)價(jià)一樣,batteries included),唯一要求就是環(huán)境中有python,而這對(duì)一個(gè)開(kāi)發(fā)人員來(lái)說(shuō)顯然不是一件困難的事情。

|-- Build.py
|-- ConfigSet.py
|-- Configure.py
|-- Context.py
|-- Errors.py
|-- Logs.py
|-- Node.py
|-- Options.py
|-- Runner.py
|-- Scripting.py
|-- Task.py
|-- TaskGen.py
|-- Tools [directory]
|-- Utils.py
|-- ansiterm.py
|-- extras
|-- fixpy2.py
`-- processor.py

以上便是所有waf的內(nèi)容,可以看到涉及到的文件不算多。Tools下包含了很多語(yǔ)言的構(gòu)建工具,比如c/c++/java/qt/ruby/tex等等,如果自己有能力定制,可以只保留自己項(xiàng)目里需要的tool,可以做到更小。(雖然個(gè)人認(rèn)為沒(méi)有必要)

核心抽象

如果是寫(xiě)編譯語(yǔ)言的(c/c++/rust/go/fc/d),那么構(gòu)建系統(tǒng)是每天都在用的。在敲擊make之后,屏幕上出現(xiàn)了一系列的自動(dòng)運(yùn)行的命令,然后就是漫長(zhǎng)的等待。用waf也一樣,一般是./waf configure build clean dist...再等機(jī)器的轟鳴停止后繼續(xù)工作流。waf提供了一些核心的抽象,從而能夠表達(dá)出構(gòu)建這個(gè)活動(dòng)的幾個(gè)關(guān)鍵方面:

像make clean dist類似,可以在構(gòu)建命令后面自行添加指令,這種capibility由Context提供

構(gòu)建系統(tǒng)最重要的功能就是按需構(gòu)建,要判斷出哪些文件要編譯而哪些是不用的,這用到了TaskGen與Task的抽象

并行構(gòu)建提升速度,由Runner來(lái)提供。

這3個(gè)抽象幾乎相互獨(dú)立,個(gè)人認(rèn)為是很好的一個(gè)抽象。

Context

每一個(gè)跟在./waf后面的指令,都對(duì)應(yīng)一個(gè)Context。如果是build/configure/list/step/install/uninstall,waf自行提供了對(duì)應(yīng)的Context的子類用于執(zhí)行這些命令,如果是其他的自定義函數(shù),那么就會(huì)依托于Context本身,可以在自定義函數(shù)里用Context自定義的函數(shù),比如recurse來(lái)遍歷子目錄執(zhí)行子目錄里的同名自定義函數(shù)。
如果項(xiàng)目根目錄下的wscript有do_sth,就可以./waf do_sth

def do_sth(ctx):
    ctx.load("compiler_cxx")    # 加載工具
    ctx.recurse(["src","dep"])  # 遍歷子目錄,執(zhí)行子目錄下wscript里的do_sth
    ctx.exec_command("touch foo.txt")
    ctx.msg("hello")

這里函數(shù)參數(shù)ctx就是指向了Context的一個(gè)實(shí)例,而do_sth是作為Context上的一個(gè)方法而存在的,可以直觀的理解為,我們?yōu)镃ontext增加了一個(gè)自定義的do_sth方法,所以可以自由調(diào)用Context里本來(lái)提供的方法。
./waf build執(zhí)行時(shí)綁定的Context是BuildConetxt,在Build.py里被定義,在waf build的時(shí)候,執(zhí)行的是wscript里def build(bld)這個(gè)方法。舉一個(gè)例子

def configure(conf):
    conf.load("compiler_cxx")
def build(bld):
    bld.shlib(source="a.cpp", target="mylib3")
    bld.program(source="main.cpp", target="app", use="mylib")
    bld.stlib(target="foo", source="b.cpp")
    # 直接調(diào)用bld
    bld(features = "c cprogram glib2",
        use      = "GLIB GIO GOBJECT",
        source   = "main.c org.glib2.test.gresource.xml",
        target   = "gsettings-test")

這里bld指向了BuildContext的一個(gè)實(shí)例,這意味著B(niǎo)uildContext里所有的方法都在這個(gè)函數(shù)里都是可用的,可以通過(guò)bld.xxx來(lái)調(diào)用。
值得注意的是,在Build.py中,可是找不到shlib/probram/stlib這3個(gè)方法的,但是在這里卻調(diào)用成功沒(méi)有報(bào)錯(cuò),這全部依賴于conf.load("compiler_cxx")這一句。執(zhí)行這句話后,就給bld指向的BuildContext實(shí)例綁定了shlib/program/stlib這3個(gè)方法。
那直接調(diào)用bld()呢?這個(gè)就要看Build.py里的BuildContex():__call__方法了。從這里開(kāi)始,就涉及到TaskGen這個(gè)抽象了。

TaskGen & Task

最終需要執(zhí)行的編譯指令、中間代碼生成等,每一條都對(duì)應(yīng)一個(gè)task,我們不可能去一個(gè)一個(gè)的寫(xiě)task,而是希望以一種聲明式的方法表達(dá)想要做的事情,這就是task_gen所完成的任務(wù)。從聲明式表達(dá)到生成task的這項(xiàng)任務(wù),由waf build完成。在執(zhí)行的過(guò)程中,會(huì)對(duì)搜集到的每個(gè)task_gen執(zhí)行一下post(),然后這個(gè)task_gen就生成了自己所有的task。作為一個(gè)靈活的構(gòu)建系統(tǒng),waf提供了很多方法來(lái)讓我們hook到post()的過(guò)程中。對(duì)于每個(gè)task,到底該不該執(zhí)行需不需要執(zhí)行,它自己會(huì)追蹤自己的依賴,職責(zé)分離,我很喜歡這個(gè)設(shè)計(jì)思路。
以前一小節(jié)為例,共在build(bld)里一共進(jìn)行了4次調(diào)用,這意味著生成了4個(gè)task_gen的實(shí)例,在真正執(zhí)行構(gòu)建過(guò)程之前,會(huì)有一個(gè)地方對(duì)這4個(gè)實(shí)例各自調(diào)用一下post(),把所有的task_gen都消滅掉,變成task。至于怎么hook,這是個(gè)比較關(guān)鍵的點(diǎn),如果理解了,就能很好的自定義waf了。
首先看看寫(xiě)好的wscript,它的聲明式體現(xiàn)在什么地方呢?體現(xiàn)在函數(shù)參數(shù)里。得益于python的語(yǔ)言特點(diǎn),可以隨便加參數(shù),然后在函數(shù)實(shí)現(xiàn)里用**kw來(lái)取這些值。這意味著可以隨便加自己想要的key=value進(jìn)去,這些加進(jìn)去的參數(shù)是可以在自定義的hook過(guò)程中取到的,這算是可自定義的一個(gè)基礎(chǔ)。(ruby自定義的能力更強(qiáng),畢竟dsl是其強(qiáng)項(xiàng),但可能限于ruby的流行程度以及發(fā)行版是否默認(rèn)安裝,讓作者最后選擇了python,不過(guò)也已經(jīng)夠用了)
在post()的過(guò)程中,會(huì)從task_gen.meths[]里依次取出方法來(lái)執(zhí)行,hook的方式就是把自定義的方法塞到這個(gè)task_gen.meths[]之中。這只要在自定義的方法上加一個(gè)@TaskGen.taskgen_method的注解就能實(shí)現(xiàn),還是挺簡(jiǎn)潔的吧?聲明式中寫(xiě)的key=val,都能通過(guò)taskgen.key取到,這樣一來(lái),幾乎就獲得了無(wú)限的能力來(lái)自定義構(gòu)建過(guò)程了。
在taskgen.meths[]里有幾項(xiàng)預(yù)定義的方法,waf也提供了指令來(lái)讓我們定制自己方法執(zhí)行的位置??偠灾?,想要什么內(nèi)容,直接在wscript里以key=val的方式指定,然后在自己的方法里用getattr來(lái)取就行了。
這也只是個(gè)支持性框架,具體到某個(gè)語(yǔ)言(c/c++)是怎么做的,到后面再看。

Runner

waf自己會(huì)默認(rèn)起和cpu core相同數(shù)量的進(jìn)程來(lái)執(zhí)行構(gòu)建認(rèn)任務(wù),而且構(gòu)建過(guò)程的輸出也很清晰漂亮。waf也提供了lazy的模式,不是一下子把所有的task_gen都轉(zhuǎn)化,所以也是用了一些技巧來(lái)達(dá)成這個(gè)目的。在看waf代碼的過(guò)程中,能看到很多pythonic和近乎炫技的技法,可見(jiàn)作者真是把python語(yǔ)言玩弄于股掌之中。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/45266.html

相關(guān)文章

  • 在 CentOS 5.8 上安裝 Graphite

    摘要:在上安裝標(biāo)簽空格分隔監(jiān)控首先說(shuō)一句,在上安裝真的很坑爹。。。或如果上面這個(gè)方法無(wú)法安裝那就用源碼安裝的方法。安裝開(kāi)始好幾次就死在安裝這個(gè)上面,版本的通過(guò)命令安裝的不行,對(duì)應(yīng)版本的包的名字叫做。 在 CentOS 5.8 上安裝 Graphite 標(biāo)簽(空格分隔): 監(jiān)控 monitor CentOS 5.8 Graphite 首先說(shuō)一句,在 CentOS 5.8 上安裝真的很坑爹...

    banana_pi 評(píng)論0 收藏0
  • Awesome Python

    摘要:漢字拼音 Awesome Python A curated list of awesome Python frameworks, libraries and software. Inspired by awesome-php. Awesome Python Environment Management Package Management Package Repositorie...

    fizz 評(píng)論0 收藏0
  • 你的 Docker 應(yīng)用是安全的嗎?

    摘要:如今,多樣化的攻擊手段層出不窮,傳統(tǒng)安全解決方案越來(lái)越難以應(yīng)對(duì)網(wǎng)絡(luò)安全攻擊。自適應(yīng)安全平臺(tái)集成了預(yù)測(cè)預(yù)防檢測(cè)和響應(yīng)的能力,為您提供精準(zhǔn)持續(xù)可視化的安全防護(hù)。 近一年來(lái),Docker 已經(jīng)逐漸成為 container 界的事實(shí)標(biāo)準(zhǔn),成為技術(shù)人員不可或缺的技能之一,就像 Docker 宣稱的那樣,「Build,Ship,and Run Any App,Anywhere」,容器極大簡(jiǎn)化了環(huán)境...

    darry 評(píng)論0 收藏0
  • Awesome Python II

    摘要: Caching Libraries for caching data. Beaker - A library for caching and sessions for use with web applications and stand-alone Python scripts and applications. dogpile.cache - dogpile.cache...

    lx1036 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

sunnyxd

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<