欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

使用genrule如何從makefile向bazel轉(zhuǎn)變

使用genrule如何從makefile向bazel轉(zhuǎn)變,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

成都創(chuàng)新互聯(lián)是一家專(zhuān)業(yè)提供吳川企業(yè)網(wǎng)站建設(shè),專(zhuān)注與做網(wǎng)站、成都網(wǎng)站設(shè)計(jì)html5、小程序制作等業(yè)務(wù)。10年已為吳川眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專(zhuān)業(yè)網(wǎng)絡(luò)公司優(yōu)惠進(jìn)行中。

0x01 背景

現(xiàn)有的makefile構(gòu)建工程如何切換到bazel構(gòu)建系統(tǒng)。

bazel提供了豐富的擴(kuò)展方式,當(dāng)然也支持從目前的makefile過(guò)渡到bazel構(gòu)建。

再次說(shuō)明下其特性:

  1. 多語(yǔ)言支持,并且支持?jǐn)U展到任何語(yǔ)言的構(gòu)建。
    擴(kuò)展DSL是starlyke語(yǔ)言,為Python的一個(gè)子集,容易上手。這一點(diǎn)是cmake和其他構(gòu)建系統(tǒng)不具備的。

  2. 支持緩存。

  3. 支持分布式構(gòu)建。

  4. 支持最小化構(gòu)建。
    在一個(gè)大型系統(tǒng)中,一個(gè)人可能只需要負(fù)責(zé)其中的一個(gè)小組件,這個(gè)組件可能又依賴(lài)其他組件。當(dāng)這個(gè)組件需要更新測(cè)試時(shí),只希望去構(gòu)建這個(gè)組件依賴(lài)的組件和這個(gè)組件本身,其他不相關(guān)的可以不構(gòu)建,這樣可以使用構(gòu)建過(guò)程更快捷。bazel就支持這種方式。

0x02 makefile的問(wèn)題

上文中說(shuō)過(guò)makefile在處理小規(guī)模軟件時(shí)還不錯(cuò),當(dāng)規(guī)模增大時(shí),makefile有以下問(wèn)題。

  1. 各個(gè)組件之間的依賴(lài)難以管理。 makefile只支持將所有的源碼放在一個(gè)目錄下,然后由頂層的。
    這個(gè)依賴(lài)關(guān)系只能是有經(jīng)驗(yàn)的人知道,新人想最小化編譯時(shí),只能試錯(cuò),發(fā)現(xiàn)有依賴(lài)未構(gòu)建時(shí),再去手動(dòng)構(gòu)建。

  2. 增量式構(gòu)建難以控制。
    這一點(diǎn)和第1點(diǎn)是相關(guān)的,因?yàn)橐蕾?lài)不能自動(dòng)化構(gòu)建,所以增量式構(gòu)建也不具備。

  3. 構(gòu)建速度不足,難以做緩存。
    makefile本身不支持緩存,需要額外的工作自行實(shí)現(xiàn)緩存。

0x03 需要解決的問(wèn)題

雖然說(shuō)bazel兼容makefile的構(gòu)建,但也不是直接的支持。需要對(duì)bazel的擴(kuò)展方式有一些了解。也有以下幾個(gè)問(wèn)題需要解決。

  1. bazel的規(guī)則中需要定義輸入輸出
    makefile中的輸出一般不定義。比如如下的makefile中。這個(gè)makefile中就沒(méi)有定義明確的輸出。

all:
	gcc hello.c

或者是這樣的。在makefile中規(guī)則中是去執(zhí)行一個(gè)make.sh腳本。

install:
	bash -x make.sh
  1. makefile一般需要在當(dāng)前目錄下執(zhí)行
    makefile中定義的輸入和輸出,都是基于當(dāng)前的目錄,而bazel是在頂層執(zhí)行的,它的工作目錄就是頂層的WORKSPACE所在的目錄。這對(duì)makefile來(lái)說(shuō)是不友好的。

