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

Hi,
Devel-CheckLib is more-or-less unloadable when using the MinGW compiler with ActivePerl. Nevertheless, I built and installed it on the x86 version of ActiveState build 1005 (perl-5.10). I skipped the 'dmake test', because the tests all fail anyway - ie I ran 'perl Makefile.PL' followed by 'dmake install'.

If I then run 'perl -MDevel::CheckLib -e 1' I get:
C:\_32\comp\Math-GMP-2.06>perl -MDevel::CheckLib -e 1 %Config::Config is read-only BEGIN failed--compilation aborted at C:/_32/ap1005/lib/ActiveState/Pat +h.pm line 12. Compilation failed in require at C:/_32/ap1005/lib/ActivePerl/Config.p +m line 46. Compilation failed in require. BEGIN failed--compilation aborted.
But if, in the same directory, I run 'perl -Mblib -MDevel::CheckLib -e 1', then there's no problem:
C:\_32\comp\Math-GMP-2.06>perl -Mblib -MDevel::CheckLib -e 1 Set up gcc environment - 3.4.5 (mingw-vista special r3)
I can even do:
C:\_32\comp\Math-GMP-2.06>perl -Mblib -MDevel::CheckLib -e "print $Dev +el::CheckLib::VERSION" Set up gcc environment - 3.4.5 (mingw-vista special r3) 0.91
But ... the thing is .... the blib does *not* contain a CheckLib.pm - it's a Math-GMP-2.06 blib !!

How is this possible ? Why should the invocation of a blib that contains nothing useful make such a difference ? What steps can I take to try and make sense of this ?

Btw, it's exactly the same scenario with ActivePerl build 1200 (perl-5.12).
And it doesn't have to be a Math-GMP blib. *Any* valid blib structure will do.

Cheers,
Rob

