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

Hi,
In a C environment '-lfoo' will have the linker look for files named 'libfoo.a', 'libfoo.dll.a', 'foo.dll.a', 'libfoo.dll' and 'foo.dll'. And it will then link to the first one it finds. (Not sure of the search order ... but I think it's as I've written it.)

However, in a (MinGW-built) Perl environment (eg if I run 'perl Makefile.PL LIBS="-L. -lfoo') the linker looks only for 'foo.a' and 'libfoo.a'.

Consequently, we sometimes find a need to rename external libraries (most commonly from *.dll.a to *.a), or to create copies with the .a extension. This can be somewhat tedious.

How might one make the '-l' switch (when used in the perl environment) look for the '.dll.a' and '.dll' extensions, as well as '.a' ?

Would it be a good idea for such a change to become a standard part of perl ?

Given that all-but-ancient versions of MinGW are quite capable of linking to MSVC-built '.lib' files, I would like to see '.lib' added to the list as well. (Perhaps that's going too far.)

OTOH, the MSVC compiler is quite capable of linking to '.a' and '.dll.a' libraries (but not directly to dll's). So maybe MSVC-built perls should be searching for '.a' and '.dll.a' libraries, as well as '.lib' ?

My main interest is in getting an answer to the first question that I asked - but I'm also interested in comments on the other points/questions raised.

Cheers,
Rob
  • Comment on [Win32] The '-l' switch, and for which files the linker looks.

Replies are listed 'Best First'.
Re: [Win32] The '-l' switch, and for which files the linker looks.
by BrowserUk (Patriarch) on Mar 07, 2008 at 23:25 UTC

    This is a quite confusing post (to me). My confusion comes from phrases like "In a C environment" and "in a (MinGW-built) Perl environment".

    I assume that by the former, you mean using 'the linker' from either directly from the command line, or indirectly via a command in a makefile.

    And in the latter, using 'the linker' indirectly through a command line generated via EU::MM (or an EU::MM generated makefile.pl).

    And later in the post you say "OTOH, the MSVC compiler is quite capable of linking to '.a' and '.dll.a' libraries (but not directly to dll's)". This is confusing because you don't link to .lib/.a files. You can link via a .lib/.a to a .dll.

    Some MS nomenclature with *nix equivalencies (as best I know them; and sorry that most of this will be old info to you, but its the bits that aren't where either you are getting confused, or I am :):

    • link.exe/ln aka. 'the linker'

      This takes a one or more .obj/.o ('object') files, and/or one or more .lib/.a ('library'/'archive') files and extracts what it needs and cobines them to produce an executable file.

    • .lib/.a files:

      These are non-executable collections of 'object files'. These are a substitute for supplying the path/names of all of the require 'object' files to the linker on the command line.

      Also a convenient way of distributing a collection of 'object' files.

      A .lib can also be an 'import library'. This doesn't contain onject files as with a normal .lib, but rather is basically an index to a .dll.

      The suffix .dll.a (which would be .dll.lib in MS-speak) has no direct equivalent in MS-land. They are both .lib. Which makes a certain amount of sense as they both serve a similar purpose. They either supply the object code for entry points; or they supply the name of a .dll which contians that entry point for dynamic linking.

    • .dll/.so ('dynamic link') files.

      These are "executable" files. Not runnable directly, but still executable.

      The 'linker' builds these. It does not use them directly.

      In order to build an executable (.exe or .dll), that is statically linked to a .dll, you need a import library. This can be generated by the 'linker' when building a .dll. Or it can be generated from a .dll later using implib.exe ('import library utility'), if you have it.

    All of which is leading up to this. I'm not sure whether the "search order" you describe for the MinGW linker is implemented by the linker itself? If it is, there is no equivalent for that using link.exe.

    About the best that could be done to resolve the problem you are seeking to address, would be for the EU::MM to generate code in the makefile.pl it creates to cause it to go looking for each of the various suffixes when generating the makefile, and hardcode which ever it finds into the makefile.

    link.exe doesn't care what the suffix on object libraries or import libraries is. It simply opens the named files and examines the contents to see if it recognises it and how to use it.

    I'm not sure how helpful any of that is?


    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 confusion comes from phrases like "In a C environment" and "in a (MinGW-built) Perl environment".

      An example:
      Case 1 - what I (sloppily) meant by a "C environment":
      gcc -o gmp.exe gmp.c -IC:/incs -LC:/libs -lgmp
      Case 2 - what I (sloppily) meant by a "Perl environment"
      perl Makefile.PL INC="-IC:/incs" LIBS="-LC:/libs -lgmp"
      In the first case, I'm just building a test executable that needs the GMP library. It builds and runs fine.

      In case 2, I'm trying to build Math::GMP - but that fails because "No library found for -lgmp". MakeMaker decrees that "-lgmp" means either "gmp.a" or "libgmp.a" - and in this particular instance, the import library that was built is named "libgmp.dll.a".

      I had this half-baked idea that it would be nice if "-lgmp" worked the same in Case 2 as it did in Case 1 - and wondered if anyone had investigated the possibility. Hence my initial post in this thread. (MSVC compilers don't support the '-L' and '-l' conventions ... I probably should have omitted any consideration of those compilers.)

      I've since been poking about a little, and I've just about decided that it's more trouble than it's worth. Far easier just to rename libgmp.dll.a to libgmp.a (and to do the same for other libraries, as necessary).

      About the best that could be done to resolve the problem you are seeking to address, would be for the EU::MM to generate code in the makefile.pl it creates to cause it to go looking for each of the various suffixes when generating the makefile, and hardcode which ever it finds into the makefile

      And wouldn't that be fun. I guess we could start by re-setting $Config{lib_ext} = ['.a', '.ddl.a', '.dll'] :-)
      Though, as regards MinGW (but not MSVC), there should be no need to do any such hardcoding at all - unless it was decided to include '.lib' into the list of sought extensions, as I originally hinted. If '.lib' is not included then MakeMaker could just stick with the '-lfoo' stuff. There would be no need to convert to fully qualified file names, as is currently the case. And the libraries would be found at link time, irrespective of whether their names terminated with '.a', '.dll.a' or '.dll'.

      Hmmm ... I wonder how much work that involves. I think that's the way it already works on nix systems, so it might not be as much work as one expects. That it would entail a major split with the way Makefiles are written for the MSVC compiler is less than enticing, but it's the thought of "what else gets broken" that's the major deterrent :-)

      Cheers,
      Rob
        MakeMaker decrees that "-lgmp" means either "gmp.a" or "libgmp.a" - and in this particular instance, the import library that was built is named "libgmp.dll.a".

        Are you saying that with your case 1 command line: gcc -o gmp.exe gmp.c -IC:/incs -LC:/libs -lgmp, the compiler or the linker does some kind of search and manages to resolve -lgmp to libgmp.dll.a?

        I guess that would mean that the suffix .dll.a has been adopted as a convention for naming import libraries. But also, if gcc manages to locate the file libgmp.dll.a, it would also mean that there was some convention that -lxxx would also search for libxxx.a and libxxx.dll.a?

        Or is this latter part just a MM convention?

        And wouldn't that be fun. I guess we could start by re-setting $Config{lib_ext} = '.a', '.ddl.a', '.dll' :-) Though, as regards MinGW (but not MSVC), there should be no need to do any such hardcoding at all - unless it was decided to include '.lib' into the list of sought extensions, as I originally hinted. If '.lib' is not included then MakeMaker could just stick with the '-lfoo' stuff. There would be no need to convert to fully qualified file names, as is currently the case. And the libraries would be found at link time, irrespective of whether their names terminated with '.a', '.dll.a' or '.dll'.

        That para still leaves me confused. (Sorry :)

        First off. link.exe will never do anything useful with a .dll file. Unless of course the file was actually a misnamed .lib (either an object library or an import library) or a misnamed .obj, in which case it would determine which type is was when it opened the file, and use it accordingly. But in anycase, naming either file type as .dll is just perverse. I guess what I'm saying here is that forget the .dll suffix when dealing with linking.

        Or does the gcc linker know how to resolve entrypoints directly against a .dll/.so?

        This is something that I remember questioning years ago when I first started building .dlls and trying to link them to .exes. If link.exe can generate an import library at the same time as it is building a .dll. And implib can generate an import library from a .dll. Why the hell can't we cut out the middle men and have link.exe resolve directly against a .dll? This was under OS/2, and the answer I got from the MS guys back then was less than informative--the great MS/IBM split occured not long after. But that's a different topic and not your concern.

        There is a lot of stuff about how MM generates makefiles for win32 that confuses the begebbers out of me.

        For example: You say that MSVC doesn't respect the -L convention, but it does have a direct equivalent -libpath:dir which MM uses (eg. -libpath:"C:\Perl\lib\CORE") but then it goes on to use fully qualified pathnames for libs in that directory, eg. C:\Perl\lib\CORE\perl58.lib.

        Hmmm ... I wonder how much work that involves. I think that's the way it already works on nix systems, so it might not be as much work as one expects. That it would entail a major split with the way Makefiles are written for the MSVC compiler is less than enticing, but it's the thought of "what else gets broken" that's the major deterrent :-)

        Strikes me if gcc can resolve a -lxxx switch to all those different file names, having MM generate full names for them on win32 just makes extra unnecessary work.

        Better for MM to generate a *nix style makefile and allow the *nix compiler that has been adapted for win32 environments, to account for the differences. Then again, if the win32 adapted compiler can resolve all those different prefix and suffix combinations to -lxxx, it seems perverse that they don't also try for a .lib suffix.

        I guess my bottom line is that whenever I've wanted to build something badly enough, including Gtk on one occasion, I managed to hack the generated makefile manually, enough to get it to work.

        But every time I've looked to work out how to get the resultant hacked makefile, to be generated that way in the first place, I've ended up getting entirely lost and frustrated with the whole object-oriented, 'executable configuration files' that is EU::MM (and Module::Build).


        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: [Win32] The '-l' switch, and for which files the linker looks.
by Anonymous Monk on Mar 08, 2008 at 15:10 UTC
    Has syphilis taken penicillin? Will he survive until tomorrow? Who killed Roger Rabbit?