make与Makefile的使用说明

本文详细介绍了make命令的使用,包括命令格式定义和常用参数。同时,解析了Makefile的规则,如预定义变量、特殊目标和文本函数。通过一个工程示例,展示了Makefile在实际项目中的应用,包括执行`make`和`make clean`的结果。

目录

一、make的使用

1.1 make命令格式定义

1.2 make命令常用参数

二、Makefile的规则

2.1 内置-预定义变量

2.2 内置-特殊目标

2.3 内置-文本函数

三、工程示例

3.1 目录结构

3.2 文件内容

3.2.1 源文件

3.2.2 头文件

3.2.3 Makefile文件

3.3 执行结果

3.3.1 make

3.3.2 make clean


一、make的使用

当执行make命令时,make会在当前的目录下搜索Makefile文件,Makefile文件里面记录了源码如何编译的详细信息。其实make会按序去寻找当前目录下的GNUmakefile、makefile、Makefile,然后取最靠前的文件执行,忽略后面的文件。可以使用 -f 强制指定make所搜寻的文件。强烈建议,始终使用 Makefile文件。

make根据Makefile文件中的数据和每个文件更改的时间戳决定哪些文件需要更新。对于这些需要更新的文件,make会基于Makefile文件发布命令进行更新,更新的方式由提供的命令行参数控制。

 

1.1 make命令格式定义

1.2 make命令常用参数

-C  dir:从当前目录切换到dir目录下执行make命令。

-C dir1  -C dir2 :切换到 dir1/dir2 目录下执行make命令;指定了多个-C选项,则每个选项都相对于前一个选项进行解释。

-f file:指定file文件作为makefile,参与make命令的执行。

 

二、Makefile的规则

target 1(目标1)  :  prerequisites(先决条件) 

<Tab> command 1(命令1)

 

target 2(目标2)  :  prerequisites(先决条件) 

<Tab> command 2(命令2)

 

# 目标可以是一个要产生的文件,也可以是一个标签。

# prerequisites为要生成目标所需要的依赖,可以为空。注意,目标和依赖之前必须使用 ':' 分隔开来。

# 命令是make执行的动作,一个规则可以含有几个命令,每个命令单独占一行,每个命令行前面必须是一个Tab字符。

# 以 '#' 字符开头的内容表示注释内容。

 

2.1 内置-预定义变量

使用make命令的时候,只要不附带参数 -R ,就会默认启用内置的预定义变量。常见的预定义变量如下:

变量名描述缺省值
CC 

C语言编译程序

cc,指向gcc
CFLAGSC编译器的额外标志
RM删除文件的命令rm -f

 

2.2 内置-特殊目标

在Makefile文件中,一些名字作为目标使用是具有特殊含义的。常见的特殊目标如下:

目标名描述
.PHONY目标的依赖是假想目标。假想目标是这样一些目标,make无条件的执行该命令,和目录下是否存在该文件以及它最后一次更新的时间没有关系。
.DEFAULT用于那些没有找到规则(具体规则或隐含规则)更新的目标。make如果无法匹配到指定目标,那么就会去执行该缺省目标。

 

2.3 内置-文本函数

在Makefile文件中,有一些内置的文本函数可以有效提高编码效率。常见的文本函数如下:

函数名(带下划线)描述
${wildcard ./*.c}可以在Makefile文件的任何地方使用该字符串,应用时该字符串被一列在指定目录下存在的并且文件名和给出文件名的格式相符合的文件所代替,文件名中间由空格隔开。如果没有和指定格式一致的文件,则函数 wildcard 的输出将会省略。
${patsubst %.c, %.o, text}将 text 字符串中所有的 '.c' 后缀变为 '.o',转换为目标文件名字符串。如果没有匹配并转换成功,则函数 patsubst 的输出为 text 的原本内容。

 

三、工程示例

3.1 目录结构

 

 

3.2 文件内容

3.2.1 源文件

/* ./src/main/main.c */

#include "add.h"
#include "sub.h"
#include "print.h"

int main()
{
    printInt("1+1=", add(1,1));
    printInt("1-1=", sub(1,1));
    printStr("wangsong");

    return 0;
}
/* ./src/math/add.c */

#include "add.h"

int add(int a, int b)
{
    return a + b;
}
/* ./src/math/sub.c */

#include "sub.h"

int sub(int a, int b)
{
    return a - b;
}
/* ./src/util/print.c */

#include <stdio.h>
#include "print.h"

void printStr(char* s)
{
    printf("%s\n", s);
}

void printInt(char* prefix , int n)
{
    printf("%s %d\n", prefix, n);
}

 

3.2.2 头文件

/* ./inc/math/add.h */

#ifndef __ADD_H__
#define __ADD_H__

#ifdef __cplusplus
extern "C"
{
#endif

int add(int a, int b);

#ifdef __cplusplus
}
#endif

#endif
/* ./inc/math/sub.h */

#ifndef __SUB_H__
#define __SUB_H__

#ifdef __cplusplus
extern "C"
{
#endif

int sub(int a, int b);

#ifdef __cplusplus
}
#endif

#endif
/* ./inc/util/print.h */

#ifndef __PRINT_H__
#define __PRINT_H__

#ifdef __cplusplus
extern "C"
{
#endif

void printStr(char* s);
void printInt(char* prefix, int n);

#ifdef __cplusplus
}
#endif

#endif

 

3.2.3 Makefile文件

# ./Makefile

BIN = ./bin/main.exe

build:
        ${MAKE} -C ./src build
        gcc -o ${BIN} ./src/*/*.o

.PHONY: clean
clean:
        ${MAKE} -C ./src clean
        rm -f ${BIN}
# ./src/Makefile

INCLUDES = -I./../inc/math \
           -I./../inc/util

DIRECTORY = ./*
SOURCES = ${wildcard $(DIRECTORY)/*.c}
OBJECTS = ${patsubst %.c, %.o, $(SOURCES)}

CC = gcc
CFLAGS = -Wall ${INCLUDES}

build:${OBJECTS}
        @echo \## src: ${SOURCES}
        @echo \## obj: ${OBJECTS}


.PHONY: clean
clean:
        rm -f ${OBJECTS}


.DEFAULT:
        @echo \#### target error, please attention!!!

 

3.3 执行结果

3.3.1 make

 

3.3.2 make clean

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值