在 Golang 開發(fā)中使用 Makefile

使用 Golang 已經(jīng)有一陣了鹿寨,在 Golang 的開發(fā)過程中新博,我已經(jīng)習(xí)慣于不斷重復(fù)地手動(dòng)執(zhí)行 go buildgo test 這兩個(gè)命令. 不過,現(xiàn)在我已經(jīng)擺脫了這個(gè)習(xí)慣脚草。如果只用到了不帶參數(shù)的簡(jiǎn)單命令赫悄,直接這么操作可能并不可怕。但是在一些復(fù)雜的任務(wù)中馏慨,如果依舊是手動(dòng)執(zhí)行 go buildgo test 埂淮,就可能會(huì)成為一個(gè)讓人頭疼的事情。

我們可以通過其他方式解決這個(gè)問題写隶。比如倔撞,可以用一個(gè) bash 腳本來完成這些工作,或者一個(gè)更好的選擇(至少對(duì)于我來說)是慕趴,寫一個(gè) makefile. make 這個(gè)工具生來就是為了做這些事情痪蝇,在 makefile 中我們可以將所有常見的任務(wù)都放在一起。我并不是一個(gè) makefile 專家冕房,所以可能不太能夠教大家如何寫一個(gè)好的 makefile. 但是在本文躏啰,我將向大家展示我所使用的 Makefile,我的大部分項(xiàng)目都使用了這些 makefile 耙册。讓我們開始吧:

# Go parameters
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get
BINARY_NAME=mybinary
BINARY_UNIX=$(BINARY_NAME)_unix

all: test build
build:
        $(GOBUILD) -o $(BINARY_NAME) -v
test:
        $(GOTEST) -v ./...
clean:
        $(GOCLEAN)
        rm -f $(BINARY_NAME)
        rm -f $(BINARY_UNIX)
run:
        $(GOBUILD) -o $(BINARY_NAME) -v ./...
        ./$(BINARY_NAME)
deps:
        $(GOGET) github.com/markbates/goth
        $(GOGET) github.com/markbates/pop


# Cross compilation
build-linux:
        CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v
docker-build:
        docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v

我比較喜歡 DRY(Don't Repeat Yourself) 原則给僵。所以,在 makefile
的開頭定義常用的命令和變量详拙,我們可以在后面方便地對(duì)定義的命令和變量進(jìn)行引用帝际。

# Basic go commands
GOCMD=go
GOBUILD=$(GOCMD) build
GOCLEAN=$(GOCMD) clean
GOTEST=$(GOCMD) test
GOGET=$(GOCMD) get

# Binary names
BINARY_NAME=mybinary
BINARY_UNIX=$(BINARY_NAME)_unix

: 前面的叫做 makefile 的目標(biāo),比如 build:, build 就是一個(gè)目標(biāo)溪厘。如果在執(zhí)行 make 命令時(shí)指定目標(biāo)胡本,比如 make run,那么 make 就會(huì)構(gòu)建該目標(biāo)畸悬。如果沒有提供任何參數(shù)侧甫,那么 make 默認(rèn)會(huì)執(zhí)行第一個(gè)目標(biāo)珊佣。在我們的示例中,也就是叫 all 的目標(biāo)會(huì)被構(gòu)建披粟。

$ make run ## call specific task
$ make     ## make tool calls "all" task

基本命令

makefile 最關(guān)鍵的部分就是構(gòu)建咒锻。當(dāng) make 進(jìn)行執(zhí)行時(shí),定義的變量會(huì)被展開守屉,$(GOBUILD) 會(huì)被展開為 go build, make 實(shí)際就會(huì)執(zhí)行 go build 命令惑艇。生成的二進(jìn)制文件被命名為 -o $(BINARY_NAME). 另外,我發(fā)現(xiàn)使用 -v 參數(shù)切換到 verbose mode 非常有用拇泛。在 verbose mode 中滨巴,你可以看到當(dāng)前正在構(gòu)建的包。

build:
  $(GOBUILD) -o $(BINARY_NAME) -v ## expands to: "go build -o mybinary -v"

因?yàn)槲覀兇蟛糠秩硕己軕邪嘲龋跃陀辛艘粋€(gè)叫做 run 的目標(biāo)恭取。run 會(huì)構(gòu)建二進(jìn)制文件,并且在 build 完成后執(zhí)行這個(gè)二進(jìn)制文件熄守。

run:
        $(GOBUILD) -o $(BINARY_NAME) -v ./...
        ./$(BINARY_NAME)

