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 子類別化。這是暫時性的解決方案。
這可能是暫時的!
標記為Abstract 的任何方法都必須由子類別實作。
這些方法有助於撰寫跨平台程式碼。
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() 以了解用法。
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`;
}
my $can_load_xs = $self->can_load_xs;
如果我們有載入 XS 的能力,則傳回 true。
這很重要,因為用於在核心建置 XS 模組的 miniperl 無法載入 XS。
use ExtUtils::MM;
my $runnable = MM->can_run($Config{make});
如果在純量內容中呼叫,它會傳回您要求的二進位檔的完整路徑 (如果找到) 或 undef
(如果未找到)。
如果在清單內容中呼叫,它會傳回在 PATH
中找到的二進位檔實例的完整路徑清單,或在未找到時傳回空清單。
從 IPC::Cmd 複製,但修改為方法 (並移除 $INSTANCES
功能)。
$useredirect = MM->can_redirect_error;
如果在 qx 算子 (或反引號) 可以將 STDERR
重新導向到 STDOUT
的作業系統上,則為 True。
my $is_dmake = $self->is_make_type('dmake');
如果 $self->make
是指定的類型,則傳回 true;可能性為
gmake GNU make
dmake
nmake
bsdmake BSD pmake-derived
my $can_dep_space = $self->can_dep_space;
如果 make
可以處理 (可能透過引號) 包含空格的相依項,則傳回 true。目前已知 GNU make 為 true,BSD pmake 衍生為 false。
$text = $mm->quote_dep($text);
保護 Makefile 單值常數 (主要是檔案名稱) 的方法,這樣即使它們不方便地有空格,make 仍會將它們視為單值。如果正在使用的 make 程式無法達成此保護,且指定的文字需要它,則會擲回例外。
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);
傳回一個適當的字串,描述正在編寫的 makefile 類型。
my @recipelines = $MM->stashmeta($text, $file);
產生一組 @recipelines
,當執行配方時,將導致文字 $text
出現在文字 $file
中。呼叫一次,並在 $file
中放入所有想要的文字。巨集不會展開,因此位置將在組態時間固定,而不會在建置時間固定。
my @commands = $MM->echo($text);
my @commands = $MM->echo($text, $file);
my @commands = $MM->echo($text, $file, \%opts);
產生一組 @commands,將 $text 列印到 $file。
如果未提供 $file,輸出將傳送至 STDOUT。
如果 $opts{append} 為 true,$file 將附加到,而不是覆寫。預設為覆寫。
如果 $opts{allow_variables} 為 true,則 $(...)
形式的 make 變數不會跳脫。其他 $
會。預設為跳脫所有 $
。
使用範例
my $make = join '', map "\t$_\n", $MM->echo($text, $file);
my $args = $mm->wraplist(@list);
取得一個項目陣列,並將它們轉換成格式良好的參數清單。在多數情況下,這只是一個類似於
FOO \
BAR \
BAZ
my $filter_make_text = $mm->maketext_filter($make_text);
在寫入磁碟之前,Make 檔的文字會透過此方法執行。它允許系統有機會對 Make 檔進行可攜性修正。
預設情況下,它不會執行任何動作。
此方法受到保護,且不打算在 MakeMaker 外部呼叫。
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
my $oneliner = $MM->oneliner($perl_code);
my $oneliner = $MM->oneliner($perl_code, \@switches);
這會根據給定的 $perl_code 和 @switches (假設為 -e) 產生一個 Perl 一行指令,適用於特定平台,適合用於 make 目標。它將使用適當的 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)"');
它目前非常簡單,可能會在圖中某個時候擴充,以包含更靈活的程式碼和開關。
my $safe_text = $MM->quote_literal($text);
my $safe_text = $MM->quote_literal($text, \%options);
這將引用 $text,以便在 shell 中逐字解釋。
例如,在 Unix 上,這將跳脫 $text 中的任何單引號,並在整個字串周圍加上單引號。
如果 $options{allow_variables} 為 true,它將保留 '$(FOO)'
make 變數不變。如果為 false,它們將像其他 $
一樣被跳脫。預設為 true。
my $escaped_text = $MM->escape_dollarsigns($text);
跳脫迷途的 $
,讓它們不被解釋為 make 變數。
它允許 $(...)
。
my $escaped_text = $MM->escape_all_dollarsigns($text);
跳脫所有 $
,讓它們不被解釋為 make 變數。
my $escaped_text = $MM->escape_newlines($text);
Shell 跳脫 $text 中的換行符號。
my $max_exec_len = $MM->max_exec_len;
計算作業系統可以執行的最大命令大小。實際上,這是 shell 命令行的最大大小。
my $make = $MM->make;
傳回我們為其產生 Makefile 的 make 變數。這會嘗試對來自 %Config 或使用者的資訊做一些正規化。
這些是產生 make 目標的方法。
產生預設目標 'all'。
my $make_frag = $mm->blibdirs_target;
建立 blibdirs 目標,它會建立我們在 blib/ 中使用的所有目錄。
blibdirs.ts 目標已過時。請改為依賴 blibdirs。
定義 clean 目標。
my $make_frag = $MM->clean_subdirs_target;
傳回 clean_subdirs 目標。clean 目標使用這個目標來呼叫包含 Makefile 的任何子目錄中的 clean。
my $make_frag = $mm->dir_target(@directories);
產生目標來建立指定的目錄,並將其權限設定為 PERM_DIR。
由於依賴目錄來確保它存在並無法順利運作(修改時間太常變更),因此 dir_target() 會在建立的目錄中建立一個 .exists 檔案。您應該依賴這個檔案。為了可攜性,您應該使用 $(DIRFILESEP) 巨集,而不是 '/' 來分隔目錄和檔案。
yourdirectory$(DIRFILESEP).exists
定義暫存目錄目標,它會在 tar(或 shar)之前儲存發行版。
定義一個目標,在暫存目錄中產生發行版,並在那個子目錄中執行 'perl Makefile.PL; make ;make test'。
傳回命令列 arg(s) 給連結器,以列出要匯出的 dlsyms。預設傳回空字串,例如 AIX 可以覆寫。
傳回 xs_make_dlsyms
方法的輸出檔案的副檔名,包含任何「.」字元。
傳回任何要加到 xs_make_dlsyms
的 $extra
引數之前的額外文字。
重複必要的共用物件,針對每個物件呼叫 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 片段的公用方法。
定義動態目標。
my $make_frag = $mm->makemakerdflt_target
傳回指定 makemakerdeflt_target 的 make 片段。此目標是 Makefile 中的第一個目標,是預設目標,而且只指向「全部」,以防任何 make 變體混淆,或在真正的「全部」目標之前加入任何內容。
my $manifypods_target = $self->manifypods_target;
產生 manifypods 目標。此目標會從 MAN1PODS 和 MAN3PODS 中的所有 POD 檔案產生 man 頁面。
my $target = $mm->metafile_target;
產生 metafile 目標。
在 distdir 中寫入關於模組的 META.yml(YAML 編碼的元資料)和 META.json(JSON 編碼的元資料)檔案。格式盡可能遵循 Module::Build。
my $metadata_hashref = $mm->metafile_data(\%meta_add, \%meta_merge);
傳回 MakeMaker 轉換成 META.yml 檔案和 META.json 檔案的資料。它始終採用格式的 2.0 版。
%meta_add 的值會覆寫那些鍵中的任何現有元資料。%meta_merge 會與它們合併。
my $meta_yml = $mm->metafile_file(@metadata_pairs);
將 @metadata_pairs 轉換為 YAML。
此方法未實作完整的 YAML 傾印器,僅限於傾印雜湊,其值為字串、未定義或字串和陣列的巢狀雜湊。未進行任何引號/跳脫。
my $make_frag = $mm->distmeta_target;
產生 distmeta 目標,將 META.yml 和 META.json 新增至 distdir 中的 MANIFEST。
my $mymeta = $mm->mymeta;
從現有的 CPAN Meta 檔案 (META.json 或 META.yml) 或內部資料產生 MYMETA 資訊作為雜湊。
$self->write_mymeta( $mymeta );
將 MYMETA 資訊寫入 MYMETA.json 和 MYMETA.yml。
定義 realclean 目標。
my $make_frag = $MM->realclean_subdirs_target;
傳回 realclean_subdirs 目標。realclean 目標使用此目標對包含 Makefiles 的任何子目錄呼叫 realclean。
my $target = $mm->signature_target;
產生簽章目標。
使用「cpansign -s」寫入 SIGNATURE 檔案。
my $make_frag = $mm->distsignature_target;
產生 distsignature 目標,將 SIGNATURE 新增至 distdir 中的 MANIFEST。
my $make_frag = $mm->special_targets
傳回包含對 make 具有特殊意義的任何目標的 make 片段。例如,.SUFFIXES 和 .PHONY。
有助於初始化 MakeMaker 物件和巨集的方法。
$mm->init_ABSTRACT
$mm->init_INST;
由 init_main 呼叫。設定所有 INST_* 變數,但與 XS 程式碼相關的變數除外。這些變數在 init_xs 中處理。
$mm->init_INSTALL;
由 init_main 呼叫。設定所有 INSTALL_* 變數 (INSTALLDIRS 除外) 和 *PREFIX。
$mm->init_INSTALL_from_PREFIX;
$mm->init_from_INSTALL_BASE
$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:編譯時設定 XS 版本的 -D 行。
由 init_main 呼叫。
$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
$MM->init_others();
初始化與 tools_other() 使用的編譯和連結相關的巨集定義,並將它們放入 $MM 物件中。
如果沒有說明,則與 ExtUtils::MakeMaker 中 WriteMakefile() 參數的文件相同。
my $make_frag = $MM->tools_other;
傳回包含 init_others() 初始化的巨集定義的 make 片段。
$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)。
$mm->init_linker;
初始化與連結相關的巨集。
PERL_ARCHIVE:要連結到動態延伸模組的 libperl.a 等效路徑。
PERL_ARCHIVE_AFTER:連結到動態延伸模組的外部函式庫之後,應該置於連結器命令列中的函式庫路徑。如果連結器是一次通過,且 Perl 包含一些 C RTL 函式的覆寫(例如 malloc()),則可能需要此設定。
EXPORT_LIST:傳遞給連結器以定義要匯出的符號的檔案名稱。
有些作業系統不需要這些設定,這種情況下請留空。
$mm->init_platform
初始化僅供特定平台使用的巨集。
一個典型的範例是作業系統特定模組的版本號碼。(例如 MM_Unix_VERSION 或 MM_VMS_VERSION)。
$mm->init_MAKE
從 MAKE 環境變數或 $Config{make} 初始化 MAKE。
用來產生特定巨集和指令的雜項方法。
定義目標和常式,將 pod 轉換為 manpage 並置於 INST_* 目錄中。
my $pod2man_macro = $self->POD2MAN_macro
傳回 POD2MAN 巨集的定義。這是一個模擬 pod2man 程式工具的程式。您只要將開關附加到巨集上,即可新增更多開關到指令中。
典型用法
$(POD2MAN) --section=3 --perm_rw=$(PERM_RW) podfile1 man_page1 ...
my $command = $mm->test_via_harness($perl, $tests);
傳回一個 $command 行,使用 Test::Harness 和給定的 $perl 來執行給定的 $tests 集合。
用於 t/*.t 檔案。
my $command = $mm->test_via_script($perl, $script);
傳回一個 $command 行,只執行單一測試,不使用 Test::Harness。不會對結果進行檢查,只會列印出來。
用於 test.pl,因為它們並不總是遵循 Test::Harness 格式。
定義一個執行 autosplit 的簡單 perl 呼叫。可能很快就會被 pm_to_blib 取代。
my $arch_ok = $mm->arch_check(
$INC{"Config.pm"},
File::Spec->catfile($Config{archlibexp}, "Config.pm")
);
一個健全性檢查,檢查 Perl 認為的架構和 Config 認為的架構是否相同。如果不同,它會傳回 false 並顯示一個診斷訊息。
在建置 Perl 時,它總是會傳回 true,因為尚未安裝任何東西。
介面有點奇怪,因為這是快速重構的結果。不要依賴它。
ExtUtils::MM_Any 是 File::Spec 的子類別。這裡註解的方法會覆寫 File::Spec。
File::Spec <= 0.83 有個錯誤,其中 catfile 的檔案部分未正規化。這個覆寫修正了該錯誤。
我還無法真正找出這些方法應該放在哪裡的。
my $test = $mm->find_tests;
傳回一個適合提供給 shell 的字串,以傳回 t/*.t 中的所有測試。
my $tests = $mm->find_tests_recursive;
傳回適合提供給 shell 的字串,以遞迴方式傳回 t/ 中的所有測試。等同於
my $tests = $mm->find_tests_recursive_in('t');
my $tests = $mm->find_tests_recursive_in($dir);
傳回適合提供給 shell 的字串,以遞迴方式傳回 $dir 中的所有測試。
my @files_to_clean = $MM->extra_clean_files;
傳回除了通常設定之外,在 clean 目標中要移除的作業系統特定檔案清單。
my @installvars = $mm->installvars;
所有 INSTALL* 變數的清單,不含 INSTALL 前置字元。適用於反覆運算或建立相關變數組。
my $wanted = $self->libscan($path);
取得檔案或目錄的路徑,如果我們不想將此檔案包含在函式庫中,則傳回空字串。否則,傳回未變更的 $path。
主要用於從安裝中排除版本控制管理目錄和基本層級的 README.pod。
my $make_frag = $mm->platform_constants
傳回定義在 init_platform() 中所有巨集的 make 片段,而不是將它們放在 constants() 中。
預設傳回空字串。專門用於在定義所有常數後,從 Makefile.PL 內部覆寫。
預設傳回空字串。用於 Makefile.PL,在物件初始化後將一些文字區塊新增到 Makefile 中。
傳回空字串。可用於 Makefile.PL,在最後將一些文字寫入 Makefile 中。
Michael G Schwern <schwern@pobox.com> 和 makemaker@perl.org 的居民,其程式碼來自 ExtUtils::MM_Unix 和 ExtUtils::MM_Win32。