内容

名称

ExtUtils::MM_Any - 平台无关的 MM 方法

概要

FOR INTERNAL USE ONLY!

package ExtUtils::MM_SomeOS;

# Temporarily, you have to subclass both.  Put MM_Any first.
require ExtUtils::MM_Any;
require ExtUtils::MM_Unix;
@ISA = qw(ExtUtils::MM_Any ExtUtils::Unix);

描述

仅供内部使用!

ExtUtils::MM_Any 是 ExtUtils::MM_* 模块集的超类。它包含一些方法,这些方法要么本质上是跨平台的,要么是以跨平台的方式编写的。

从 ExtUtils::MM_Any ExtUtils::MM_Unix 继承。这是一个临时的解决方案。

这可能是临时的!

方法

任何标记为抽象的方法都必须由子类实现。

跨平台辅助方法

这些方法有助于编写跨平台代码。

os_flavor 抽象

my @os_flavor = $mm->os_flavor;

@os_flavor 是操作系统类型,通常对应于我们正在使用的 MM_*.pm 文件。

@os_flavor 的第一个元素是主要系列(例如 Unix、Windows、VMS、OS/2 等),其余是子系列。

一些例子

Cygwin98       ('Unix',  'Cygwin', 'Cygwin9x')
Windows        ('Win32')
Win98          ('Win32', 'Win9x')
Linux          ('Unix',  'Linux')
MacOS X        ('Unix',  'Darwin', 'MacOS', 'MacOS X')
OS/2           ('OS/2')

这用于为操作系统类型编写代码。有关使用,请参阅 os_flavor_is()。

os_flavor_is

my $is_this_flavor = $mm->os_flavor_is($this_flavor);
my $is_this_flavor = $mm->os_flavor_is(@one_of_these_flavors);

检查当前操作系统是否属于给定的类型之一。

这对于像这样的代码很有用

if( $mm->os_flavor_is('Unix') ) {
    $out = `foo 2>&1`;
}
else {
    $out = `foo`;
}

can_load_xs

my $can_load_xs = $self->can_load_xs;

如果我们有能力加载 XS,则返回 true。

这很重要,因为用于在核心代码中构建 XS 模块的 miniperl 无法加载 XS。

can_run

use ExtUtils::MM;
my $runnable = MM->can_run($Config{make});

如果在标量上下文中调用,它将返回找到的二进制文件的完整路径,如果未找到,则返回 undef

如果在列表上下文中调用,它将返回在 PATH 中找到的二进制文件实例的完整路径列表,如果未找到,则返回空列表。

IPC::Cmd 复制而来,但修改为方法(并删除了 $INSTANCES 功能)。

can_redirect_error

$useredirect = MM->can_redirect_error;

如果在 qx 运算符(或反引号)可以将 STDERR 重定向到 STDOUT 的操作系统上,则为真。

is_make_type

my $is_dmake = $self->is_make_type('dmake');

如果 $self->make 是给定的类型,则返回真;可能性是

gmake    GNU make
dmake
nmake
bsdmake  BSD pmake-derived

can_dep_space

my $can_dep_space = $self->can_dep_space;

如果 make 可以处理(可能通过引用)包含空格的依赖项,则返回真。目前已知 GNU make 为真,BSD pmake 衍生版本为假。

quote_dep

$text = $mm->quote_dep($text);

保护 Makefile 单值常量(主要是文件名)的方法,以便 make 即使它们不方便地包含空格,仍然将它们视为单值。如果正在使用的 make 程序无法实现这种保护,并且给定的文本需要它,则会抛出异常。

split_command

my @cmds = $MM->split_command($cmd, @args);

大多数操作系统都有一个最大命令长度,它们可以一次执行。大型模块可以轻松地生成远远超过该限制的命令。有必要将长命令拆分为一系列较短的命令。

split_command 将返回一系列 @cmds,每个 @cmds 处理 args 的一部分。它们将共同处理所有参数。@cmds 中的每条单独行都不会超过 $self->max_exec_len,同时注意宏扩展。

$cmd 应包含任何开关和重复的初始参数。

如果没有给出 @args,则不会返回 @cmds。

参数对将始终保存在单个命令中,这是一种针对 pm_to_blib 和 pod2man 之类对参数对起作用的启发式方法。这使得以下内容安全

$self->split_command($cmd, %pod2man);

make_type

返回一个合适的字符串,描述正在编写的 Makefile 的类型。

stashmeta

my @recipelines = $MM->stashmeta($text, $file);

