Go項(xiàng)目編寫(xiě)Makefile規(guī)則文件概述
make介紹
借助Makefile我們?cè)诰幾g過(guò)程中不再需要每次手動(dòng)輸入編譯的命令和編譯的參數(shù),可以極大簡(jiǎn)化項(xiàng)目編譯過(guò)程。
make是一個(gè)構(gòu)建自動(dòng)化工具,會(huì)在當(dāng)前目錄下尋找Makefile或makefile文件。如果存在相應(yīng)的文件,它就會(huì)依據(jù)其中定義好的規(guī)則完成構(gòu)建任務(wù)。
Makefile介紹
我們可以把Makefile簡(jiǎn)單理解為它定義了一個(gè)項(xiàng)目文件的編譯規(guī)則。借助Makefile我們?cè)诰幾g過(guò)程中不再需要每次手動(dòng)輸入編譯的命令和編譯的參數(shù),可以極大簡(jiǎn)化項(xiàng)目編譯過(guò)程。同時(shí)使用Makefile也可以在項(xiàng)目中確定具體的編譯規(guī)則和流程,很多開(kāi)源項(xiàng)目中都會(huì)定義Makefile文件。
本文不會(huì)詳細(xì)介紹Makefile的各種規(guī)則,只會(huì)給出Go項(xiàng)目中常用的Makefile示例。
Makefile文件教程解析
我們教程主要是講的是 Makefile 。很多 Linux(Unix) 做開(kāi)發(fā)的初學(xué)者不了解 Makefile 是什么,甚至大部分 Windows 開(kāi)發(fā)工程師對(duì) Makefile 都特別陌生。這個(gè)其實(shí)很正常,如果你是在 Windows 下作開(kāi)發(fā)的話不需要去考慮這個(gè)問(wèn)題,因?yàn)?Windows 下的集成開(kāi)發(fā)環(huán)境(IDE)已經(jīng)內(nèi)置了 Makefile,或者說(shuō)會(huì)自動(dòng)生成 Makefile,我們不用去手動(dòng)編寫(xiě)。
Linux 中卻不能這樣,需要我們?nèi)ナ謩?dòng)的完成這項(xiàng)工作。Linux 下可以學(xué)習(xí)的開(kāi)發(fā)語(yǔ)言有很多,常見(jiàn)的有 C/C++語(yǔ)言、python、java 等等。如果你想要在 Linux(Unix) 下做開(kāi)發(fā)的話,不了解 Makefile 是一件非常失敗的事情,甚至說(shuō)你就成為不了一個(gè)合格的 Linux 開(kāi)發(fā)工程師。不懂 Makefile,就操作不了多文件編程,就完成不了相對(duì)于大的工程項(xiàng)目的操作。如果你想在 Linux(Unix) 環(huán)境下做開(kāi)發(fā)的話,Makefile 是必須掌握的一項(xiàng)技能。
那么,究竟什么是 Makefile 呢?
Makefile 可以簡(jiǎn)單的認(rèn)為是一個(gè)工程文件的編譯規(guī)則,描述了整個(gè)工程的編譯和鏈接等規(guī)則。其中包含了那些文件需要編譯,那些文件不需要編譯,那些文件需要先編譯,那些文件需要后編譯,那些文件需要重建等等。
編譯整個(gè)工程需要涉及到的,在 Makefile 中都可以進(jìn)行描述。換句話說(shuō),Makefile 可以使得我們的項(xiàng)目工程的編譯變得自動(dòng)化,不需要每次都手動(dòng)輸入一堆源文件和參數(shù)。
以 Linux 下的C語(yǔ)言開(kāi)發(fā)為例來(lái)具體說(shuō)明一下,多文件編譯生成一個(gè)文件,編譯的命令如下所示:
gcc -o outfile name1.c name2.c ...
outfile 要生成的可執(zhí)行程序的名字,nameN.c 是源文件的名字。這是我們?cè)?Linux 下使用 gcc 編譯器編譯 C 文件的例子。如果我們遇到的源文件的數(shù)量不是很多的話,可以選擇這樣的編譯方式。如果源文件非常的多的話,就會(huì)遇到下面的這些問(wèn)題。
1) 編譯的時(shí)候需要鏈接庫(kù)的的問(wèn)題。拿C語(yǔ)言來(lái)說(shuō),編譯的時(shí)候 gcc 只會(huì)默認(rèn)鏈接一些基本的C語(yǔ)言標(biāo)準(zhǔn)庫(kù),很多源文件依賴的標(biāo)準(zhǔn)庫(kù)都需要我們手動(dòng)鏈接。
下面列舉了一些需要我們手動(dòng)鏈接的標(biāo)準(zhǔn)庫(kù):
- name1.c 用到了數(shù)學(xué)計(jì)算庫(kù) math 中的函數(shù),我們得手動(dòng)添加參數(shù) -Im;
- name4.c 用到了小型數(shù)據(jù)庫(kù) SQLite 中的函數(shù),我們得手動(dòng)添加參數(shù) -lsqlite3;
- name5.c 使用到了線程,我們需要去手動(dòng)添加參數(shù) -lpthread。
因?yàn)橛泻芏嗟奈募?,還要去鏈接很多的第三方庫(kù)。所以在編譯的時(shí)候命令會(huì)很長(zhǎng),并且在編譯的時(shí)候我們可能會(huì)涉及到文件鏈接的順序問(wèn)題,所以手動(dòng)編譯會(huì)很麻煩。
如果我們學(xué)會(huì)使用 Makefile 就不一樣了,它會(huì)徹底簡(jiǎn)化編譯的操作。把要鏈接的庫(kù)文件放在 Makefile 中,制定相應(yīng)的規(guī)則和對(duì)應(yīng)的鏈接順序。這樣只需要執(zhí)行 make 命令,工程就會(huì)自動(dòng)編譯。每次想要編譯工程的時(shí)候就執(zhí)行 make ,省略掉手動(dòng)編譯中的參數(shù)選項(xiàng)和命令,非常的方便。
2) 編譯大的工程會(huì)花費(fèi)很長(zhǎng)的時(shí)間。
如果我們?nèi)プ鲰?xiàng)目開(kāi)發(fā),免不了要去修改工程項(xiàng)目的源文件,每次修改后都要去重新編譯。一個(gè)大的工程項(xiàng)目可不止有幾個(gè)的源文件,里面的源文件個(gè)數(shù)可能有成百上千個(gè)。例如一個(gè)內(nèi)核,或者是一個(gè)軟件的源碼包。這些都是我們做開(kāi)發(fā)經(jīng)常會(huì)遇到的。要完成這樣的文件的編譯,我們消耗的時(shí)間可不是一點(diǎn)點(diǎn)。如果文件特別大的話我們可能要花上半天的時(shí)間。
對(duì)于這樣的問(wèn)題我們 Makefile 可以解決嗎?當(dāng)然是可以的,Makefile 支持多線程并發(fā)操作,會(huì)極大的縮短我們的編譯時(shí)間,并且當(dāng)我們修改了源文件之后,編譯整個(gè)工程的時(shí)候,make 命令只會(huì)編譯我們修改過(guò)的文件,沒(méi)有修改的文件不用重新編譯,也極大的解決了我們耗費(fèi)時(shí)間的問(wèn)題。
這其實(shí)是我們遇到的比較常見(jiàn)的問(wèn)題,當(dāng)然可能遇到的問(wèn)題還會(huì)有很多,比如:工程文件中的源文件的類型很多,編譯的話需要選擇的編譯器;文件可能會(huì)分布在不同的目錄中,使用時(shí)需要調(diào)價(jià)路徑。這些問(wèn)題都可以通過(guò) Makefile 解決。并且文件中的 Makefile 只需要完成一次,一般我們只要不增加或者是刪除工程中的文件,Makefile 基本上不用去修改,編譯時(shí)只用一個(gè) make 命令。為我們提供了極大的便利,很大程度上提高編譯的效率。
規(guī)則概述
Makefile由多條規(guī)則組成,每條規(guī)則主要由兩個(gè)部分組成,分別是依賴的關(guān)系和執(zhí)行的命令。
其結(jié)構(gòu)如下所示:
[target] ... : [prerequisites] ...
<tab>[command]
...
...
其中:
targets:規(guī)則的目標(biāo)
prerequisites:可選的要生成 targets 需要的文件或者是目標(biāo)。
command:make 需要執(zhí)行的命令(任意的 shell 命令)。可以有多條命令,每一條命令占一行。
舉個(gè)例子:
build: CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o xx
示例
.PHONY: all build run gotool clean help
BINARY="bluebell"
all: gotool build
build:
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o ${BINARY}
run:
@go run ./
gotool:
go fmt ./
go vet ./
clean:
@if [ -f ${BINARY} ] ; then rm ${BINARY} ; fi
help:
@echo "make - 格式化 Go 代碼, 并編譯生成二進(jìn)制文件"
@echo "make build - 編譯 Go 代碼, 生成二進(jìn)制文件"
@echo "make run - 直接運(yùn)行 Go 代碼"
@echo "make clean - 移除二進(jìn)制文件和 vim swap files"
@echo "make gotool - 運(yùn)行 Go 工具 'fmt' and 'vet'"以上就是Go項(xiàng)目編寫(xiě)Makefile規(guī)則概述的詳細(xì)內(nèi)容,更多關(guān)于Go項(xiàng)目編寫(xiě)Makefile規(guī)則的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
解決Go語(yǔ)言數(shù)據(jù)庫(kù)中null值的問(wèn)題
這篇文章主要介紹了解決Go語(yǔ)言數(shù)據(jù)庫(kù)中null值的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
goFrame的隊(duì)列g(shù)queue對(duì)比channel使用詳解
這篇文章主要為大家介紹了goFrame的gqueue對(duì)比channel使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
gRPC的發(fā)布訂閱模式及REST接口和超時(shí)控制
這篇文章主要為大家介紹了gRPC的發(fā)布訂閱模式及REST接口和超時(shí)控制,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
golang通過(guò)gorm操作sqlite設(shè)置主鍵自增的步驟
這篇文章主要介紹了golang通過(guò)gorm操作sqlite設(shè)置主鍵自增的詳細(xì)步驟,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-09-09
Go語(yǔ)言panic和recover的用法實(shí)例
panic()和recover()是Go語(yǔ)言中用于處理錯(cuò)誤的兩個(gè)重要函數(shù),本文主要介紹了Go語(yǔ)言panic和recover的用法實(shí)例,panic()用于中止程序并引發(fā)panic,而recover()用于捕獲panic并恢復(fù)程序的執(zhí)行,感興趣的可以了解一下2024-01-01
以Golang為例詳解AST抽象語(yǔ)法樹(shù)的原理與實(shí)現(xiàn)
AST?使用樹(shù)狀結(jié)構(gòu)來(lái)表達(dá)編程語(yǔ)言的結(jié)構(gòu),樹(shù)中的每一個(gè)節(jié)點(diǎn)都表示源碼中的一個(gè)結(jié)構(gòu),本文將以GO語(yǔ)言為例,為大家介紹一下AST抽象語(yǔ)法樹(shù)的原理與實(shí)現(xiàn),希望對(duì)大家有所幫助2024-01-01
golang API開(kāi)發(fā)過(guò)程的中的自動(dòng)重啟方式(基于gin框架)
這篇文章主要介紹了golang API開(kāi)發(fā)過(guò)程的中的自動(dòng)重啟方式(基于gin框架),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12
Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解
這篇文章主要為大家介紹了Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12