通常來講蜈垮,test 命令應(yīng)該是 makefile 的一部分。我個(gè)人總是喜歡使用 verbose mode 來更好地 debug 和觀測(cè) test 的運(yùn)行裕照。

test:
  $(GOTEST) -v ./...

如果項(xiàng)目使用 CI(Continuous Integration)/CD(Continuous Delivery), 哪怕僅僅是為了一致性攒发,將一系列依賴維護(hù)在包里面也是一個(gè)非常好的做法。這可以通過 deps 目標(biāo)來完成晋南,它會(huì)通過 go get 命令獲取所有相關(guān)的依賴惠猿。

deps:
        $(GOGET) github.com/markbates/goth
        $(GOGET) github.com/markbates/pop

clean 來結(jié)束這一節(jié)的內(nèi)容。rm -f 命令被用來移除名為
$(BINARY_XXX) 的二進(jìn)制文件负间。

clean:
        $(GOCLEAN)
        rm -f $(BINARY_NAME)
        rm -f $(BINARY_UNIX)

交叉編譯命令

如果項(xiàng)目開發(fā)是在一個(gè)系統(tǒng)上紊扬,而需要在另一個(gè)系統(tǒng)上運(yùn)行,那么在 makefile 中包含一個(gè)交叉編譯的命令是非常方便的唉擂。我通常在容器的 Linux 平臺(tái)上運(yùn)行二進(jìn)制餐屎,所以 makefile 包含了 Linux 構(gòu)建。

build-linux:
        CGO_ENABLED=0 GOOS=linux GOARCH=amd64 $(GOBUILD) -o $(BINARY_UNIX) -v

如果你的代碼使用了 C binding玩祟,你可能會(huì)遇到一些問題腹缩。CGO 的問題在于你需要一個(gè)與給定平臺(tái)兼容的 gcc. 如果開發(fā)在 OSX/Windows 上完成,那么你需要有一個(gè)能夠兼容 Linux 的 gcc. 至少對(duì)我來說空扎,在 OSX 上使用配置 gcc 交叉編譯 C 代碼并不容易藏鹊。如果需要 CGO, docker 鏡像是創(chuàng)建 Linux 構(gòu)建的最好方式。這種方式唯一的要求就是必須安裝 Docker转锈。

docker-build:
        docker run --rm -it -v "$(GOPATH)":/go -w /go/src/bitbucket.org/rsohlich/makepost golang:latest go build -o "$(BINARY_UNIX)" -v

本文的 Makefile 示例可在 這里 找到盘寡。


譯者:原文使用的 Makefile 其實(shí)還可以更好,比如在原文下面的評(píng)論中指出撮慨,至少應(yīng)該指明 .PHONY:, 另外 build 應(yīng)該是 run 的前提條件竿痰。不過脆粥,我們可以學(xué)習(xí)其中可取的部分。

本文譯自:Golang: Don’t afraid of makefiles

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末影涉,一起剝皮案震驚了整個(gè)濱河市变隔,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蟹倾,老刑警劉巖匣缘,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鲜棠,居然都是意外死亡肌厨,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門豁陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夏哭,“玉大人,你說我怎么就攤上這事献联。” “怎么了何址?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵里逆,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我用爪,道長(zhǎng)原押,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任偎血,我火速辦了婚禮诸衔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘颇玷。我一直安慰自己笨农,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布帖渠。 她就那樣靜靜地躺著谒亦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪空郊。 梳的紋絲不亂的頭發(fā)上份招,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音狞甚,去河邊找鬼锁摔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛哼审,可吹牛的內(nèi)容都是我干的谐腰。 我是一名探鬼主播孕豹,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼怔蚌!你這毒婦竟也來了巩步?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬榮一對(duì)情侶失蹤桦踊,失蹤者是張志新(化名)和其女友劉穎椅野,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體籍胯,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡竟闪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了杖狼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炼蛤。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蝶涩,靈堂內(nèi)的尸體忽然破棺而出理朋,到底是詐尸還是另有隱情,我是刑警寧澤绿聘,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布嗽上,位于F島的核電站,受9級(jí)特大地震影響熄攘,放射性物質(zhì)發(fā)生泄漏兽愤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一挪圾、第九天 我趴在偏房一處隱蔽的房頂上張望浅萧。 院中可真熱鬧,春花似錦哲思、人聲如沸洼畅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽土思。三九已至,卻和暖如春忆嗜,著一層夾襖步出監(jiān)牢的瞬間己儒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工捆毫, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闪湾,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓绩卤,卻偏偏與公主長(zhǎng)得像途样,于是被迫代替她去往敵國(guó)和親江醇。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容