国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Waf - a Python based build system

sunnyxd / 1596人閱讀

摘要:以上便是所有的內容,可以看到涉及到的文件不算多。用也一樣,一般是再等機器的轟鳴停止后繼續工作流。這個抽象幾乎相互獨立,個人認為是很好的一個抽象。從聲明式表達到生成的這項任務,由完成。

前言

看懂這篇文章需要一點使用waf的經驗,不過也不費事,看看例子也夠了。

構建系統簡談

軟件構建系統不像是個很多人在研究的東西,所以在網絡上很少能找到剖析某個構建系統原理、或者闡述構建系統principle的文章??磏s3的過程中接觸到了waf,發現其文檔waf book[https://waf.io/book/]很好的闡述了構建系統的一些基礎知識,個人認為比cmake的文檔好一些。因為其核心只有十幾個文件,這個構建系統只需要一個10k+的waf文件,所以可以放到版本庫里(像對python的評價一樣,batteries included),唯一要求就是環境中有python,而這對一個開發人員來說顯然不是一件困難的事情。

|-- 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的內容,可以看到涉及到的文件不算多。Tools下包含了很多語言的構建工具,比如c/c++/java/qt/ruby/tex等等,如果自己有能力定制,可以只保留自己項目里需要的tool,可以做到更小。(雖然個人認為沒有必要)

核心抽象

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

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

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

并行構建提升速度,由Runner來提供。

這3個抽象幾乎相互獨立,個人認為是很好的一個抽象。

Context

每一個跟在./waf后面的指令,都對應一個Context。如果是build/configure/list/step/install/uninstall,waf自行提供了對應的Context的子類用于執行這些命令,如果是其他的自定義函數,那么就會依托于Context本身,可以在自定義函數里用Context自定義的函數,比如recurse來遍歷子目錄執行子目錄里的同名自定義函數。
如果項目根目錄下的wscript有do_sth,就可以./waf do_sth

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

這里函數參數ctx就是指向了Context的一個實例,而do_sth是作為Context上的一個方法而存在的,可以直觀的理解為,我們為Context增加了一個自定義的do_sth方法,所以可以自由調用Context里本來提供的方法。
./waf build執行時綁定的Context是BuildConetxt,在Build.py里被定義,在waf build的時候,執行的是wscript里def build(bld)這個方法。舉一個例子

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")
    # 直接調用bld
    bld(features = "c cprogram glib2",
        use      = "GLIB GIO GOBJECT",
        source   = "main.c org.glib2.test.gresource.xml",
        target   = "gsettings-test")

這里bld指向了BuildContext的一個實例,這意味著BuildContext里所有的方法都在這個函數里都是可用的,可以通過bld.xxx來調用。
值得注意的是,在Build.py中,可是找不到shlib/probram/stlib這3個方法的,但是在這里卻調用成功沒有報錯,這全部依賴于conf.load("compiler_cxx")這一句。執行這句話后,就給bld指向的BuildContext實例綁定了shlib/program/stlib這3個方法。
那直接調用bld()呢?這個就要看Build.py里的BuildContex():__call__方法了。從這里開始,就涉及到TaskGen這個抽象了。

TaskGen & Task

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

Runner

waf自己會默認起和cpu core相同數量的進程來執行構建認任務,而且構建過程的輸出也很清晰漂亮。waf也提供了lazy的模式,不是一下子把所有的task_gen都轉化,所以也是用了一些技巧來達成這個目的。在看waf代碼的過程中,能看到很多pythonic和近乎炫技的技法,可見作者真是把python語言玩弄于股掌之中。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/45266.html

相關文章

  • 在 CentOS 5.8 上安裝 Graphite

    摘要:在上安裝標簽空格分隔監控首先說一句,在上安裝真的很坑爹。。?;蛉绻厦孢@個方法無法安裝那就用源碼安裝的方法。安裝開始好幾次就死在安裝這個上面,版本的通過命令安裝的不行,對應版本的包的名字叫做。 在 CentOS 5.8 上安裝 Graphite 標簽(空格分隔): 監控 monitor CentOS 5.8 Graphite 首先說一句,在 CentOS 5.8 上安裝真的很坑爹...

    banana_pi 評論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 評論0 收藏0
  • 你的 Docker 應用是安全的嗎?

    摘要:如今,多樣化的攻擊手段層出不窮,傳統安全解決方案越來越難以應對網絡安全攻擊。自適應安全平臺集成了預測預防檢測和響應的能力,為您提供精準持續可視化的安全防護。 近一年來,Docker 已經逐漸成為 container 界的事實標準,成為技術人員不可或缺的技能之一,就像 Docker 宣稱的那樣,「Build,Ship,and Run Any App,Anywhere」,容器極大簡化了環境...

    darry 評論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 評論0 收藏0

發表評論

0條評論

sunnyxd

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<