生成一组 @recipelines,这些 @recipelines 将导致字面量 $text 在执行配方时最终出现在字面量 $file 中。调用它一次,使用您想要在 $file 中的所有文本。Make 宏不会扩展,因此位置将在配置时固定,而不是在构建时固定。

echo

my @commands = $MM->echo($text);
my @commands = $MM->echo($text, $file);
my @commands = $MM->echo($text, $file, \%opts);

生成一组 @commands,这些 @commands 将 $text 打印到 $file。

如果没有给出 $file,则输出将转到 STDOUT。

如果 $opts{append} 为真,则 $file 将被追加而不是覆盖。默认情况下是覆盖。

如果 $opts{allow_variables} 为真,则形式为 $(...) 的 make 变量将不会被转义。其他 $ 将被转义。默认情况下是转义所有 $

使用示例

my $make = join '', map "\t$_\n", $MM->echo($text, $file);

wraplist

my $args = $mm->wraplist(@list);

将项目数组转换为格式良好的参数列表。 在大多数情况下,这仅仅是类似于

FOO \
BAR \
BAZ

maketext_filter

my $filter_make_text = $mm->maketext_filter($make_text);

在写入磁盘之前,Makefile 的文本将通过此方法运行。 它允许系统有机会对 Makefile 进行可移植性修复。

默认情况下,它什么也不做。

此方法受保护,不打算在 MakeMaker 之外调用。

cd 摘要

my $subdir_cmd = $MM->cd($subdir, @cmds);

这将生成一个 make 片段,它在给定的 $dir 中运行 @cmds。 粗略等效于此,但跨平台。

cd $subdir && $cmd

目前 $dir 只能向下移动一级。 "foo" 很好。 "foo/bar" 不行。 "../foo" 就更不行了。

生成的 $subdir_cmd 没有前导制表符或尾随换行符。 这使得它更容易嵌入到 make 字符串中。 例如。

    my $make = sprintf <<'CODE', $subdir_cmd;
foo :
    $(ECHO) what
    %s
    $(ECHO) mouche
CODE

oneliner 摘要

my $oneliner = $MM->oneliner($perl_code);
my $oneliner = $MM->oneliner($perl_code, \@switches);

这将根据给定的 $perl_code 和 @switches(假设为 -e)生成一个适合在 make 目标中使用的 perl 单行命令,该命令对您所在的特定平台安全。 它将使用正确的 shell 引号和转义符。

$(PERLRUN) 将用作 perl。

$perl_code 中的任何换行符都将被转义。 前导和尾随换行符将被剥离。 使这个习语更容易

my $code = $MM->oneliner(<<'CODE', [...switches...]);
some code here
another line here
CODE

用法可能是这样的

# an echo emulation
$oneliner = $MM->oneliner('print "Foo\n"');
$make = '$oneliner > somefile';

$perl_code 中的美元符号将使用 quote_literal 方法来保护免受 make 的影响,除非它们被识别为 make 变量 $(varname),在这种情况下,它们将保留下来供 make 展开。 请记住引用 make 宏,否则它可能会被用作裸词。 例如

# Assign the value of the $(VERSION_FROM) make macro to $vf.
$oneliner = $MM->oneliner('$vf = "$(VERSION_FROM)"');

它目前非常简单,可能会在图中扩展以包含更灵活的代码和开关。

quote_literal 摘要

my $safe_text = $MM->quote_literal($text);
my $safe_text = $MM->quote_literal($text, \%options);

这将引用 $text,以便它在 shell 中被逐字解释。

例如,在 Unix 上,这将转义 $text 中的任何单引号,并在整个内容周围加上单引号。

如果 $options{allow_variables} 为真,它将保留 '$(FOO)' make 变量不变。 如果为假,它们将像其他 $ 一样被转义。 默认值为真。

escape_dollarsigns

my $escaped_text = $MM->escape_dollarsigns($text);

转义多余的 $,以便它们不被解释为 make 变量。

它允许通过 $(...)

escape_all_dollarsigns

my $escaped_text = $MM->escape_all_dollarsigns($text);

转义所有 $,以防止它们被解释为 make 变量。

escape_newlines 摘要

my $escaped_text = $MM->escape_newlines($text);

在 $text 中转义换行符。

max_exec_len 摘要

my $max_exec_len = $MM->max_exec_len;

计算操作系统可以执行的最大命令大小。实际上,这是 shell 命令行的最大大小。

make

my $make = $MM->make;

返回我们为其生成 Makefile 的 make 变体。这尝试对来自 %Config 或用户的信息进行一些规范化。

