To achieve great things, two things are needed: a plan and not quite enough time.--------完成杰出的事需要两件事情: 一个计划以及不是很充足时间。
这篇例子建立在上一篇制作动态库的博客:
https://blog.csdn.net/weixin_46027505/article/details/105238962
我们发现一系列操作下来,有时可能记不住,或者懒得在重新一个一个敲命令,那么这时可以编写一个makefile来帮助我们。
接下来开启神奇之旅。
Linux 环境下的程序员如果不会使用GNU make来构建和管理自己的工程,应该不是好的专业程序员。
在 Linux(unix )环境下使用GNU 的make工具能够比较容易的构建一个属于你自己的工程,整个工程的编译只需要一个命令就可以完成编译、连接以至于最后的执行。
- 不过这需要我们投入一些时间去完成一个或者多个称之为Makefile 文件的编写。
1, makefile简单介绍
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
Makefile 文件描述了整个工程的编译、连接等规则。
其中包括:工程中的哪些源文件需要编译以及如何编译、需要创建那些库文件以及如何创建这些库文件、如何最后产生我们想要的可执行文件。
尽管看起来可能是很复杂的事情,但是为工程编写Makefile 的好处是能够使用一行命令来完成“自动化编译”,一旦提供一个正确的 Makefile。编译整个工程你所要做的唯一的一件事就是在shell 提示符下输入make命令。整个工程完全自动编译,极大提高了效率。
2, makefile结构
#以'#'开头的行表示注释
#定义变量VAR,强制赋值为myapp
VAR=myapp
#在VAR之前定义的值后面再追加app这个值,这时该变量值扩展为myapp123
VAR+=123
#如果之前VAR没有被定义,则定义并使用myapp;否则使用之前的值。
VAR?=myapp
#第一条目标为总的目标,一般是all:
#依赖可以是文件(目录)或为其他目标
#动作可以是Linux命令,动作的那一行第一个字符必须是以TAB键
target: depend1 depend2 depend3 ...
[TAB] action1
[TAB] action2
depend1:
[TAB] action
#独立目标
target1:
[TAB] action1
[TAB] action2
3, make使用
make 找makefile或Makefile文件执行总的目标
make clean 执行makefile文件中的clean目标
make -C directory 进入到directory文件夹中去执行总的目标
make clean -C direcotry 进入到directory文件夹中去执行clean目标
make -f comm_makefile 通过-f选项指定一个makefile文件
make VAR=value 给Makefile传一个参数VAR,其值为value
默认的情况下,make命令会在当前目录下按顺序找寻文件名为“GNUmakefile”、“makefile”、“Makefile”的文件,找到 后就解释并执行该文件,如果找不到就提示错误并退出。一般Makeifle文件名我们会用Makefile或makefile,而不会使用 GNUmakefile。
接下来我们以之前的静态库和动态库为例讲解makefile的编写和使用。
4, 例子
- 删除上次博客中的一些东西,得到
4.1 第一个makefile
- 然后我们先在static_ku里编写一个自动生成静态库并将动态库复制到xuxiaohei的lib下
vim makefile
#这里这里all是整个makefile文件的第一个目标,也就是总的目标,当我们输入make命令时就是要完成这个目标;
#该目标有依赖 dostatic和 动作 make install
#其中依赖 dostatic 也是makefile文件的目标,所以整个makefile要先执行完dostatic目标后才能执行动作;
#在动作make install前面有个 @ 符,这个符号会让执行make名时不打印这条命令本身,即不打印make install
#而只是输出命令执行的结 果;另外make命令在执行过程中,也会多次载入makefile文件;
all: dostatic
@make install
dostatic:
gcc -c add.c sub.c
ar -crs libmystatic.a add.o sub.o
install:
cp libmystatic.a ../xuxiaohei/lib/
#clear是一个单独的目标,他用来将编译生成的object临时文件删除
clear:
rm *.o
-
下面make
-
下面我们make clear
-
发现确实删除了.o文件
4.2 第二个makefile
接下来我们在shared_ku下进行同样的事
#定义变量
LIB=../xuxiaohei/lib
all:
gcc -fpic -shared add.c sub.c -o libmyshared.so
cp libmyshared.so ${LIB}
4.3 第三个makefile
我们如何在test下完成上面两个makefile呢?
我们先把之前生成的全部删除
- 然后在我们在test下新建一个makefile,完成上面的合体功能。
all:
@echo"start creat staticku..."
make -C ./static_ku/
echo"start creat sharedku"
make -C ./shared_ku/
make clear -C static_ku