Linux下makefile模板

提供一个简单的 Makefile 模板,根据需要作相应修改,可以适用于很多小项目。

CC=gcc
SRCS=$(wildcard *.c */*.c)
OBJS=$(patsubst %.c, %.o, $(SRCS))
FLAG=-g
NAME=$(wildcard *.c)
TARGET=$(patsubst %.c, %, $(NAME))

$(TARGET):$(OBJS)
    $(CC) -o $@ $^ $(FLAG)

%.o:%.c
    $(CC) -o $@ -c $< -g

clean:
    rm -rf $(TARGET) $(OBJS)

解释一下:

1)第1行指定编译器为 gcc,可以根据需要修改为 g++ 或者 arm-linux-gcc 等交叉编译工具链。 
(2)第2行是为了获取匹配模式的文件名,*.c 表示当前工程目录的 c 文件,*/*.c 表示所有下一级目录的 .c 文件。 
(3)第3行是将 $(SRCS) 中的 .c 文件替换成 .o 文件。 
(4)第4行用于指定编译选项,根据需要添加,比如 -g、-ml、-Wall、-O2 等等。 
(5)第56行,同样使用了 wildcard 和 patsubst 函数来处理,目的是为了指定最终生成的可执行文件名。 
(6)第8$(TARGET):$(OBJS) 表示由 .o 文件链接成可执行文件。 
(7)注意第9行前面是一个 <tab> 键,而 $@ 表示目标,也就是 $(TARGET),$^ 表示依赖列表,也就是 $(OBJS) 。 
(8)第11%.o:%.c 表示由 .c 文件生成 .o 文件。 
(9)第12行中的 $< 表示搜索到的第一个匹配的文件。 
(10)第14行的clean是伪目标(.PHONY),它不需要依赖,执行 make 命令时是不会执行的,当执行 make clean 时才会执行。

另外,Makefile 的赋值除了使用等号(=),还可以使用 := 、+= 、?= 符号。 具体含义如下:

:= 表示简单赋值(注意右边的 $ 值只会向上寻找)
+= 表示追加赋值
?= 表示判断赋值(判断左边是否已经定义过,如果是则忽略本次赋

例子:
一、line1的源码

line1.h

#ifndef _LINE_1_H   
#define _LINE_1_H   
    void line1_print(const char *strMsg);  
#endif  
line1.cpp

#include "line1.h"  
#include <stdio.h>  
void line1_print(const char *strMsg)  
{  
    printf("This is line1 print %s.\r\n",strMsg);  
}  

二、line2的源码

line2.h

#ifndef _LINE_2_H   
#define _LINE_2_H   
    void line2_print(const char *strMsg);  
#endif
line2.cpp

#include "line2.h"  
#include <stdio.h>  
void line2_print(const char *strMsg)  
{  
    printf("This is line2 print %s.\r\n",strMsg);  
}  

三、main的源码

main.cpp

#include "line1.h"  
#include "line2.h"  

int main(int argc,char **argv)  
{  
    line1_print("hello runfarther");  
    line2_print("hello runfarther");  

    return 0;  
}  

对上面的代码,在不用Makefile时,我们可以直接用命令行来编译,得到我们的可执行程序main.out:

g++ -c main.c   
g++ -c line1.c   
g++ -c line2.c   
g++ -o main.out main.o line1.o line2.o  

为了编译工作更加方便,我们通常会编写Makefile来完成编译,我们先看一个用于编译和链接上面代码的例子:

main.out:main.o line1.o line2.o  
    g++ -o main.out main.o line1.o line2.o  
main.o:main.c line1.h line2.h  
    g++ -c main.c  
line1.o:line1.c line1.h  
    g++ -c line1.c  
line2.o:line2.c line2.h  
    g++ -c line2.c  

从例子可以看出,Makefile一般的格式是:

target:components   
    rule  

第一行表示的是依赖关系,第二行是规则,特别要注意,rule这行必须是Tab键开头。

比如说我们上面的那个Makefile文件的前面二行:

main.out:main.o line1.o line2.o  
    g++ -o main.out main.o line1.o line2.o  

表示我们的目标(target)main.out的依赖对象(components)是main.o line1.o line2.o,当依赖的对象在被修改的话,就要去执行规则一行所指定的命令g++ -o main.out main.o line1.o line2.o。注意规则这行是以一个TAB键开头。

接下来我来介绍下Makefile中的四个有用的特殊符号意义和使用,他们分别是@、$@、$^、$<

一、@
这个符串通常用在“规则”行中,表示不显示命令本身,而只显示它的结果,例如Makefile中的内容为:

DIR_OBJ=./obj  
CMD_MKOBJDIR=if [ -d ${DIR_OBJ} ]; then exit 0; else mkdir ${DIR_OBJ}; fi  

mkobjdir:  
    @${CMD_MKOBJDIR}  

命令行执行如下:

make mkobjdir

此时不会显示在命令行不会显示出if [ -d ${DIR_OBJ} ]; then exit 0; else mkdir ${DIR_OBJ}; fi,但如果规则行的TAB后没有以@开头,则会显示,不信可以试试。

二、 @ @ 、 ^、$<

这三个分别表示:
$@ ————–代表目标文件(target)

$^ —————代表所有的依赖文件(components)

$<—————代表第一个依赖文件(components中最左边的那个)。
好了,知道了他们的意义后,如果使用上面三个变量,那么简化的Makefile文件为:

main.out:main.o line1.o line2.o  
    g++ -o $@ $^  
main.o:main.c line1.h line2.h  
    g++ -c $<  
line1.o:line1.c line1.h  
    g++ -c $<  
line2.o:line2.c line2.h  
    g++ -c $<  

当然,还可以进一步简化,有兴趣可以再去研究下,这里就不展示了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值