目标

这些是生成 make 目标的方法。

all_target

生成默认目标 'all'。

blibdirs_target

my $make_frag = $mm->blibdirs_target;

创建 blibdirs 目标,该目标创建我们在 blib/ 中使用的所有目录。

blibdirs.ts 目标已弃用。依赖 blibdirs 而不是它。

clean (o)

定义 clean 目标。

clean_subdirs_target

my $make_frag = $MM->clean_subdirs_target;

返回 clean_subdirs 目标。clean 目标使用它来对包含 Makefile 的任何子目录调用 clean。

dir_target

my $make_frag = $mm->dir_target(@directories);

生成目标以创建指定的目录并将它的权限设置为 PERM_DIR。

因为依赖于目录只是为了确保它存在并不太好(修改时间变化太频繁),所以 dir_target() 在创建的目录中创建了一个 .exists 文件。你应该依赖于它。为了可移植性,你应该使用 $(DIRFILESEP) 宏而不是 '/' 来分隔目录和文件。

yourdirectory$(DIRFILESEP).exists

distdir

定义一个临时目录目标,该目标将在 tar(或 shar)之前保存分发。

dist_test

定义一个目标,该目标在临时目录中生成分发,并在该子目录中运行 'perl Makefile.PL; make ;make test'。

xs_dlsyms_arg

返回用于文件列表 dlsyms 导出到链接器的命令行参数。默认返回空字符串,可以被例如 AIX 覆盖。

xs_dlsyms_ext

返回 xs_make_dlsyms 方法的输出文件的扩展名,包括任何 "." 字符。

xs_dlsyms_extra

返回要附加到 xs_make_dlsyms$extra 参数的任何额外文本。

xs_dlsyms_iterator

迭代必要的共享对象,为每个对象调用 xs_make_dlsyms 方法,并使用适当的参数。

xs_make_dlsyms

$self->xs_make_dlsyms(
    \%attribs, # hashref from %attribs in caller
    "$self->{BASEEXT}.def", # output file for Makefile target
    'Makefile.PL', # dependency
    $self->{NAME}, # shared object's "name"
    $self->{DLBASE}, # last ::-separated part of name
    $attribs{DL_FUNCS} || $self->{DL_FUNCS} || {}, # various params
    $attribs{FUNCLIST} || $self->{FUNCLIST} || [],
    $attribs{IMPORTS} || $self->{IMPORTS} || {},
    $attribs{DL_VARS} || $self->{DL_VARS} || [],
    # optional extra param that will be added as param to Mksymlists
);

实用程序方法,返回调用 Mksymlists 的 Makefile 代码段。

dynamic (o)

定义动态目标。

makemakerdflt_target

my $make_frag = $mm->makemakerdflt_target

返回包含 makemakerdeflt_target 的 make 片段。此目标是 Makefile 中的第一个目标,是默认目标,仅在任何 make 变体出现混淆或在实际 'all' 目标之前插入任何内容时指向 'all'。

manifypods_target

my $manifypods_target = $self->manifypods_target;

生成 manifypods 目标。此目标从 MAN1PODS 和 MAN3PODS 中的所有 POD 文件生成手册页。

metafile_target

my $target = $mm->metafile_target;

生成 metafile 目标。

在 distdir 中写入关于模块的 META.yml(YAML 编码元数据)和 META.json(JSON 编码元数据)文件。格式尽可能遵循 Module::Build 的格式。

metafile_data

my $metadata_hashref = $mm->metafile_data(\%meta_add, \%meta_merge);

返回 MakeMaker 转换为 META.yml 文件和 META.json 文件的数据。它始终是格式的 2.0 版。

%meta_add 的值将覆盖这些键中任何现有的元数据。%meta_merge 将与它们合并。

metafile_file

my $meta_yml = $mm->metafile_file(@metadata_pairs);

将 @metadata_pairs 转换为 YAML。

此方法没有实现完整的 YAML 转储器,仅限于转储一个哈希,其值是字符串、undef 或嵌套的哈希和字符串数组。没有进行任何引用/转义。

distmeta_target

my $make_frag = $mm->distmeta_target;

生成 distmeta 目标,将 META.yml 和 META.json 添加到 distdir 中的 MANIFEST 中。

mymeta

my $mymeta = $mm->mymeta;

从现有的 CPAN 元数据文件 (META.json 或 META.yml) 或内部数据生成 MYMETA 信息作为哈希。

write_mymeta

$self->write_mymeta( $mymeta );

