博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
通用 Makefile 的编写方法以及多目录 makefile 写法
阅读量:4047 次
发布时间:2019-05-25

本文共 5540 字,大约阅读时间需要 18 分钟。

 

 

 

1 make分中预定义变量表

  • $* 不包含扩展名的目标文件名称。
  • $+ 所有的依赖文件,以空格分开,并以出现的先后为序,可能包含重复的依赖文件。
  • $< 第一个依赖文件的名称。
  • $? 所有的依赖文件,以空格分开,这些依赖文件的修改日期比目标的创建日期晚。
  • $@ 目标的完整名称。
  • $^ 所有的依赖文件,以空格分开,不包含重复的依赖文件。
  • $% 如果目标是归档成员,则该变量表示目标的归档成员名称。例如,如果目标名称
  • 为 mytarget.so(image.o),则 @为mytarget.so,而@为mytarget.so,而% 为 image.o。
  • AR 归档维护程序的名称,默认值为 ar。
  • ARFLAGS 归档维护程序的选项。
  • AS 汇编程序的名称,默认值为 as。
  • ASFLAGS 汇编程序的选项。
  • CC C 编译器的名称,默认值为 cc。
  • CCFLAGS C 编译器的选项。
  • CPP C 预编译器的名称,默认值为 $(CC) -E。
  • CPPFLAGS C 预编译的选项。
  • CXX C++ 编译器的名称,默认值为 g++。
  • CXXFLAGS C++ 编译器的选项。
  • FC FORTRAN 编译器的名称,默认值为 f77。
  • FFLAGS FORTRAN 编译器的选项。

2 典型例子

CC := g++CFLAGS := -g -Wall -c -std=c++17 -I/usr/local/libusb-1.0.24/include/LDFLAG := -L/usr/local/libusb-1.0.24/lib/ -lusb-1.0SRCS := $(wildcard *.cpp)OBJS := $(patsubst %cpp,%o, $(SRCS))TARGET := testall:$(TARGET)%.o:%.cpp        $(CC) $(CFLAGS) $^ -o $@$(TARGET):$(OBJS)        $(CC) $(LDFLAG) $^ -o $@clean:        rm -rf $(TARGET) *.o
  •  

2.1 常见赋值操作的含义

  • = 是最基本的赋值
  • := 是覆盖之前的值
  • ?= 是如果没有被赋值过就赋予等号后面的值
  • += 是添加等号后面的值

2.2 := 和 = 的区别

“=”

make会将整个makefile展开后,再决定变量的值。也就是说,变量的值将会是整个makefile中最后被指定的值。看例子:

x = fooy = $(x) barx = xyz
  •  

在上例中,y的值将会是 xyz bar ,而不是 foo bar 。

“:=”

“:=”表示变量的值决定于它在makefile中的位置,而不是整个makefile展开后的最终值。

x := fooy := $(x) barx := xyz
  •  

在上例中,y的值将会是 foo bar ,而不是 xyz bar 了。

3 多个文件时,如何编写Makefile

例子1:将 bin src obj include 单独存放时,Makefile文件的通用编写方法

文件存放说明:

  • bin: 存放编译生成的二进制文件
  • src: 存放源文件 (add.c multis.c sub.c main.c)
  • obj: 存放编译生成的目标文件
  • include: 存放头文件 (add.h multis.h sub.h)
  • Makefile 文件和 bin、src、include处于同一级目录。

Makefile文件的写法:

