Skip to content

Commit 03afffa

Browse files
authored
allow additional search paths (#25)
For certain build systems (e.g. nix, guix, spack) we need to tell libwhich about non-standard search paths. Currently the only way of doing so is by setting `LD_LIBRARY_PATH`, which difficult to scope just to libwhich execution, and as a result can influence the runtime behavior of other executables. This patch allows you to set `LIBWHICH_LIBRARY_PATH=x:y:z`, which libwhich uses to set `LD_LIBRARY_PATH` before it reruns itself, so `dlopen(...)` can locate libraries in these search paths.
1 parent ccec856 commit 03afffa

1 file changed

Lines changed: 21 additions & 0 deletions

File tree

libwhich.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,16 @@ int mainCRTStartup(void) // actually is WINAPI without mangling (but ABI is the
133133
#else
134134
#include <dlfcn.h>
135135
#include <stdio.h>
136+
#include <unistd.h>
136137
typedef char WCHAR;
137138
#define T(str) str
139+
140+
#if defined(__APPLE__)
141+
#define LIBWHICH_LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
142+
#else
143+
#define LIBWHICH_LD_LIBRARY_PATH "LD_LIBRARY_PATH"
144+
#endif
145+
138146
#endif
139147

140148
#ifndef RTLD_LAZY
@@ -336,6 +344,19 @@ int main(int argc, STR *argv)
336344
fputs(T(")\n"), stdout);
337345
return 1;
338346
}
347+
#ifndef _WIN32
348+
// If LIBWHICH_LIBRARY_PATH is set, re-run the program with LD_LIBRARY_PATH
349+
// or DYLD_LIBRARY_PATH set instead, so dlopen picks up these library paths.
350+
const char *libwhich_path = getenv("LIBWHICH_LIBRARY_PATH");
351+
if (libwhich_path) {
352+
setenv(LIBWHICH_LD_LIBRARY_PATH, libwhich_path, 1);
353+
unsetenv("LIBWHICH_LIBRARY_PATH");
354+
if (execvp(argv[0], (char **)argv) == -1) {
355+
perror("libwhich: execvp");
356+
return 1;
357+
}
358+
}
359+
#endif
339360
struct vector_t before = dllist();
340361
void *lib = dlopen(libname, RTLD_LAZY);
341362
if (!lib) {

0 commit comments

Comments
 (0)