拿你有的,换你要的;这个世界一直如此,很残酷,却很公平!

链接

CC = gcc
INCLUDES = -I./
//gcc -I. -I/usr/xxxxx 的意思是,同时还要再 . 目录(即 执行gcc的当前目录) 以及 /usr/xxxxx 目录下搜索头文件。
LIB_PATH =
LIB_FLAGS = $(LIB_PATH)
CFLAGS += -O2 -Wall _fPIC
FLAGS = $(INCLUDES ) -c -g
OBJ = o
SRCS += $(wildcard *.c)
OBJS = $(patsubst %.c,%.o,$(SRCS))
TARGET = libbzlib.so

一般我们可以使用“$(wildcard *.c)”来获取工作目录下的所有的.c文件列表。

复杂一些用法;可以使用“$(patsubst %.c,%.o,$(wildcard *.c))”,首先使用“wildcard”函数获取工作目录下的.c文件列表;之后将列表中所有文件名的后缀.c替换为.o。

这样我们就可以得到在当前目录可生成的.o文件列表。


main:main.o mytool1.o mytool2.o (main是你最终程序的名字,后面是他的附属关系,)
(Tab键)gcc -o main main.o mytool1.o mytool2.o (输入之前一定要先按TAB键,链接!)
main.o:main.c mytool1.h mytool2.h (又一个附属关系)
(Tab键)gcc -c main.c (编译)
mytool1.o:mytool1.c mytool1.h
(Tab键)gcc -c mytool1.c (编译)
mytool2.o:mytool2.c mytool2.h
(Tab键)gcc -c mytool2.c(编译)
保存退出,然后执行make命令就OK啦!

三、make 是如何工作的
在默认的方式下,也就是我们只输入make 命令。那么,
1、make 会在当前目录下找名字叫“Makefile”或“makefile”的文件。
2、如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到“edit”这个文件,并把这个文件作为最
终的目标文件。
3、如果edit 文件不存在,或是edit 所依赖的后面的 .o 文件的文件修改时间要比edit 这个文件新,那么,他就会执行后面所定
义的命令来生成edit 这个文件。
4、如果edit 所依赖的.o 文件也存在,那么make 会在当前文件中找目标为.o 文件的依赖性,如果找到则再根据那一个规则生成.o
文件。(这有点像一个堆栈的过程)
5、当然,你的C 文件和H 文件是存在的啦,于是make 会生成.o 文件,然后再用 .o 文件生命make 的终极任务,也就是执
行文件edit 了。
这就是整个 make 的依赖性,make 会一层又一层地去找文件的依赖关系,直到最终编译出第一个目标文件。在找寻的过程中,
如果出现错误,比如最后被依赖的文件找不到,那么make 就会直接退出,并报错,而对于所定义的命令的错误,或是编译不
成功,make 根本不理。make 只管文件的依赖性,即,如果在我找了依赖关系之后,冒号后面的文件还是不在,那么对不起,
我就不工作啦。
通过上述分析,我们知道,像clean 这种,没有被第一个目标文件直接或间接关联,那么它后面所定义的命令将不会被自动执行,
不过,我们可以显示要make 执行。即命令——“make clean”,以此来清除所有的目标文件,以便重编译。
于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的
目标file.o 会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o 的文件也是最新的啦,于是file.o 的文件修改
时间要比edit 要新,所以edit 也会被重新链接了(详见edit 目标文件后定义的命令)。
而如果我们改变了“command.h”,那么,kdb.o 、command.o 和files.o 都会被重编译,并且,edit 会被重链接。
四、makefile 中使用变量
在上面的例子中,先让我们看看edit 的规则:
edit : main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
cc -o edit main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
我们可以看到[.o]文件的字符串被重复了两次,如果我们的工程需要加入一个新的[.o]文件,那么我们需要在两个地方加(应该
是三个地方,还有一个地方在clean 中)。当然,我们的makefile 并不复杂,所以在两个地方加也不累,但如果makefile 变得
复杂,那么我们就有可能会忘掉一个需要加入的地方,而导致编译失败。所以,为了makefile 的易维护,在makefile 中我们可
以使用变量。makefile 的变量也就是一个字符串,理解成C 语言中的宏可能会更好。
比如,我们声明一个变量,叫objects, OBJECTS, objs, OBJS, obj, 或是OBJ,反正不管什么啦,只要能够表示obj 文件就行了。
我们在makefile 一开始就这样定义:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
于是,我们就可以很方便地在我们的makefile 中以“$(objects)”的方式来使用这个变量了,于是我们的改良版makefile 就变成
下面这个样子:
objects = main.o kbd.o command.o display.o
insert.o search.o files.o utils.o
edit : $(objects)
cc -o edit $(objects)
main.o : main.c defs.h
cc -c main.c
kbd.o : kbd.c defs.h command.h
cc -c kbd.c
command.o : command.c defs.h command.h
cc -c command.c
display.o : display.c defs.h buffer.h
cc -c display.c
insert.o : insert.c defs.h buffer.h
cc -c insert.c
search.o : search.c defs.h buffer.h
cc -c search.c
files.o : files.c defs.h buffer.h command.h
cc -c files.c
utils.o : utils.c defs.h
cc -c utils.c
clean :
rm edit $(objects)
于是如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。

posted @ 2023-01-09 09:57  bowuwb  阅读(195)  评论(0编辑  收藏  举报
Fork me on GitHub