0、前言
由于项目中经常需要用到MakeFile的编写,但是有经常容易忘掉其中某些字符含义,因此特写出此Makefile博客,用来直接的参考而非对Makefile的详细讲解。
1、一个普通的Makefile脚本示例
# 这是一个简单的Makefile,没有使用变量及其它东西
# 生成文件名为main的可执行文件
# -lm 是连接数学库
main:cjsonmain.o cJSON.o
gcc -o main cjsonmain.o cJSON.o -lm
main.o:cjsonmain.c cJSON.h
gcc -g -c cjsonmain.c
cJSON.o:cJSON.c cJSON.h
gcc -g -c cJSON.c
clean:
rm -rf *.o main
下面是我的工程目录图示
2、升级版的Makefile脚本示例
Makefile有三个非常有用的变量,其分别含义为:
(1) $@--目标文件;
(2)$^--所有的依赖文件;
(3)$<--第一个依赖文件;
# 这是一个makefile文档
# CC :指定编译器
# CFLAG :制定编译选项
# target :生成可执行应用的名字
# $(target) :此方法为引用target变量
# $@ :目标文件
# $^ :所有依赖文件
# $< :第一个依赖文件
CC=gcc
CFLAG= -g
target=app
$(target):xxx.o aff.o
$(CC) $(CFLAG) -o $@ $^
xxx.o:xxx.c aff.h
$(CC) -c $< -o $@
aff.o:aff.c aff.h
$(CC) -c $< -o $@
clean:
rm -rf *.o $(target)
3、再升级版Makefile(完全使用通配符进行编写)
在下面所示Makefile编写中,源文件、头文件以及库等,直接添加进相应的变量中即可实现大型工程一键编译
COMPILE_COMPILER=
TARGET=app
CC = $(CROSS_COMPILER)gcc
LD = $(CROSS_COMPILER)gcc
CPP = $(CROSS_COMPILER)g++
# 当前目录
DIR_PRJ:=$(shell pwd)
DIR_INC:=$(DIR_PRJ)/inc
DIR_SRC:=$(DIR_PRJ)/src
# *.h头文件
INCLUDE+=-I$(DIR_PRJ)/
INCLUDE+=-I$(DIR_INC)/
INCLUDE+=-I$(DIR_INC)/soap
# *.c源码
SRC:=$(wildcard $(DIR_PRJ)/*.c)
SRC+=$(wildcard $(DIR_SRC)/*.c)
# 编译flag
CFLAGS+=-g -I$(INCLUDE)
CPPFLAGS+=-g -I$(INCLUDE)
# 库
LIBS=-lpthread
LIBS+=
STATIC_OLIB+=
# 链接flag
LDFLAGS+=-g -I$(INCLUDE)
OBJS := $(SRC:.c=.o)
DEP := $(OBJS:.o=.d)
all: $(TARGET)
$(TARGET):$(SRC) $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) $(STATIC_OLIB) $(LIBS) -o $@
-include $(DEP)
%.o:%.c
$(CC) $(INCLUDE) $(CFLAGS) -MM -MT $@ -MF $(patsubst %.o, %.d, $@) $<
$(CC) $(INCLUDE) $(CFLAGS) -c $< -o $@
%.o:%.cpp
$(CPP) $(INCLUDE) $(CPPFLAGS) -c $< -o $@
clean :
rm -f $(TARGET) $(OBJS) $(DEP) *.o
4、 Makefile 编译动态库示例
Makefile编译动态连接库,其实蛮简单的,把TARGET目标改一下名称,然后再编写选项中加上-fpic和链接输出时加上-shared即可,其它的不用动。
COMPILE_COMPILER=
TARGET=libIdReader.so
CC=$(CROSS_COMPILER)gcc
LD=$(CROSS_COMPILER)g++
CPP=$(CROSS_COMPILER)g++
# 配置目录
DIR_PRJ:=$(shell pwd)/../source/
DIR_SRC:=$(DIR_PRJ)
DIR_COMMON:=$(DIR_PRJ)/common
DIR_FAL:=$(DIR_PRJ)/fal
DIR_HAL:=$(DIR_PRJ)/hal
DIR_PAL:=$(DIR_PRJ)/pal
DIR_LIB:=$(DIR_PRJ)/libs
DIR_LIB_SYIDLIB:=$(DIR_LIB)/syidlib
# *.h头文件
INCLUDE+=-I$(DIR_PRJ)/
INCLUDE+=-I$(DIR_COMMON)/
INCLUDE+=-I$(DIR_FAL)/
INCLUDE+=-I$(DIR_HAL)/
INCLUDE+=-I$(DIR_PAL)/
INCLUDE+=-I$(DIR_LIB_SYIDLIB)/
# *.c源码
SRC:=$(wildcard $(DIR_PRJ)/*.c)
SRC+=$(wildcard $(DIR_COMMON)/*.c)
SRC+=$(wildcard $(DIR_FAL)/*.c)
SRC+=$(wildcard $(DIR_HAL)/*.c)
SRC+=$(wildcard $(DIR_PAL)/*.c)
SRC+=$(wildcard $(DIR_LIB_SYIDLIB)/*.c)
# 编译flag
CFLAGS+=-g -I$(INCLUDE) -std=gnu99
CPPFLAGS+=-g -I$(INCLUDE)
# 库
LIBS=-lpthread -lm -lcurl -lidinfo
LIBS+=
STATIC_OLIB+=
# 链接flag
LDFLAGS+=-g -I$(INCLUDE) -L$(DIR_LIB_SYIDLIB) -Wl,-rpath=${LD_LIBRARY_PATH}:$(DIR_LIB_SYIDLIB)
OBJS := $(SRC:.c=.o)
DEP := $(OBJS:.o=.d)
all: $(TARGET)
$(TARGET):$(SRC) $(OBJS)
$(LD) $(LDFLAGS) $(OBJS) $(STATIC_OLIB) $(LIBS) -shared -o $@
-include $(DEP)
%.o:%.c
$(CC) $(INCLUDE) $(CFLAGS) -MM -MT $@ -MF $(patsubst %.o, %.d, $@) $<
$(CC) $(INCLUDE) $(CFLAGS) -c -fpic $< -o $@
%.o:%.cpp
$(CPP) $(INCLUDE) $(CPPFLAGS) -c -fpic $< -o $@
clean :
rm -f $(TARGET) $(OBJS) $(DEP) *.o