英语法语西班牙语

Ad


OnWorks 网站图标

makepp_functions - 云端在线

通过 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器在 OnWorks 免费托管服务提供商中运行 makepp_functions

这是命令 makepp_functions,可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器

程序:

您的姓名


makepp_functions -- makepp 中的函数

商品描述


A: 绝对文件名,
绝对文件名_无链接,
断然,
添加前缀,
添加后缀,
和, B: 基名, C: 呼叫, D: 是,
dir_noslash, E: 错误, F: 文件subst,
过滤,
过滤掉,
filter_out_dirs,
查找文件,
find_first_upwards,
查找程序,
查找字符串,
find_upwards,
第一个可用,
第一个字,
foreach, I: 如果,
如果是真的,
推断链接器,
推断对象,
信息, J: 加入, M: 制作,
制作地图,
制造商,
地图,
"mktemp", N: 不目录, O: 只有_生成,
only_nontargets,
only_phony_targets,
only_stale,
only_targets,
或,
起源, P: patsubst,
珀尔,
假,
预建,
打印, R: 真实路径,
相对文件名,
关系到, S: 贝壳,
分类,
跳闸,
副,
后缀, T: 暂时的, W: 警告,
通配符,
字,
词汇表,
话, X: 参数

任何格式为“$(name)”的表达式,其中“name”不是变量的名称,或
“$(name arg1 arg2 arg3)”被解释为函数调用。 名称可能包含字母,
下划线或连字符; 为避免混淆,您可以使用连字符或下划线
可以互换,因为内部连字符转换为下划线。 评估这样的
表达式只是调用 Perl 子例程。 如果“name”前面有“&”,它运行
makepp 进程中该名称的内置命令或脚本,并返回标准
输出。 这需要为 PerlIO 构建 perl。 如果名称未命名函数
它被转换为调用调用。

