http://www.perlmonks.org?node_id=993633


in reply to Re^3: Module::Install hacking
in thread Module::Install hacking

If you've a mind to check that it works ok for you,

With the addition of site/bin to my path, it does:

C:\>perl -MGtk2::WebKit -E"say $Gtk2::WebKit::VERSION; <>; print $]" & + echo %errorlevel% 0.09 5.014002255 C:\>

But where does the site/bin directory come from? It's not a part of the standard perl distribution; nor the ActiveState distributions.


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
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.

RIP Neil Armstrong

Replies are listed 'Best First'.
Re^5: Module::Install hacking
by syphilis (Archbishop) on Sep 14, 2012 at 04:55 UTC
    Thanks for running the check !!

    But where does the site/bin directory come from?

    For my AS build of perl-5.14, I have:
    C:\>perl -V:installsitebin installsitebin='C:\_32\ap1400\site\bin'; C:\>perl -V:installsitescript installsitescript='C:\_32\ap1400\site\bin'; C:\>perl -V:sitebin sitebin='C:\_32\ap1400\site\bin'; C:\>perl -V:sitebinexp sitebinexp='C:\_32\ap1400\site\bin'; C:\>
    So, if perl/site/bin is not there from the start, I guess it gets created whenever a module wants to install something into either installsitebin, installsitescript, sitebin, or sitebinexp.
    I expect that ppm will install anything that's cound in blib/script into whatever is specified by $Config{installsitescript}.

    Bit of a pity that the AS builds specify that config setting. (My MinGW build specifies nothing for installsitescript, and specifies perl/bin for installsitebin.)

    Cheers,
    Rob
      I expect that ppm will install anything that's cound in blib/script into whatever is specified by $Config{installsitescript}.

      All well and good, but as it never gets added to the path, it will always require manual intervention for anything that uses it, to work.

      I'll say this once and forever hold my peace on it, but your whole renaming dlls, sticking them in a "common place", and using --force to install them is fundamentally flawed.

      What happens when one of your renamed dlls changes? You have just recreated the whole msvcrt.dll dll-hell scenario over again.

      I install two of your packages each has a dependency upon a different version of one or more of your renamed dlls. Whichever order I install them in, one of them gets the wrong thing.

      And if I install some other package that uses the same dll, but under its real name, what then? If I use both modules in the same script, then I'm going to be using 2 different versions of the same code...

      MS (belatedly) got around to solving the problem when they implemented side-by-side assemblies.

      From the point of view of someone who will not have to go through the work of changing everything, and with a less than strong attitude toward properness, I think that you should be either:

      1. shipping these dlls under their real names, with each package that uses them, and place them in the same directory as the dll(s) that use them -- probably site\lib\auto\Package\Name\Name.dll.

        That way, when the day comes that one of your packages needs a later version of one of your renamed-to-sis dlls, its installation won't break every previous one still using the older version. And even if one script uses two packages that each depend upon a different versions, everything will still work because of the side-by-side feature.

      2. At a stretch, if the multiple copies of the same thing issue really offends you, then create a separate package -- say MinGW::Redist -- and make it a dependency of all the other packages. It would need a perl component that caused the dlls to be loaded (from its site\lib\auto\MinGW\Redist\ path), but that could be as simple as:
        package MinGW::Redist; use Win32; Win32::LoadLibrary( 'libgcc_s_dw2_1.dll' ) or die $^E; Win32::LoadLibrary( 'libstdc++-6.dll' ) or die $^E; ... 1;

      The latter would avoid the need for --force, but would not resolve the problem of different packages needing different versions.

      Overall, the former is both the simplest and best solution.


      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      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.

      RIP Neil Armstrong

        What happens when one of your renamed dlls changes?

        These dll's are part of the MinGW compiler - they will only change when I switch to a different version of MinGW. (That *will* happen, but hopefully not with great frequency.)

        When I do upgrade my compiler from the current 4.5.2 to (say) 4.6.3 then the renamed dll will change from libgcc_sis_452.dll to libgcc_sis_463.dll.
        I don't see any problems with that - packages that need libgcc_s_452.dll will still install $Config{installsitebin}/libgcc_sis_452.dll, and those that need libgcc_sis_463.dll will install $Config{installsitebin}/libgcc_sis_463.dll.
        Eventually, as time goes by,all of the ppm packages will need libgcc_sis_463.dll, and there'll be a 100Kb libgcc_sis_452.dll sitting in the users $Config{installsitebin} folder that is no longer needed. (I think I can live with that :-)

        Similarly for libstdc++-6.dll (which is the *only* other dll I rename). It, too, is a MinGW compiler dll - and I'll be renaming it to something other that cpp++-6_sis.dll when I upgrade my MinGW compiler.

        I didn't properly stress it in my previous post, but these 2 dlls are the *only* dlls that I rename with my x86 builds.
        With my x64 builds there are also only 2 dlls that I rename - libgcc_s_sjlj-1.dll (which is the mingw64 counterpart of mingw's libgcc_s_dw2-1.dll) and libstdc++-6.dll (same name as mingw's corresponding file).

        I install two of your packages each has a dependency upon a different version of one or more of your renamed dlls. Whichever order I install them in, one of them gets the wrong thing

        Shit !! - I hope you're referring to a hypothetical situation here :-)
        So far, there has been no version change. So, such a situation should not yet have arisen, and should not ever arise so long as I adhere to the principle I've just outlined (of giving different versions different names).

        1. shipping these dlls under their real names, with each package that uses them, and place them in the same directory as the dll(s) that use them

        This is precisely what I do with *all* dll's except the 3 mentioned above - and I used to it with those 3 as well. But there's a problem with that approach wrt those 3 dlls.
        Let's say I'm building the FOO extension with my x64 gcc-4.7.0 compiler, and I put a copy of its libgcc_s_sjlj-1.dll in blib/arch/auto/FOO (alongside blib/arch/auto/FOO/FOO.dll). That works fine in most places, but if someone installs my FOO binaries on Strawberry Perl, the libgcc_s_sjlj-1.dll that I packaged never gets loaded.
        This happens because Strawberry Perl itself loads libgcc_s_sjlj-1.dll - only *it* will load Strawberry's 4.6.3 version of libgcc_s_sjlj-1.dll, thereby preventing the libgcc_s_sjlj-1.dll that I provided from being loaded by FOO.
        Unless the 2 versions of libgcc_s_sjlj-1.dll have an identical set of entry points (and they don't), you've got trouble.
        It's this problem that led me to adopting my current approach.

        With x86 perls, this type of problem is less likely, but still possible.
        To phrase it in general terms - the approach you've outlined in 1. is not guaranteed to work if perl itself loads a dll that has the same name as a dll that I've placed in blib/arch/auto/FOO. And, in the real world of x64 Strawberry Perl, it's guaranteed to fail.

        One thing, however ... I've just been checking ... and it seems that mingw perl itself doesn't load libstdc++-6.dll. That being so, there's no reason to apply the same treatment to that dll. (I'll check on that and phase it out if I can.)

        Similarly with your second option, I think:
        Win32::LoadLibrary( 'libgcc_s_dw2_1.dll' ) or die $^E;
        will either die or fail to load the the dll that I want if a dll named 'libgcc_s_dw2_1.dll' has already been loaded by perl itself.

        In summary, as long as I limit this to the 3 (hopefully-reduceable-to-2) dll files specified above, I'm pretty confident I can be handle this without much drama. (Famous last words ;-)

        Cheers,
        Rob
        Just a couple of peripheral points that I didn't make earlier:

        All well and good, but as it never gets added to the path, it will always require manual intervention for anything that uses it, to work

        I consider this to be a bug in ActivePerl, or the person using it.
        Surely $Config{installsitebin} should be in the path - even if no such directory exists initially.
        The whole purpose of placing something in blib/script is that it will be installed into a "path" folder. Lots of modules put things in blib/script, for that very purpose.

        The latter would avoid the need for --force

        The need to use --force at all for what I'm doing is, IMO, a design flaw in PPM - which just makes having to do it all the more annoying.
        All I'm doing is having PPM overwrite an existing file (installed by a previous 'ppm install') with an *identical* file.
        If *I* had control over PPM, it would allow such overwriting - and call for '--force' only if the 2 files were different.
        But ... there's not much I can do about that.

        Cheers,
        Rob
        I dont think your solution would work. If you loadlibrary an absolute path DLL so 2 dll are in the process with the same name, I think it is "undefined" which DLL will be used in a future DLL loading that is dependent on that base name. I dont know if Windows is smart enough to try the 1st DLL with that base name, if the imports can not be resolved, then try 2nd DLL with same base name.

        Only SxS, but that isn't Win2000 compatible, and SxS generally isn't used in Mingw, or pure LoadLibrary/GetProcAddress would work. I am not saying that SxS is impossible with Mingw, just that I've never seen it done. ld doesn't have any manifest specific flags in --help.