10

我正在尝试将 XS 编译成 perl [ed(ikegami): 这就是说他正在使用 ::MakeMaker'smake perl创建一个perl带有静态链接的 C 供应商库]但是当我这样做时,新版本的 perl 不支持动态加载模块。每当我尝试运行具有类似use Socket(或任何其他模块)的 perl 代码时,我都会得到:

Can't load module Socket, dynamic loading not available in this perl.

是否有我设置不正确的编译器/链接器开关或什么?所有这些都是在 1998 年和 2004 年在另一个盒子上编译的(在 PA-RISC 上旧的 hpux),但我们正在转向一个新盒子(hpux11 itanium),我正在碰壁。

这是我的 Makefile.PL:

use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    'NAME'      => 'Udtutil',
    'VERSION_FROM' => 'Udtutil.pm', # finds $VERSION
    'LIBS'      => '-L/usr/ud/PFUSION/Udtutil -L/usr/ud/lib -lapidummy ' .
                   '-lshare -ludsql -ludmach -lbasic ' .
                   '-lperf -lret1 -lides -lpipe -lfunc -lndx -lrep -lshm ' .
                   '-lmglm -lulc -lglm -ltpmem2 -lcmn ' .
                   '-llicn -ludus -lunix -lbci -lunirpc -lxmldl -leda ' .
                   '-lsslU2097e -lcryptoU2097e ' .
                   '-lodbc -lstd_v2 -lstream -lCsup -lpthread -lm -lcl ' .
                   '-ldld ' .
                   '-lnfaclnt -lodsdummy -lcl ' .
                   '-lCsup -lcl -lelf -lm -lcurses -lsec -lpam ',
    'INC'       => '-I/usr/ud/include',     # e.g., '-I/usr/include/other' 
    'OPTIMIZE'  => '-O -Ae +DD64 -q -z +u4 -w ',
    'LINKTYPE'  => 'dynamic',
    'OBJECT'    => '$(BASEEXT)$(OBJ_EXT) funchead.o interfunc.o callcf.o efs_init.o',
);

这是我的 .xs 文件,Udtutil.xs

#ifdef __cplusplus
extern "C" {
#endif
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "/usr/ud/include/share.h"
#include "/opt/iibase/PFUSION/Udtutil/udtutil.h"
#ifdef __cplusplus
}
#endif

extern int U_IGNSIGSET;

extern int Iflags[2];

#if OS_NT

#define U_backsig(ignsigcnt) { if (((U_IGNSIGSET=(ignsigcnt)) == 0) && (Iflags[0] || Iflags[1])) U_sig_resend(); if (!U_IGNSIGSET && pU_sigflags && U_sigflags) NT_sig_kill(); }

#else

#define U_backsig(ignsigcnt) { if (((U_IGNSIGSET=(ignsigcnt)) == 0) && (Iflags[0] || Iflags[1])) U_sig_resend(); }

#endif

MODULE = Udtutil                PACKAGE = Udtutil

int startudt(value1,value2)
    int value1
    int value2

    CODE:
    int jmpret, sat;

    U_SET_JMP(jmpret,sat);
    if (jmpret) {
            /* proceed with initialization */
            udtcallbasic_init(value1,value2);
            RETVAL = 1;
    } else {
            /* shutdown unibasic and return unsuccessful value */
            udtcallbasic_done(1);
            RETVAL = 0;
    }

    OUTPUT:
    RETVAL

void stopudt(status)
    int status

    CODE:
    udtcallbasic_done(status);

void calludt(progname, argcount, ...)
    char * progname
    int argcount

    PPCODE:
    char * returnval;
    int paramspassed = 0;
    int status = 0;
    char ** arglist = NULL;
    int i;

    if (argcount + 2 == items) {
            /* build the C array from the Perl array */
            paramspassed = 1;
            arglist = (char **)malloc(argcount);
            for (i = 0; i < argcount; i++) {
                    arglist[i] = (char *)malloc(sv_len(ST(i+2))+1);
                    strcpy(arglist[i], SvPV(ST(i+2),PL_na));
            }

            /* make the call into the database */
            status = U_callbas(&returnval, progname, argcount, arglist);

            for (i = 0; i < argcount; i++) {
                    free(arglist[i]);
            }
            free(arglist);

            /* EXTEND(sp, 2); */
            XPUSHs(sv_2mortal(newSViv(paramspassed)));
            XPUSHs(sv_2mortal(newSViv(status)));

            if (status == 0) {
                    /* EXTEND(sp, 1); */
                    XPUSHs(sv_2mortal(newSVpv(returnval, 0)));
                    free(returnval);
            }
    } else {
            /* EXTEND(sp, 1); */
            XPUSHs(sv_2mortal(newSViv(paramspassed)));
    }

