21.打造专业的编译器环境(中)

阅读: 评论:0

21.打造专业的编译器环境(中)

21.打造专业的编译器环境(中)

目录

 

1.第二阶段任务

2.关键的实现要点

3.开发中的经验假设

4.解决方案设计

5.makefile中嵌入shell的for循环

6.注意事项

7.工程makefile中的关键构成

8.链接时注意事项

综合


1.第二阶段任务

完成编译整个工程的makefile文件

调用模块makefile编译生成静态库文件

链接所有模块的静态文件,最终得到可执行程序

2.关键的实现要点

  • 如何自动创建build文件夹以及子文件夹?
  • 如何进入每一个模块文件夹进行编译?
  • 编译成功后如何链接所有模块静态库?

3.开发中的经验假设

项目中的各个模块字设计阶段就已经基本确定,因此,在之后的开发过程中不会频繁随意的增加或者减少!

 

4.解决方案设计

1.定义变量保存模块名列表(模块名变量)

2.利用shell中的for循环遍历模块名变量

3.在for循环中进入模块文件夹进行编译

4.循环结束后链接所有的模块静态库文件

5.makefile中嵌入shell的for循环

6.注意事项

makefile中嵌入shell代码时,如果需要使用shell变量的值,必须在变量名前加上$$(例:$$dir)!

先写一个shell脚本测试一下

aston@ubuntu:~/disciple$ ./test.sh 
common
module
main
aston@ubuntu:~/disciple$ cat test.sh 
MODULES="common module main"for dir in $MODULES; 
doecho $dir
done

编写makefile

aston@ubuntu:~/disciple$ make test
common
module
main
aston@ubuntu:~/disciple$ cat makefile 
#MODULES := common module main
MODULES := common module main
test :@set -e; for dir in $(MODULES); do echo $$dir; done

7.工程makefile中的关键构成

8.链接时注意事项

  • gcc在进行静态链接时必须遵循严格的依赖关系

  • 如果不清楚库之间的依赖,可以使用-Xlinker自动确定依赖关系

获取当前工程的绝对路径,同时得到编译存放的相对路径

.PHONY : all compile linkMODULES := common module mainDIR_PROJECT := $(realpath .)
DIR_BUILD := build
DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))all :@echo "$(DIR_PROJECT)"@echo "$(DIR_BUILD_SUB)"test :@set -e; for dir in $(MODULES); do echo $$dir; done

测试一下:

/home/aston/disciple

build/common build/module build/main

 

自动创建对应目录

测试一下

.PHONY : all compile linkMODULES := common module main
MKDIR := mkdir 
RM := rm -rfDIR_PROJECT := $(realpath .)
DIR_BUILD := build
DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))all :@echo "$(DIR_PROJECT)"@echo "$(DIR_BUILD_SUB)"compile : $(DIR_BUILD) $(DIR_BUILD_SUB)@set -e; for dir in $(MODULES); do echo $$dir; done
$(DIR_BUILD) $(DIR_BUILD_SUB) :$(MKDIR) $@
common  main  makefile  module
aston@ubuntu:~/disciple$ make compile
mkdir  build
mkdir  build/common
mkdir  build/module
mkdir  build/main
common
module
main
aston@ubuntu:~/disciple$ ls
build  common  main  makefile  module
aston@ubuntu:~/disciple$ ls build/
common  main  module

现在就可以进去每个模块进行编译

compile : $(DIR_BUILD) $(DIR_BUILD_SUB)@echo "Begin "@set -e; for dir in $(MODULES); do cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd ..; done@echo ""

测试一下:

aston@ubuntu:~/disciple$ make compile
mkdir  build
mkdir  build/common
mkdir  build/module
mkdir  build/main
Begin 
make[1]: Entering directory `/home/aston/disciple/common'
makefile:41: /home/aston/disciple/build/common/common.dep: No such file or directory
makefile:41: /home/aston/disciple/build/common/func.dep: No such file or directory
Creating /home/aston/disciple/build/common/
Creating /home/aston/disciple/build/common/
make[1]: Leaving directory `/home/aston/disciple/common'
make[1]: Entering directory `/home/aston/disciple/common'
ar crs  /home/aston/disciple/build/common.a /home/aston/disciple/build/common/common.o /home/aston/disciple/build/common/func.o
Success! Target ==> /home/aston/disciple/build/common.a
make[1]: Leaving directory `/home/aston/disciple/common'
make[1]: Entering directory `/home/aston/disciple/module'
makefile:41: /home/aston/disciple/build/module/module.dep: No such file or directory
Creating /home/aston/disciple/build/module/
make[1]: Leaving directory `/home/aston/disciple/module'
make[1]: Entering directory `/home/aston/disciple/module'
ar crs  /home/aston/disciple/build/module.a /home/aston/disciple/build/module/module.o
Success! Target ==> /home/aston/disciple/build/module.a
make[1]: Leaving directory `/home/aston/disciple/module'
make[1]: Entering directory `/home/aston/disciple/main'
makefile:41: /home/aston/disciple/build/main/main.dep: No such file or directory
Creating /home/aston/disciple/build/main/
make[1]: Leaving directory `/home/aston/disciple/main'
make[1]: Entering directory `/home/aston/disciple/main'
ar crs  /home/aston/disciple/build/main.a /home/aston/disciple/build/main/main.o
Success! Target ==> /home/aston/disciple/build/main.a
make[1]: Leaving directory `/home/aston/disciple/main'