Replies are listed 'Best First'.
Re: Devel::CheckLib problem
by BrowserUk (Patriarch) on Dec 09, 2010 at 13:59 UTC

    At line 333 of CheckLib.pm, swap:

    sub _findcc { my @flags = grep { length } map { quotewords('\s+', 0, $_ || ()) } @Config{qw(ccflags ldflags)};

    For:

    sub _findcc { my @flags = @Config{qw(ccflags ldflags)}; @flags = grep { length } map { quotewords('\s+', 0, $_ || ()) } @f +lags;

    And the module will load.

    And no, I have no idea why that should affect a fix, but it seems to on my 64-bit AS1007 setup.

    All I can add at this point is that with the original, when it gets to line 13 of Config_Heavy.pl it goes tits up:

    ... >> [0] C:/Perl64/lib/Config.pm : 76: die "&Config::AUTOLOA +D failed on $Config::AUTOLOAD"; >> [0] C:/Perl64/lib/Config_heavy.pl : 13: die $@ if $@ && +$@ !~ /^Can't locate ActivePerl\/Config\.pm/; &Config::AUTOLOAD failed on Config::launcher at C:/Perl64/lib/Config.p +m line 76. BEGIN failed--compilation aborted at C:/Perl64/lib/ActivePerl/Config.p +m line 4. Compilation failed in require at C:/Perl64/lib/Config_heavy.pl line 11 +. BEGIN failed--compilation aborted at C:/Perl64/lib/Config_heavy.pl lin +e 15. Compilation failed in require at C:/Perl64/lib/Config.pm line 74. >> [0] C:/Perl64/lib/File/Temp.pm : 870: local($., $@, $!, $^E +, $?); >> [0] C:/Perl64/lib/File/Temp.pm : 871: cleanup(); >> [0] C:/Perl64/lib/File/Temp.pm : 877: if (!$KEEP_ALL) { >> [0] C:/Perl64/lib/File/Temp.pm : 880: @{ $fi +les_to_unlink{$$} } : () ); >> [0] C:/Perl64/lib/File/Temp.pm : 881: foreach my $file (@ +files) { >> [0] C:/Perl64/lib/File/Temp.pm : 895: @{ $dir +s_to_unlink{$$} } : () ); >> [0] C:/Perl64/lib/File/Temp.pm : 896: foreach my $dir (@d +irs) { >> [0] C:/Perl64/lib/File/Temp.pm : 908: @{ $files_to_unlink +{$$} } = () >> [0] C:/Perl64/lib/File/Temp.pm : 910: @{ $dirs_to_unlink{ +$$} } = ()

    But with the change, that line runs fine:

    ... >> [0] C:/Perl64/lib/Config_heavy.pl : 13: die $@ if $@ && +$@ !~ /^Can't locate ActivePerl\/Config\.pm/; >> [0] C:/Perl64/lib/Config_heavy.pl : 19: our $summary = <<'!END!'; >> [0] C:/Perl64/lib/Config_heavy.pl : 52: my $summary_expanded; >> [0] C:/Perl64/lib/Config_heavy.pl : 73: local *_ = \my $a; >> [0] C:/Perl64/lib/Config_heavy.pl : 74: $_ = <<'!END!'; >> [0] C:/Perl64/lib/Config_heavy.pl : 1155: my $i = 0; ...

    However, even with the fix, the suggested test line produces no output. I'm not sure if that is good or bad?, but I guess it is at least progress:

    C:\test>perl -MDevel::CheckLib -e1 C:\test>

    Let me know If I can try anything else to help you solve this.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Between your suggested change to _findcc() and Chris Marshall's suggestion, I've arrived at:
      sub _findcc { my @flags = @Config{qw(ccflags ldflags)}; @flags = grep { length } map { quotewords('\s+', 1,$_) } @flags;
      That works pretty well. There's now just the one failing test in the Devel::CheckLib test suite:
      t/multi-word-compiler.........Subroutine STORE redefined at C:/_32/ap1 +005/lib/Config_heavy.pl line 1177. Set up gcc environment - 3.4.5 (mingw-vista special r3) %Config::Config is read-only # Looks like your test died before it could output anything. t/multi-word-compiler.........dubious Test returned status 255 (wstat 65280, 0xff00) DIED. FAILED test 1 Failed 1/1 tests, 0.00% okay
      Looks like STORE gets redefined to a form that we don't want. I think the error is in response to the following line in t/multi-word-compiler.t:
      $Config{cc} = "$^X $Config{cc}";
      Needless to say, 'perl -Mblib t/multi-word-compiler.t' passes the test :-))))
      C:\_32\comp\Devel-CheckLib-0.91>perl -Mblib t/multi-word-compiler.t 1..1 Set up gcc environment - 3.4.5 (mingw-vista special r3) ok 1 - Good multi-word compiler is OK
      Cheers,
      Rob

        I'd try replacing $Config{cc} = "$^X $Config{cc}"; with $Config{cc} = $^X . ' ' . $Config{cc};.

        That's based on nothing more than guesswork as I didn't actually download the whole package, just the .pm file. (You'd already said most of the tests failed:)

        I'm fascinated by the /blib thing. Does it work if you load some other inconsequential module; say bytes or less or maybe just strict?

        I've got this niggle in the back of my head. Something about adding coderefs to @INC or %INC, I forget the dtails. Maybe putting something (anything) in those stops some too-clever-by-half piece of code getting invoked?


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Devel::CheckLib problem
by BrowserUk (Patriarch) on Dec 09, 2010 at 14:25 UTC

    FWIW, I can reproduce the problem with Config.pm outside of Devel::CheckLib.pm:

    C:\test>perl -MConfig -E"say for @Config{ qw[ccflags ldflags] }" &Config::AUTOLOAD failed on Config::launcher at C:/Perl64/lib/Config.p +m line 76. BEGIN failed--compilation aborted at C:/Perl64/lib/ActivePerl/Config.p +m line 4. Compilation failed in require at C:/Perl64/lib/Config_heavy.pl line 11 +. BEGIN failed--compilation aborted at C:/Perl64/lib/Config_heavy.pl lin +e 15. Compilation failed in require at C:/Perl64/lib/Config.pm line 74. C:\test>perl -MConfig -E"say @Config{ qw[ccflags ldflags ]}" -nologo -GF -W3 -MD -Zi -DNDEBUG -Ox -GL -fp:precise -DWIN32 -D_CONSOL +E -DNO_STRICT -DHAVE_DES_FCRYPT -DWIN64 -DCONSERVATIVE -DUSE_SITECUST +OMIZE -DPRIVLIB_LAST_IN_INC -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_S +YS -DUSE_PERLIO -DPERL_MSVCRT_READFIX-nologo -nodefaultlib -debug -op +t:ref,icf -ltcg -libpath:"C:\Perl64\lib\CORE" -machine:AMD64

    But I've still no real idea why that happens.

    My best guess is that %Config is some kind of tied or magic-applied hash and it doesn't like having its elements aliased.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      My best guess is that %Config is some kind of tied or magic-applied hash and it doesn't like having its elements aliased

      Yes, in order for MinGW to work with ActivePerl, it's necessary to override a number of %Config values. They do this with something along the lines of:
      my $obj = tied %Config::Config; if(mingw_detected) { $obj->{cc} = 'gcc'; $obj->{make} = 'dmake'; .... }
      I still don't get how the presence (and loading) of an empty blib can make a difference to the loading of Devel::CheckLib ... though it's probably not as important as I first thought.

      I'll see how I go with what you've come up with already. Thanks !

      Cheers,
      Rob