会不会写Makefile,可以从一个侧面说明一个人是否具备完成大型工程能力。因为Makefile关系到了整个工程的编译规则。(生成目标与所有文件的依赖关系,源文件的依赖关系)
静态链接库与动态链接库的编译
# 编译静态链接库, c选项表示创建,r选项表示插入/替换
g++ -c ${SRC}
ar cr libxxx.a ${OBJ}
# 编译动态链接库,-fPIC生成位置独立的代码,动态载入,多个进程可共享
g++ -fPIC -shared -o libxxx.so ${SRC}
通用Makefile: 所有源文件在一个目录里
- 使用变量
CC = gcc
XX = g++
# 编译链接选项
CFLAGS = -Wall -O3 -g -c
- 使用通配符
$@ 表示目标文件
$^ 表示所有的依赖文件
$< 表示第一个依赖文件
- 使用变量替换引用
OBJECTS = $(SOURCES:.c=.o)
- 使用内置函数
wildcard : 扩展通配符
notdir : 去除路径
patsubst :替换通配符
For Example:
文件列表
/src
Makefile
sort.c
sort.h
test_sort.c
Makefile
CC = gcc
XX = g++
# 编译链接选项
CFLAGS = -Wall -O3 -g -c
INCLUDES = -I.
LDFLAGS =
# 源文件列表
SOURCES = $(wildcard *.c *.cpp)
# 目标文件列表
OBJECTS = $(SOURCES:.c=.o)
# OBJECTS = $(patsubst %.c,%.o,$(patsubst,%.cpp,%.o))
# 可执行文件名
TARGET = test_sort
all: $(TARGET)
# 生成可执行文件(链接)
$(TARGET): $(OBJECTS)
$(CC) $(LDFLAGS) $(OBJECTS) -o $@
# 生成目标文件(编译)
%.o: %.c
$(XX) $(CFLAGS) $(INCLUDES) $< -o $@
.cpp.o:
$(CC) $(CFLAGS) $(INCLUDES) $< -o $@
# 辅助命令:清除目标文件、清除所有生成文件、运行可执行程序
.PHONY: clean cleanall run
clean:
rm -rf $(OBJECTS)
cleanall:
rm -rf $(OBJECTS) $(TARGET)
run:
./$(TARGET)