当我运行时perl Makefile.PL,一切看起来都很好:

> perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for Udtutil
Writing MYMETA.yml

当我运行makeormake perl时,一切顺利,它会创建一个新的本地 perl 二进制文件。

但是,当我执行时./perl mytest.pl,如果mytest.pl*使用*s 任何模块,我会得到:

Can't load module Socket, dynamic loading not available in this perl.

关于如何编译这个新的 perl 并仍然保持动态加载工作的任何建议?


附加信息:

这是旧盒子(有效的)的配置数据:

 > perl -V:usedl
 usedl='define';

 > perl -V
 Summary of my perl5 (5.0 patchlevel 4 subversion 4) configuration:   Platform:
     osname=hpux, osvers=10, archname=PA-RISC2.0
     uname='hp-ux autocrft b.10.20 u 9000893 341130351 unlimited-user license '
     hint=recommended, useposix=true, d_sigaction=define
     bincompat3=y useperlio=undef d_sfio=undef   Compiler:
     cc='cc', optimize='-O', gccversion=
     cppflags='-D_HPUX_SOURCE -Aa'
     ccflags ='-D_HPUX_SOURCE -Aa'
     stdchar='unsigned char', d_stdstdio=define, usevfork=false
     voidflags=15, castflags=0, d_casti32=define, d_castneg=define
     intsize=4, alignbytes=8, usemymalloc=y, prototype=define   Linker and Libraries:
     ld='ld', ldflags ='-L/usr/local/lib -L/usr/ud/lib'
     libpth=/usr/local/lib /usr/lib/pa1.1 /usr/ud/lib /lib /usr/lib /usr/ccs/lib
     libs=-lnet -lnsl_s -lndbm -ldld -lm -lc -lndir -lcrypt
     libc=/lib/libc.sl, so=sl
     useshrplib=false, libperl=libperl.a
     Dynamic Linking:
     dlsrc=dl_hpux.xs, dlext=sl, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-B,deferred '
     cccdlflags='+z', lddlflags='-b -L/usr/local/lib -L/usr/ud/lib'


 Characteristics of this binary (from libperl):    Built under hpux  
 Compiled at May  7 1998 13:59:51   @INC:
     /opt/perl5/lib/PA-RISC2.0/5.00404
     /opt/perl5/lib
     /opt/perl5/lib/site_perl/PA-RISC2.0
     /opt/perl5/lib/site_perl
     .

...这是来自新盒子的配置数据(不工作的盒子):

 > ./perl -V:usedl
 usedl='define';

 > ./perl -V
 Summary of my perl5 (revision 5 version 14 subversion 2) configuration:
       Platform:
     osname=hpux, osvers=11.31, archname=IA64.ARCHREV_0-LP64
     uname='hp-ux autocrft b.11.31 u ia64 1650208369 unlimited-user license '
     config_args=''
     hint=previous, useposix=true, d_sigaction=define
     useithreads=undef, usemultiplicity=undef
     useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef
     use64bitint=define, use64bitall=define, uselongdouble=undef
     usemymalloc=n, bincompat5005=undef   Compiler:
     cc='cc', ccflags ='+DD64 -Ae -D_HPUX_SOURCE -Wl,+vnocompatwarnings -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
     optimize='+O2 +Onolimit',
     cppflags='-Aa -D__STDC_EXT__ -D_HPUX_SOURCE +DD64 -Ae -D_HPUX_SOURCE -Wl,+vnocompatwarnings -I/usr/local/include +DD64 -Ae -D_HPUX_SOURCE -Wl,+vnocompatwarn ings -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'
     ccversion='B3910B', gccversion='', gccosandvers=''
     intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=87654321
     d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
     ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
     alignbytes=8, prototype=define   Linker and Libraries:
     ld='/usr/bin/ld', ldflags =' -L/usr/lib/hpux64'
     libpth=/usr/lib/hpux64
     libs=-L/usr/lib/hpux64 -lnsl -lnm -ldl -ldld -lm -lsec -lc
     perllibs=-lnsl -lnm -ldl -ldld -lm -lsec -lc
     libc=/usr/lib/hpux64/libc.so, so=so, useshrplib=false, libperl=libperl.a
     gnulibc_version=''
     Dynamic Linking:
     dlsrc=dl_hpux.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E -Wl,-B,deferred '
     cccdlflags='+DD64', lddlflags='-b +vnocompatwarnings'


 Characteristics of this binary (from libperl):
 Compile-time options: PERL_DONT_CREATE_GVSV PERL_MALLOC_WRAP
                         PERL_PRESERVE_IVUV USE_64_BIT_ALL USE_64_BIT_INT
                         USE_LARGE_FILES USE_PERLIO USE_PERL_ATOF   Built under hpux
 Compiled at Apr 13 2012 09:27:33
   @INC:
     /opt/iibase/perl/lib/site_perl/5.14.2/IA64.ARCHREV_0-LP64
     /opt/iibase/perl/lib/site_perl/5.14.2
     /opt/iibase/perl/lib/5.14.2/IA64.ARCHREV_0-LP64
     /opt/iibase/perl/lib/5.14.2
     .
