Makefile 是构建和管理 C/C++ 项目时常用的工具,其中函数(functions)是其强大功能的重要组成部分。以下围绕 Makefile 中常用函数进行详细讲解,结合示例帮助理解。
1. 文本处理函数
(1)$(subst FROM,TO,TEXT)
- 功能:将
TEXT
中的FROM
替换为TO
。 - 示例:
SRC = foo.c bar.c OBJ = $(subst .c,.o,$(SRC)) # OBJ 的值为 foo.o bar.o
(2)$(patsubst PATTERN,REPLACEMENT,TEXT)
- 功能:对
TEXT
中符合PATTERN
的部分,用REPLACEMENT
替换。 - 示例:
SRC = foo.c bar.c baz.c OBJ = $(patsubst %.c,%.o,$(SRC)) # OBJ 的值为 foo.o bar.o baz.o
(3)$(strip STRING)
- 功能:去除
STRING
开头和结尾的空格。 - 示例:
TEXT = hello world CLEAN_TEXT = $(strip $(TEXT)) # CLEAN_TEXT 的值为 "hello world"
(4)$(findstring FIND,TEXT)
- 功能:在
TEXT
中查找FIND
,如果找到则返回FIND
,否则返回空。 - 示例:
RESULT = $(findstring world,hello world) # RESULT 的值为 "world"
(5)$(filter PATTERN...,TEXT)
- 功能:从
TEXT
中筛选出符合PATTERN
的部分。 - 示例:
FILES = foo.c bar.h baz.c SRC_FILES = $(filter %.c,$(FILES)) # SRC_FILES 的值为 foo.c baz.c
(6)$(filter-out PATTERN...,TEXT)
- 功能:从
TEXT
中剔除符合PATTERN
的部分。 - 示例:
FILES = foo.c bar.h baz.c NON_SRC_FILES = $(filter-out %.c,$(FILES)) # NON_SRC_FILES 的值为 bar.h
(7)$(sort LIST)
- 功能:对
LIST
中的元素去重并排序。 - 示例:
UNSORTED = baz.c foo.c bar.c foo.c SORTED = $(sort $(UNSORTED)) # SORTED 的值为 bar.c baz.c foo.c
2. 文件名操作函数
(1)$(dir NAMES...)
- 功能:提取文件路径中的目录部分。
- 示例:
FILES = src/foo.c include/bar.h DIRS = $(dir $(FILES)) # DIRS 的值为 "src/ include/"
(2)$(notdir NAMES...)
- 功能:提取文件名,去掉目录部分。
- 示例:
FILES = src/foo.c include/bar.h NAMES = $(notdir $(FILES)) # NAMES 的值为 "foo.c bar.h"
(3)$(suffix NAMES...)
- 功能:提取文件的后缀名。
- 示例:
FILES = foo.c bar.h baz.o SUFFIXES = $(suffix $(FILES)) # SUFFIXES 的值为 ".c .h .o"
(4)$(basename NAMES...)
- 功能:提取文件名,去掉后缀。
- 示例:
FILES = foo.c bar.h baz.o BASENAMES = $(basename $(FILES)) # BASENAMES 的值为 "foo bar baz"
(5)$(addsuffix SUFFIX,NAMES...)
- 功能:为
NAMES
中的每个元素添加后缀SUFFIX
。 - 示例:
NAMES = foo bar baz FILES = $(addsuffix .c,$(NAMES)) # FILES 的值为 "foo.c bar.c baz.c"
(6)$(addprefix PREFIX,NAMES...)
- 功能:为
NAMES
中的每个元素添加前缀PREFIX
。 - 示例:
NAMES = foo bar baz FILES = $(addprefix src/,$(NAMES)) # FILES 的值为 "src/foo src/bar src/baz"
(7)$(join LIST1,LIST2)
- 功能:将
LIST1
和LIST2
的元素按位置拼接。 - 示例:
LIST1 = foo bar baz LIST2 = .c .h .o JOINED = $(join $(LIST1),$(LIST2)) # JOINED 的值为 "foo.c bar.h baz.o"
3. 条件判断函数
(1)$(if CONDITION,THEN-PART[,ELSE-PART])
- 功能:根据
CONDITION
是否为空,返回THEN-PART
或ELSE-PART
。 - 示例:
VALUE = foo RESULT = $(if $(VALUE),Value is set,Value is empty) # RESULT 的值为 "Value is set"
(2)$(or CONDITION1,CONDITION2,...)
- 功能:返回个非空的
CONDITION
。 - 示例:
VAR1 = VAR2 = foo RESULT = $(or $(VAR1),$(VAR2)) # RESULT 的值为 "foo"
(3)$(and CONDITION1,CONDITION2,...)
- 功能:如果所有
CONDITION
都非空,则返回最后一个CONDITION
,否则返回空。 - 示例:
VAR1 = foo VAR2 = bar RESULT = $(and $(VAR1),$(VAR2)) # RESULT 的值为 "bar"
4. 其他常用函数
(1)$(foreach VAR,LIST,TEXT)
- 功能:对
LIST
中的每个元素,执行TEXT
,并将结果拼接。 - 示例:
FILES = foo.c bar.c baz.c OBJS = $(foreach FILE,$(FILES),$(FILE:.c=.o)) # OBJS 的值为 "foo.o bar.o baz.o"
(2)$(call FUNCTION,PARAM1,PARAM2,...)
- 功能:调用自定义函数
FUNCTION
,并传递参数。 -
示例:
```makefile
define my_func
echo $(1) $(2)
endefRESULT = $(call my_func,Hello,World)
RESULT 的值为 “echo Hello World” 的执行结果
```
(3)$(value VAR)
- 功能:获取变量
VAR
的值(递归展开)。 - 示例:
FOO = bar BAR = $(FOO) RESULT = $(value BAR) # RESULT 的值为 "bar"
(4)$(eval TEXT)
- 功能:动态解析并执行
TEXT
。 -
示例:
```makefile
FILES = foo.c bar.c
define generate_rule
$(1).o: $(1).c
gcc -c $$< -o $$@
endef$(foreach FILE,$(FILES),$(eval $(call generate_rule,$(basename $(FILE)))))
```
5. 综合示例
以下是一个综合示例,展示如何结合多个函数构建规则:
```makefile
SRC = foo.c bar.c baz.c
OBJ = $(patsubst %.c,%.o,$(SRC))
DEP = $(addprefix dep/,$(notdir $(OBJ:.o=.d)))
all: $(OBJ)
%.o: %.c
gcc -c $< -o $@
clean:
rm -f $(OBJ) $(DEP)
```
Makefile 的函数提供了强大的文本处理和自动化能力,能够显著简化构建脚本的编写。掌握这些函数后,可以高效地管理项目构建流程,减少重复劳动。建议通过实际项目练习,加深对函数的理解和应用。