常用makefile模板

makefile常用模板

# 指令编译器和选项
# GCC编译选项CFLAGS参数
# 选项            说明
# -c              用于把源码文件编译成 .o 对象文件,不进行链接过程
# -o              用于连接生成可执行文件,在其后可以指定输出文件的名称
# -g              用于在生成的目标可执行文件中,添加调试信息,可以使用GDB进行调试
# -Idir           用于把新目录添加到include路径上,可以使用相对和绝对路径,“-I.”、“-I./include”、“-I/opt/include”
# -Wall           生成常见的所有告警信息,且停止编译,具体是哪些告警信息,请参见GCC手册,一般用这个足矣!
# -w              关闭所有告警信息
# -O              表示编译优化选项,其后可跟优化等级0\1\2\3,默认是0,不优化, 使用: -O1,-O2,-O3
# -fPIC           用于生成位置无关的代码
# -v              (在标准错误)显示执行编译阶段的命令,同时显示编译器驱动程序,预处理器,编译器的版本号
# -fopenmp        打开nmp并行编译选项,防止老版本的gcc不包含OpenMP的支持


# GCC链接选项LDFLAGS参数

# 选项              说明
# -llibrary        链接时在标准搜索目录中寻找库文件,搜索名为liblibrary.a 或 liblibrary.so
# -Ldir            用于把新目录添加到库搜索路径上,可以使用相对和绝对路径,“-L.”、“-L./include”、“-L/opt/include”
# -Wl,option       把选项 option 传递给连接器,如果 option 中含有逗号,就在逗号处分割成多个选项
# -static          使用静态库链接生成目标文件,避免使用共享库,生成目标文件会比使用动态链接库大
# -m32             生成32位的代码。
# -m64             生成64位的代码。

# = 是最基本的赋值                               #不推荐使用,容易搞混淆,不推荐使用
# := 是覆盖之前的值                              #表示直接赋值,赋予当前位置的值
# ?= 是如果没有被赋值过就赋予等号后面的值            #表示如果该变量没有被赋值,则赋予等号后的值
# += 是添加等号后面的值                           #将等号后面的值添加到前面的变量上

# '@' 符号的使用
#     通常makefile会将其执行的命令行在执行前输出到屏幕上。如果将‘@’添加到命令行前,这个命令将不被make回显出来。
# '-' 符号的使用     
#     通常删除,创建文件如果碰到文件不存在或者已经创建,那么希望忽略掉这个错误,继续执行,就可以在命令前面添加 -,
#     -rm dir;
#     -mkdir aaadir;
# '$' 符号的使用
#     美元符号$,主要扩展打开makefile中定义的变量
# '$$' 符号的使用
#     $$ 符号主要扩展打开makefile中定义的shell变量


# $@   表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。
# $%   仅当目标是函数库文件中,表示规则中的目标成员名。例如,如果一个目标是"foo.a(bar.o)",那么,"$%"就是"bar.o",
#      "$@"就是"foo.a"。如果目标不是函数库文件(Unix下是[.a],Windows下是[.lib]),那么,其值为空。
# $<   依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
# $?   所有比目标新的依赖目标的集合。以空格分隔。
# $^   所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。

# .PHONY  是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突,另一种是提交执行makefile时的效率。
# makefile 语法规则
# TARGETS : PREREQUISITES 
#      [Tab]COMMAND
#或
# TARGETS : PREREQUISITES;COMMAND


# addprefix       添加前缀
# addsuffix       添加后缀
# wildcard        获取文件名列表
# notdir          去除目录
# basename        去除后缀
# patsubst        模式替换
# info            显示变量
# lastword        获取路径无关的文件名

# makefile中的shell命令用法: $(shell shell_command...)
# dirname         获取文件路径(shell命令)
# pwd             获取当前路径(shell命令)

# 连接库
# -l  指定连接时期望连接的库的名字
# -L  指定连接库的搜索路径