針對(duì)這2個(gè)問(wèn)題,通過(guò)查看bazel的issue和文檔并沒(méi)有發(fā)現(xiàn)好的解決方式。回答人基本上就推薦你去用對(duì)應(yīng)語(yǔ)言的擴(kuò)展,這對(duì)很多發(fā)有工程來(lái)說(shuō)是不現(xiàn)實(shí)的。原因有:

  1. 對(duì)應(yīng)語(yǔ)言的擴(kuò)展不大可能無(wú)縫支持。
    多半需要自己去修改構(gòu)建的代碼。比如我遇到的1個(gè)c語(yǔ)言的工程,使用cc_external_rule就行不通。

  2. 額外的學(xué)習(xí)成本。
    這個(gè)對(duì)應(yīng)的語(yǔ)言的擴(kuò)展也是需要時(shí)間去學(xué)習(xí)的,也是隱藏的成本。

所以,對(duì)bazel有興趣的多語(yǔ)言構(gòu)建項(xiàng)目,希望以這樣的理想方式過(guò)渡。

  1. 現(xiàn)有的makefile工程可以無(wú)痛過(guò)渡。

  2. 新開(kāi)發(fā)或者大規(guī)模重構(gòu)的工程,可以直接上bazel。

通過(guò)總結(jié),給出了以下的過(guò)渡方案,基本上可以滿足再有的makefile工程。

0x04 過(guò)渡方案

方案要點(diǎn):

  1. 使用bazel的沙盒環(huán)境變量,保留makefile的構(gòu)建時(shí)的環(huán)境變量。
    這些環(huán)境變量可能INSTALLROOT這種安裝環(huán)境變量,也可能有LD_LIBRARY_PATH這種編譯鏈接環(huán)境變量。

  2. 使用genrule規(guī)則,可以快速切換到makefile所在的目錄,執(zhí)行make。

示例工程見(jiàn)gitee。https://gitee.com/ul1n/bazel-demo/tree/makefile 包含src和lib兩個(gè)目錄。各自有自己的makefile。其中src依賴(lài)lib。

方案中的第1點(diǎn)可以非常方便地通過(guò)bazel build時(shí)的選項(xiàng)--action_env傳遞。第2點(diǎn)實(shí)現(xiàn)有點(diǎn)曲折,不過(guò)并不復(fù)雜。這里詳細(xì)說(shuō)明下。

通過(guò)熟悉bazel文檔我們知道genrule可以實(shí)現(xiàn)任何構(gòu)建過(guò)程。這里我們希望如下的genrule。只定義基本的屬性,其中cmd里可以cd到BUILD_PATH,BUILD_PATH可以自動(dòng)變化,不同的子目錄,就變化為所屬的目錄相對(duì)路徑。同時(shí)可以生成一個(gè)偽目標(biāo),滿足genrule的要求。

genrule(
    name="hello",
    srcs=["srcs"],
    cmd="cd $(BUILD_PATH) && make",
    outs=["test"]
)

那么如何自動(dòng)地控制BUILD_PATH的環(huán)境變量呢?bazel不支持直接傳遞環(huán)境變量給genrule的上下文,換說(shuō)法就是cmd中的環(huán)境變量,需要提前聲明好。通過(guò)查看官方的一些示例,可以這樣來(lái)實(shí)現(xiàn)。

注:BUILD文件中涉及的bazel的語(yǔ)法可以參考官方文檔進(jìn)行熟悉。

定義一個(gè)def.bzl文件。這個(gè)bzl就是可以為引用它的BUILD文件中引入一個(gè)BUILD_PATH的環(huán)境變量。

def _var_providing_rule_impl(ctx):
    build_path = ctx.build_file_path
    loc, _ = build_path.rsplit('/', 2)

    return [platform_common.TemplateVariableInfo({"BUILD_PATH":loc}),]

var_providing_rule = rule(
    implementation = _var_providing_rule_impl,
    attrs = { "var_value": attr.string() }
)

然后在lib目錄下添加一個(gè)BUILD文件。這份文件編寫(xiě)的非常通用,可以放在任何一個(gè)makefile目錄下。除了有其他依賴(lài)需要在genrule的srcs屬性中添加。

load("//:def.bzl", "var_providing_rule")

