linux make命令與makefile檔案

2021-10-06 02:40:33 字數 4100 閱讀 9334

3. 語法

最後的實踐

通俗的來講:

其實和 shell 指令碼差不多,只不過有一些自己的規則可以讓你使用起來更方便,比如你寫 shell 指令碼的話,只能寫在乙個檔案裡然後執行這個檔案,makefile 可以讓你執行這個裡面的某一條命令。

makefile檔案由一系列規則(rules)構成。每條規則的形式如下。

:[tab]

上面第一行冒號前面的部分,叫做"目標"(target),冒號後面的部分叫做"前置條件"(prerequisites);第二行必須由乙個tab鍵起首,後面跟著"命令"(commands)。

"目標"是必需的,不可省略;"前置條件"和"命令"都是可選的,但是兩者之中必須至少存在乙個。

當目標是檔名的時候,比如這時的目標是a.txt:

a.txt: b.txt c.txt

cat b.txt c.txt > a.txt

當目標為乙個操作的名字時,比如這個clean,稱為『偽目標』,但是當你執行make clean的時候,如果正好有乙個檔案叫做clean,那麼這個命令不會執行。因為make發現clean檔案已經存在,就認為沒有必要重新構建了,就不會執行指定的rm命令。

clean:

rm *.o

所以,一般我們會明確宣告clean是"偽目標":

.phony: clean

clean:

rm *.o temp

多個偽目標直接用空格隔開

像.phony這樣的內建目標名還有不少,可以檢視手冊。

var-lost:

export foo=bar

echo

"foo=[$$foo]"

上面**執行後(make var-lost),取不到foo的值。因為兩行命令在兩個不同的程序執行。乙個解決辦法是將兩行命令寫在一行,中間用分號分隔。

兩行命令寫在一行,中間用分號分隔。

換行符前加反斜槓轉義。

加上.oneshell:

var-kept:

export foo=bar;

echo

"foo=[$$foo]"

var-kept:

export foo=bar; \

echo

"foo=[$$foo]"

.oneshell:

var-kept:

export foo=bar;

echo

"foo=[$$foo]"

用 #

make會列印每條命令,然後再執行,這就叫做回聲(echoing)。

在命令的前面加上@,就可以關閉回聲。

注:通常只在注釋和純顯示的echo命令前面加上@。

test:

@# 這是測試

@echo todo

txt = hello world

test:

@echo $(txt)

用shell變數,需要在美元符號前,再加乙個美元符號,這是因為make命令會對美元符號轉義。

test:

@echo $$home

variable = value

# 在執行時擴充套件,允許遞迴擴充套件。

variable := value

# 在定義時擴充套件。

variable ?= value

# 只有在該變數為空時才設定值。

variable += value

# 將值追加到變數的尾端。

1、$@

$@指代當前目標,就是make命令當前構建的那個目標。比如,make foo的 $@ 就指代foo。

2、$<

<指代

第乙個前

置條件。

比如,規

則為t:

p1p2

,那

麼< 指代第乙個前置條件。比如,規則為 t: p1 p2,那麼

《指代第乙個前

置條件。

比如,規

則為t:

p1p2

,那麼< 就指代p1。

等等…

ifeq (

$(cc)

,gcc)

libs=

$(libs_for_gcc)

else

libs=

$(normal_libs)

endif

list = one two three

all:

for i in

$(list)

;do \

echo $$i

; \ done

# 等同於

all:

for i in one two three;

do \

echo

$i; \

done

$(

function arguments)

# 或者

$

makefile提供了許多內建函式,可供呼叫。下面是幾個常用的內建函式。

1、shell 函式:

用來執行 shell 命令

srcfiles :=

$(shell echo src/.txt)

2、call 函式:

$(call variable,param,param,…)

$(1)

,$(2)

等等表示param,param,…

等等…還有好多函式

我專案中的一些實踐:

shell := /bin/bash

.phony: prerequ-program client server prod_server prod_client

install:|prerequ-program

define require_install

iftest

"$(shell which

$(1))"=

""; \

then \

brew install

$(2)

; \ else \

echo

$(1)

is exists. skip install

; \ fi

endef

prerequ-program:

@$(call require_install,mongod,mongo)

mkdir -p ./db/

if["$"=""]

;then mongod --bind_ip 127.0.0.1 --fork --dbpath ./db/ --logpath ./db/mongod.log;

fi @echo "start mongod success!"

# 開發模式

server:

cd server &&

npminstall

&&npm run dev

client:

cd client &&

npminstall

&&npm run dev

# 生產模式

prod_server:

cd server &&

npminstall

&&npm start

prod_client:

cd client &&

npminstall

&&npm run build

比如我的專案要安裝 mongodb,那麼呼叫shell函式判斷一下有沒有 mongod,沒有的話就brew install mongo,否則在當前目錄下新建檔案mkdir -p ./db/

gcc除錯基礎作用命令和工程管理器make

gdb g test.c o test gdb test gdb run 執行 gdb list 檢視原始碼 gdb quit 結束 gdb break 21 在21行進行斷點 gdb next 斷點下一步,不進入子函式 gdb print result 輸出斷點處的result gdb print...

source命令與 命令

參考 source 命令是 bash shell 的內建命令,從 c shell 而來。source 命令的另一種寫法是點符號,用法和 source 相同,從bourne shell而來。source 命令可以強行讓乙個指令碼去立即影響當前的環境。source 命令會強制執行指令碼中的全部命令,而忽...

apt get 命令與dpkg命令

它的引數有很多,如果需要可以通過 help來檢視 現在你已經知道如何安裝和刪除軟體包,下面的命令可以讓你獲取最新的軟體包套件資訊 在你更改了 etc apt sources.list後需要執行這個命令以令改動生效。sudo apt get update 然後您可以用 更新所有有新版本的套件 sudo...