1. 背景

    在linux下不管写C还是C++,文件少的时候我们可以通过单个编译成执行文件来完成,但文件多了,特别是一个文件因为调用了别一个文件的函数而需要包含编译时,那时单独编译就显得十分费劲了,这时候不得不得项目管理工具----->Makefile.

    Windows下由于有大量IDE(集成开发环境), 项目管理都可以通过IDE来自动完成,所以在开发上减去了项目管理上的麻烦.

 

    2. 关于程序的编译和链接

  一般来说,无论是C还是C++,首先要把源文件编译成中间代码文件,在Windows下也就是 .obj 文件,UNIX下是 .o 文件,即 Object File,这个动作叫做编译(compile),一般来说,每个源文件都应该对应于一个中间目标文件(O文件或是OBJ文件)。然后再把大量的Object File合成执行文件,这个动作叫作链接(link)。

  编译时,编译器需要的是语法的正确,函数与变量的声明的正确。对于后者,通常是你需要告诉编译器头文件的所在位置(头文件中应该只是声明,而定义应该放在C/C++文件中),只要所有的语法正确,编译器就可以编译出中间目标文件。

  链接时,主要是链接函数和全局变量,所以,我们可以使用这些中间目标文件(O文件或是OBJ文件)来 链接我们的应用程序。链接器并不管函数所在的源文件,只管函数的中间目标文件(Object File),在大多数时候,由于源文件太多,编译生成的中间目标文件太多,而在链接时需要明显地指出中间目标文件名,这对于编译很不方便,所以,我们要给 中间目标文件打个包,在Windows下这种包叫“库文件”(Library File),也就是 .lib 文件,在UNIX下,是Archive File,也就是 .a 文件。

    下面我们来看看如何自己快速的写出简单易用的项目管理工具--->Makefile


    3. Makefile

    简单的说,makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至可以在makefile中执行shell脚本。makefile带来的好处就是——“自动化编译”,一旦写好,只需要一个make命令,整个工程完全自动编译,极大的提高了软件开发的效率。

    Makefile规则:

    linux网络编程----->项目管理工具----->Makefile_第1张图片


    Makefile工作原理:

        linux网络编程----->项目管理工具----->Makefile_第2张图片


    makefile中常用的变量与函数:[切记]

    • 常用函数:

      • wildcard: 获取当前目录下指定类型文件

      • patsubst: 替换指定类型

    • 常用变量

      • $@ 目标的完整名称         [常用]

      • $^ 所有的依赖文件,以空格分开,不包含重复的依赖文件 [常用]

      • $< 第一个依赖文件的名称     [常用]

      • $* 不包含扩展名的目标文件名称

      • $+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件

    

    介绍了这么多,下面我们直接来看看代码.

    1. 编译当前目录下所有的.c文件[也可以make 指定生成目标文件]

SRC = $(wildcard ./*.c)			#获取当前目录下所有的.c文件
OBJ = $(patsubst ./%.c, ./%, $(SRC))	#将所有.c文件去掉.c
#变量赋值,编译时指定的参数 -lpthread 指定线程所需库,-std=gnu99 指定c99标准编译 
#-g 添加调试信息,供gdb调试使用 -Wall 更多提示
CC = gcc -g -Wall -std=gnu99 -lpthread

all:$(OBJ)

#生成所有目标
%:%.c
	$(CC) $< -o $@


#伪目录,使执行make命令时不生成后面的目标,一般在清理命令中经常使用
.PHONY:clean
#清理所有目标文件  '@' 不输出至屏幕
clean:
	@rm -f $(OBJ)	


    2. 指定编译目标文件

src = $(wildcard ./*.c)   		#获取当前目录下所有的.c文件
obj = $(patsubst ./%.c, ./%.o, $(src))	#将所有.c文件替换成.o
#变量赋值,编译时指定的参数 -lpthread 指定线程所需库,
#-std=gnu99 指定c99标准编译 -g 添加调试信息,供gdb调试使用 -Wall 更多提示
CC = gcc -g -Wall -std=gnu99 -lpthread

#指定目标 成生server client
all:server client

#指定成生server目标所依赖项和命令
server: warp.o server.o
	$(CC) $^ -o $@

#指定生成client目标所依赖项和命令
client: warp.o client.o
	$(CC) $^ -o $@

%.o:%.c
	$(CC) -c $< -o $@

#伪目录,使执行make命令时不生成后面的目标,一般在清理命令中经常使用 
.PHONY:clean
clean:
	@rm -f $(obj) #清理所有.o文件  '@' 不输出至屏幕


makefile依赖原理

    linux网络编程----->项目管理工具----->Makefile_第3张图片