var_providing_rule(
    name="set_build_path",
    var_value=""
)

filegroup(
    name="srcs",
    srcs=glob(["**"])
)

genrule(
    name = "default",
    srcs=["srcs"],
    cmd="cd $(BUILD_PATH) && make && cd - && touch $(RULEDIR)/out.txt",
    visibility=["//visibility:public"],
    outs=["out.txt"],
    toolchains=[":set_build_path"]
)

在src目錄下添加如下的BUILD文件,與lib中的基本上一致,只是srcs中多了對(duì)lib中規(guī)則的依賴(lài)。

load("//:def.bzl", "var_providing_rule")

var_providing_rule(
    name="set_build_path",
    var_value=""
)

filegroup(
    name="srcs",
    srcs=glob(["**"])
)

genrule(
    name = "default",
    srcs=["srcs", "//lib:default"],
    cmd="cd $(BUILD_PATH) && make && cd - && touch $(RULEDIR)/out.txt",
    outs=["out.txt"],
    toolchains=[":set_build_path"]
)

這里對(duì)cmd參數(shù)做一下說(shuō)明。

1 切換到BUILD文件所在的目錄。
2 執(zhí)行make。這個(gè)也可以換成需要的命令,比如make install。
3 切換到上一個(gè)目錄,也就是WORKSPACE文件所在的目錄。
4 創(chuàng)建一個(gè)偽輸出out.txt。RULEDIR是bazel約定的規(guī)則產(chǎn)出物的目錄。是一個(gè)相對(duì)路徑,這是為什么第3步中要切回目錄的原因。

用&&連接是為了在失敗時(shí)能立刻退出執(zhí)行。

添加完成后,就可以通過(guò)如下的命令執(zhí)行這個(gè)構(gòu)建過(guò)程了。

bazel build --sandbox_writable_path=$INSTALLROOT --action_env=C_INCLUDE_PATH=$INSTALLROOT/include --action_env=INSTALLROOT=$INSTALLROOT //src:default

其中--sandbox_writable_path選項(xiàng)是為了開(kāi)放權(quán)限,保證makefile中需要執(zhí)行的目錄創(chuàng)建操作。另外兩個(gè)環(huán)境變量,則是為了保證原來(lái)的makefile可以成功構(gòu)建。執(zhí)行完成后,會(huì)在當(dāng)前目錄的tmp/bin/目錄下生成app可執(zhí)行文件。tmp/lib下生成動(dòng)態(tài)鏈接庫(kù)。這樣一來(lái),只要配置的環(huán)境變量合適,就可以完美執(zhí)行原有的構(gòu)建流程了。

0x05 總結(jié)

這種實(shí)現(xiàn)方式可能不是最好的,但目前來(lái)說(shuō)是最直接的。當(dāng)然也希望有知道更好方式的同學(xué)告知下。目前這種實(shí)現(xiàn)方式還有以下幾個(gè)問(wèn)題。

  1. 產(chǎn)出物是偽造的,對(duì)于bazel來(lái)說(shuō)不是sound(可感知)的。無(wú)法緩存INSTALLROOT的產(chǎn)生物。

  2. 產(chǎn)生物不可感知,那么INSTALLROOT被刪除的情況下,bazel的構(gòu)建可能什么都不會(huì)做,因?yàn)樗恢繧NSTALLROOT的存在。

這2個(gè)問(wèn)題作如下解答: 如果是需要緩存的大型模塊,那么可以產(chǎn)生真正的產(chǎn)出物,同時(shí)復(fù)制一份到RULEDIR。但I(xiàn)NSTALLROOT被刪除這一塊無(wú)法通過(guò)技術(shù)手段保證。

關(guān)于使用genrule如何從makefile向bazel轉(zhuǎn)變問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

當(dāng)前題目:使用genrule如何從makefile向bazel轉(zhuǎn)變
網(wǎng)站網(wǎng)址:http://www.chinadenli.net/article38/isjdpp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站網(wǎng)站維護(hù)微信小程序網(wǎng)站排名品牌網(wǎng)站設(shè)計(jì)響應(yīng)式網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

綿陽(yáng)服務(wù)器托管