Geoffrey Broadwell schrieb:
I've noticed several patches from you today in which you're adding code
to try to load an existing library under additional library names for
cygwin support. It's beginning to look like this is a common operation.
See "=item loadlib DLL versioning" in README_cygwin.pod
I posted such a proposal some time ago to some ffi knowledgeable lists.
(parrot, cffi, ...)
Recently I had the idea that mingw/cygwin/MSVC can profit from resolving
the needed dll names from the resp. import library.
This name is always fixed without versioning and arch prefixes.
I needed this for the OpenGL bindings, so I wrote a utility routine in
runtime/parrot/library/OpenGL.pir called _load_lib_with_fallbacks() that
encapsulates this sort of fallback behavior.
It would be easy to split that routine out into a utility library, and
use it everywhere, but I've got some concerns for which I'd like input
from the Parrot Porters:
1. If this is indeed a really common operation, it might be worth
moving it "down the stack". Instead of using a PIR library,
perhaps we should allow the loadlib opcode to take arguments
other than a single simple string, and use the additional info
to define fallbacks that are automatically tried.
Arguments yes, but no list of fallback names please.
As optional argument the version number is okay.
2. It's not clear to me that a simple list of names is appropriate
everywhere. It works when all the variations are unique (and
fully compatible), but it doesn't work so well when the name of
library A on one platform is the same as library B on another
platform. But perhaps this is a problem that doesn't exist in
the wild, or is so rare it's simpler just to special case it.
It exists in the ffi world since ages and has not been solved.
3. If we try to do something "smarter" for #2, I fear being sucked
into a vortex of complexity, and I really don't want to go there.
It's not too much of a complex technical problem.
I report my proposal here because I cannot find it anymore.
Thanks to the Windows DLL Hell L<http://en.wikipedia.org/wiki/DLL_hell>
and the impossibility of file hardlinks, windows dll names are hopefully
versioned, so either the loadlib function or the various pir's needs
more logic for maintainance convenience.
Keep the lib_paths and share_ext search, add more name munging for
special platforms.
Either
1) add the version to each loadlib call, and stem the version from
POSIX versions within get_path().
loadlib lib, 'libSDL-1.2.so.0'
=> try: libSDL-1.2.so.0, libSDL-1.2.so
stemmed: libSDL.so
on WIN32: SDL-1.2.dll, SDL.dll
on cygwin: cygSDL-1.2.dll, cygSDL.dll
Maybe also detect the "-1.2.so.0" and convert it to "-1.2.0.dll"
2) add an optional version argument to loadlib. (preferred)
loadlib lib, 'SDL', '1.2.0'
=> Try: first always prefix with "lib"
libSDL-1.2.0.so, libSDL-1.2.so.0, libSDL-1.2.so, libSDL.so
other rules stay as they are. (lib_paths + share_ext)
on WIN32: no lib prefix and try versions.
SDL-1-2-0.dll, SDL-1-2.dll, SDL-1.2.0.dll, SDL-1.2.dll, SDL.dll
on cygwin: cyg prefix and try versions with '.' and '-'.
cygSDL-1.2.dll, cygSDL-1.2.0.dll, cygSDL-1-2-0.dll, cygSDL-1-2.dll
All the pir's for the latest packaged libraries are fixed with RT#51328.
RT#51328 also applies the addional lib => cyg dll logic, but does not
help with versioned dll's, as for ncurses and SDL most prominently.
Examples what we want to avoid:
loadlib $P1, 'libform'
+if $P1 goto has_lib
+loadlib $P1, 'cygform-8'
+has_lib:
loadlib $P1, 'libncurses'
+if $P1 goto has_lib1
+loadlib $P1, 'cygncurses-8'
+has_lib1:
# third try
loadlib libsdl, 'libSDL-1.2.so.0'
+ loadlib libsdl, 'cygSDL-1-2-0'
+ $I0 = typeof libsdl
+ if $I0 != .Undef goto OK
loadlib image_lib, 'libSDL_image-1.2.so.0'
$I0 = typeof image_lib
if $I0 != .Undef goto OK_HINT2
+ loadlib image_lib, 'cygSDL_image-1-2-0'
+ $I0 = typeof image_lib
+ if $I0 != .Undef goto OK
+
See also other ffi's, such as cffi, how they do deal or not with this
problem. Years ago I wrote an overview at
http://autocad.xarch.at/lisp/ffis.html