脚本源码
由于很多应用项目依赖诸多第三方开源库,这些开源库各有不同的核心目录、库目标和输出位置,这里的核心目录是指仅产生so库的工程目录,库目标是指仅产生so库的make目标,输出位置是相对于核心目录的,但不必是子目录,可用..来回溯到父目录的某位置,更高层目录的位置,依次类推。为了统一支持它们,使用了一些技巧,详见示例脚本如下
实现技巧
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中加入新的依赖库,指定核心目录、库目标和输出位置即可,其它地方不用改。![]()
由于很多应用项目依赖诸多第三方开源库,这些开源库各有不同的核心目录、库目标和输出位置,这里的核心目录是指仅产生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中加入新的依赖库,指定核心目录、库目标和输出位置即可,其它地方不用改。