Linux下Makefile文件常用知识总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40758751/article/details/83239744

1.Makefile文件命令的使用

一般有两种用法

#1
make
#2
make command

第一种用法会自动执行Makefile中的所有指令,第二种用法会执行Makefile中的指定指令。

2.Makefile文件命令的一般写法

目标: 依赖项1 依赖项2

(tab)命令1

(tab)命令2

(tab)......

例如:

helloworld: main.cpp
    g++ -c main.cpp -o main.o
    g++ main.o -o helloworld
clean:
    rm -rf main.o

3.Makefile中的变量

OBJS = programA.o programB.o
OBJS-ADD = $(OBJS) programC.o
OBJS-ADD += programD.o

其中OBJS,OBJS-ADD都表示字符串变量,可用'='赋值。

$(变量)表示取得该变量的值。

+=表示对字符串变量追加字符串操作。

4.Makefile中的自动变量

$@    #1指代目标集合
$<    #2指代第一个依赖项
$?    #3指代比目标新的依赖目标的集合
$^    #4指代所有依赖目标的集合, 会去除重复的依赖目标
$+    #5指代所有依赖目标的集合, 不会去除重复的依赖目标

#1指代目标集合
#2指代第一个依赖项
#3指代比目标新的依赖目标的集合
#4指代所有依赖目标的集合, 会去除重复的依赖目标
#5指代所有依赖目标的集合, 不会去除重复的依赖目标 

5.Makefile中函数的使用

一般的函数调用语法

$(<function> <arguments1>,<arguments2>...)
# 或者
${<function> <arguments1>,<arguments2>...}

function是函数名,arguments是函数参数。

5.Makefile中常用的函数

字符串替换函数: $(subst <from>,<to>,<text>)

功能: 把字符串<text> 中的 <from> 替换为 <to>

返回: 替换过的字符串

# Makefile 内容
all:
    @echo $(subst t,e,maktfilt)  <-- 将t替换为e

# bash 中执行 make
$ make
makefile

模式字符串替换函数: $(patsubst <pattern>,<replacement>,<text>)

功能: 查找<text>中的单词(单词以"空格", "tab", "换行"来分割) 是否符合 <pattern>, 符合的话, 用 <replacement> 替代.

返回: 替换过的字符串

# Makefile 内容
all:
    @echo $(patsubst %.c,%.o,programA.c programB.c)

# bash 中执行 make
$ make
programA.o programB.o

执行内部指令函数: $(shell <shell command>)

它的作用就是执行一个shell命令, 并将shell命令的结果作为函数的返回.

作用和 `<shell command>` 一样, ` 是反引号

模式文件列表函数$(wildcard <pattern>)

功能:获取工作目录下匹配<pattern>模式的所有文件列表

返回:获取到的文件列表

# Makefile 内容
all:
    @echo $(wildcard *.c)

# bash 中执行 make
$ make
programA.c programB.c

6.Makefile中的通配符

  • *     :: 表示任意一个或多个字符
  • ?     :: 表示任意一个字符
  • [...] :: ex. [abcd] 表示a,b,c,d中任意一个字符, [^abcd]表示除a,b,c,d以外的字符, [0-9]表示 0~9中任意一个数字
  • ~     :: 表示用户的home目录

7.Makefile 命令前缀

Makefile 中书写shell命令时可以加2种前缀 @ 和 -, 或者不用前缀.

3种格式的shell命令区别如下:

  • 不用前缀 :: 输出执行的命令以及命令执行的结果, 出错的话停止执行
  • 前缀 @   :: 只输出命令执行的结果, 出错的话停止执行
  • 前缀 -   :: 命令执行有错的话, 忽略错误, 继续执行

8.Makefile头文件依赖

g++ -c -MMD main.cpp -o main.o

该指令在编译main.cpp时会生成一个main.d的文件,其内容为main.cpp的所有依赖项。

进而我们可以使用指令符"-include"将其包含进来

#DEP_FILE为.d文件的文件列表
-include$(DEP_FILE)

实现头文件依赖

9.使Makefile支持多个子目录

该处使用foreach函数实现

CXX_SOURCES = $(foreach dir,$(SUBDIR),$(wildcard  $(dir)/*.cpp))

dir为变量,SUBDIR为目录列表,该函数依次访问SUBDIR中的各个目录,创建.cpp文件列表。

10.已经写好的Makefile模板

#单个目录下的全自动Makefile
#EXE表示生成的可执行文件的文件名,此处以helloworld为例

EXE = helloworld
CXX_SOURCES = $(wildcard  *.cpp)
CXX_OBJECTS = $(patsubst  %.cpp, %.o, $(CXX_SOURCES))
DEP_FILES = $(patsubst  %.o, %.d, $(CXX_OBJECTS))

$(EXE): $(CXX_OBJECTS)
	g++ $(CXX_OBJECTS) -o $@

%.o: %.cpp
	g++ -c -MMD $< -o $@

-include $(DEP_FILES)

clean:
	rm -rf $(CXX_OBJECTS) $(DEP_FILES) $(EXE)
#多个目录下的半自动Makefile
#EXE表示生成的可执行文件的文件名,此处以helloworld为例
#SUBDIR为目录列表,需手动添加
#该Makefile应放置在项目目录下

EXE = helloworld
SUBDIR = src object
#CXX_SOURCES = $(wildcard  *.cpp)
CXX_SOURCES = $(foreach dir,$(SUBDIR),$(wildcard  $(dir)/*.cpp))
CXX_OBJECTS = $(patsubst  %.cpp, %.o, $(CXX_SOURCES))
DEP_FILES = $(patsubst  %.o, %.d, $(CXX_OBJECTS))

$(EXE): $(CXX_OBJECTS)
	g++ $(CXX_OBJECTS) -o $@

%.o: %.cpp
	g++ -c -MMD $< -o $@

-include $(DEP_FILES)

clean:
	rm -rf $(CXX_OBJECTS) $(DEP_FILES) $(EXE)

本文部分借鉴了https://www.cnblogs.com/wang_yb/p/3990952.html 

上述博主总结的比本人更加完整,全面。

猜你喜欢

转载自blog.csdn.net/qq_40758751/article/details/83239744
今日推荐