I just ran into the problem that this function does nothing on macOS. Indeed, it only works on Linux with glibc or uClibc, and Cygwin. (There's equivalent but separate code for native Windows, of course.)
A little investigation suggests that macOS and other platforms could use dladdr to get this information. This seems rather obvious, so is there any reason this has not already been implemented? dladdr is not standardized, of course, but it does seem to be implemented on FreeBSD, NetBSD and OpenBSD. The only reason not to use it that I can think of is that it requires -ldl, but that seems a fairly small price to pay on platforms that don't have another solution. I tried it on macOS, and it worked as expected. I attach a proof of concept patch for current git master. Things I can think of that would need to be improved: check that the returned path isn't NULL, add the same support to the relocatable-lib module (I've just patched relocatable-lib-lgpl). But since it's so obvious, I thought I'd check first that there isn't a fatal flaw! -- https://rrt.sc3d.org
From e03c16c8827d83d1a77ad19f121b9ee3ab0dd860 Mon Sep 17 00:00:00 2001 From: Reuben Thomas <r...@sc3d.org> Date: Thu, 1 May 2025 20:45:19 +0100 Subject: [PATCH] relocatable-lib-lgpl: use dladdr to get path to shared library Where neither the Windows nor Linux solution is available, use dladdr to get the path of a shared library. --- lib/relocatable.c | 10 ++++++++++ modules/relocatable-lib-lgpl | 3 +++ 2 files changed, 13 insertions(+) diff --git a/lib/relocatable.c b/lib/relocatable.c index 15b3bc442d..f83fb0ff17 100644 --- a/lib/relocatable.c +++ b/lib/relocatable.c @@ -71,6 +71,12 @@ # define GetModuleFileName GetModuleFileNameA #endif +#if !(defined _WIN32 && !defined __CYGWIN__) && !(defined __EMX__) && \ + !((defined __linux__ && (__GLIBC__ >= 2 || defined __UCLIBC__)) || defined __CYGWIN__) +/* We are on Unix and need dlopen. */ +#include <dlfcn.h> +#endif + /* Faked cheap 'bool'. */ #undef bool #undef false @@ -449,6 +455,10 @@ find_shared_library_fullname () } fclose (fp); } +#else + Dl_info info; + dladdr (find_shared_library_fullname, &info); + shared_library_fullname = strdup (info.dli_fname); #endif } diff --git a/modules/relocatable-lib-lgpl b/modules/relocatable-lib-lgpl index b8ecb51ef8..da905347cd 100644 --- a/modules/relocatable-lib-lgpl +++ b/modules/relocatable-lib-lgpl @@ -7,6 +7,7 @@ doc/relocatable.texi lib/relocatable.h lib/relocatable.c lib/relocatable.valgrind +m4/libdl.m4 m4/relocatable-lib.m4 m4/build-to-host.m4 @@ -18,9 +19,11 @@ gl_RELOCATABLE_LIBRARY if test $RELOCATABLE = yes; then AC_LIBOBJ([relocatable]) fi +gl_LIBDL Makefile.am: DEFS += -DNO_XMALLOC +lib_LDFLAGS += $(LIBDL) Include: "relocatable.h" -- 2.49.0