制作适合特定perl脚本的cygwin“发布版”

Δ posted @ 2008年7月09日 18:34 in linux与windows协作 with tags cygwin Perl w32 linux , 3769 阅读

说明:

像本文这样的再发布(把cygwin的一部分题取出来于其他程序结合重新发布)不知道是否违反相关的协议,希望熟悉版权的朋友告诉我一下,另外,有什么发布的注意事项(关于声明,版权,协议,等),也希望各位过来人告知。本人语文很差,由刚刚写Blog,可能写的很乱,希望大家谅解。


历史背景:

我和朋友合作“开发”(面向的用户是既不熟悉linux和cygwin又不熟悉perl的),我在linux上写perl程序然后他拿到Windows下在ActivePerl下运行。以前一直没有问题,可最近打算在一个“项目”中使用perlxs,这下问题就来了。由于需要win32下的gcc和make,只好找一台有windows的机器,在cygwin下进行。我一开始用ActivePerl,可是生成的Makefile不能用。make报错: 

Makefile:465: *** multiple target patterns. Stop.

只好用 cygwin的perl,成功的编译出来,却无法用ActivePerl运行,一运行cmd就死了。于是我把cygwin的

perl.exe cygwin1.dll cygperl5_8.dll cygcrypt-0.dll

发给他(朋友不愿意装一个庞大的cygwin,也希望最后发布的文件)。结果提示缺少pm文件。我传给他一个,又提示少另一个,我实在忍受不了,决定让perl自己解决这个问题。于是,工作开始了。


正文:

首先面临的一个问题是:我这边只要有上述几个文件就可以正常运行perl程序,而他那边不行。查阅资料,才知道cygwin在注册表中储存了mount信息,perl在@INC中查找模块时会利用这个信息找到模块。我的cygwin装在D:\cygwin.下面是cygwin在注册表中添加的信息(导出后):

cygwin.reg

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2]
"cygdrive prefix"="/cygdrive"
"cygdrive flags"=dword:00000022

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/]
"native"="D:\\cygwin"
"flags"=dword:0000000a

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/bin]
"native"="D:\\cygwin/bin"
"flags"=dword:0000000a

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/lib]
"native"="D:\\cygwin/lib"
"flags"=dword:0000000a

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\Program Options]

 于是我又编写了一个uncygwin.reg,用来删除相关的主键:

uncygwin.reg

 

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin]

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2]
"cygdrive prefix"="/cygdrive"
"cygdrive flags"=dword:00000022

[-HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/]
"native"="D:\\cygwin"
"flags"=dword:0000000a

[-HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/bin]
"native"="D:\\cygwin/bin"
"flags"=dword:0000000a

[-HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\mounts v2\/usr/lib]
"native"="D:\\cygwin/lib"
"flags"=dword:0000000a

[HKEY_LOCAL_MACHINE\SOFTWARE\Cygnus Solutions\Cygwin\Program Options]

 

 这样以后导入uncygwin.reg就可以取消cygwin环境(这时请关闭所有的cygwin程序,否则没有效果)(取消cygwin环境后你在打开cygwin,看看提示符有什么变化),再导入cygwin.reg就可以恢复cygwin环境。如果要使用请修改相关路径。

第二步:

经过艰苦的学习和反复的尝试,写出了如下的perl脚本(代码写的很粗糙,大家见笑了)(代码着色好像有些问题)。

 cygwin-perl.pl

 

#!/usr/bin/perl

use strict;
use File::Copy;
use File::Basename;
use File::Path;
use FindBin;

my $plf=shift @ARGV; # 最终发布的perl程序作为参数传过来
my $err; # 用来存放错误信息
# 下面两个都是本机perl库文件位置前缀,请根据需要修改
my $lib_prefix="/cygdrive/d/cygwin/lib/perl5/5.8";
my $cyglib_prefix="/cygdrive/d/cygwin/lib/perl5/5.8/cygwin";

open NEED,'>>','needed.txt';
open LOG,'>>','need.log';

print LOG localtime() . "\n\n"; #记录时间

# 下面while中的语句是运行程序并捕获错误
while (do{$err=`$FindBin::Bin/perl.exe $plf 2>&1`;$?;}) {
  $_=$err;
# 获得所需模块名
  if (my ($missing)=m/Can't\s+locate\s+(\S+)/){
    my $libf="${lib_prefix}/${missing}";
    my $cyglibf="${cyglib_prefix}/${missing}";
    my $dir=dirname $missing;
    print NEED $missing,"\n";
    print LOG $missing,"\n";
# 复制文件   
    if (-e $libf) {
      mkpath $dir;
      copy $libf,$missing;
    }
    elsif (-e $cyglibf) {
      mkpath $dir;
      copy $cyglibf,$missing;
   }
  }
}
print LOG "--------------------\n";
close NEED;
close LOG;

原理:perl在找不到模块时会给出像

Can't locate strict.pm ....

这样的出错信息,只要在不断的自动运行中,每次捕获这个错误讯息并将所需模块复制到相应目录中去,直到可以正常运行。

用法见下面。

第三步:

有了以上的准备工作,就可以开始了,为了方便说明,下面是目录结构:

 

+ basic
|----perl.exe
|----cygwin1.dll
|----cygperl5_8.dll
|----cygcrypt-0.dll
|----cygwin-perl.pl

+ hello
|----hello.pl   # 主perl程序
|----Mytest.pm  # 调用perlxs的模块
|----Mytest.dll # 由c编译成的库

 

下面是cmd命令行(预先已导入uncygwin.reg):

 

> cd hello

# cygwin 装在 D:\ 映射到 POSIX 格式就是 /cygdrive/d/ ,使用-I包含所需库
hello> ..\basic\perl.exe -I /cygdrive/d/cygwin/lib/perl5/5.8 -I /cygdrive/d/cygwin/lib/perl5/5.8/cygwin ..\basic\cygwin-perl.pl hello.pl

现在的hello目录:

+ hello
|----hello.pl   # 主perl程序
|----Mytest.pm  # 调用perlxs的模块
|----Mytest.dll # 由c编译成的库
|---+auto
|   |---+DynaLoader
|       |----dl_findfile.al
|   
|---+warnings
|   |----register.pm
|
|----AutoLoader.pm
|----Carp.pm
|----......
.
.
.
|----need.log   # Log
|----needed.txt # 全部所需文件列表。

现在该有的都有了,把basic目录下的几个文件copy到hello目录下就可以发布了。

最后别忘了导入cygwin.reg以便以后使用。

 

Avatar_small
how to Add Signature 说:
2022年8月09日 15:49

Gmail is a user-friendly interface that brings a lot of features to the users like Gmail Signature, Google Hangouts, and more. In case, you have to send multiple emails daily then you may allow to add Gmail Signature. how to Add Signature to Gmail This saves your time and also lets the body of mails have the signature of you as an individual or if as an entity. Gmail is a user-friendly interface that brings a lot of features to the users like Gmail Signature, Google Hangouts, and more.

Avatar_small
West Bengal Madhyami 说:
2022年8月18日 12:43

The exams will be held in the months of February & March 2023. The students who will be appearing for the secondary exams can download the WB Madhyamik 10th Exam Guess Paper 2023, WB Madhyamik 10th Exam New Model Paper 2023, West Bengal Madhyamik Question Paper 2023 WB Madhyamik 10th Sample Question Paper 2023, West Bengal WB WBBSE 10th Model Question Paper 2023 from the official website or from our website in the month of November 2023.


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter