PodMaster has asked for the wisdom of the Perl Monks concerning the following question:

Hello.

After I generate my code with

perl -MExtUtils::Miniperl -e writemain>butter.c
and then compile it with
cl -c -nologo -Gf -W3 -IC:\perl\lib\CORE -DWIN32 -D_CONSOLE -DNO_STRIC +T -DPERLDLL -DPERL_CORE -O1 -MD -DNDEBUG -DPERL_EXTERNAL_GLOB butter +.c
, I attempt to link it
link -nologo -nodefaultlib -release -libpath:"C:/Perl\lib\CORE" -mac +hine:x86 oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.l +ib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib net +api32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32. +lib odbccp32.lib msvcrt.lib msvcrt.lib perl56.lib butter.obj
at which point i'm faced with
butter.obj : error LNK2001: unresolved external symbol _PL_op_mutex
butter.obj : error LNK2001: unresolved external symbol _PL_do_undump
butter.exe : fatal error LNK1120: 2 unresolved externals
Now if I do a search on my \perl\lib\CORE, for op_mutex, op.h, embedvar.h, perlapi.h, perlvars.h, and perl56.lib come up as containing the string.

What's a monk to do?
Here is the c code generated.

/* * "The Road goes ever on and on, down from the door where it began." */ #ifdef OEMVS #pragma runopts(HEAP(1M,32K,ANYWHERE,KEEP,8K,4K)) #endif #include "EXTERN.h" #define PERL_IN_MINIPERLMAIN_C #include "perl.h" static void xs_init (pTHX); static PerlInterpreter *my_perl; #if defined (__MINT__) || defined (atarist) /* The Atari operating system doesn't have a dynamic stack. The stack size is determined from this value. */ long _stksize = 64 * 1024; #endif int main(int argc, char **argv, char **env) { int exitstatus; #ifdef PERL_GLOBAL_STRUCT #define PERLVAR(var,type) /**/ #define PERLVARA(var,type) /**/ #define PERLVARI(var,type,init) PL_Vars.var = init; #define PERLVARIC(var,type,init) PL_Vars.var = init; #include "perlvars.h" #undef PERLVAR #undef PERLVARA #undef PERLVARI #undef PERLVARIC #endif PERL_SYS_INIT3(&argc,&argv,&env); #if defined(USE_THREADS) || defined(USE_ITHREADS) /* XXX Ideally, this should really be happening in perl_alloc() or * perl_construct() to keep libperl.a transparently fork()-safe. * It is currently done here only because Apache/mod_perl have * problems due to lack of a call to cancel pthread_atfork() * handlers when shared objects that contain the handlers may * be dlclose()d. This forces applications that embed perl to * call PTHREAD_ATFORK() explicitly, but if and only if it hasn't * been called at least once before in the current process. * --GSAR 2001-07-20 */ PTHREAD_ATFORK(Perl_atfork_lock, Perl_atfork_unlock, Perl_atfork_unlock); #endif if (!PL_do_undump) { my_perl = perl_alloc(); if (!my_perl) exit(1); perl_construct(my_perl); PL_perl_destruct_level = 0; } exitstatus = perl_parse(my_perl, xs_init, argc, argv, (char **)NUL +L); if (!exitstatus) { exitstatus = perl_run(my_perl); } perl_destruct(my_perl); perl_free(my_perl); PERL_SYS_TERM(); exit(exitstatus); return exitstatus; } /* Register any extra external extensions */ static void xs_init(pTHX) { char *file = __FILE__; dXSUB_SYS; }
and here is my perl -V


Summary of my perl5 (revision 5 version 6 subversion 1) configuration:
Platform:
osname=MSWin32, osvers=4.0, archname=MSWin32-x86-multi-thread
uname=''
config_args='undef'
hint=recommended, useposix=true, d_sigaction=undef
usethreads=undef use5005threads=undef useithreads=define usemultiplicity=define
useperlio=undef d_sfio=undef uselargefiles=undef usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
Compiler:
cc='cl', ccflags ='-nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT -DHAVE_DES_FCRYPT -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DPERL_MSVCRT_READFIX',
optimize='-O1 -MD -DNDEBUG',
cppflags='-DWIN32'
ccversion='', gccversion='', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=undef, longlongsize=8, d_longdbl=define, longdblsize=10
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=4
alignbytes=8, usemymalloc=n, prototype=define
Linker and Libraries:
ld='link', ldflags ='-nologo -nodefaultlib -release -libpath:"C:/Perl\lib\CORE" -machine:x86'
libpth="C:\Program Files\Microsoft Visual Studio\VC98\mfc\lib" "C:\Program Files\Microsoft Visual Studio\VC98\lib" "C:\Perl\lib\CORE"
libs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
perllibs= oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib
libc=msvcrt.lib, so=dll, useshrplib=yes, libperl=perl56.lib
Dynamic Linking:
dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '
cccdlflags=' ', lddlflags='-dll -nologo -nodefaultlib -release -libpath:"C:/Perl\lib\CORE" -machine:x86'


Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY USE_ITHREADS PERL_IMPLICIT_CONTEXT PERL_IMPLICIT_SYS
Locally applied patches:
ActivePerl Build 633
Built under MSWin32
Compiled at Jun 17 2002 21:33:05
@INC:
C:/Perl/lib
C:/Perl/site/lib
.