将 MYMETA 信息写入 MYMETA.json 和 MYMETA.yml。

realclean (o)

定义 realclean 目标。

realclean_subdirs_target

my $make_frag = $MM->realclean_subdirs_target;

返回 realclean_subdirs 目标。这由 realclean 目标用于对包含 Makefile 的任何子目录调用 realclean。

signature_target

my $target = $mm->signature_target;

生成签名目标。

使用 "cpansign -s" 写入文件 SIGNATURE。

distsignature_target

my $make_frag = $mm->distsignature_target;

生成 distsignature 目标,将 SIGNATURE 添加到 distdir 中的 MANIFEST。

special_targets

my $make_frag = $mm->special_targets

返回包含对 make 具有特殊意义的任何目标的 make 片段。例如,.SUFFIXES 和 .PHONY。

Init 方法

帮助初始化 MakeMaker 对象和宏的方法。

init_ABSTRACT

$mm->init_ABSTRACT

init_INST

$mm->init_INST;

由 init_main 调用。设置所有 INST_* 变量,除了与 XS 代码相关的变量。这些在 init_xs 中处理。

init_INSTALL

$mm->init_INSTALL;

由 init_main 调用。设置所有 INSTALL_* 变量(除了 INSTALLDIRS)和 *PREFIX。

init_INSTALL_from_PREFIX

$mm->init_INSTALL_from_PREFIX;

init_from_INSTALL_BASE

$mm->init_from_INSTALL_BASE

init_VERSION 抽象

$mm->init_VERSION

初始化表示 MakeMaker 和其他工具版本的宏

MAKEMAKER:MakeMaker 模块的路径。

MM_VERSION:ExtUtils::MakeMaker 版本

MM_REVISION:ExtUtils::MakeMaker 版本控制修订版(用于向后兼容)

VERSION:模块的版本

VERSION_MACRO:哪个宏表示版本(通常是 'VERSION')

VERSION_SYM:与版本类似,但可以安全地用作 RCS 修订版号

DEFINE_VERSION:-D 行,用于在编译时设置模块版本

XS_VERSION:.xs 文件中的版本。默认为 $(VERSION)

XS_VERSION_MACRO:哪个宏表示 XS 版本。

XS_DEFINE_VERSION:-D 行,用于在编译时设置 xs 版本。

由 init_main 调用。

init_tools

$MM->init_tools();

初始化 tools_other() 使用的简单宏定义,并将它们放置在 $MM 对象中。这些使用保守的跨平台版本,应使用特定于平台的版本来覆盖以提高性能。

至少定义以下宏。

Macro             Description

NOOP              Do nothing
NOECHO            Tell make not to display the command itself

SHELL             Program used to run shell commands

ECHO              Print text adding a newline on the end
RM_F              Remove a file
RM_RF             Remove a directory
TOUCH             Update a file's timestamp
TEST_F            Test for a file's existence
TEST_S            Test the size of a file
CP                Copy a file
CP_NONEMPTY       Copy a file if it is not empty
MV                Move a file
CHMOD             Change permissions on a file
FALSE             Exit with non-zero
TRUE              Exit with zero

UMASK_NULL        Nullify umask
DEV_NULL          Suppress all command output

init_others

$MM->init_others();

初始化与工具_other()使用的编译和链接相关的宏定义,并将它们放置在$MM对象中。

如果没有描述,则与ExtUtils::MakeMaker中记录的WriteMakefile()的参数相同。

tools_other

my $make_frag = $MM->tools_other;

返回一个包含init_others()初始化的宏定义的make片段。

init_DIRFILESEP 摘要

$MM->init_DIRFILESEP;
my $dirfilesep = $MM->{DIRFILESEP};

初始化DIRFILESEP宏,它是文件路径中目录和文件名之间的分隔符。例如,在Unix上为/,在Win32上为\,在VMS上为空。

例如

# instead of $(INST_ARCHAUTODIR)/extralibs.ld
$(INST_ARCHAUTODIR)$(DIRFILESEP)extralibs.ld

这有点像黑客,但它避免了MM_*变体之间的大量代码重复。

不要将此用作目录之间的分隔符。一些操作系统在子目录之间使用不同的分隔符,以及在目录和文件名之间(例如:VMS上的VOLUME:[dir1.dir2]file)。

init_linker 摘要

$mm->init_linker;

初始化与链接相关的宏。

PERL_ARCHIVE: 与动态扩展链接的libperl.a等效路径。

