电子说
在 Makefile 中调用函数的方法跟变量的使用类似,以“()”或“{}”符号包含函数
名和参数,具体语法如下:
$(函数名 参数)
# 或者使用花括号
${函数名 参数}
下面以常用的 notdir、 patsubst、 wildcard
函数为例进行讲解,并且示例中都是我们后面 Makefile 中使用到的内容.
notdir 函数用于去除文件路径中的目录部分。它的格式如下:
$(notdir 文件名)
例如输入参数 ./sources/func.c
,函数执行后的输出为 func.c
,也就是说它会把输入
中的 ./sources/
路径部分去掉,保留文件名。使用范例如下:
# 把路径中的“./sources/”部分去掉,输出为: hello_func.c
$(notdir ./sources/hello_func.c)
wildcard 函数用于获取文件列表,并使用空格分隔开。它的格式如下:
$(wildcard 匹配规则)
例如函数调用 $(wildcard *.c)
,函数执行后会把当前目录的所有 .c
文件列出。假设在 sources目录下有 func.c、main.c ,使用范例如下:
$(wildcard sources/*.c)
# 函数的输出为:
sources/func.c sources/main.c
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 是最方便的
# 生成的可执行文件名
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)
make
make run
make clean
审核编辑:汤梓红
全部0条评论
快来发表一下你的评论吧 !