Makefile 的编译动态库,静态库,和执行文件的三个例子。
这里仅做记录,推荐使用 cmake 。
cmake 交叉编译工程例子
编译 bin 执行文件
Makefile
# = 最基本的赋值
# := 覆盖之前的值
# ?= 如果没有被赋值过就赋予等号后面的值
# += 添加等号后面的值
# $@ 目标集合
# $% 当目标是函数库文件时, 表示其中的目标文件名
# $< 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
# $? 比目标新的依赖目标的集合
# $^ 所有依赖目标的集合, 会去除重复的依赖目标
# $+ 所有依赖目标的集合, 不会去除重复的依赖目标
# $* 这个是GNU make特有的, 其它的make不一定支持
PROJECT_PATH= $(shell pwd)
ifeq ($(debug),1)
TARGET := $(PROJECT_PATH)/../bin/debug/test
else
TARGET := $(PROJECT_PATH)/../bin/release/test
endif
ifeq ($(os), lib_linux)
GCC_PATH =
endif
# ar 创建静态库
# cr 不是一个命令,而一个目标和依赖的定义。这种用法是为"ar"命令来服务
CC := $(GCC_PATH)gcc
CPP := $(GCC_PATH)g++
AR := $(GCC_PATH)ar
RM := rm -f
INC_DIR += -I ./
INC_DIR += -I ./include
LIB_DIR += -L ./
LIBS += -lpthread -lm
CFLAGS += $(INC_DIR) $(LIB_DIR) $(LIBS) $(OS_FLAG)
CFLAGS += -Wall -O2
CFLAGS += -DLINUX
ifeq ($(debug),1)
CFLAGS += -g
CFLAGS += -DDEBUG
endif
# 扫描目录下的所有源文件,会向下依次遍历,可用 "\" 隔行添加多个目录
MY_PATH += $(PROJECT_PATH)
DIRS += $(shell find $(MY_PATH) -type d)
$(warning "DIRS =$(DIRS)")
SRCS_C += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
SRCS_CC += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cc))
SRCS_CPP += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS_C := $(SRCS_C:%.c=%.o)
OBJS_CC := $(SRCS_CC:%.cc%.o)
OBJS_CPP := $(SRCS_CPP:%.cpp=%.o)
$(warning "SRCS_C =$(SRCS_C)")
$(warning "SRCS_CC =$(SRCS_CC)")
$(warning "SRCS_CPP =$(SRCS_CPP)")
# 为 .c 生成 .o
%.o: %.c
$(CC) -c $(CFLAGS) $< -o $@
all:$(TARGET)
$(TARGET):$(OBJS_C)
$(CC) $(CFLAGS) $? -o $@
clean:
$(RM) $(OBJS_C) $(TARGET)
编译动态库
Makefile
# = 最基本的赋值
# := 覆盖之前的值
# ?= 如果没有被赋值过就赋予等号后面的值
# += 添加等号后面的值
# $@ 目标集合
# $% 当目标是函数库文件时, 表示其中的目标文件名
# $< 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
# $? 比目标新的依赖目标的集合
# $^ 所有依赖目标的集合, 会去除重复的依赖目标
# $+ 所有依赖目标的集合, 不会去除重复的依赖目标
# $* 这个是GNU make特有的, 其它的make不一定支持
PROJECT_PATH= $(shell pwd)
ifeq ($(debug),1)
SHARED_LIB := $(PROJECT_PATH)/../lib/debug/test.so
else
SHARED_LIB := $(PROJECT_PATH)/../lib/release/test.so
endif
ifeq ($(os), lib_linux)
GCC_PATH =
endif
# ar 创建静态库
# cr 是为"ar"命令来服务
CC := $(GCC_PATH)gcc
CPP := $(GCC_PATH)g++
AR := $(GCC_PATH)ar
RM := rm -f
CFLAGS += $(INC_DIR) $(LIB_DIR) $(LIBS) $(OS_FLAG)
CFLAGS += -Wall -O2
CFLAGS += -DLINUX
ifeq ($(os), linux)
CFLAGS += -DHAVE_LRINTF
endif
#CFLAGS += -DHAVE_SYS_TYPES_H
ifeq ($(os), arm)
CFLAGS += -static
endif
ifeq ($(debug),1)
CFLAGS += -g
CFLAGS += -DDEBUG
endif
# 添加头文件和库路径
INC_DIR += -I ./
INC_DIR += -I ./include
LIB_DIR += -L ./
LIBS += -lpthread -lm
# 扫描目录下的所有源文件,会向下依次遍历,可用 "\" 隔行添加多个目录
MY_PATH += $(PROJECT_PATH)
DIRS += $(shell find $(MY_PATH) -type d)
$(warning "DIRS =$(DIRS)")
SRCS_C += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
SRCS_CC += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cc))
SRCS_CPP += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS_C := $(SRCS_C:%.c=%.o)
OBJS_CC := $(SRCS_CC:%.cc%.o)
OBJS_CPP := $(SRCS_CPP:%.cpp=%.o)
$(warning "SRCS_C =$(SRCS_C)")
$(warning "SRCS_CC =$(SRCS_CC)")
$(warning "SRCS_CPP =$(SRCS_CPP)")
# 为.C生成.o文件
%.o:%.c
$(CC) $(CFLAGS) -fpic -c $< -o $@
.PHONY:clean all
all:$(SHARED_LIB)
$(SHARED_LIB):$(OBJS_C)
$(RM) $@
$(CC) -shared $? -o $@
$(RM) $(OBJS_C)
clean:
$(RM) $(SHARED_LIB) $(OBJS_C)
编译静态库
Makefile
# = 最基本的赋值
# := 覆盖之前的值
# ?= 如果没有被赋值过就赋予等号后面的值
# += 添加等号后面的值
# $@ 目标集合
# $% 当目标是函数库文件时, 表示其中的目标文件名
# $< 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
# $? 比目标新的依赖目标的集合
# $^ 所有依赖目标的集合, 会去除重复的依赖目标
# $+ 所有依赖目标的集合, 不会去除重复的依赖目标
# $* 这个是GNU make特有的, 其它的make不一定支持
PROJECT_PATH= $(shell pwd)
ifeq ($(debug),1)
STATIC_LIB := $(PROJECT_PATH)/../lib/debug/test.a
else
STATIC_LIB := $(PROJECT_PATH)/../lib/release/test.a
endif
ifeq ($(os), lib_linux)
GCC_PATH =
endif
# ar 创建静态库
# cr 不是一个命令,而一个目标和依赖的定义。这种用法是为"ar"命令来服务
CC := $(GCC_PATH)gcc
CPP := $(GCC_PATH)g++
AR := $(GCC_PATH)ar
RM := rm -f
INC_DIR += -I ./
INC_DIR += -I ./include
LIB_DIR += -L ./
LIBS += -lpthread -lm
CFLAGS += $(INC_DIR) $(LIB_DIR) $(LIBS) $(OS_FLAG)
CFLAGS += -Wall -O2
CFLAGS += -DLINUX
ARFLAGS +=
ifeq ($(os), linux)
CFLAGS += -DHAVE_LRINTF
endif
#CFLAGS += -DHAVE_SYS_TYPES_H
ifeq ($(os), arm)
CFLAGS += -static
endif
ifeq ($(debug),1)
CFLAGS += -g
CFLAGS += -DDEBUG
endif
# 扫描目录下的所有源文件,会向下依次遍历,可用 "\" 隔行添加多个目录
MY_PATH += $(PROJECT_PATH)
DIRS += $(shell find $(MY_PATH) -type d)
$(warning "DIRS =$(DIRS)")
SRCS_C += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.c))
SRCS_CC += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cc))
SRCS_CPP += $(foreach dir, $(DIRS), $(wildcard $(dir)/*.cpp))
OBJS_C := $(SRCS_C:%.c=%.o)
OBJS_CC := $(SRCS_CC:%.cc%.o)
OBJS_CPP := $(SRCS_CPP:%.cpp=%.o)
$(warning "SRCS_C =$(SRCS_C)")
$(warning "SRCS_CC =$(SRCS_CC)")
$(warning "SRCS_CPP =$(SRCS_CPP)")
# 为 .c 生成 .o
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
.PHONY:clean all
all:$(STATIC_LIB)
# 生成静态库文件
$(STATIC_LIB):$(OBJS_C)
$(AR) cr $(STATIC_LIB) $?
$(RM) $(OBJS_C)
clean:
$(RM) $(STATIC_LIB) $(OBJS_C)