____________________________________________________
** The Third rule of perl club is a statement of fact: pod is sexy.

Replies are listed 'Best First'.
Re: compiling miniperl ( unresolved external symbol _PL_op_mutex )
by robartes (Priest) on Oct 14, 2002 at 14:01 UTC
    This might be extremely silly of me, but does:
    libpath:"C:/Perl\lib\CORE"
    not look a bit odd to you? Shouldn't that first forward slash be a backslash? Unresolved symbols are usually caused by the compiler not finding the libraries containing said symbols (or not being told where to find them).

    CU
    Robartes-

      All DOS and WinXY variants do understand the forward slash, even if M$ established the convention of using the butt ugly backslash as directory separator on their systems by making COMMAND.COM (and only COMMAND.COM; CMD.EXE may also have inherited this boneheadedness, not sure) not understand forward ones and using them as program option prefix as opposed to the Unix' dash. You can write unlink "C:/Windows/Win.Com"; in your Perl/Win32 scripts and it'll work as expected (or not expected, as it were).

      Makeshifts last the longest.

        Actually, many, many MS program don't handle forward slash as a path separator (from the command line) and even some of the default "dialogues" don't (so if you get an "open file" dialogue, you probably can't use /).

        cmd.exe does handle / as a directory separator (command.com doesn't), but that only matters when using / in the command path, not when using / later in the command line. This is because command-line processing is done separately by each executable (because DOS gives programs their command line unlike Unix that gives programs a list of their command arguments).

        So, in particular, "link" needs to interpret / on the command line to find the options you are giving it. But testing shows that "/libpath:c:/perl\lib" works since "link /libpath:c:/foo/nologo" still prints the "logo" (while "link /libpath:c:/foo /nologo" doesn't).

        Also, there are some advanced things that only work with \ and/or in Unicode. For example, Registry keys and values can contain / but can't contain \ (so you can't use / as a path separator for Registry keys). And you can't disable "path parsing" by putting "//?/" in front of the path to the file you are trying to open. So if you want to open a file who's path is longer than MAX_PATH characters, you have to preceed it with \\?\ in Unicode (and use the "wide character" interface).

                - tye (who wishes the escape character for Per's ' was ' not \)
        I didn't know that, thanks! (Been a while since I've done any serious work on Win32 systems.)

        The thing is now whether or not link is smart enough to figure out that / is also a directory seperator.

        CU
        Robartes-

Re: compiling miniperl ( unresolved external symbol _PL_op_mutex )
by Zaxo (Archbishop) on Oct 15, 2002 at 07:53 UTC

    Unresolved symbols at link time often come from libs and object files getting linked in the wrong order. If one uses a symbol from a library which has already been linked, the later use remains unresolved.

    In this case, the error message says butter.obj has a pair of undefined symbols, but it is the last object to be linked. You know that perl56.lib provides those symbols, so linking butter.obj before that lib should work.

    Another possibility: #include "ppport.h"

    After Compline,
    Zaxo

Re: compiling miniperl ( unresolved external symbol _PL_op_mutex )
by PodMaster (Abbot) on Oct 23, 2002 at 02:08 UTC
    Well, after asking around quite a bit, it appears it is a bug in ExtUtils::Miniperl.

    Mattia Barbone came through with

    Add

    char PL_do_undump = 0;
    perl_mutex PL_op_mutex;

    before main; This looks like the right solution; I do not know why
    Miniperl does not add them itself, though.

    Regards
    Mattia

    Mattia wrote App::Packer which is where PerlBin is headed towards (maybe).

    ____________________________________________________
    ** The Third rule of perl club is a statement of fact: pod is sexy.