Fix filenames and paths used in DLL shared library generation by nirbheek · Pull Request #417 · mesonbuild/meson (original) (raw)

Shared library, name 'foo', version 'X[.Y[.Z]]'

host prefix suffix install_dir filenames
mingw 'lib' '.dll' bindir libfoo-X.Y.Z.dll <- libfoo-X.dll <- libfoo.dll

That is, technically, the "correct" way (see below for why it's not immediately useful). However, most projects use the libfoo-X.dll form only, as this is how libtool names DLLs by default.

DLLs normally go into bindir, but plugins are usually installed into libdir/name-of-the-application-or-library-the-plugin-is-for/ (the application is responsible for finding the plugins there). IIRC, meson allows install_dir to be changed by the user, so this should be OK.

It is not stressed in the comments above, but import libraries are not versioned in any way, and i know of no practical way to install multiple versions of an import library (from different versions of a -dev package). I wonder how various GNU distributions handle this...

The name of the DLL that a binary links to comes from the import library (if an import library is used; in case of direct DLL linking, it comes from the DLL file itself, probably). Anyway, if the import library libfoo.dll.a contains the name libfoo-3.dll, then linking to that import library does, in effect, link to libfoo-3.dll. The name that an import library contains seems to depend entirely on what -o option was. That is, gcc ... -Wl,--out-implib=libfoo.dll.a -o libfoo-1.dll will make an implib libfoo.dll.a that links to libfoo-1.dll.

This is why having real libfoo-X.Y.Z.dll and less-specifically-versioned symlinks libfoo-X.dll and libfoo.dll is not practical - programs linked with -lfoo will use the implib, and implib is hardcoded to link to the DLL it was made for, which in this case would be libfoo-X.Y.Z.dll. To link to libfoo-X.dll one would need to actually repeat the linking step multiple times, producing a real libfoo[-X[.Y[.Z]]].dll shared libs and libfooSOMETHING.dll.a implibs (SOMETHING to ensure that they don't overwrite each other), then deleting all DLLs except one, replacing them with symlinks. Projects would still need to specify -lfooSOMETHING to link to the more narrowly-versioned library. All that sounds really crazy and no one in their right mind would do this (and indeed, i haven't seen anyone doing this).

So yes, libfoo-X.dll is what 99.9% of all libtool-using projects have on Windows.

CMake-built DLLs and implibs use anything, but can be coerced into using libfoo-X.dll and libfoo.dll.a by specifying some special arguments (at least 80% of existing CMake-using projects do not specify these special arguments).

Niche and custom buildsystems use arbitrary naming (usually fooX.dll or foo.dll).

MinGW does not use soname. If that option is provided, ld will silently ignore it.

Direct linking to DLLs without an import library is supported, but:

  1. Either bindir (where DLLs are) must be in -L path, or libfoo.dll.a files must be symlinks to their respective DLLs
  2. See the numbered list at the end of the section (the link above) for reasons why import libraries might be used instead of direct DLL linkage
  3. I vaguely remember some problem in replacing all .dll.a files with links to DLLs, but i can't remember what the problem was (maybe autotools tests didn't work correctly? Or some tooling assumed that .dll.a files are actually ARchives, not PE files? Can't remember).

It is possible to produce an import library for existing DLL (i.e. without the necessity of --out-implib at link time), but it requires a .def file. Such .def file can be generated from a DLL too, or written by hand. That said, this process can have many gotchas and exotic corner-cases that i am not aware of (i used this trick only for %1 of all packages i've made).

Debug symbol file, name 'foo'

host method prefix suffix install_dir
mingw debug-link * * *
mingw build-id * * *

MinGW-gcc and MinGW-gdb seem to have full support for separate debug info files
I have used debug-link method (and can confirm that it works) with the /foo/bar/libfoo-X.dll -> /foo/bar/libfoo-X.dll.dbg convention myself (objcopy and gdb have some undocumented kinks, at least on Windows, which makes generating separate debug info files harder than it should be, but it's still doable), but if documentation is to be believed, debuginfo files can be located in a specially-designated global directory too.
build-id method seems to be working as well (my gcc-4.9.2 does not recognize --build-id option, but ld does, when passed via -Wl,), although i have absolutely no experience in using it and did not check that mingw-gdb picks up the debuginfo files successfully.

Either way, the name of the debuginfo file is baked into a shared library, and is either arbitrary (debug-link) or random (build-id; unless you specify a particular build-id via --build-id=0x...).