PERL_ARCHIVE_AFTER: 与动态扩展链接的外部库之后应放在链接器命令行上的库路径。如果链接器是一次性链接器,并且Perl包含一些对C RTL函数的覆盖,例如malloc(),则可能需要这样做。

EXPORT_LIST: 传递给链接器以定义要导出的符号的文件名。

某些操作系统不需要这些,在这种情况下将其留空。

init_platform

$mm->init_platform

初始化任何仅供平台特定使用的宏。

一个典型的例子是您特定于操作系统的模块的版本号。(例如,MM_Unix_VERSION或MM_VMS_VERSION)。

init_MAKE

$mm->init_MAKE

从MAKE环境变量或$Config{make}初始化MAKE。

工具

一个用于生成特定宏和命令的方法集合。

manifypods

定义目标和例程,将pod转换为手册页并将它们放入INST_*目录。

POD2MAN_macro

my $pod2man_macro = $self->POD2MAN_macro

返回POD2MAN宏的定义。这是一个模拟pod2man实用程序的程序。您可以通过简单地在宏上追加来添加更多开关到命令。

典型用法

$(POD2MAN) --section=3 --perm_rw=$(PERM_RW) podfile1 man_page1 ...

test_via_harness

my $command = $mm->test_via_harness($perl, $tests);

返回一个 $command 行,该行使用 Test::Harness 和给定的 $perl 运行给定的 $tests 集。

用于 t/*.t 文件。

test_via_script

my $command = $mm->test_via_script($perl, $script);

返回一个 $command 行,该行只运行单个测试,不使用 Test::Harness。不会对结果进行检查,只会打印结果。

用于 test.pl,因为它们并不总是遵循 Test::Harness 格式。

tool_autosplit

定义一个简单的 perl 调用,运行 autosplit。可能很快就会被 pm_to_blib 弃用。

arch_check

my $arch_ok = $mm->arch_check(
    $INC{"Config.pm"},
    File::Spec->catfile($Config{archlibexp}, "Config.pm")
);

一个健全性检查,检查 Perl 认为的体系结构和 Config 认为的体系结构是否相同。如果不相同,它将返回 false 并显示诊断消息。

在构建 Perl 时,它将始终返回 true,因为还没有安装任何东西。

接口有点奇怪,因为这是快速重构的结果。不要依赖它。

File::Spec 包装器

ExtUtils::MM_Any 是 File::Spec 的子类。这里提到的方法覆盖了 File::Spec。

catfile

File::Spec <= 0.83 存在一个 bug,即 catfile 的文件部分没有规范化。此覆盖修复了该 bug。

杂项

我无法确定这些方法应该放在哪里。

find_tests

my $test = $mm->find_tests;

返回一个适合馈送到 shell 的字符串,以返回 t/*.t 中的所有测试。

find_tests_recursive

my $tests = $mm->find_tests_recursive;

返回一个适合馈送到 shell 的字符串,以返回 t/ 中的所有测试,但递归地。等同于

my $tests = $mm->find_tests_recursive_in('t');

find_tests_recursive_in

my $tests = $mm->find_tests_recursive_in($dir);

返回一个适合馈送到 shell 的字符串,以返回 $dir 中的所有测试,递归地。

extra_clean_files

my @files_to_clean = $MM->extra_clean_files;

返回一个列表,其中包含在 clean 目标中要删除的特定于操作系统的文件,除了通常的集合之外。

installvars

my @installvars = $mm->installvars;

所有 INSTALL* 变量的列表,不带 INSTALL 前缀。对于迭代或构建相关变量集很有用。

libscan

my $wanted = $self->libscan($path);

接受一个文件或目录的路径,如果我们不想将此文件包含在库中,则返回一个空字符串。否则,它将返回未更改的 $path。

主要用于从安装中排除版本控制管理目录和基本级别的 README.pod

platform_constants

my $make_frag = $mm->platform_constants

返回一个 make 片段,定义了在 init_platform() 中初始化的所有宏,而不是将它们放在 constants() 中。

post_constants (o)

默认情况下返回一个空字符串。专门用于在 Makefile.PL 中定义所有常量后进行覆盖。

post_initialize (o)

默认情况下返回一个空字符串。在 Makefile.PL 中用于在对象初始化后向 Makefile 添加一些文本块。

postamble (o)

返回一个空字符串。可以在 Makefile.PL 中用于在 Makefile 末尾写入一些文本。

作者

Michael G Schwern <[email protected]> 和 [email protected] 的居民,代码来自 ExtUtils::MM_Unix 和 ExtUtils::MM_Win32。