与变量一样,您可以选择“$(name ...)”或“${name ...}”。 如果你想
嵌入同一个括号,必须成对,其他无所谓:"$(name
...(){..." 或 "${name ...{}(...}"。(但是对于 map 和 perl,第一个结束括号结束
表达式。)加倍允许参数跨越多行。 换行符是
然后将其视为空格,但可能在“定义”中除外。 还有语法“$[name ...]”
或 $[[name ...]],它在阅读 makefile 时被评估,在探索规则之前
和其他构造。

Makepp 有许多可能有用的内置函数。 它支持几乎所有
GNU make 的文本函数(详见 GNU make 的文档),以及它的一些
自己的。 你可以定义 Perl 子程序来做任何你喜欢的事情。 见“子”声明
以及有关扩展 makepp 的部分以获取更多详细信息。

条件 主要工作内容
条件 1[,条件 2[,条件 3...]]
and 函数提供“短路”AND 运算。 每个参数是
展开,有序。 如果参数扩展为空字符串,则处理停止并
扩展的结果是空字符串。 如果所有参数都扩展为非
空字符串则扩展的结果是最后一个参数的扩展。

if 细绳, 结果-如果-字符串-非空[, 结果-如果-字符串-空白]
如果是真的 细绳, 结果-如果-字符串-真[, 结果-如果-字符串-假]
“ifeq”等语句的替代。 如果字符串不为空(即
条件为真),则返回第二个参数(“then”子句)(在
变量扩展); 如果字符串为空,则第三个参数(“else”子句)是
回。

例如,

CFLAGS := $(if $(过滤 gcc egcc, $(CC)), -g -Wall, -g)

如果变量 CC 是“gcc”或“egcc”,并且“-g”,则将 CFLAGS 定义为“-g -Wall”
除此以外。 (这是默认构建规则所做的。)

"iftrue" 与 "if" 类似,只是字符串 0 被视为空白。

or 条件 1[,条件 2[,条件 3...]]
or 函数提供“短路”或操作。 每个参数都被扩展,
为了。 如果参数扩展为非空字符串,则处理停止并且
扩展的结果是那个字符串。 如果在所有参数都展开后,所有的
它们是假的(空),那么展开的结果就是空字符串。

文件 文件名 主要工作内容
绝对文件名
绝对的
将相对文件名转换为绝对文件名而不 . or ..。 例如,
“$(absolute_filename xyz.c)”可能会返回“/usr/src/our_project/subdir/xyz.c”。

绝对文件名_nolink
实路径
与 absolute_filename 类似,但可确保解析符号链接。

基本名 档名
basename 是整个文件名(包含目录),减去和之后的文本
包括上一期。 例如,“$(basename myfile/version-1.0-module.c)”是
“myfile/version-1.0-module”

DIR 档名
提取文件名列表中每个文件的目录部分,包括尾随
削减。 如果文件名中没有目录,则返回“./”。

目录_noslash 文件名
与 "$(dir )" 相同,只是它不返回尾部斜杠。

文件subst 图案, 代替,
对文件名执行模式替换。 这与 patsubst 的不同之处在于
当给出目录的备用名称时,它将正确执行(只要
它们在百分号之前)。 例如,

$(filesubst ./src/%.c, %.o, $(通配符 src/*.c))

将与 filesubst 一起使用,但不能与 patsubst 一起使用。

过滤器输出目录 档名
返回所有不引用目录的文件名。

查找文件 文档名称,
在指定路径中查找文件,如果没有,则在环境变量 PATH 中查找
指定的。 这对于查找二进制文件或包含文件很有用。 例如,

TCL_INCLUDE := -I$(dir_noslash $(findfile tcl.h, \
/usr/local/stow/tcl-8.4.5-nothread/包括\
/usr/include/tcl8.4 /usr/include/tcl \
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))

这将定位文件 文件 通过搜索上述所有目录。 绝对的
返回文件的路径。 然后“$(dir_noslash)”提取该目录,它
被放入包含路径。

查找程序 姓名
返回列表中可以在 PATH 中找到的第一个程序。 这很有用
当有多个等效的程序可以使用,而您只想
选择其中之一。 比如这里是几个常用的默认定义
如果你没有在你的 makefile 中放置一个 makepp 提供的变量:

CC = $(find_program gcc egcc pgcc c89 cc) # 和更多,取决于机器
F77 = $(查找程序 f77 g77 fort77)
CXX = $(find_program g++ c++ pg++ cxx CC aCC)

如果没有找到任何程序,"$(find_program)" 返回未找到的字符串,并且
记录未找到的内容。 这通常不会产生一个功能性的 makefile,但是它
将倾向于产生更好的错误消息。 例如,如果你做类似的事情
这个:

%.o : %.c
$(CC) $(输入) -o $(输出)

并且 makepp 在上面的列表中找不到 C 编译器,它会替换为 not-found。
否则,shell 将尝试执行源文件和由此产生的错误
消息可能真的很奇怪。

向上查找 文件名
在目录 ., .., .. 中搜索给定名称的文件/ ..,../../..等,
直到找到文件或到达根目录或找到目录
在不同的文件系统上。 (最后一个要求是为了防止出现问题
自动挂载程序或挂起的网络文件系统。)如果您有 根Makepp文件,这也是
阻止搜索更高的障碍。

例如,如果您有一个包含多级子目录的项目,您可以
在所有的 makefile 中包含这个公共片段(例如,通过使用“include”
陈述):

TOP_LEVEL_INCLUDE_DIR := $(find_upwards 包括)
# 搜索包含该目录的目录
# 包含子目录。

%.o : %.c
$(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(输入) -o $(输出)

“find_upwards”可以帮助解决的另一个问题是定位顶级目录
的一个构建。 像这样定义变量通常很有用:

顶部 := ../../..

如果您有一些仅位于顶级目录中的重要信息。 但
这很难维护,因为不同级别的“..”数量不同
的目录树。 相反,您可以使用“find_upwards”来定位一个文件
已知仅存在于顶级目录中。 例如,假设
文件“LICENSE”仅位于顶级目录中。 那么你可以这样做:

顶部 := $(dir_noslash $(find_upwards LICENSE))

"$(find_upwards LICENSE)" 返回许可证文件的完整路径;
"$(dir_noslash ...)" 去掉文件名,只返回目录。

(注意“include”语句会自动向上搜索文件,所以有
没有必要做这样的事情:

包括 $(find_upwards top_level_rules.mk)

相反,你可以做

包括 top_level_rules.mk

它也能正常工作。)

如果未找到该文件,“find_upwards”将中止构建并显示错误消息。

如果指定多个文件, find_upwards 将搜索第一个,然后
第二个,以此类推。 换句话说,

$(find_upwards 文件 1 文件 2)

相当于

$(find_upwards 文件1) $(find_upwards 文件2)

如果要查找任何一个文件,请改用“find_first_upwards”。

向上查找 file1 file2 ...
此函数的行为类似于“find_upwards”,除了它返回任何
它找到的列表中的文件。 具体来说,它检查当前目录
列表中的任何文件,并返回第一个存在或可以构建的文件。
如果没有文件存在或可以在该目录中构建,它会检查 .., 然后
../ ..等,直到它到达根目录或目录
位于不同的文件系统上。

第一个可用 file1 file2 ...
返回列表中存在或可以构建的第一个文件。 这对
调整您的 makefile 以在多个不同的机器或网络上工作,其中
重要的文件可能位于不同的地方。 例如,这里有一行来自
我的生成文件之一:

TCL_LIB = $(第一个可用\
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so \
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so \
/net/na1/tcl8.4a3/lib/libtcl8.4.a \
/net/na1/tcl8.4a3/lib/libtcl8.4.sl)

此行将在上述所有位置检查 Tcl 库,并在
它找到的第一个。 链接命令然后包含 $(TCL_LIB) 所以我们得到
适当的 Tcl 库。

推断链接器 file1 file2 ...
给定一个目标文件列表,如果它们还没有,首先构建它们。 然后找到
它们是否依赖于 Fortran、C++ 或 C 源并返回相应的
编译器(它比“ld”更知道如何链接)。

推断对象 file1 file2 ..., 模式
$(infer_objects object1.o object2.o, *.o)

如果您使用有关头文件名的标准约定,makepp 能够
猜测哪些“.o”或“.lo”文件需要与您的程序链接。 我用这个
从包含许多不同模块中使用的模块的库目录中挑选文件
程式。 而不是制作库“.a”文件并让链接器挑选出
相关模块,makepp可以为你挑选相关模块。 这样,只
相关模块被编译。

Makepp 用于推断对象依赖关系的算法取决于约定
头文件“xyz.h”中定义的所有类或函数的实现是
编译成一个名为“xyz.o”(或“xyz.lo”)的目标文件。 所以makepp的算法
推断对象依赖关系从一个或几个我们知道必须是的对象开始
链接到程序中。 它查看哪些文件包含在“#include”中
这些源,并尝试为每个包含的对象找到相应的目标文件
文件。

"$(infer_objects)" 需要在程序的依赖列表中提及,例如
这个:

myprog: $(infer_objects main.o another_object.o, \
**/*.o /other/library/dirs/**/*.o)
$(CXX) $(输入) -o $(输出) $(LIBS)

“$(infer_objects)”函数接受两个参数(用逗号分隔,如图所示)。
第一个是已知需要的一个或几个目标文件(通配符是
此处允许)。 第二个是可能的对象列表(通常你会使用
此处的通配符)可以在必要时链接。 从这个返回值
函数是一个列表,首先包含第一个参数中的所有对象,并且
然后在这些之后,包含在第二个参数中的所有其他对象
第一个参数中的对象所需要的。

例如,假设“main.o”来自“main.cpp”,其中包括“my_class.h”。
“$(infer_objects)”查找名称为“my_class.o”的文件。 如果恰好是这样的
找到文件,将其添加到列表中。 (如果找到两个目标文件“my_class.o”
在不同的目录中,会打印一条警告消息。)“infer_objects”也
检查“my_class.cpp”以查看它包含的内容以及附加的目标文件
默示。

临时表
临时表 字首
临时表 字首XXX
温度 /
返回当前不存在的不可预测的临时文件名。 无名
指向同一个文件会返回两次,即使相对路径不同,
在一次 makepp 运行中(除了可能使用传统的递归 make,或者如果 Perl
在规则操作中运行的代码调用“f_mktemp”)。 在 makepp 结束时运行所有
此函数返回的文件将被删除,如果它们存在(同样除了那些
此函数在规则内运行的 Perl 代码中返回)。

参数末尾的任意数量的大写“X”被替换成那么多
随机字母和数字。 越多,碰撞的可能性就越小
与其他进程,所以如果你给一个前缀像“/tmp/abc。”,你应该够了
“X”。 如果有多个 X,则第一个字符来自进程 ID。 如果
没有,好像有十个,据说足够了 (8.4e17
可能性或 Windows 上的 3.7e15)。 如果没有参数,前缀默认为
"时间。" 在当前目录中。

请注意,您不想将这样的名称命名为规则目标和依赖项。 这
结果是正确的,但每次运行 makepp 时都会重新创建它。

此外,由于它总是不同的,因此只有在使用时才应该在规则操作中使用它
":build_check ignore_action":

TMPFILE ;= $(mktemp) # 1 次调用; “=”表示 3 个调用:3 个文件
A 计数 B 计数::build_check ignore_action
生产和 Bs >$(TMPFILE)
&grep -c /A/ $(TMPFILE) -o A-count
&grep -c /B/ $(TMPFILE) -o B-count

或者您应该导出它并让 Shell 评估它:

导出 TMPFILE ;= $(mktemp)
A 计数 B 计数:
generate-As-and-Bs >$$TMPFILE # makepp 没有看到 var 值
fgrep -c A $$TMPFILE >A-count
fgrep -c B $$TMPFILE >B-count

最后一种形式重复之前的返回值,因此您可以在模式规则中使用它:

%.x: %.y
&grep foo $(input) -o $(mktemp)
&sed bar $(mktemp /) -o $(output) # 对&grep的输出进行操作

不目录 档名
返回文件名的非目录部分,即最后一个之后的所有内容
如果有斜杠,则为斜杠,否则为整个文件名。

仅生成 档名
仅返回列表中由 makepp 生成的文件名,而不是从
修改,根据构建信息文件。

这个函数在干净的目标规则中很有用(当然“makeppclean”是
首选变体):

$(虚假清洁):
&rm -f $(only_generated **/*)

仅_非目标 档名
只返回列表中那些不是任何规则目标的文件名(或者
显式或模式规则)。 您可以指定通配符(请参阅“$(wildcard)”
有关 makepp 通配符的更多详细信息,请参阅函数)。 这可用于生成
分配目标,例如:

.PHONY:分发

分配:
&mkdir our_product-$(VERSION)
&cp $(filter-out %~, $(only_nontargets *)) our_product-$(VERSION)
tar cf - our_product-$(VERSION) | gzip -9c > our_product-$(VERSION).tar.gz

在这种情况下,“$(only_nontargets *)”返回当前目录中的每个文件
这不是某些规则的目标。 “$(filter_out %~, ...)”删除编辑器
备份。

与“only_targets”(见上文)类似,“only_nontargets”只知道那些
已经被定义了。 如果你用它来定义变量,这只是一个问题
使用“:=”赋值; 如果您在依赖项列表或主体中使用它
规则,所有其他规则都已经看到了。

仅陈旧 档名
仅返回列表中由 makepp 生成的文件名,而不是从
根据构建信息文件进行了修改,但不再是任何规则的目标。

此功能可用于确保对此类文件没有依赖关系,
不强制所有目标的干净构建:

$(虚假同花顺):
&rm -f $(only_stale **/*)

实际上,最好编写一个调用 makepp 生成的脚本
陈旧文件列表,然后让该脚本删除所有列出的文件
当前不受源代码控制,以防万一生成的文件成为源
文件。 Makepp 没有内置这样的功能,因为 makepp 是(并且可能
应该保持)对源代码控制不可知。

只有_targets 档名
仅返回列表中实际上是某个规则目标的那些文件名
(显式或模式规则)。 您可以指定通配符(包括 makepp 的
特殊通配符,“**”)在文件名中。 (有关更多信息,请参阅“$(wildcard)”函数
细节。 这可以用于干净的目标,例如:

.PHONY:干净

清洁:
&rm -f $(only_targets *)

现在,如果您键入“makepp clean”,它将删除它知道如何构建的所有内容。 但
不要创建干净的目标,而是使用“makeppclean”!

另一个可能有用的地方是避免包含陈旧的 .o 你的文件
建造。 例如,如果您构建这样的库:

mylib.a: *.o
&rm -f $(输出)
$(AR) cr $(输出) $(输入)

然后你删除了一些源文件但忘记删除相应的 .o 文件,
.o 文件仍然存在。 这意味着它们仍将被纳入
图书馆,尽管它们不再有用。 如果你修改你的
像这样的规则:

mylib.a: $(only_targets *.o)
&rm -f $(输出)
$(AR) cr $(输出) $(输入)

那么这个问题就不会发生了。

请注意,这仅指已知为目标的文件 at
调用 “唯一目标”。 如果“only_targets”出现在依赖项或操作中
规则,那么所有可能的目标都将是已知的,因为依赖项和操作不是
评估直到规则被执行。 但是,如果您评估尝试评估它
之前在 makefile 中使用“:=”变量,如下所示:

ALL_TARGETS := $(only_targets *)

目标 1:依赖项 1
行动

目标 2:依赖项 2
行动

那么“only_targets”将不知道后续规则。

类似地,“only_targets”不知道在生成文件中生成的目标是
加载了递归make。 (但无论如何你都不应该使用递归make;使用
使用“load_makefile”语句,或使用隐式生成文件加载代替。)

相对文件名 file1 file2 文件 3[, 削减]
返回这些文件相对于当前目录的名称(
生成文件在)。 这也可以用来清除不必要的“./”和其他垃圾
路径:

目录:=。
子目录:= ..
FNAME := $(DIR)/../otherdir/$(SUBDIR)/文件
X := $(相对文件名 $(FNAME))

If 削减 为真(通常为 1)返回的文件名保证包含斜杠
如有必要,在前面加上“./”,这样您就可以将其用作可执行文件名,而无需
担心命令搜索路径会覆盖目录位置。

如果路径经过根目录,则是您的主目录或
构建系统的“$(ROOT)”,或在 Windows 上的驱动器根目录(取决于
环境,这也发生在 /cygdrive/c or /c),绝对路径将是
而是返回。

关系到 file1 file2 文件 3[, 目录]
返回这些文件相对于指定目录的名称。 这是
无论出于何种原因,您必须从
不同的目录(默认当前目录):

source_backup.tar:
cd .. && tar cf $(relative_to $(output), ..) $(relative_to ., ..)

后缀 名字...
提取名称中每个文件名的后缀。 如果文件名包含句点,
后缀是从最后一个句点开始的所有内容。 否则,后缀是
空字符串。 这通常意味着当名称不是时结果将为空,
如果 names 包含多个文件名,则结果可能包含更少的文件名。

例如,

$(后缀src/foo.c src-1.0/bar.c hacks)

产生结果“.c .c”。

临时
让 makepp 知道指定的目标可能会被生成的规则删除
他们。 类似于“虚假”,除了 makepp 期望该名称的真实文件
will 可能会受到规则的影响。 如果只是临时规则,则不会执行规则
目标已过时。

通配符 模式
返回与存在的给定模式匹配的所有文件的排序名称,或那些
尚不存在但可以根据 makepp 知道的规则构建的文件
大约在它评估表达式的时候。 在最后一点,它有所不同
来自规则输入通配符,这些通配符甚至适用于由稍后发现的规则创建的文件。

Makepp 支持所有常用的 shell 通配符(“*”、“?”和“[]”)。 它还有一个
通配符“**”匹配任意数量的中间目录。 (这个想法是
从 zsh 窃取。)例如,“**/*.c”匹配所有 .c 整个源中的文件
树。 "objects/**/*.o" 匹配所有 .o 包含在任何位置的文件
子目录 对象 或其任何子目录或其任何子目录。 这
“**”通配符不会跟随软链接到任何级别的目录,也不会
尝试输入存在但无法读取的目录。 还有文件和
“$(wildcard)”不会返回存在但无法读取的目录。

主要工作内容
添加前缀 字首,
为每个单词添加前缀字符串。 这主要是针对 GNU make
兼容性; 使用 rc-style 扩展,这可以以更具可读性的方式完成
喜欢这个:

模块:= abcd
X_OLD_STYLE := $(addprefix $(OBJDIR)/, $(addsuffix .o, $(MODULES)))
X_NEW_STYLE := $(OBJDIR)/$(MODULES).o # 这不是更容易阅读吗?

添加后缀 后缀,
将后缀字符串附加到每个单词。 这主要是针对 GNU make
兼容性; 使用 rc-style 扩展,这可以以更具可读性的方式完成
喜欢这个:

X_OLD_STYLE := $(addsuffix .o, $(MODULES))
X_NEW_STYLE := $(MODULES).o

呼叫 多变的[, 字]...
函数“call”的独特之处在于它可以用来考虑 变量 作为一个
参数化函数您可以将复杂的表达式分配给 变量 并使用
“调用”将其内容扩展为由参数化的不同值 稍后的。 在
其他 make 系统,一个主要用于扩展目的的变量
“呼叫”,被称为 .

在宏扩展期间,临时变量 $1, $2, “......” 参考
在调用期间提供给“call”的参数。 变量 $0 将扩展到
宏的名称(即 变量) 那个“呼叫”目前正在扩大。

没有限制,宏可以“调用”多少个参数或多少个
宏可能期望的参数。 如果您将更多参数作为宏传递给“call”
需要,所有超出的参数都将被丢弃。 如果您传递的参数少于 a
宏期望,所有超出的参数都折叠为空字符串。

先举个简单的例子:

休息 = $(wordlist 2, $(words $(1)),$(1))
列表 = ABCDE
但首先:= $(呼叫休息,$(列表))

在这里,变量“$(butfirst)”将包含列表“BCDE”。

现在用一个更复杂的例子来展示什么是可能的:

休息 = $(wordlist 2,$(words $(1)),${1})
mymap = $(如果 $2,$(调用 $1,$(第一个词 $2)) $(调用 $0,$1,$(调用其余部分,$2)))
downcase = ${makeperl lc("$1")}

UCWORDS = 所有这些单词都是大写
DCWORDS := $(调用 mymap,downcase,$(UCWORDS))

现在“$(DCWORDS)”包含“所有这些单词都是大写的”。 顺便说一句:它没有
区别,我们是否通过访问参数 $1, “${1}” or “$(1)” 在一个宏中。

如果没有,您可以直接使用该变量,就好像它是一个函数一样
那个名字的功能。 这在内部转换为“呼叫”,所以这些是
当量:

讨论 = 0 美元变成了 1 美元 2 美元。
直接= $(讨论一个,参数)
调用 = $(调用讨论,一个,参数)

"$[call]" 是否也应该扩展宏的 "$[]" 似乎有争议
表达式,或者一个函数是否应该总是做同样的事情,不管它如何
叫做。 选择后者,因为使用正常的 make 语法,它将是
不可能将 "$[1], $[2]..." 放入变量中(它们会被什么都不替换,
在赋值之前。)因此,如果你有一个宏来定义一个
规则,您希望在解析规则时看到像 "$(output)" 这样的表达式,所以
你必须保护他们免受“呼叫”:

定义规则
$ 2:$ 1
mycommand $$(输入) -o $$(输出)
恩德夫
$[我的规则我的输入,我的输出]

过滤 模式
返回列表中与模式匹配的所有单词。 模式可能只是其他
单词或文件名通配符(即,“*”、“?”和“[az]”被识别),或者它们可能
有一个“%”字符,这意味着匹配该点的任何字符串(与“*”相同)。

过滤掉 模式
返回列表中与模式不匹配的所有单词。 模式可能只是
换句话说,或文件名通配符(即识别“*”、“?”和“[az]”),或
它们可能有一个“%”字符,这意味着匹配该点的任何字符串(与
“*”)。

例如:

libproduct.a: $(filter_out test_*, $(通配符 *.o))

将把所有 .o 存在或可以构建的文件,除了以 test_,
lib生产.a.

查找字符串 找, in
退货 发现, 如果它是一个子串 in.

第一个字
返回第一个单词。

地图 话, 代码
制作地图 话, 代码
类似于 Perl 的映射,适用 代码 依次返回每个单词并返回
结果。 第一个变体是普通的 Perl 代码,而第二个变体首先通过
perlcode 通过 Make 风格的变量扩展。 这两个词都扩展了
案例。

单词在 $_ 中,除非您取消定义 $_,否则将返回。 这是为了
“patsubst”不容易处理的修改。 只有第一个逗号是分隔符,
任何其他人都被视为 代码.

# 切换单词。 双括号,允许在 perlcode 中出现括号,或使用 ${}:
X = $((映射 $(VALUES), s/(.+)-(.+)/$2-$1/))
# 你可以使用 make 表达式,但是你必须使用 $$ 来表示 Perl $:
Y = $(makemap $(VALUES), tr/$(OLDCHARS)/$(NEWCHARS)/ 或 $$_ = 'failed')
# 你可以消除候选人:
Y = $(map $(VALUES), undef $_ if /no_good/)

加入 词1, 字2
对第一个单词和第二个单词进行成对连接。

模式物质 图案, 代替,
对单词列表中的每个单词执行替换。 “%”字符匹配任何
细绳。 最好通过一个例子来说明这一点:

OBJS = $(patsubst %.c, object_dir/%.o, $(C_SOURCES))

获取 C_SOURCES 中的每个文件并返回 object_dir 中的目标文件的名称。
有时使用替换引用更简洁,例如,上面可以
被写成

OBJS = $(C_SOURCES:%.c=object_dir/%.o)

分类 word1 word2 word3 ...
按词汇顺序对单词进行排序并删除重复项。

剥离 绳子
从字符串中删除前导和尾随空格并替换每个内部
一个或多个空白字符的序列,带有一个空格。 因此,“$(strip ab
c )" 结果为 "abc"。

SUBST 从,到,文本
对文本文本执行文本替换:每次出现的 from 都被替换
到。 结果被替换为函数调用。 例如,

$(subst ee,EE,街上的脚)

替换字符串“fEEt on the strEEt”。

n,文本
返回 n第一句话 文本. 合法的价值观 n 从 1 开始
或最后从 -1 向后。 如果 n 大于单词的数量 文本是,
值为空。

词汇表 索引列表,
词汇表 第一个索引, 最后一个索引,
在第一种形式中,您提供一个索引列表(从开头的 1 或
从末尾的 -1 向后)以选择您想要的单词。 在第二种形式中你
指定要返回的单词范围。

文本
返回单词的数量 文本.

其他 主要工作内容
的foreach 变量、列表、文本
前两个论点, VAR名单, 在做任何其他事情之前被扩展; 笔记
最后一个参数 text 不会同时展开。 然后对于每个单词
list 的扩展值,由 var 扩展值命名的变量设置为
那个词,文字就展开了。 大概文本包含对该变量的引用,
所以它的扩展每次都会不同。

这个简单的例子设置变量 到所有文件的列表
列表中的目录 迪尔斯:

目录:= abcd
文件 := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

这里的文字是“$(wildcard $(dir)/*)”。 第一次重复找到 dir 的值“a”,
所以它产生与“$(wildcard a/*)”相同的结果; 第二次重复产生
"$(wildcard b/*)" 的结果; 第三个是“$(wildcard c/*)”。

此示例与以下示例具有相同的结果(除了设置“dirs”):

文件 := $(通配符 a/* b/* c/* d/*)

当文本很复杂时,你可以通过给它一个名字来提高可读性,
附加变量:

find_files = $(通配符 $(dir)/*)
目录:= abcd
文件 := $(foreach 目录,$(dirs),$(find_files))

这里我们以这种方式使用变量 find_files。 我们使用普通的“=”来定义一个
递归扩展变量,使其值包含对
在foreach的控制下重新展开; 一个简单扩展的变量不会做,
因为通配符在定义 find_files 时只会被调用一次。

注意:不要将它与“$(foreach)”特殊变量混淆。

info 文本
警告 文本
错误 文本
输出文本返回空。 第一个到 STDOUT,第二个到 STDERR,
第三个额外中止处理。

预建 目标
使 目标
逐字返回其参数,但首先构建列出的所有文件。 这很有用
在评估 make 表达式时需要给定文件时。 这通常会发生
当你有一个构建,其中所涉及的文件集是由某个 shell 计算的
命令。 例如,

文件列表:
# shell 命令来计算要放入程序的文件列表

my_program : $(&cat $(prebuild file_list))

如果您需要多个规则中的列表,使用
最多扩展一次变量:

file_list ;= $(&cat $(prebuild file_list))

my_program1 : ao $(file_list)

my_program2 : bo $(file_list)

如果您只指定了“$(&cat file_list)”,则 makepp 不会强制
file_list 在执行 shell 命令之前是最新的。 使用 "$(prebuild )"
是解决这个问题的最好方法。 你可能想尝试其他的东西,比如
这个:

my_program : file_list $(&cat file_list)

但这不起作用,因为在 makepp 尝试之前评估了“$(&cat file_list)”
构建“文件列表”。

only_phony_targets 名称
仅返回列表中作为某些规则的虚假目标的名称(或者
显式或模式规则)。 您可以指定通配符(包括 makepp 的特殊
通配符,“**”)在文件名中。 (有关更多详细信息,请参阅“$(wildcard)”函数。
这可用于对目标进行分组,例如:

$(虚假测试):$(only_phony_targets */**/tests)

起源 变量
给定一个变量的名称,告诉你它的值来自哪里。

perl的 代码
编译器 代码
评估块中的 perlcode 并返回结果。 第一个变体是普通的 Perl
代码,而第二个变体首先通过 Make-style 变量传递 perlcode
扩张。

请注意,与所有函数一样,所使用的函数分隔符可能不会出现在
单引号或双引号字符串之外的 perlcode。 但是你可以把它加倍
最后一个例子:

自变量=1
VAR1 = ${perl ($VAR + 1) * 3}
VAR2 = $(perl do { $VAR *= 3; 返回 $VAR + 1 } 如果 $VAR)
VAR3 = $(makeperl $(VAR1) * 3 + $$VAR) # 一个 Make var 和一个 Perl var
VAR = $((perl if( ... ) { ... }))


表示单词列表实际上是虚假目标,并返回
目标。 它的用途是这样的:

$(虚假全部):my_program

$(虚假清洁):
&rm -f *.o my_program

您也可以在
你的生成文件:

.PHONY:全部干净

打印 文本
输出文本并返回它。 这对于调试最有用,当你不
理解为什么变量替换会产生这样的结果。 例如,

XYZ := $(打印 $(patsubst %.c, %o, $(SOURCE_FILES)))

将打印出“patsubst”调用的结果。

XYZ := $(patsubst %.c, %o, $(打印 $(SOURCE_FILES)))

将打印出“patsubst”调用的最后一个参数。

外壳命令
返回给定 shell 命令的输出,用空格替换换行符。

请注意,与所有函数一样,所使用的函数分隔符可能不会出现在
单引号或双引号字符串之外的 shell 命令。 但你可以加倍
如第二个例子:

date = $(shell date) # 更好: $(perl scalar localtime)
VAR = ${{shell f() { echo hello; }; F}}

参数 命令,参数[,后缀[,长度]]
返回一个以换行符分隔的命令列表,每个命令都以指定的开头
命令,并以列表中尽可能多的元素结尾,而无需遍历
长度 (默认 1000)个字符。

这样做的目的是避免溢出系统上的命令长度限制。
例如,如果有很多生成的文件,那么你可能想要你的
干净的目标(你不应该有,因为“makeppclean”更有效)到
看起来像这样:

$(虚假清洁):
$(xargs $(RM), $(only_targets **/*))

这也有副作用,如果列表不生成任何命令
恰好是空的。 但在这种情况下,最好使用内置的 &rm,
因为内置命令的参数仅受 Perl 内存的限制:

$(虚假清洁):
&rm -f $(only_targets **/*)

如果指定了第三个参数,则它用于后缀每个命令。 这是
用于指定重定向器,例如(尽管这里再次 &echo 会有所帮助):

显现:
&rm -f $@
&触摸$@
$(xargs echo, $(only_nontargets **/*), >> $@)

此文档中的一些基于 GNU make 文档。

请注意,如果在 makefile 初始化期间调用函数,例如
导出变量、错误或警告消息的扩展将报告行号 0。

使用 onworks.net 服务在线使用 makepp_functions


免费服务器和工作站

下载 Windows 和 Linux 应用程序

Linux 命令

Ad