# 参考:https://www.cnblogs.com/shaochuanhe/articles/14495457.html

# $(foreach <var>,<list>,<text>)   语法
#   这个函数的意思是,把参数<list>;中的单词逐一取出放到参数<var>;所指定的变量中,然后再执行< text>;所包含的表达式。
#   每一次<text>;会返回一个字符串,循环过程中,<text>;的所返回的每个字符串会以空格分隔,最后当整个循环结束时,<text>;
#   所返回的每个字符串所组成的整个字符串(以空格分隔)将会是foreach函数的返回值。
#   所以,<var>;最好是一个变量名,<list>;可以是一个表达式,而<text>;中一般会使用<var>;这个参数来依次枚举<list>;
#   中的单词。举个例子:
#       names := a b c d
#       files := $(foreach n,$(names),$(n).o)
#   上面的例子中,$(name)中的单词会被挨个取出,并存到变量“n”中,“$(n).o”每次根据“$(n)”计算出一个值,这些值以空格分隔,
#   最后作为foreach函数的返回,所以,$(files)的值是“a.o b.o c.o d.o”。

# $(filter PATTERN…,<text>) 
#    函数名称:过滤函数—filter。 
#    函数功能:过滤掉字串<text>中所有不符合模式“PATTERN”的单词,保留所有符合此模式的单词。可以使用多个模式。
#    模式中一般需要包含模式字符“%”。存在多个模式时,模式表达式之间使用空格分割。 
#    返回值:空格分割的<text>字串中所有符合模式“PATTERN”的字串。 
#    函数说明:“filter”函数可以用来去除一个变量中的某些字符串,

# $(filter-out <pattern>,<text>)
#   函数名称:反过滤函数,与filter函数功能相反
#   函数说明:函数的功能是功能和 filter 函数正好相反,但是用法相同。去除符合模式
#   pattern 的字符串,保留符合的字符串。返回值是保留的字符串。

# $(strip, <text>) 去空字符语句,去掉字串中开头和结尾的空字符(空字符包括空格、[Tab]等不可显示字符)。

# $(patsubst pattern, replacement, text)
#    寻找text中符合pattern格式的内容,用replacement代替他们。

#------------- compile using -------------------
# make clean
# make deep clean
# make solution=debug    #debug solution
# make                   #release solution -> TARGET_NAME
# make type=.a           #libtt_xxx.a
# make type=.so          #libtt_xxx.so
# make type=test         #lib test.exe


#------------- omp code using -------------------
# pragma omp parallel            //C,C++使用以#pragma omp开头的标准预处理指令
# pragma omp parallel for
#pragma omp parallel for num_threads(4)



#------------- compile marcros -----------------
solution = release
type = main

# .c
# CC := gcc
# .cpp
CC := g++

SYS_PLATFORM := _LINUX#pre marco define

CCFLAG :=
CCFILE := %.c
ifeq ($(CC), g++)
	CCFLAG += -std=c++11
	CCFILE := %.cpp
endif
ifeq ($(solution), debug)
	CCFLAG += -g
else 
	#optimization level option
	CCFLAG += -O3 -static -fopenmp
	# CCFLAG = -O3 -shared -fopenmp
endif

# CCFLAG += -Wall
# CCFLAG += -m64
# CCFLAG += -w#close warnning
CCFLAG += $(addprefix -D , $(SYS_PLATFORM))#pre-define marco,  为 c/c++代码传递宏参数
CCOBJFLAG := $(CCFLAG) -c

#-------------- path marcros -------------------
BIN_PATH := ./prj#bin file path
OBJ_PATH := ./obj#object file path
SRC_PATH := .#src file root path

#-------------- compile marcros -----------------
# optional: TARGET_NAME
#------------------------------------------------
ifeq ($(type), main)
	TARGET_NAME := main.exe
	FILE_LIST := main.flist
else ifeq ($(type), test)
	TARGET_NAME := test.exe
	FILE_LIST := test.flist