INC_DIR=./includeBIN_DIR=./binSRC_DIR=./srcOBJ_DIR=./objSRC=${wildcard ${SRC_DIR}/*.c}OBJ=${patsubst %.c, $(OBJ_DIR)/%.o, ${notdir ${SRC}}}#用于查看变量的值#test:#   echo $(SRC)#   echo $(OBJ)TARGET=mainBIN_TARGET=${BIN_DIR}/${TARGET}CC=gccCFLAGS= -g -Wall -I${INC_DIR}${BIN_TARGET}:${OBJ}    ${CC} ${OBJ} -o $@${OBJ_DIR}/%.o:${SRC_DIR}/%.c    ${CC} ${CFLAGS} -c $< -o $@clean:    find ${OBJ_DIR} -name *.o -exec rm -rf {} \;
  •  
  • 说明:
  • notdir ${SRC}: 去除.c 文件中的目录,如:./src/mytest.c, 通过notdir之后得到 mytest.c。
  • $(wildcard .cpp /xxx/xxx/.cpp) 为获取当前目录下和/xxx/xxx/目录下所有.cpp文件名
  • (patsubst(patsubst(SRC))为替换所有的.cpp为.o
  • find ${OBJ_DIR} -name *.o -exec rm -rf {} \;输入man find,查看find命令中 -exec的具体用法。

Execute command; true if 0 status is returned. All following arguments to find are taken to be argu‐ 

ments to the command until an argument consisting of ;' is encountered. The string{}’ is replaced 
by the current file name being processed everywhere it occurs in the arguments to the command, not just 
in arguments where it is alone, as in some versions of find. Both of these constructions might need to 
be escaped (with a `\’) or quoted to protect them from expansion by the shell. See the EXAMPLES sec‐ 
tion for examples of the use of the -exec option. The specified command is run once for each matched 
file. The command is executed in the starting directory. There are unavoidable security problems 
surrounding use of the -exec action; you should use the -execdir option instead.

例子2:多个文件存放在不同的目录时,Makefile的写法。

文件存放说明:

  • add 目录 (add.c add.h)
  • sub 目录 (sub.c sub.h)
  • mutis 目录 (mutis.c mutis.h)
  • main 目录(main.c Makefile)

Makefile文件的写法:

CUR_DIR=add/sub/mutis/main文件所处的目录ADD_DIR=${CUR_DIR}/addSUB_DIR=${CUR_DIR}/subMUL_DIR=${CUR_DIR}/multisMAIN_DIR=${CUR_DIR}/mainINC_DIR= -I${ADD_DIR} \         -I${SUB_DIR} \         -I${MUL_DIR} \         -I${MAIN_DIR}SRC = ${wildcard  ${ADD_DIR}/*.c} \      ${wildcard  ${SUB_DIR}/*.c} \      ${wildcard  ${MUL_DIR}/*.c} \      ${wildcard  ${MAIN_DIR}/*.c}OBJ = ${patsubst %.c, %.o, ${SRC}}TARGET=mainCC=gccCCFLAGS=-g -Wall ${INC_DIR}${TARGET}: ${OBJ}    ${CC} ${notdir ${OBJ} } -o $@    echo "Compile done."${OBJ}:${SRC}    $(CC) ${CCFLAGS} -c $? clean:    rm -f ${OBJ}    rm -f *.o    rm -f *~    rm -f ${TARGET}    echo "Clean done."
  •  

改进版本:

CUR_DIR=/home/plv/Desktop/demo_multi_makefile/test3ADD_DIR=${CUR_DIR}/addSUB_DIR=${CUR_DIR}/subMUL_DIR=${CUR_DIR}/multisMAIN_DIR=${CUR_DIR}/mainINC_DIR= -I${ADD_DIR} \         -I${SUB_DIR} \         -I${MUL_DIR} \         -I${MAIN_DIR}SRC = ${wildcard  ${ADD_DIR}/*.c} \      ${wildcard  ${SUB_DIR}/*.c} \      ${wildcard  ${MUL_DIR}/*.c} \      ${wildcard  ${MAIN_DIR}/*.c}OBJ = ${patsubst %.c, %.o, ${SRC}}TARGET=mainCC=gccCCFLAGS=-g -Wall ${INC_DIR}${TARGET}: ${OBJ}    ${CC} ${OBJ} -o $@    @echo "Compile done."#${OBJ}:${SRC}#   $(CC) ${CCFLAGS} -c $? $(OBJ):%.o:%.c    @echo "Compiling $< ==> $@"    ${CC} ${CCFLAGS} -c $< -o $@clean:    @rm -f ${OBJ}    @echo "Clean object files done."    @rm -f *~    @echo "Clean tempreator files done."    @rm -f ${TARGET}    @echo "Clean target files done."    @echo "Clean done."
  •  

说明:

1.@ echo "" 表示执行该条命令,但不输出该命令的内容。

2.改进版本中将

${OBJ}:${SRC}    $(CC) ${CCFLAGS} -c $?
  •  

替换成了, 

$(OBJ):%.o:%.c    @echo "Compiling $< ==$@"    ${CC} ${CCFLAGS} -c $< -o $@

 

 

4、编译动态库

CC = g++CC_FLAG = -D_NOMNG -D_FILELINE#set your inc and libINC = LIB = -lpthread -L./ -lsvrtool#make target lib and relevant obj PRG = libsvrtool.soOBJ = Log.o#all targetall:$(PRG)$(PRG):$(OBJ)	$(CC) -shared -o $@ $(OBJ) $(LIB).SUFFIXES: .c .o .cpp.cpp.o:	$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o.PRONY:cleanclean:	@echo "Removing linked and compiled files......;	rm -f $(OBJ) $(PRG)

5、编译静态库

CC = g++CC_FLAG = -D_NOMNG -D_FILELINE#static library use 'ar' command AR = ar#set your inc and libINC = LIB = -lpthread -L./ -lsvrtool#make target lib and relevant obj PRG = libsvrtool.aOBJ = Log.o#all targetall:$(PRG)$(PRG):$(OBJ)	${AR} rv ${PRG} $?.SUFFIXES: .c .o .cpp.cpp.o:	$(CC) $(CC_FLAG) $(INC) -c $*.cpp -o $*.o.PRONY:cleanclean:	@echo "Removing linked and compiled files......"	rm -f $(OBJ) $(PRG)

 

随机组合、举一反三会写出适合项目的makefile.

 

转载地址:http://ovfci.baihongyu.com/

你可能感兴趣的文章
关于货币符号以及发音、币别码
查看>>
关于预处理器的学习
查看>>
ARM,S3C2410中脉宽调制定时器
查看>>
Zebra Bar-One 不能批量打印离散号码
查看>>
Platform创建WinCE内核时的编译错误
查看>>
玻璃杯
查看>>
柳永 《雨霖铃》
查看>>
MD2410开发板通过仿真器烧Bootloader简单流程
查看>>
MD2410仿真器烧Bootloader补充[1]:JTAG
查看>>
Meav《One I Love》
查看>>
林锐《高质量C++/C 编程指南》附录之《C++/C 代码审查表》
查看>>
林锐《高质量C++/C 编程指南》附录之《C++/C 编程质量试题》
查看>>
SC6600D_init.s
查看>>
最近比较烦
查看>>
祝福君君
查看>>
南澳西冲东冲穿越2日游
查看>>
又是一年毕业时
查看>>
我用一天时间做了一个MTK版本【转】
查看>>
把人生看透
查看>>
LED背光学习_可变模式分数电荷泵实现低功耗手机LCD背光驱动方案
查看>>