Makefile(二)

函数格式及示例

在 Makefile 中调用函数的方法跟变量的使用类似,以“ ( ) ”或“ ()”或“ (){}”符号包含函数

名和参数,具体语法如下:

$(函数名 参数)
# 或者使用花括号
${函数名 参数}

下面以常用的 notdir、 patsubst、 wildcard 函数为例进行讲解,并且示例中都是我们后面 Makefile 中使用到的内容.

notdir 函数

notdir 函数用于去除文件路径中的目录部分。它的格式如下:

$(notdir 文件名)

例如输入参数 ./sources/func.c,函数执行后的输出为 func.c,也就是说它会把输入
中的 ./sources/ 路径部分去掉,保留文件名。使用范例如下:

# 把路径中的“./sources/”部分去掉,输出为: hello_func.c
$(notdir ./sources/hello_func.c)

wildcard 函数

wildcard 函数用于获取文件列表,并使用空格分隔开。它的格式如下:

$(wildcard 匹配规则)

例如函数调用 $(wildcard *.c),函数执行后会把当前目录的所有 .c 文件列出。假设在 sources目录下有 func.c、main.c,使用范例如下:

 $(wildcard sources/*.c)
  # 函数的输出为:
 sources/func.c sources/main.c

patsubst 函数

patsubst 函数功能为模式字符串替换。它的格式如下:

$(patsubst 匹配规则, 替换规则, 输入的字符串)

当输入的字符串符合匹配规则,那么使用替换规则来替换字符串,当匹配规则中有 % 号时,
替换规则也可以例程 % 号来提取 % 匹配的内容加入到最后替换的字符串中。有点抽象,请
直接阅读以下示例:

 $(patsubst %.c, build_dir/%.o, hello_main.c )
 # 函数的输出为:
 build_dir/hello_main.o
 # 执行如下函数
 $(patsubst %.c, build_dir/%.o, hello_main.xxx )
 # 由于 hello_main.xxx 不符合匹配规则"%.c",所以函数没有输出

第一个函数调用中,由于 hello_main.c 符合 %.c 的匹配规则(% 在 Makefile 中的类似于 * 通
配符
),而且 %hello_main.c 中提取出了 hello_main 字符,把这部分内容放到替换规
build_dir/%.o% 号中,所以最终的输出为 build_dir/hello_main.o

第二个函数调用中,由于由于 hello_main.xxx 不符合 %.c 的匹配规则,.xxx.c
不上,所以不会进行替换,函数直接返回空的内容。

示例

假如我们有以下目录结构:

.
├── includes
│   ├── add_one.h
│   └── func.h
├── makefile
└── sources
    ├── add_one.c
    ├── func.c
    └── main.c

文件内容如下:

add_one.h

int add_one(int x, int y);

func.h

void func(void);

add_one.c

int add_one(int x, int y)
{
    return x + y;
}

func.c

#include "stdio.h"

void func(void)
{
    printf("This is %s file !", __FILE__);
}

main.c

#include "stdio.h"
#include "add_one.h"
#include "func.h"

int main()
{
    int x = 9, y = 8;
    int sum = 0;

    sum = add_one(x, y);

    printf("%d + %d = %d\n", x, y, sum);
    func();

    return 0;
}

如果我们不借助makefile的话,直接运行指令:

gcc -o main.exe .\sources\main.c .\sources\func.c .\sources\add_one.c -I .\includes\

即可完成编译

以后我们的源文件 .c 增多,目录结构更复杂,此时借助 makefile 是最方便的

使用makefile

# 生成的可执行文件名
TARGET = main.exe
# 编译器
CC = gcc

#存放中间文件的路径
BUILD_DIR = build
#存放源文件的文件夹
SRC_DIR = sources
#存放头文件的文件夹
INC_DIR = includes 

# 源文件
SRCS = $(wildcard $(SRC_DIR)/*.c)  #列出 sources 目录下的文件
# 目标文件(*.o)
OBJS = $(patsubst %.c, $(BUILD_DIR)/%.o, $(notdir $(SRCS)))
# 头文件
DEPS = $(wildcard $(INC_DIR)/*.h)

# #################
# 编译选项
# #################
# 指定头文件的路径
CFLAGS = $(patsubst %, -I%, $(INC_DIR))
# 输出编译警告
COPTION = -Wall   

# 生成目标文件
$(BUILD_DIR)/$(TARGET): $(OBJS)
	$(CC) -o $@ $^ $(CFLAGS) $(COPTION)

#*.o 文件的生成规则
$(BUILD_DIR)/%.o: $(SRC_DIR)/%.c $(DEPS)
	@mkdir -p $(BUILD_DIR)
	$(CC) -o $@ -c $< $(CFLAGS) $(COPTION)

# 运行.exe
run:
	@$(BUILD_DIR)/$(TARGET)

# 删除生成的文件
clean:
	rm -rf $(BUILD_DIR)
  1. 编译
make
  1. 运行
make run
  1. 删除文件
make clean
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

点灯大师~

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

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

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

打赏作者

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

抵扣说明:

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

余额充值