4

3 回答 3

1

不知道这是否会有很大帮助,但您可以查看 App::Staticperl。我能够在 Solaris 中使用它构建 DBI 和 DBD::Informix,也许它也可以在 HP-UX 中使用。

于 2012-04-17T21:51:42.500 回答
1

我不知道这封电子邮件中是否有任何有用的东西是我收集并保存为 Perl 的 DBD::Informix 模块的背景信息的一部分。

Date: Wed, 13 Aug 1997 13:02:04 -0500 (CDT)
From: "Kent S. Gordon" [email deleted]
Subject: Re: Easy way to force static Informix libraries with DBD:Informix

>> "kgor" == Kent S Gordon <kgor@inetspace.com> wrote:
> Is there a easy way to create a DBD:Informix that uses static Informix
> libraries, but dynamic system libraries for everything else.

I have succeeded in building a perl with DBD:Informix that uses dynamic
loading for everything except DBD:Informix and DBI.  I got a runtime error of
not being able to find the symbol of boot_DBI if DBI was also not
statically built into perl.  Here is a short discription of what I did.

1)  Built perl 5.004_2 normally.
2)  Installed perl.
3)  Built DBI statically (make static).
4)  Installed DBI (make install).  This is not just the install of the perl
    binary, since DBI.a is needed later.
5)  Changed DBD Makefile.pl to call esql -static and esql -static -libs
    instead of esql and esql -libs.
6)  Created DBD Makefile using perl Makefile.PL.
7)  Built DBD statically (make static and make perl, etc.)
8)  The make test_static failed, due to wanting to create a dynamic object
    (Informix.sl failed due to trying fixup a symbol)
9)  Installed with make -k install to get pass error creating Informix.sl,
    while still installing Informix.pm (could not find a special install
    for static perl.
10) Installed new perl executable.  It seems to work after some initial
    test.

Kent S. Gordon
Senior Software Engineer
iNetSpace Co.
[Phone and email deleted]

我当时注意到,由于对 Informix.sl 的引用,Kent 必须在 HP-UX 上构建。我认为这里没有任何用处,但这是我在构建 Perl 的静态链接版本时所拥有的唯一额外信息。如您所见,它已接近 15 岁。

我想知道 Perl 5.14.x 是否仍然完全支持和测试静态链接模块?

于 2012-04-16T16:07:13.277 回答
0

从 perlxstut 手册页

动态加载与静态加载

通常认为,如果系统不具备动态加载库的能力,则无法构建 XSUB。这是不正确的。您可以构建它们,但是您必须将 XSUBs 子例程与 Perl 的其余部分链接起来,从而创建一个新的可执行文件。这种情况类似于 Perl 4。

本教程仍然可以在这样的系统上使用。XSUB 构建机制将检查系统并在可能的情况下构建一个可动态加载的库,或者构建一个静态库,然后可选地,一个新的静态链接可执行文件,其中链接了该静态库。

如果您希望在可以动态加载库的系统上构建静态链接的可执行文件,您可以在以下所有示例中执行不带参数的命令“make”,而是运行命令“make perl”。

如果您选择生成了这样一个静态链接的可执行文件,那么不要说“make test”,而应该说“make test_static”。在根本无法构建动态加载库的系统上,简单地说“make test”就足够了。

它说如果您使用行命令“make perl”,那么您就是在告诉它静态构建。

于 2013-08-20T12:56:30.977 回答