Skip to content

Commit 2910074

Browse files
authored
Link stdc++ and force-preload libmono on Linux (#1139)
* Fix geninterop.py include paths * Ensure that monoclr is linked as a C++ library * Force preload libmono and fix bug in LD_LIBRARY_PATH forwarding
1 parent 960286d commit 2910074

File tree

4 files changed

+22
-2
lines changed

4 files changed

+22
-2
lines changed

setup.py

+1
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ def _build_monoclr(self):
404404
# build the clr python module
405405
clr_ext = Extension(
406406
"clr",
407+
language="c++",
407408
sources=["src/monoclr/pynetinit.c", "src/monoclr/clrmod.c"],
408409
extra_compile_args=cflags.split(" "),
409410
extra_link_args=libs.split(" "),

src/monoclr/pynetclr.h

+8
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@
1212
#define MONO_DOMAIN "Python.Runtime"
1313
#define PR_ASSEMBLY "Python.Runtime.dll"
1414

15+
#ifdef __cplusplus
16+
extern "C" {
17+
#endif
18+
1519
typedef struct
1620
{
1721
MonoDomain *domain;
@@ -29,4 +33,8 @@ void PyNet_Finalize(PyNet_Args *);
2933
void main_thread_handler(PyNet_Args *user_data);
3034
char *PyNet_ExceptionToString(MonoObject *);
3135

36+
#ifdef __cplusplus
37+
}
38+
#endif
39+
3240
#endif // PYNET_CLR_H

src/monoclr/pynetinit.c

+10-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,15 @@ PyNet_Args *PyNet_Init(int ext)
1919
pn_args->shutdown = NULL;
2020
pn_args->module = NULL;
2121

22+
#ifdef __linux__
23+
// Force preload libmono-2.0 as global. Without this, on some systems
24+
// symbols from libmono are not found by libmononative (which implements
25+
// some of the System.* namespaces). Since the only happened on Linux so
26+
// far, we hardcode the library name, load the symbols into the global
27+
// namespace and leak the handle.
28+
dlopen("libmono-2.0.so", RTLD_LAZY | RTLD_GLOBAL);
29+
#endif
30+
2231
if (ext == 0)
2332
{
2433
pn_args->init_name = "Python.Runtime:Initialize()";
@@ -122,7 +131,7 @@ void main_thread_handler(PyNet_Args *user_data)
122131
strcpy(new_ld_library_path, py_libdir);
123132
strcat(new_ld_library_path, ":");
124133
strcat(new_ld_library_path, ld_library_path);
125-
setenv("LD_LIBRARY_PATH", py_libdir, 1);
134+
setenv("LD_LIBRARY_PATH", new_ld_library_path, 1);
126135
}
127136
}
128137

tools/geninterop/geninterop.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,8 @@ def preprocess_python_headers():
174174
include_py = sysconfig.get_config_var("INCLUDEPY")
175175
include_dirs.append(include_py)
176176

177+
include_args = [c for p in include_dirs for c in ["-I", p]]
178+
177179
defines = [
178180
"-D", "__attribute__(x)=",
179181
"-D", "__inline__=inline",
@@ -198,7 +200,7 @@ def preprocess_python_headers():
198200
defines.extend(("-D", "PYTHON_WITH_WIDE_UNICODE"))
199201

200202
python_h = os.path.join(include_py, "Python.h")
201-
cmd = ["clang", "-pthread", "-I"] + include_dirs + defines + ["-E", python_h]
203+
cmd = ["clang", "-pthread"] + include_args + defines + ["-E", python_h]
202204

203205
# normalize as the parser doesn't like windows line endings.
204206
lines = []

0 commit comments

Comments
 (0)