else 
	TARGET_NAME := libtt_xxx$(type)
	FILE_LIST := lib.flist
endif

TARGET := $(BIN_PATH)/$(TARGET_NAME)

$(info $(FILE_LIST))

#-------------- source marcros ------------------
FILE_TEXT := $(shell cat $(FILE_LIST))         #获取文件内容
$(strip,$(FILE_TEXT))         #去掉字串中开头和结尾的空字符(空字符包括空格、[Tab]等不可显示字符)
VARIABLE := $(foreach n,$(FILE_TEXT),$(n))  #消除回车符号等特殊字符

HEADER := $(filter-out $(CCFILE), $(VARIABLE))
HEADER := $(foreach n,$(HEADER),-I$(SRC_PATH)/$(n))

SRC := $(filter $(CCFILE), $(VARIABLE))
# SRC := $(addprefix $(SRC_PATH)/, $(SRC))
OBJ := $(patsubst $(CCFILE), %.o, $(SRC))

OBJ_DIR := $(addprefix $(OBJ_PATH)/, $(sort $(shell dirname $(SRC))))

# #-------------- library marcros -----------------
# # INC_PATH := $(HEADER) -I./ffmpeg/include # header file path
INC_PATH := $(HEADER)# header file path
# #LIBS = -ldiv   #dynamic library
# ## LIBS = libdiv.a  #static library
LIB_PATH := #-L/usr/local/lib
# # LIBS := -lavformat -lavcodec -lswscale -lswresample -lavutil -lavfilter -lavdevice -lpostproc
# # LIBS += -lm  -lz  -lpthread -lx264 -lx265
LIBS := -lm

LIBS += $(shell pkg-config --libs opencv4)
INC_PATH += $(shell pkg-config --cflags opencv4)


# clean files list
CLEAN_LIST := $(addprefix $(OBJ_PATH)/, $(OBJ))
DEEPCLEAN_LIST := $(TARGET) $(CLEAN_LIST)


# $(info $(FILE_TEXT) )
# $(info $(CCFLAG) )
# $(info $(VARIABLE) )
# $(info $(HEADER) )
# $(info $(SRC) )
# $(info $(OBJ) )
# $(info $(BIN_PATH) )
# $(info $(OBJ_DIR) )
# $(info $(INC_PATH) )
# $(info $(CLEAN_LIST) )
# $(info $(DEEPCLEAN_LIST) )

# default rule
default : all

#-------------- create directionary----------------
$(shell mkdir -p $(BIN_PATH))
$(shell mkdir -p $(OBJ_DIR))


#-------------- bin -------------------------------
# link
$(TARGET): $(OBJ)
	$(CC) -o $@ $(addprefix $(OBJ_PATH)/, $^) -lm $(LIB_PATH) $(LIBS)

# compile
%.o: %.c*
	@echo $@ 
	@echo $<
	$(CC) $(CCOBJFLAG) -o $(addprefix $(OBJ_PATH)/, $@) $(addprefix $(SRC_PATH)/, $<) $(INC_PATH)

#-------------- phonies ----------------------------
.PHONY : all
all : $(TARGET)

# .PHONY : lib
# all : $(TARGET)

.PHONY: clean
clean:
	@echo clean $(CLEAN_LIST)
	@rm -f $(CLEAN_LIST)

.PHONY: deepclean
deepclean:
	@echo deep-clean $(DEEPCLEAN_LIST)
	@rm -f $(DEEPCLEAN_LIST)
	@rm -r $(OBJ_PATH)

配套main.flist文件列表

文件路径相对于makefile当前目录

include
... 添加其他头文件目录
src/main.cpp 
... 添加其它相关.c/.cpp文件

使用

命令如下

make
make solution=debug
make solution=release
make solution=release type=main
make solution=release type=test
make solution=release type=.a
make solution=release type=.so

根据自己的项目修改makefile中的名称和main.flist文件内容即可,支持main/test/.a/.so的4种类型的项目属性

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿尔发go

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值