英语法语西班牙语

Ad


OnWorks 网站图标

makepp_extending - 云端在线

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

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

程序:

您的姓名


makepp_extending -- 如何使用 Perl 扩展 makepp

商品描述


Makepp 内部足够灵活,因此通过编写一点 Perl 代码,您可以
添加功能或执行许多其他操作。

总类 笔记 on 写作 Perl的 工作 制造商
每个 makefile 都位于其自己的包中。 因此,一个 makefile 中的定义不会影响
另一个 makefile 中的定义。 一组通用功能,包括所有标准
文本操作函数在创建包时被导入到包中。

Makefile 变量作为 Perl 标量存储在该包中。 (也有例外情况
this:自动变量和CC这样的变量的默认值实际上是
作为不带参数的函数实现。 目标特定变量、命令行变量和
环境变量不会以这种方式出现。)因此,您编写的任何 Perl 代码都可以访问所有
生成文件变量。 全局变量存储在“Mpp::global”包中。 看
Makefile 变量的详细信息。

每个语句(ifperl / ifmakeperl、perl / makeperl、sub / makesub),
函数(perl / makeperl、map / makemap)和规则操作(perl / makeperl)
直接在 makefile 中编写 Perl 代码有两种方式。 第一个绝对是
普通 Perl,这意味着您必须使用“f_”前缀,如下一节所述,如果
你想调用 makepp 函数。 第二种变体首先将语句传递给
Make 风格的变量扩展,这意味着您必须将希望 Perl 看到的“$”加倍。

结束处理很特殊,因为 makepp 的数据量很大(取决于您的构建系统)
正常退出时,结构将需要几秒钟的时间来进行垃圾收集。 所以我们做了一个
暴力退出。 在主进程中,您仍然可以有“END”块,但如果您有任何
全局文件句柄它们可能不会被刷新。 但你应该使用现代词汇
文件句柄,超出范围时会正确关闭。

在 Perl 代码中直接作为规则操作运行或通过您定义的命令运行,它是
对面的。 “END”块不会运行,但全局文件句柄会为您刷新。 这
全局对象的“DESTROY”永远不会运行。

添加 文字的 功能
您可以通过简单地定义一个 Perl 子例程来向 makepp 的指令集添加一个新函数
名称相同,但带有前缀“f_”。 例如:

子 f_myfunc {
我的 $argument = &arg; # 为参数命名。
my( undef, $mkfile, $mkfile_line ) = @_; # 命名参数。

...在这里做点什么

返回$return_value;
}

XYZ := $(myfunc 我的 func 参数)

如果您的函数不带参数,则无需执行任何操作。 如果你的函数需要一个
argument,如上例所示,使用简单的访问器 &arg 来获取它。 如果你
如果需要更多参数,您需要下面描述的更复杂的访问器“args”。

这些访问器处理应传递给任何“f_”的相同三个参数
函数,即函数参数、makefile 对象和行描述符
消息。 因此,您可以在第一种情况下使用高效的 &arg 形式。

