makefile

Makefile规则和命令执行条件

规则

​ 目标:依赖1 依赖2
​ 命令

命令执行的条件:

​ 依赖文件比目标文件新
​ 或者没有目标

执行顺序

当我们执行命令make的时候,后面没有带参数,makefile会编译默认遇到的第一个目标。

伪目标

伪目标的规则所定义的命令不是去创建文件,而仅仅通过make指定目标来执行一些特定系统命令或其依赖为目标的规则(如all),称为伪目标。

  • all:执行主要的编译工作,通常用作缺省目标,放在最前面。
  • Install:执行编译后的安装工作,把可执行文件、配置文件、文档等分别拷到不同的安装目录。
  • clean:删除编译生成的二进制文件
  • distclean:删除除源文件之外的所有中间生成文件,如配置文件,文档等。
  • tags:为vim等编辑器生成tags文件。
  • help:打印当前Makefile的帮助信息,比如有哪些目标可以有make指定去执行。
  • .PHONY是一个伪目标,可以防止在Makefile中定义的只执行命令的目标和工作目录下的实际文件出现名字冲突,另一种是提高执行makefile时的效率。

= := ?= +=区别

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

=

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

x = foo
y = $(x) bar
x = xyz

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

:=

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

x := foo
y := $(x) bar
x := xyz

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

符号

@

通常makefile会将其执行的命令行在执行前输出到屏幕上。如果将‘@’添加到命令行前,这个命令将不被make回显出来。

例如:@echo --compiling module----; // 屏幕输出 --compiling module----

​ echo --compiling module----; // 没有@ 屏幕输出echo --compiling module----

自动目标

  • $@ : 目标集合
  • $% : 当目标是函数库文件时, 表示其中的目标文件名
  • $< : 第一个依赖目标. 如果依赖目标是多个, 逐个表示依赖目标
  • $? : 比目标新的依赖目标的集合
  • $^ : 所有依赖目标的集合, 会去除重复的依赖目标
  • $+ : 所有依赖目标的集合, 不会去除重复的依赖目标
  • $* : 这个是GNU make特有的, 其它的make不一定支持

多目录时Makefile编写实例

文件存放说明:

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

Makefile写法

CUR_DIR=/home/test

ADD_DIR=${CUR_DIR}/add
SUB_DIR=${CUR_DIR}/sub
MUL_DIR=${CUR_DIR}/multis
MAIN_DIR=${CUR_DIR}/main

INC_DIR= -I${ADD_DIR} \
         -I${SUB_DIR} \
         -I${MUL_DIR} \
         -I${MAIN_DIR}
#获取所有.c文件的文件名
SRC = ${wildcard  ${ADD_DIR}/*.c} \
      ${wildcard  ${SUB_DIR}/*.c} \
      ${wildcard  ${MUL_DIR}/*.c} \
      ${wildcard  ${MAIN_DIR}/*.c}
#将所有的.c替换成.o
OBJ = ${patsubst %.c, %.o, ${SRC}}

TARGET=main
CC=gcc
CCFLAGS=-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."

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×