简介:
makefile可以理解为是一门脚本语言,按照我们设定的步骤一步步运行指令。在linux开发过程中没有像Windows那样的图形化一键编译的功能,在linux上的c语言程序开发使用的是gcc编译工具完成源码文件到二进制文件的转变。当工程比较大的时候,工程里有很多源文件、头文件、第三方库等等,如果我们还是用gcc命令来编译的话会显得很麻烦,也容易出错。
这时候我们可以使用makefile工具来帮助我们完成工程代码的编译,直接使用make命令即可完成全自动编译过程。在书写makefile过程中一定要遵循它的规则,否则会出现错误的情况。
基本规则:
目标 : 依赖
[tab]命令
例如main.c源文件生成main二进制可执行文件:
main : main.o
gcc main.o -o main
main.o :main.c
gcc -c main.c -o main.o
clear:
rm *.o main
基本模板
简单c代码工程如下:
| 文件夹 | 描述 |
|---|---|
| inc | 存放工程头文件 |
| lib | 存放动态、静态库文件 |
| src | 源文件 |
Makefile文件与inc、lib、src文件夹同一目录下:

Makefile 文件内容:
CC = gcc
SRC = $(wildcard src/*.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = main
INC_PATH = -I inc/
#links
$(TARGET) : $(OBJ)
$(CC) $(OBJ) -o $(TARGET)
#compile
%.o : %.c
$(CC) -c $< -o $@ $(INC_PATH)
.PHONY:clean
clean:
@echo "Remove linked and compiled files......"
@rm -rf $(OBJ) $(TARGET)
简单解释一下:
变量CC是为了指定编译器,SRC是指定源码文件路径,OBJ是指定 .o 依赖文件,TARGET是指定生成的目标文件名,INC_PATH 是指定头文件路径
wildcard和patsubst 都来自makefile内置的函数,wildcard是通过匹配符将所有的 .c 文件存放到变量$(SRC)中,patsubst 是将所有的 .c 文件改为后缀 .o 文件
%.o 和 %.c 通用匹配,比如main.o的依赖文件就是main.c,add.o的依赖文件就是add.c
$< :代表第一个依赖文件
$@ :代表目标文件
最后是clean,用于删除编译过程中生成的中间文件和可执行文件。
动态库和静态库的生成
静态库:
静态库可以由一个或多个 .c 源文件构成,他人使用时只需要提供 .a 静态库文件和 .h 头文件即可。静态库在链接过程中就已经引用到二进制可执行文件中去了,文件比较大,不易更新。
原理:
1、先生成 .o 文件: gcc -c add.c -o add.o
2、生成静态库: ar rcs add.a add.o
# static lib
static_OBJ = src/add.o
static_TARGET = lib/static/libadd.a
INC_PATH = -I inc/
# static
$(static_TARGET):$(static_OBJ)
ar rcs $(static_TARGET) $(static_OBJ)
#compile
%.o : %.c
$(CC) -c $< -o $@ $(INC_PATH)
.PHONY:clean
clean:
@echo "Remove linked and compiled files......"
@rm -rf $(static_OBJ) $(static_TARGET)
动态库:
动态库也可以由一个或多个 .c 源文件构成,使用时只需要提供 .so和 .h 文件。动态库是在二进制可执行文件运行时才会链接,不使用不会链接。优点是文件小、移植性强。
原理:
gcc src/mul.c -fPIC -shared -I inc/ -o lib/shared/libmul.so
makefile不过是分成了两步来完成
# shared lib
shared_OBJ = src/mul.o
shared_TARGET = lib/shared/libmul.so
CC = gcc
INC_PATH = -I inc/
# shared
$(shared_TARGET):$(shared_OBJ)
$(CC) $(shared_OBJ) -fPIC -shared -o $(shared_TARGET)
#compile
%.o : %.c
$(CC) -c $< -o $@ $(INC_PATH)
.PHONY:clean
clean:
@echo "Remove linked and compiled files......"
@rm -rf $(shared_OBJ) $(shared_TARGET)
链接动静态库
动态库和静态库的链接:
静态库:
gcc main.c -ladd -L lib/static -o main
add是静态库名,-L 指定静态库地址
动态库:
gcc main.c -lmul -L lib/shared -Wl,-rpath=lib/shared -o main
mul是动态库名,-L 指定动态库地址, -Wl,-rpath= 指定运行时链接地址
CC = gcc
SRC = $(wildcard src/*.c)
OBJ = $(patsubst %.c, %.o, $(SRC))
TARGET = main
INC_PATH = -I inc/
LIB_NAMES = -ladd -lmul
LIB_PATH = -L lib/static -L lib/shared
LIB_SO_PATH = -Wl,-rpath=lib/shared
#links
$(TARGET) : $(OBJ)
$(CC) $(OBJ) $(LIB_NAMES) $(LIB_PATH) $(LIB_SO_PATH) -o $(TARGET)
#compile
%.o : %.c
$(CC) -c $< -o $@ $(INC_PATH)
.PHONY:clean
clean:
@echo "Remove linked and compiled files......"
@rm -rf $(OBJ) $(TARGET)

2491

被折叠的 条评论
为什么被折叠?