&arg 访问器会为您处理以下事项: 如果参数已经存在
扩展(例如,在“$(my$(function) arg)”中查找函数的名称,arg 是
作为字符串传递并返回。 如果论证还需要扩展,这就是
通常情况下,它是对字符串的引用。 &arg 访问器为您扩展它,
为此,它需要 makefile 对象作为其第二个参数。

如果您期望更多参数(可能数量可变),则该作业由“args”执行。
该访问器采用与 arg 相同的 3 个参数,以及其他参数:

max:参数数量(默认 2):给 ~0 (maxint) 表示无限
min:参数数量(如果 max 约为 0,则默认为 0,否则与 max 相同)
only_comma:不要在逗号周围占用空格,通常用于非文件名

最多使用扩展前存在的最大、但至少最少的逗号来分割
论据。 makepp 内置函数的一些示例:

my( $prefix, $text ) = 参数 $_[0], $_[1], $_[2], 2, 2, 1; # 添加前缀
对于我的 $cond ( args $_[0], undef, $_[2], ~0 ) ... # 和、或
我的 @args= 参数 $_[0], $_[1], $_[2], ~0, 1, 1; # 称呼
my( $filters, $words ) = args $_[0], $_[1], $_[2]; # 筛选

该函数应返回一个标量字符串(而不是数组),然后将其插入到
此时的文本。

如果你的函数遇到错误,它应该使用通常的 Perl die 语句终止。
这将被 makepp 捕获并显示一条错误消息,显示文件名和行
将打印出导致错误的表达式的编号。

该函数的功能基本上没有限制; 您可以访问该文件,运行
shell命令等

目前,出现在依赖项和规则操作中的表达式已得到扩展
一次,而目标中出现的表达式会扩展两次,因此请小心,如果您的
函数有副作用并且存在于目标的表达式中。

请注意,函数计算的环境(特别是 cwd)将
不一定与 Makefile 中的规则所在的环境相匹配
函数被评估并被执行。 如果这对你来说是个问题,那么你的函数
可能应该看起来像这样:

子 f_foo {
...
chdir $makefile->{CWD};

...等
}

功能 a Perl的 模块
如果将函数放入包含文件中,则每个 Makeppfile 都会有一个副本
使用它。 为了避免这种情况,您可以将它们编写为带有“Exporter”的普通 Perl 模块
接口,并使用它。 这将加载更快并节省内存:

perl { 使用 mymodule }
珀尔{
使用我的::模块; # 将 : 放在新行上,因此通常不会解析它
}

如果您需要 Makefile 中通常可用的任何函数(例如“f_”
函数,“arg”或“args”),您必须将此行放入您的模块中:

使用 Mpp::Subs;

缺点是模块与直接函数位于不同的包中
出现在 makefile 中。 所以你需要将所有内容作为参数传入,或者构造
用 Perl 的“调用者”函数命名。

调用 外部 Perl的 脚本
如果您通过“系统”调用外部 Perl 脚本,或者作为规则操作,makepp 将分叉一个
新进程(除非它是最后一个规则操作)并启动一个全新的 Perl 解释器。
这没有什么问题,只是有一个更有效的方法:

&命令 争论...
这可以是规则操作。 它会调用一个函数 命令 带有“c_”前缀,并且
传递剩余的内容(可选地引用 makepp 样式——与
外壳)参数。 如果找不到这样的函数,则会将所有字符串传递给
“跑步”。

sub c_mycmd { 我的@args = @_; ... }

$(假callcmd):
&mycmd 'arg with space' arg2 "arg3" # 调用 c_mycmd

%.输出:%.输入
&myscript -o $(output) $(input) # 调用外部 myscript

您可以在内置框架内编写命令,从而允许您使用
它们具有相同的标准选项以及它们提供的 I/O 处理。

块运算符“Mpp::Cmds::frame”后跟一个单字母选项列表
内置函数(最大为“qw(fi I o O rs)”)。 即使您指定自己的选项
覆盖其中之一,您仍然给出标准选项的单个字母。

每个自己的选项都指定为“[qw(n name), \$参考, 参数, 子]”。 前两个
元素是短名称和长名称,后跟变量引用,并且可以选择
是否接受参数的布尔值。 如果没有 arg,变量是
每次给出选项时都会递增,否则选项值将存储在其中。

sub c_my_ocmd { # 典型输出情况
本地@ARGV = @_;
Mpp::Cmds::frame {

...用 @ARGV 在这里打印一些内容,选项已经自动删除

} 'f', qw(o O);
}

sub c_my_icmd { # 有 2 个选项的典型输入情况
本地@ARGV = @_;
我的($短,$长);
Mpp::Cmds::frame {

...在这里用 <> 做一些事情

} qw(i I rs), # s 仅指定 --separator,而不指定 -s
[qw(s Short), \$short], # 无选项 arg -> $short == 1
[qw(l long), \$long, 1, sub { warn "got arg $long"}];
}

这是一个简单的命令,仅将每个输入的第一个字符大写
记录(相当于“&sed '$$_ = "\u\L$$_"'”):

子 c_uc {
本地@ARGV = @_;
Mpp::Cmds::frame {
打印“\u\L$_”而<>;
} 'f', qw(i I o O rs);
}

在框架处理的块中,您可以嵌套块来执行关键操作
操作,例如打开其他文件。

Mpp::Cmds::执行 { ... } '消息';

这将输出带有“--verbose”的消息(每个命令都接受)当且仅当
命令成功运行。 但如果该块评估为假,它就会死亡
否定的消息。

运行 脚本 争论...
这是一个普通的 Perl 函数,您可以在 makefile 中的任何 Perl 上下文中使用。
它类似于 system 的多参数形式,但它在内部运行 Perl 脚本
当前进程。 对于 makepp 语句,perl 函数或您自己的函数
这是运行 makepp 的进程。 但对于子流程执行的规则
它。 脚本被解析的次数与调用的次数一样多,但是您可以将真实的
工作到一个库中,就像 pod2html 一样。 然后这个库可以在顶层使用,所以
它已经存在:

perl { use mylib } # 分叉到所有不需要重新解析的规则

%.输出:%.输入
makeperl { 运行 qw'myscript -o $(输出) $(输入)' }

如果脚本调用“exit”,关闭标准文件描述符或依赖于系统
之后进行清理(打开文件、内存...),这可能是“运行”的问题。 如果
如果您在语句或 Perl 函数中调用“run”,makepp 可能会受到干扰,或者
清理仅发生在 makepp 结束时。

如果您遇到上述问题之一,请在外部运行脚本,即从
而是使用命令行。 在规则内清理不成问题,尤其是
作为规则的最后一个操作,因为规则子进程无论如何都会退出,
除了 Windows 上。

写作 选择您 签名 方法
有时您希望 makepp 使用不同的技术来计算签名方法。 为了
例如,假设您有一个依赖于共享库的二进制文件。 通常,如果你
更改共享库,您不必重新链接依赖于它的可执行文件,因为
链接是在运行时完成的。 (但是,重新链接可执行文件是可能的
可能是必要的,这就是为什么我没有将其设为默认值。)你想要什么 makepp
要做的就是共享库具有相同的签名,即使它发生了变化。

这可以通过多种方式来完成。 最简单的方法是创建自己的新
签名方法(我们称之为“shared_object”)。 您将使用此签名方法
仅适用于链接二进制文件的规则,如下所示:

我的程序:*.o lib1/lib1.so lib2/lib2.so
: 签名共享对象
$(CC) $(输入) -o $(输出)

现在我们必须创建签名方法。

所有签名方法必须是自己的类,并且类中必须包含一些特殊的
项(有关详细信息,请参阅发行版中的 Mpp/Signature.pm)。 班级名称必须是
前缀为“Mpp::Signature::”,所以在这种情况下我们的类应该被调用
“Mpp::签名::共享对象”。 我们必须创建一个名为 共享对象.pm 并把
它变成一个 Mpp::签名 Perl 包含路径中某处的目录; 最容易的地方
可能在 Mpp/签名 makepp 安装中的目录(例如,
/usr/local/share/makepp/Mpp/Signature 或您安装它的任何地方)。

有关本课程中必须进行的内容的准确详细信息,您应该仔细查看
文件 Mpp/签名.pm 而且可能也是 Mpp/Signature/exact_match.pm 在 makepp 中
分配。 但在我们的例子中,我们想做的就是对
现有的签名机制; 如果文件是共享库,我们想要一个常量
签名,而如果文件是其他任何内容,我们希望依赖 makepp 的正常
签名机制。 最好的方法是继承
“Mpp::Signature::c_compilation_md5”,这是通常选择的签名方法
当 makepp 识别出链接命令时。

所以文件 Mpp/签名/shared_object.pm 可能包含以下内容:

用严格;
包 Mpp::Signature::shared_object;
使用 Mpp::Signature::c_compilation_md5;
我们的@ISA = qw(Mpp::Signature::c_compilation_md5); # 表示继承。
我们的 $shared_object = 祝福 \@ISA; # 帮助 makepp 找到的魔法
# 该方法的子例程。 全部
# 签名方法必须具有其中之一。
# 该值未被使用,只是任何对象。
# 现在这是当我们需要签名时调用的方法
# 此签名方法处于活动状态的任何目标或依赖项:
子签名{
my ($self, # 这与 $shared_object 相同。
$finfo) = @_; # 包含所有内容的特殊结构
# makepp 知道这个文件。 看
# Mpp/File.pm 了解详细信息。

if ($finfo->{NAME} =~ /\.s[oa]$/) { # 文件名以 .so 还是 .sa 结尾?
返回 $finfo->file_exists ? '存在':'';
# 如果文件总是返回相同的签名
# 存在。 在这种情况下,签名是
# 字符串“存在”。
}

Mpp::签名::c_compilation_md5::签名;
# 如果文件不是以 .so 或 .sa 结尾,
# 委托给makepp常用的签名方法。
}

该文件作为 makepp 发行版中的示例提供,还包含一些附加内容
意见。

顺便说一句,我们为什么不将其设为默认值呢? 嗯,有时需要改变
共享库将需要重新链接您的程序。 如果您更改了
共享库定义的符号,或者它依赖于其他库的符号
因为,有时可能需要重新链接。

例如,假设共享库调用您的程序所调用的一些子例程
提供。 例如,假设您更改共享库,因此它现在调用外部
子程序“xyz()”。 除非您对链接器使用“-E”或“--export-dynamic”选项
(对于 GNU binutils;其他链接器有不同的选项名称),符号“xyz()”可能不
即使它存在于您的程序中,也可供运行时链接器访问。

更糟糕的是,假设您在另一个库中定义了“xyz()”(称之为 库xyz), 像这样:

my_program: main.o lib1/lib1.so xyz/libxyz.a

由于“libxyz”是 .a 文件而不是 。所以 文件,那么“xyz()”可能不会被拉入
正确地从 libxyz.a 除非你重新链接你的二进制文件。

Mpp::Signature 方法不仅控制用于确定是否存在的字符串
文件已更改,但用于比较字符串的算法已更改。 例如,
makepp 发行版中的签名方法“target_newer”仅要求
目标比依赖项更新,而签名方法“exact_match”(和
依赖于它的所有内容,例如“md5”和“c_compilation_md5”)都要求
文件具有与上次构建相同的签名。

以下是一些可能有用的其他类型的签名方法,可以帮助您实现
的可能性。 如果通用目的足够,其中一些最终可能会被
合并到 makepp 中:

· 共享库的签名方法,返回所有导出的校验和
符号,以及其他库中需要的所有符号。 这解决了
上面的例子有问题,并保证在所有情况下都有正确的链接。
在 makepp 发行版中已经进行了一次实验性尝试来做到这一点(请参阅
Mpp/签名/shared_object.pm),但它只适用于 GNU binutils 和 ELF
目前的图书馆。

· 忽略写入文件的日期戳的签名方法。 例如,如果你
产生一个 .c 使用某些坚持输入字符串的程序自动文件
像这样:

static char * date_stamp = "无人于 01 年 2004 月 XNUMX 日自动生成";

您可以编写一个专门忽略日期戳更改的签名方法。
因此,如果日期戳是唯一发生更改的内容,makepp 将不会重建。

· 一种签名方法,以正常方式计算签名,但忽略
决定是否重建时的体系结构依赖性。 这可能有用
真正独立于体系结构的文件; 目前,如果您构建在一种架构上,
当您切换时,makepp 将坚持重建甚至与体系结构无关的文件
到不同的架构。

· 一种知道如何忽略乳胶文件中注释的签名方法,如
“c_compilation_md5”方法知道如何忽略 C 文件中的注释。

· 一种用于自动文档提取的签名方法,仅对
注释文档提取器需要并忽略对源的其他更改
文件中。

未完成
该文档尚未完成。 它应该涵盖如何编写自己的扫描仪
包括文件和类似的东西。

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


免费服务器和工作站

下载 Windows 和 Linux 应用程序

  • 1
    括号
    括号
    Brackets 是一个免费的现代开源软件
    专为 Web 打造的文本编辑器
    发展。 用 HTML、CSS 和
    带有专注可视化工具的 JavaScript 和
    准备...
    下载支架
  • 2
    免费的pascal编译器
    免费的pascal编译器
    一个 32/64/16 位 Pascal 编译器,用于
    Win32/64/CE、Linux、Mac OS X/iOS、
    Android、FreeBSD、OS/2、Game Boy
    Advance、任天堂 NDS 和 DOS;
    语义兼容...
    下载免费的 Pascal 编译器
  • 3
    佳能 EOS 数码信息
    佳能 EOS 数码信息
    佳能没有快门计数
    包含在一个的EXIF信息中
    图像文件,而不是尼康和
    宾得。 没有基于佳能的官方
    应用 ...
    下载佳能 EOS 数码信息
  • 4
    EFInd
    EFInd
    rEFInd 是 rEFIt 引导的一个分支
    经理。 像 rEFIt 一样,rEFInd 可以
    自动检测您安装的 EFI 启动
    loaders,它提供了一个漂亮的 GUI
    启动选项菜单...
    下载 rEFInd
  • 5
    快递卢克GSI
    快递卢克GSI
    这个 SourceForge 下载页面是为了
    授权用户下载我构建的源代码
    GSI,基于 phhusson 的伟大
    工作。 我构建了 Android Pie 和
    安卓 1...
    下载 ExpressLuke GSI
  • 6
    音乐播音员
    音乐播音员
    Music Caster 是一个托盘音乐播放器
    可以让您将本地音乐投射到
    Google Cast 设备。 在第一次运行时,
    你需要点击你的箭头
    塔...
    下载音乐播音员
  • 更多 ”

Linux 命令

Ad