接下来就是实现link

先将.a文件加上前缀,定义最终生成目标的名和路径

MODULE_LIB := $(addsuffix  .a, $(MODULES))
MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))
APP := app.out
APP := $(addprefix $(DIR_BUILD)/, $(APP))
all :@echo "$(MODULE_LIB)"

测试一下:

make all
build/common.a build/module.a build/main.a
build/app.out
.PHONY : all compile linkMODULES := common module main
MKDIR := mkdir 
RM := rm -rfCC := gcc
LFALGS :=DIR_PROJECT := $(realpath .)
DIR_BUILD := build
DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
MODULE_LIB := $(addsuffix  .a, $(MODULES))
MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))
APP := app.out
APP := $(addprefix $(DIR_BUILD)/, $(APP))all :@echo "$(MODULE_LIB)"@echo "$(APP)"compile : $(DIR_BUILD) $(DIR_BUILD_SUB)@echo "Begin "@set -e; for dir in $(MODULES); do cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd ..; done@echo ""
link $(APP) : $(MODULE_LIB)@echo "Begin "$(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS)@echo "link success ..."
$(DIR_BUILD) $(DIR_BUILD_SUB) :$(MKDIR) $@

测试一下:

make link
Begin 
gcc -o build/app.out -Xlinker "-(" build/common.a build/module.a build/main.a -Xlinker "-)" 
link success ...
aston@ubuntu:~/disciple$ ./build/app.out 
Version: 1.0.0
main()::start main ...
void common() ...
module_main()::start module ...
void foo()::Hello, D.T.Software ...

优化一下:

.PHONY : all compile link clean rebuild MODULES := common module main
MKDIR := mkdir 
RM := rm -rfCC := gcc
LFALGS :=DIR_PROJECT := $(realpath .)
DIR_BUILD := build
DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
MODULE_LIB := $(addsuffix  .a, $(MODULES))
MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))
APP := app.out
APP := $(addprefix $(DIR_BUILD)/, $(APP))all : compile $(APP)@echo "Target File ==>$(APP)"compile : $(DIR_BUILD) $(DIR_BUILD_SUB)@echo "Begin "@set -e; for dir in $(MODULES); do cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd ..; done@echo ""
link $(APP) : $(MODULE_LIB)@echo "Begin "$(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS)@echo "link success ..."
$(DIR_BUILD) $(DIR_BUILD_SUB) :$(MKDIR) $@
clean :$(RM) $(DIR_BUILD)
rebuild : clean all@echo ""
  • To be continued…

思考:

当前整个项目的makefile是否存在潜在的问题?是否需要重构?

综合


.PHONY : all compile link clean rebuildMODULES := common module mainMKDIR := mkdir
RM := rm -frCC := gcc
LFLAGS := DIR_PROJECT := $(realpath .)
DIR_BUILD := build
DIR_BUILD_SUB := $(addprefix $(DIR_BUILD)/, $(MODULES))
MODULE_LIB := $(addsuffix .a, $(MODULES))
MODULE_LIB := $(addprefix $(DIR_BUILD)/, $(MODULE_LIB))APP := app.out
APP := $(addprefix $(DIR_BUILD)/, $(APP))all : compile $(APP)@echo "Success! Target ==> $(APP)"compile : $(DIR_BUILD) $(DIR_BUILD_SUB)@echo "Begin to compile ..."@set -e; for dir in $(MODULES); do cd $$dir && $(MAKE) all DEBUG:=$(DEBUG) && cd .. ; done@echo "Compile Success!"link $(APP) : $(MODULE_LIB)@echo "Begin to link ..."$(CC) -o $(APP) -Xlinker "-(" $^ -Xlinker "-)" $(LFLAGS)@echo "Link Success!"$(DIR_BUILD) $(DIR_BUILD_SUB) : $(MKDIR) $@clean : @echo "Begin to clean ..."$(RM) $(DIR_BUILD)@echo "Clean Success!"rebuild : clean all

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

本文发布于:2024-01-31 10:52:45,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170666956827991.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:编译器   环境   专业
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23