Makefile學習

一、多個if判斷

DEMO := 2

all:
ifeq ($(DEMO), 1)
    @echo "DEMO 1"
else ifeq ($(DEMO), 2)
    @echo "DEMO 2"
else ifeq ($(DEMO), 3)
    @echo "DEMO 3"
else
    @echo "DEMO Other"
endif

輸出:html

DEMO 2
DEMO2

 

二、打印變量

可使用 ${} 或者$() 或者 $ ,其中 $ 用於單字符變量,對於多字符變量,只能用前面兩個python

DEMO := 1
X := 1

all:
        @echo \$$\{DEMO\} = ${DEMO}
        @echo \$$\(DEMO\) = $(DEMO)
        @echo \$$\X = $X

輸出:shell

${DEMO} = 1
$(DEMO) = 1
$X = 1

 

三、=、:= 和 ?=

x := 1
y = 1
x ?= 2

all:
        @echo x=$(x)
        @echo y=$(y)

y = 2
y ?= 3

輸出:編程

x=1
y=2

 

四、ifdef和ifndef使用

X := 1
Y :=
Z := 2

all:
ifndef X
        @echo "X = $(X)"
else ifdef Y
        @echo "Y = ${Y}"
else ifdef Z
        @echo "Z = ${Z}"
endif

輸出:bash

Z = 2

 

五、origin得到變量來源

w1 := $(origin W)
x1 := $(origin X)
y1 := $(origin Y)
Z := 1
z1 := $(origin Z)
c := $(origin CC)


all:
        @echo "W: ${w1}"
        @echo "X: ${x1}"
        @echo "Y: ${y1}"
        @echo "Z: ${z1}"
        @echo "CC: ${c}"

運行:post

$ X=1 make -f mk5 Y=2
W: undefined
X: environment
Y: command line
Z: file
CC: default

 

六、遞歸編譯的三種方式

目錄結構:ui

.
├── Makefile
├── sub1
│   └── Makefile
├── sub2
│   └── Makefile
├── sub3
│   └── Makefile
├── sub4
│   └── Makefile
└── sub5
    └── Makefile

子目錄的Makefile內容只輸出一句話:url

sub1/Makefile內容:
all:
        @echo "\tThis is sub1"

sub2/Makefile內容:
all:
        @echo "\tThis is sub2"

sub3/Makefile內容:
all:
        @echo "\tThis is sub3"

sub4/Makefile內容:
all:
        @echo "\tThis is sub4"

sub5/Makefile內容:
all:
        @echo "\tThis is sub5"

頂層Makefile內容以下:spa

SUB_DIRS := $(sort $(wildcard sub*))

all: subdir
        @echo "\t\t**** method 2 ****"
        @echo "In top dir"
        @cd sub1 && make -s
        @cd sub2 && make -s
        @cd sub3 && make -s
        @cd sub4 && make -s
        @cd sub5 && make -s

        @echo "\n\t\t**** method 3 ****"
        @echo "In top dir"
        @for dir in $(SUB_DIRS); do \
                make -s -C $$dir; \
        done

.PHONY: log $(SUB_DIRS)
subdir:log $(SUB_DIRS)

log:
        @echo "SUB_DIRS: \n\t$(SUB_DIRS)"
        @echo "\n\t\t**** method 1 ****"
        @echo "In top dir"

$(SUB_DIRS):
        @make -s -C $@

輸出:.net

SUB_DIRS: 
        sub1 sub2 sub3 sub4 sub5

                **** method 1 ****
In top dir
        This is sub1
        This is sub2
        This is sub3
        This is sub4
        This is sub5
                **** method 2 ****
In top dir
        This is sub1
        This is sub2
        This is sub3
        This is sub4
        This is sub5

                **** method 3 ****
In top dir
        This is sub1
        This is sub2
        This is sub3
        This is sub4
        This is sub5

 

七、make -n 或者 make --just-print

能夠用於調試Makefile的一些問題,此時make執行時只顯示所要執行的命令,但不會真正的去執行這些命令

 

八、make -s 或者 make --slient

禁止全部執行命令的顯示,就好像全部的命令行均使用"@"開始同樣

 

九、.PHONY

使用這個修飾的目標,對應的命令會被無條件執行。而若是沒有修飾的話,對於沒有依賴文件的目標,只要目標文件不存在時纔會執行定義的命令。

