Skip to content

Commit c7db273

Browse files
committed
Set LD_LIBRARY_PATH before starting Mono.
Mono doesn't observe the rpath set when the lib is built, so get the folder the Python shared object has been loaded from and add that to LD_LIBRARY_PATH. Without this, if there are multiple Pythons installed the wrong object can be loaded.
1 parent 5b9e0dd commit c7db273

File tree

1 file changed

+24
-3
lines changed

1 file changed

+24
-3
lines changed

src/monoclr/pynetinit.c

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,15 @@
1010
// Author: Christian Heimes <christian(at)cheimes(dot)de>
1111

1212
#include "pynetclr.h"
13+
#include "stdlib.h"
1314

1415
#ifndef _WIN32
1516
#include "dirent.h"
17+
#include "dlfcn.h"
18+
#include "libgen.h"
19+
#include "alloca.h"
1620
#endif
1721

18-
#if PY_MAJOR_VERSION > 2
19-
#include <stdlib.h>
20-
#endif
2122

2223
// initialize Mono and PythonNet
2324
PyNet_Args* PyNet_Init(int ext) {
@@ -97,6 +98,26 @@ void main_thread_handler (gpointer user_data) {
9798
MonoObject *exception = NULL;
9899

99100
#ifndef _WIN32
101+
// Get the filename of the python shared object and set
102+
// LD_LIBRARY_PATH so Mono can find it.
103+
Dl_info dlinfo = {0};
104+
if (0 != dladdr(&Py_Initialize, &dlinfo)) {
105+
char* fname = alloca(strlen(dlinfo.dli_fname) + 1);
106+
strcpy(fname, dlinfo.dli_fname);
107+
char* py_libdir = dirname(fname);
108+
char* ld_library_path = getenv("LD_LIBRARY_PATH");
109+
if (NULL == ld_library_path) {
110+
setenv("LD_LIBRARY_PATH", py_libdir, 1);
111+
} else {
112+
char* new_ld_library_path = alloca(strlen(py_libdir)
113+
+ strlen(ld_library_path)
114+
+ 2);
115+
strcpy(new_ld_library_path, py_libdir);
116+
strcat(new_ld_library_path, ":");
117+
strcat(new_ld_library_path, ld_library_path);
118+
setenv("LD_LIBRARY_PATH", py_libdir, 1);
119+
}
120+
}
100121

101122
//get python path system variable
102123
PyObject* syspath = PySys_GetObject("path");

0 commit comments

Comments
 (0)