您的位置:

深度解析makefile filter-out

一、filter-out:什么是filter-out

在makefile中,filter-out函数是过滤掉一个列表中的某些元素。

filter-out函数的语法为:

$(filter-out pattern…,text)

其中,pattern为要过滤掉的模式,text为要过滤的文本。filter-out函数返回的是从text中过滤掉了包含pattern的元素之后得到的结果。

二、filter-out:如何使用filter-out

filter-out函数可以配合其他函数使用,比如wildcard函数、patsubst函数等。以下是一个例子:

SOURCES := $(wildcard src/*.cpp)
OBJECTS := $(patsubst src/%.cpp,obj/%.o,$(SOURCES))
TARGET := main

$(TARGET): $(filter-out obj/main.o,$(OBJECTS))
    $(CC) $^ -o $@

在这个例子中,SOURCES表示所有src目录下的.cpp文件,OBJECTS表示把所有SOURCES的.cpp文件生成对应的.o文件,TARGET表示最终的可执行文件。$(filter-out obj/main.o,$(OBJECTS))表示从OBJECTS中排除obj/main.o文件。

三、filter-out:常见用途

1. 同时编译多个可执行文件

在一个项目中,可能会有多个可执行文件,那么我们就需要构建多个目标,使用filter-out可以方便的过滤掉指定的目标文件。

EXECUTABLES := foo bar baz main
TARGETS := $(filter-out main,$(EXECUTABLES))

all: $(TARGETS) # 编译 targets

$(TARGETS): %: %.c
    $(CC) $^ -o $@

在这个例子中,我们有四个可执行文件,分别是foo、bar、baz和main。我们使用TARGETS变量来存储需要编译的目标,使用filter-out函数来过滤掉main目标。最终使用all来编译TARGETS目标。

2. 排除依赖文件

在makefile中,TARGET: prerequisites规则表示TARGET目标依赖于prerequisites中的文件。使用filter-out函数可以方便的排除某些依赖文件。

TARGET := main
PREREQUISITES := foo.o bar.o main.o
OBJECTS := $(filter-out main.o,$(PREREQUISITES))

$(TARGET): $(OBJECTS)
    $(CC) $^ -o $@

在这个例子中,我们定义了TARGET和PREREQUISITES两个变量,表示目标和所有依赖项,OBJECTS表示从所有依赖项中排除main.o的目标物件。最终使用$(CC)命令把OBJECTS链接成可执行文件。

3. 过滤掉系统环境变量

有时候在makefile中需要过滤掉系统环境变量,这时候,可以使用filter-out函数。

SYSTEM_ENV := HOME PATH TERM
VARS := $(filter-out $(SYSTEM_ENV),$(.VARIABLES))

$(info $(VARS))

在这个例子中,我们使用$(.VARIABLES)来获取makefile中的所有变量,使用filter-out函数过滤掉SYSTEM_ENV中的变量。最终使用$(info)函数把过滤结果输出到终端。

四、filter-out:小结

filter-out函数是makefile的一个重要函数,可以配合其他函数使用,比如wildcard函数、patsubst函数等。它的常见用途包括同时编译多个可执行文件、排除依赖文件和过滤掉系统环境变量等。学会使用filter-out函数,可以更加方便的进行makefile的编写。