實例:

all:
        @echo "all is compiled"

.PHONY:clean
clean:
        @echo "clean is compiled"

體會下面的輸出:

//此時當前目錄只有一個Makefile文件
$ ls
Makefile

//執行make後,all做爲第一個目標,因爲當前目錄下不存在all這個文件,因此all的命令被執行
$ make
all is compiled
$ make all
all is compiled

// clean因爲是PHONY的,因此每次都執行
$ make clean
clean is compiled

// 而後在當前目錄下分別建立all和clean兩個文件
$ touch all
$ touch clean
$ ls
all  clean  Makefile

// 此時在編譯all時,all的命令就不會執行了,由於當前目錄已經存在all文件,而且all沒有任何依賴文件
$ make
make: 'all' is up to date.
$ make all
make: 'all' is up to date.

// clean因爲是PHONY的,命令無條件執行
$ make clean
clean is compiled

// 將all刪除,發現all又能夠執行了
$ rm all 
$ ls
clean  Makefile
$ make all
all is compiled

// clean因爲是PHONY的,命令無條件執行
$ make clean
clean is compiled

 

若是在對Makefile作個修改:

all:clean
        @echo "all is compiled"

.PHONY:clean
clean:
        @echo "clean is compiled"

 即,將all的依賴文件設置爲clean,那麼此後,all也會被無條件執行了

$ ls
all  clean  Makefile
$ make all
clean is compiled
all is compiled
$ make
clean is compiled
all is compiled

 

十、模式匹配

  • %

當前目錄下有以下幾個文件:

$ ls
abc.A.abc  a.c  demo2.y  demo.sh  donglin.w  Makefile

Makefile內容以下:

all:demo demo2.x pengdonglin.w helloAworld
        @echo "all command"

%:%.c
        @echo generate $@ through $<

%:%.sh
        @echo generate $@ through $<

%.x:%.y
        @echo generate $@ through $<

hello%world:abc.%.abc
        @echo generate $@ through $<

peng%:%
        @echo generate $@ through $<

下面是運行結果:

generate demo through demo.sh
generate demo2.x through demo2.y
generate pengdonglin.w through donglin.w
generate helloAworld through abc.A.abc
all command

 

 十一、make -p 或 make --print-data-base

能夠查看在當前環境下make內置了那些規則

 

 十二、 $(if $(KBUILD_VERBOSE:1=),@)  語法釋疑

 https://blog.csdn.net/lcw_202/article/details/6656633

 等價於:

$(if $(patsubst %1,%,$(KBUILD_VERBOSE)),@)

也就是,若是KBUILD_VERBOSE爲1,那麼上面的表達式就是空,不然的話,就是@,這樣後面的命令就會靜默輸出

 

 1三、調用shell腳本

Makefile中的shell用法

makefile中的shell編程注意點

Shell腳本——make命令和Makefile文件

https://www.jb51.net/article/109797.htm

shell 文件內調用makefile文件

#!/bin/bash
cd ctemplate-2.1
./configure
sudo make -f install
cd ../
cd TemplateProcesser
make

說明:./configure文件是shell腳本文件,即shell內調用shell文件是很容易的;TemplateProcesser目錄內有Makefile文件,調用方式,直接:make

makefile文件內調用shell腳本文件:

SHELL := /bin/bash
test:
@pwd
cd ./TemplateProcesser && pwd
sh ./build.sh
@pwd

說明:build.sh爲shell腳本文件。

調用perl文件
/usr/bin/perl *.pl
調用python文件
/usr/bin/env *.py

 

 1三、X:Y:Z

X := 1.o 2.o 3.o
Y := 4.o 5.o 6.o

all:$(X) $(Y)

X_c := $(patsubst %.o,%.c,$(X))
Y_c := $(patsubst %.o,%.c,$(Y))

$(X):%.o:%.c
        @echo "$@ <---- $<"

$(Y):%.o:%.c
        @echo "$@ <==== $<"

.PHONY:$(X_c) $(Y_c)

 

 輸出:

1.o <---- 1.c
2.o <---- 2.c
3.o <---- 3.c
4.o <==== 4.c
5.o <==== 5.c
6.o <==== 6.c

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

===

相關文章
相關標籤/搜索