gcc编译器makefile学习笔记
1、使用到的函数
patsubst函数使用方法
可以替换名称。使用函数的时候,使用$()括起来,函数名 需要替换的内容,更替的内容,基于什么内容更替。例子如下:
#头文件目录
INCDIRS := inc
INCLUDE := $(patsubst %,-I%,$(INCDIRS))
#结果:
#INCLUDE = -Iinc
例子的意思是将变量INCDIRS
里面的%
(表示所有内容),更替为-I%
(也就是在之前的内容的基础上在头部添加-I)。
dir函数的使用方法
获取带有相对or绝对路径的文件的路径。也就是相当于去掉文件信息,只要目录信息。
C_FILE := \
main.c \
src/print.c
C_DIRS :=$(dir $(C_FILE))
#终端输出结果:
#./ src/
C文件有main.c和src目录下的print.c文件,
使用函数以后,结果就变成了./ src/。
notdir函数的使用方法
去掉路径信息,之保留文件信息。
C_FILE := \
main.c \
src/print.c
C_NDIR :=$(notdir $(C_FILE))
#终端输出结果:
#main.c print.c
如图,去掉了路径信息,保留了文件信息。
2、解决了什么问题
输出路径
头文件变动,C文件重编译
3、目录结构以及代码
main.c
#include "inc/print.h"
int main(void)
{
print();
}
src下的print.c
#include "../inc/print.h"
#include "stdio.h"
void print(void)
{
printf("%s\n",str);
}
inc下的print.h
#ifndef _PRINT_H
#define _PRINT_H
#define str "hes love"
void print(void);
#endif
makefile如下
CC := gcc
#生成程序名称
TARGET := temp
#存放中间
BUILD_DIR := build
#C文件以及相对目录
C_FILE := \
main.c \
src/print.c
#头文件目录
INCDIRS := \
inc
#头文件添加-I被编译器使用
INCLUDE := $(patsubst %,-I%,$(INCDIRS))
#C文件目录
C_DIRS :=$(dir $(C_FILE))
#C文件去掉目录信息
C_NDIR :=$(notdir $(C_FILE))
#需要生成的.o
C_OBJS :=$(patsubst %.c,$(BUILD_DIR)/%.o , $(C_NDIR) )
#生成依赖头文件存储文件
ALL_DEPENDS :=$(patsubst %.c,$(BUILD_DIR)/%.d,$(C_NDIR))
#设置C文件目录
VPATH := $(C_DIRS)
#伪变量
.PHONY:clean all
#创建存放中间文件的目录,以及生成可执行文件
all:$(BUILD_DIR) $(TARGET)
#生成可执行文件
$(TARGET):$(C_OBJS)
$(CC) -o $@ $^
#引用依赖的头文件
-include $(ALL_DEPENDS)
#将C_OBJS列表里面的.o按照要求编译出来,并且生成.d文件存储头文件依赖
$(C_OBJS):$(BUILD_DIR)/%.o:%.c
$(CC) -c -MD $(INCLUDE) -o $@ $<
#创建中间文件存放的文件夹,-p表示存在就不重新创建了
$(BUILD_DIR):
-mkdir -p $@
#清除中间文件,以及存放中间文件的文件夹
clean:
-rm -rf $(BUILD_DIR)
首先利用函数,得到源文件的目录信息,和文件信息,使用变量存储起来。
源文件的目录信息
是编译的时候进行自动寻找到C文件。
源文件的文件信息
是生成文件的时候,全部的中间文件存放到一起。
VPATH的作用是自动寻找到源文件。是makefile自带的。
ALL_DEPENDS
是利用GCC
编译器生成依赖头文件的存放文件,后缀是.d,存放C文件依赖的头文件,在编译的时候加上-MD
即可生成。
使用-include $(ALL_DEPENDS)
导入.d文件
效果
输入make编译,然后运行生成的文件。
更改print.h中的字符串之后重新编译。
达到预期效果,本文到此结束。