Skip to content

Commit 5062377

Browse files
committed
Changes to the monoclr build so it builds for python 3.
1 parent 6eb59ec commit 5062377

File tree

4 files changed

+170
-24
lines changed

4 files changed

+170
-24
lines changed

setup.py

+11
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,17 @@ def build_extension(self, ext):
115115
if CONFIG == "Debug":
116116
defines.extend(["DEBUG", "TRACE"])
117117

118+
if sys.platform != "win32" and DEVTOOLS == "Mono":
119+
defines.append("MONO_LINUX")
120+
121+
if hasattr(sys, "abiflags"):
122+
if "d" in sys.abiflags:
123+
defines.append("PYTHON_WITH_PYDEBUG")
124+
if "m" in sys.abiflags:
125+
defines.append("PYTHON_WITH_PYMALLOC")
126+
if "u" in sys.abiflags:
127+
defines.append("PYTHON_WITH_WIDE_UNICODE")
128+
118129
cmd = [
119130
_xbuild,
120131
"pythonnet.sln",

src/monoclr/clrmod.c

+43-14
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,50 @@ PyDoc_STRVAR(clr_module_doc,
2525
static PyNet_Args *pn_args;
2626
char** environ = NULL;
2727

28+
#if PY_MAJOR_VERSION >= 3
29+
static struct PyModuleDef clrdef = {
30+
PyModuleDef_HEAD_INIT,
31+
"clr", /* m_name */
32+
clr_module_doc, /* m_doc */
33+
-1, /* m_size */
34+
clr_methods, /* m_methods */
35+
NULL, /* m_reload */
36+
NULL, /* m_traverse */
37+
NULL, /* m_clear */
38+
NULL, /* m_free */
39+
};
40+
#endif
41+
42+
static PyObject *_initclr() {
43+
PyObject *m;
44+
45+
/* Create the module and add the functions */
46+
#if PY_MAJOR_VERSION >= 3
47+
m = PyModule_Create(&clrdef);
48+
#else
49+
m = Py_InitModule3("clr", clr_methods, clr_module_doc);
50+
#endif
51+
if (m == NULL)
52+
return;
53+
PyModule_AddObject(m, "facade", Py_True);
54+
Py_INCREF(Py_True);
55+
56+
pn_args = PyNet_Init(1);
57+
if (pn_args->error) {
58+
return NULL;
59+
}
60+
return m;
61+
}
62+
63+
#if PY_MAJOR_VERSION >= 3
64+
PyMODINIT_FUNC
65+
PyInit_clr(void) {
66+
return _initclr();
67+
}
68+
#else
2869
PyMODINIT_FUNC
2970
initclr(void)
30-
{
31-
PyObject *m;
32-
33-
/* Create the module and add the functions */
34-
m = Py_InitModule3("clr", clr_methods, clr_module_doc);
35-
if (m == NULL)
36-
return;
37-
PyModule_AddObject(m, "facade", Py_True);
38-
Py_INCREF(Py_True);
39-
40-
pn_args = PyNet_Init(1);
41-
if (pn_args->error) {
42-
return;
43-
}
71+
_initclr();
4472
}
73+
#endif
4574

src/monoclr/python.c

+22
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,29 @@
1616

1717
#include <Python.h>
1818

19+
#if (PY_MAJOR_VERSION > 2)
20+
#include <wchar.h>
21+
#endif
22+
1923
int main(int argc, char **argv) {
24+
#if (PY_MAJOR_VERSION > 2)
25+
int i, result;
26+
size_t len;
27+
wchar_t **wargv = (wchar_t**)malloc(sizeof(wchar_t*)*argc);
28+
for (i=0; i<argc; ++ i) {
29+
len = strlen(argv[i]);
30+
wargv[i] = (wchar_t*)malloc(sizeof(wchar_t)*(len+1));
31+
if (len == mbsrtowcs(wargv[i], (const char**)&argv[i], len, NULL))
32+
wargv[i][len] = 0;
33+
}
34+
result = Py_Main(argc, wargv);
35+
for (i=0; i<argc; ++i) {
36+
free((void*)wargv[i]);
37+
}
38+
free((void*)wargv);
39+
return result;
40+
#else
2041
return Py_Main(argc, argv);
42+
#endif
2143
}
2244

src/runtime/runtime.cs

+94-10
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,50 @@ namespace Python.Runtime {
2525

2626
static class NativeMethods
2727
{
28+
#if MONO_LINUX
29+
static public IntPtr LoadLibrary(string fileName) {
30+
return dlopen(fileName, RTLD_NOW | RTLD_SHARED);
31+
}
32+
33+
static public void FreeLibrary(IntPtr handle) {
34+
dlclose(handle);
35+
}
36+
37+
static public IntPtr GetProcAddress(IntPtr dllHandle, string name) {
38+
// clear previous errors if any
39+
dlerror();
40+
var res = dlsym(dllHandle, name);
41+
var errPtr = dlerror();
42+
if (errPtr != IntPtr.Zero) {
43+
throw new Exception("dlsym: " + Marshal.PtrToStringAnsi(errPtr));
44+
}
45+
return res;
46+
}
47+
48+
const int RTLD_NOW = 2;
49+
const int RTLD_SHARED = 20;
50+
51+
[DllImport("libdl.so")]
52+
private static extern IntPtr dlopen(String fileName, int flags);
53+
54+
[DllImport("libdl.so")]
55+
private static extern IntPtr dlsym(IntPtr handle, String symbol);
56+
57+
[DllImport("libdl.so")]
58+
private static extern int dlclose(IntPtr handle);
59+
60+
[DllImport("libdl.so")]
61+
private static extern IntPtr dlerror();
62+
#else
2863
[DllImport("kernel32.dll")]
2964
public static extern IntPtr LoadLibrary(string dllToLoad);
3065

3166
[DllImport("kernel32.dll")]
3267
public static extern IntPtr GetProcAddress(IntPtr hModule, string procedureName);
3368

34-
3569
[DllImport("kernel32.dll")]
3670
public static extern bool FreeLibrary(IntPtr hModule);
71+
#endif
3772
}
3873

3974
public class Runtime {
@@ -54,49 +89,96 @@ public class Runtime {
5489
#endif
5590

5691
#if (PYTHON23)
57-
public const string dll = "python23";
5892
public const string pyversion = "2.3";
5993
public const int pyversionnumber = 23;
6094
#endif
6195
#if (PYTHON24)
62-
public const string dll = "python24";
6396
public const string pyversion = "2.4";
6497
public const int pyversionnumber = 24;
6598
#endif
6699
#if (PYTHON25)
67-
public const string dll = "python25";
68100
public const string pyversion = "2.5";
69101
public const int pyversionnumber = 25;
70102
#endif
71103
#if (PYTHON26)
72-
public const string dll = "python26";
73104
public const string pyversion = "2.6";
74105
public const int pyversionnumber = 26;
75106
#endif
76107
#if (PYTHON27)
77-
public const string dll = "python27";
78108
public const string pyversion = "2.7";
79109
public const int pyversionnumber = 27;
80110
#endif
81111
#if (PYTHON32)
82-
public const string dll = "python32";
83112
public const string pyversion = "3.2";
84113
public const int pyversionnumber = 32;
85114
#endif
86115
#if (PYTHON33)
87-
public const string dll = "python33";
88116
public const string pyversion = "3.3";
89117
public const int pyversionnumber = 33;
90118
#endif
91119
#if (PYTHON34)
92-
public const string dll = "python34";
93120
public const string pyversion = "3.4";
94121
public const int pyversionnumber = 34;
95122
#endif
96123
#if ! (PYTHON23 || PYTHON24 || PYTHON25 || PYTHON26 || PYTHON27 || PYTHON32 || PYTHON33 || PYTHON34)
97124
#error You must define one of PYTHON23 to PYTHON34
98125
#endif
99126

127+
#if (PYTHON23)
128+
internal const string dllBase = "python23";
129+
#endif
130+
#if (PYTHON24)
131+
internal const string dllBase = "python24";
132+
#endif
133+
#if (PYTHON25)
134+
internal const string dllBase = "python25";
135+
#endif
136+
#if (PYTHON26)
137+
internal const string dllBase = "python26";
138+
#endif
139+
#if (PYTHON27)
140+
internal const string dllBase = "python27";
141+
#endif
142+
#if (MONO_LINUX)
143+
#if (PYTHON32)
144+
internal const string dllBase = "python3.2";
145+
#endif
146+
#if (PYTHON33)
147+
internal const string dllBase = "python3.3";
148+
#endif
149+
#if (PYTHON34)
150+
internal const string dllBase = "python3.4";
151+
#endif
152+
#else
153+
#if (PYTHON32)
154+
internal const string dllBase = "python32";
155+
#endif
156+
#if (PYTHON33)
157+
internal const string dllBase = "python33";
158+
#endif
159+
#if (PYTHON34)
160+
internal const string dllBase = "python34";
161+
#endif
162+
#endif
163+
164+
#if (PYTHON_WITH_PYDEBUG)
165+
internal const string dllWithPyDebug = "d";
166+
#else
167+
internal const string dllWithPyDebug = "";
168+
#endif
169+
#if (PYTHON_WITH_PYMALLOC)
170+
internal const string dllWithPyMalloc = "m";
171+
#else
172+
internal const string dllWithPyMalloc = "";
173+
#endif
174+
#if (PYTHON_WITH_WIDE_UNICODE)
175+
internal const string dllWithWideUnicode = "u";
176+
#else
177+
internal const string dllWithWideUnicode = "";
178+
#endif
179+
180+
public const string dll = dllBase + dllWithPyDebug + dllWithPyMalloc + dllWithWideUnicode;
181+
100182
// set to true when python is finalizing
101183
internal static Object IsFinalizingLock = new Object();
102184
internal static bool IsFinalizing = false;
@@ -108,7 +190,7 @@ public class Runtime {
108190
/// Intitialize the runtime...
109191
/// </summary>
110192
internal static void Initialize() {
111-
193+
112194
is32bit = IntPtr.Size == 4;
113195

114196
if (0 == Runtime.Py_IsInitialized())
@@ -211,8 +293,10 @@ internal static void Initialize() {
211293
#if (PYTHON32 || PYTHON33 || PYTHON34)
212294
IntPtr dll = NativeMethods.LoadLibrary(Runtime.dll);
213295
_PyObject_NextNotImplemented = NativeMethods.GetProcAddress(dll, "_PyObject_NextNotImplemented");
296+
#if !MONO_LINUX
214297
NativeMethods.FreeLibrary(dll);
215298
#endif
299+
#endif
216300

217301

218302
// Determine whether we need to wrap exceptions for versions of

0 commit comments

Comments
 (0)