MENU

makefile文件编写技巧

前言

之前用C++写的都是一些小小几个文件,所以直接使用gcc/g++直接编译文件。但是最近做一个webserver项目,涉及到头文件且多个文件存在有依赖关系,因此使用makefile编译变得更方便。
编译过程为:源文件首先会生成中间目标文件,再由中间目标文件生成执行文件。也即编译+链接过程。

makefile

makefile编写按照如下格式

target ... : requisites ...  目标 : 依赖
    command                     命令(注意命令必须要以Tab键开始)

大致执行过程:①先在目录中找到makefile或Makefile文件 ②在makefile文件中找到第一个目标target做为最终生成目标文件 ③判断最终目标文件是否存在,不存在最终目标文件或者.o的依赖文件更新时间比最终目标文件新,则重新执行编译生成最终目标文件

makefile常用几个函数

  • wildcard

    $(wildcard PATTERN)
    
    # 用法
    $(wildcard *.cpp) 含义是指:匹配当前目录下的所有.cpp结尾的文件。
    
  • patsubst

    # 意义:将字符串text中符合模式pattern的字符串替换成replacement
    $(patsubst pattern, replacement, text)
    
    # 通常使用
    $(patsubst %.cpp, %.o, $(wildcard *.cpp))
    
  • filter-out

    # 意义:过滤掉字串“TEXT”中所有符合模式“PATTERN”的单词
    $(filter-out PATTERN, TEXT) 
    
    # 通常使用
    $(filter-out main.cpp, $(SOURCE))
    

makefile伪目标

常常在makefile末尾clean中看到.PHONY关键字,即为声明一个伪目标。
默认情况下make认为目标对应着一个文件、make会比较目标文件和依赖文件的新旧决定是否执行命令。
举个例子:假如把clean做为一个目标并生成clean文件,当再次执行make clean时候,由于发现命令下发现有该文件且不存在不变化则不再执行删除命令。而伪目标则恰好可以解决这个问题。

  • 伪目标通过.PHONY关键字声明,并且先声明后执行
  • 伪目标不对应(不生成)任何实际文件
  • 伪目标不管依赖是否有diff,每次都执行命令
# 示例
.PHONY: clean
clean :
    rm *.o -rf

makefile常见自动化变量

  • $@ 表示当前目标(即:前面的值)
  • $< 表示依赖目标文件的第一项(即:后面的值)
  • $^ 表示依赖目标文件的所有集合(去除重复的依赖目标)
# 举例

## ①假设编译main.cpp、test.cpp目标文件
常规情况:(需要写两次编译命令)
    main.o : main.cpp
        g++ -std=c++11 -c main.cpp -o main.o

    test.o : test.cpp
        g++ -std=c++11 -c test.cpp -o test.o

改用自动化变量方式:(使用$<代替为依赖文件、$@代替为目标文件)
    %.o : %.cpp
        g++ -std=c++11 -c $< -o $@

## ②假设编译为一个最终可执行文件,目标文件假设为$(TARGET)、依赖文件假设为$(OBJ)
常规情况:
    (TARGET) : $(OBJ)
        g++ -std=c++11 -o $(TARGET) $(OBJ)

改用自动化变量方式:(使用%^代替为依赖文件集合、$@代替为目标文件)
    (TARGET) : $(OBJ)
        g++ -std=c++11 -o %@ %^
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码