由于很多應用項目依賴諸多第三方開源庫,這些開源庫各有不同的核心目錄、庫目標和輸出位置,這里的核心目錄是指僅產生so庫的工程目錄,庫目標是指僅產生so庫的make目標,輸出位置是相對于核心目錄的,但不必是子目錄,可用..來回溯到父目錄的某位置,更高層目錄的位置,依次類推。為了統一支持它們,使用了一些技巧,詳見示例腳本如下
1
.PHONY: all clean lib core
2
3
thirdlib=openssl-1.0.1u?build_ssl ACE_wrappers/ace json ncurses-6.0??lib
4
coremod=main
5
6
dir = `echo $@ | awk -F? '{print $$1}'`
7
aim = `echo $@ | awk -F? '{print $$2}'`
8
out = `echo $@ | awk -F? '{print $$3}'`
9
10
copy=\cp -Pf ${dir}/${out}/*.so* output
11
12
define MAKE_SUBDIR
13
echo "${dir},${aim},${out}"; \
14
if [ "$(MAKECMDGOALS)" != "clean" ]; then \
15
$(MAKE) ${aim} -C ${dir}; \
16
if [ "$$is_cp" -eq "1" ]; then \
17
$(copy); \
18
fi \
19
else \
20
$(MAKE) clean -C ${dir}; \
21
fi
22
endef
23
24
all: lib core
25
26
lib: $(thirdlib)
27
28
$(thirdlib)::
29
@is_cp=1; $(MAKE_SUBDIR)
30
31
core: $(coremod)
32
33
$(coremod)::
34
@is_cp=0; $(MAKE_SUBDIR)
35
36
clean: $(thirdlib) $(coremod)

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

實現技巧
1)使用?作為分隔符,所分隔的3個域依次為核心目錄、庫目標、輸出位置;使用awk來獲取各域,分別為dir、aim和out;在運行過程中,值dir一定非空,而aim為空則表示默認目標,out為空表示輸出位置即為dir目錄。
2)copy為命令變量,功能為每當一個庫編譯完成后,將輸出的so庫拷貝到output下,并保持軟鏈接;對于有的開源庫,需在編譯前,使用對應的選項來調用configure,使其生成so庫。
3)為了重用代碼,定義了MAKE_SUBDIR命令包,參數變量為is_cp,當is_cp為1時,表示當前編譯的是依賴庫,否則是主程序。
4)thirdlib和coremod為依賴文件,使用了雙冒號規則,這樣一來,只要在thirdlib中加入新的依賴庫,指定核心目錄、庫目標和輸出位置即可,其它地方不用改。