3
3
from setuptools import setup ,find_packages ,Command ,Extension
4
4
from wheel .bdist_wheel import bdist_wheel
5
5
from setuptools .command .build_ext import build_ext
6
+ import distutils
6
7
from subprocess import check_output ,check_call
7
8
8
9
import sys ,os
9
10
10
11
PY_MAJOR = sys .version_info [0 ]
11
12
PY_MINOR = sys .version_info [1 ]
12
13
14
+ CONFIGURED_PROPS = "configured.props"
13
15
14
16
15
17
def _get_interop_filename ():
@@ -24,10 +26,11 @@ def _get_interop_filename():
24
26
return os .path .join ("src" ,"runtime" ,interop_filename )
25
27
26
28
27
- def _get_flags ():
29
+ def _write_configure_props ():
28
30
# Up to Python 3.2 sys.maxunicode is used to determine the size of
29
31
# Py_UNICODE, but from 3.3 onwards Py_UNICODE is a typedef of wchar_t.
30
32
import ctypes
33
+
31
34
unicode_width = ctypes .sizeof (ctypes .c_wchar )
32
35
33
36
defines = [
@@ -44,18 +47,41 @@ def _get_flags():
44
47
if "m" in sys .abiflags :
45
48
defines .append ("PYTHON_WITH_PYMALLOC" )
46
49
47
- flags = []
48
-
49
50
# check the interop file exists, and create it if it doesn't
50
51
interop_file = _get_interop_filename ()
51
52
if not os .path .exists (interop_file ):
52
53
print ("Creating {0}" .format (interop_file ))
53
54
geninterop = os .path .join ("tools" ,"geninterop" ,"geninterop.py" )
54
55
check_call ([sys .executable ,geninterop ,interop_file ])
55
-
56
- flags .append ("-p:PythonInteropFile=\" {}\" " .format (os .path .basename (interop_file )))
57
- flags .append ("-p:DefineConstants=\" {}\" " .format (" " .join (defines )))
58
- return flags
56
+
57
+ import xml .etree .ElementTree as ET
58
+
59
+ proj = ET .Element ("Project" )
60
+ props = ET .SubElement (proj ,"PropertyGroup" )
61
+ f = ET .SubElement (props ,"PythonInteropFile" )
62
+ f .text = os .path .basename (interop_file )
63
+
64
+ c = ET .SubElement (props ,"ConfiguredConstants" )
65
+ c .text = " " .join (defines )
66
+
67
+ ET .ElementTree (proj ).write (CONFIGURED_PROPS )
68
+
69
+
70
+ class Configure (Command ):
71
+ """Configure command"""
72
+
73
+ description = "Configure the pythonnet build"
74
+ user_options = []
75
+
76
+ def initialize_options (self ):
77
+ pass
78
+
79
+ def finalize_options (self ):
80
+ pass
81
+
82
+ def run (self ):
83
+ self .announce ("Writing configured.props..." ,level = distutils .log .INFO )
84
+ _write_configure_props ()
59
85
60
86
61
87
class DotnetLib (Extension ):
@@ -86,6 +112,13 @@ def run(self):
86
112
dotnet_modules = [lib for lib in orig_modules if isinstance (lib ,DotnetLib )]
87
113
other_modules = [lib for lib in orig_modules if not isinstance (lib ,DotnetLib )]
88
114
115
+ if dotnet_modules :
116
+ if os .path .isfile (CONFIGURED_PROPS ):
117
+ self .announce ("Already configured" ,level = distutils .log .INFO )
118
+ else :
119
+ self .announce ("Writing configured.props..." ,level = distutils .log .INFO )
120
+ _write_configure_props ()
121
+
89
122
for lib in dotnet_modules :
90
123
output = lib .args .pop ("output" )
91
124
opts = sum (
@@ -97,7 +130,6 @@ def run(self):
97
130
)
98
131
99
132
opts .extend (["--configuration" ,self .dotnet_config ])
100
- opts .extend (_get_flags ())
101
133
opts .extend (["--output" ,os .path .join (self .build_lib ,output )])
102
134
103
135
self .spawn (["dotnet" ,"build" ,lib .path ]+ opts )
@@ -138,7 +170,9 @@ def finalize_options(self):
138
170
139
171
try :
140
172
mono_libs = check_output ("pkg-config --libs mono-2" ,shell = True ,encoding = "utf8" )
141
- mono_cflags = check_output ("pkg-config --cflags mono-2" ,shell = True ,encoding = "utf8" )
173
+ mono_cflags = check_output (
174
+ "pkg-config --cflags mono-2" ,shell = True ,encoding = "utf8"
175
+ )
142
176
cflags = mono_cflags .strip ()
143
177
libs = mono_libs .strip ()
144
178
@@ -153,13 +187,14 @@ def finalize_options(self):
153
187
ext_modules .append (clr_ext )
154
188
except Exception :
155
189
import traceback
190
+
156
191
traceback .print_exc ()
157
192
print ("Failed to find mono libraries via pkg-config, skipping the Mono CLR loader" )
158
193
159
194
160
195
setup (
161
196
name = "pythonnet" ,
162
- version = "3.0.0- dev1" ,
197
+ version = "3.0.0. dev1" ,
163
198
description = ".Net and Mono integration for Python" ,
164
199
url = "https://pythonnet.github.io/" ,
165
200
license = "MIT" ,
@@ -168,7 +203,11 @@ def finalize_options(self):
168
203
install_requires = ["pycparser" ],
169
204
long_description = long_description ,
170
205
# data_files=[("{install_platlib}", ["{build_lib}/pythonnet"])],
171
- cmdclass = {"build_ext" :BuildDotnet ,"bdist_wheel" :bdist_wheel_patched },
206
+ cmdclass = {
207
+ "build_ext" :BuildDotnet ,
208
+ "bdist_wheel" :bdist_wheel_patched ,
209
+ "configure" :Configure ,
210
+ },
172
211
ext_modules = ext_modules ,
173
212
classifiers = [
174
213
"Development Status :: 5 - Production/Stable" ,