1
1
#!/usr/bin/env python3
2
2
#
3
- # Copyright 2015-2021 the openage authors. See copying.md for legal info.
3
+ # Copyright 2015-2025 the openage authors. See copying.md for legal info.
4
4
5
5
"""
6
6
Runs Cython on all modules that were listed via add_cython_module.
@@ -73,7 +73,7 @@ def remove_if_exists(filename):
73
73
filename .unlink ()
74
74
75
75
76
- def cythonize_wrapper (modules , ** kwargs ):
76
+ def cythonize_wrapper (modules , force_optimized_lib = False , ** kwargs ):
77
77
""" Calls cythonize, filtering useless warnings """
78
78
bin_dir , bin_modules = kwargs ['build_dir' ], []
79
79
src_dir , src_modules = Path .cwd (), []
@@ -88,29 +88,40 @@ def cythonize_wrapper(modules, **kwargs):
88
88
with redirect_stdout (cython_filter ):
89
89
if src_modules :
90
90
cythonize (src_modules , ** kwargs )
91
- windows_include_python_debug_build_wrapper (src_modules , bin_dir )
91
+ if sys .platform == 'win32' and force_optimized_lib :
92
+ windows_use_optimized_lib_python (src_modules , bin_dir )
92
93
93
94
if bin_modules :
94
95
os .chdir (bin_dir )
95
96
cythonize (bin_modules , ** kwargs )
96
- windows_include_python_debug_build_wrapper (bin_modules , bin_dir )
97
+ if sys .platform == 'win32' and force_optimized_lib :
98
+ windows_use_optimized_lib_python (bin_modules , bin_dir )
97
99
os .chdir (src_dir )
98
100
99
101
100
- def windows_include_python_debug_build_wrapper (modules , path ):
102
+ def windows_use_optimized_lib_python (modules , path ):
103
+ """
104
+ Add an #ifdef statement in cythonized .cpp files to temporarily undefine _DEBUG before
105
+ #include "Python.h"
106
+
107
+ This function modifies the generated C++ files from Cython to prevent linking to
108
+ the debug version of the Python library on Windows. The debug version of the
109
+ Python library cannot import Python libraries that contain extension modules.
110
+ """
111
+
101
112
for module in modules :
102
113
module = str (module )
103
- if ( path ) :
114
+ if path :
104
115
module = path + "\\ " + module
105
116
module = module .removesuffix (".py" ).removesuffix (".pyx" )
106
117
module = module + ".cpp"
107
- with open (module , "r" ) as file :
118
+ with open (module , "r" , encoding = 'utf8' ) as file :
108
119
text = file .read ()
109
120
text = text .replace ("#include \" Python.h\" " ,
110
121
"#ifdef _DEBUG\n #define _DEBUG_WAS_DEFINED\n #undef _DEBUG\n #endif\n \
111
122
#include \" Python.h\" \n #ifdef _DEBUG_WAS_DEFINED\n #define _DEBUG\n \
112
123
#undef _DEBUG_WAS_DEFINED\n #endif" , 1 )
113
- with open (module , "w" ) as file :
124
+ with open (module , "w" , encoding = 'utf8' ) as file :
114
125
file .write (text )
115
126
116
127
@@ -144,6 +155,8 @@ def main():
144
155
))
145
156
cli .add_argument ("--threads" , type = int , default = cpu_count (),
146
157
help = "number of compilation threads to use" )
158
+ cli .add_argument ("--force_optimized_lib" , action = "store_true" ,
159
+ help = "edit compiled .cpp files to link to optimized version of python libary" )
147
160
args = cli .parse_args ()
148
161
149
162
# cython emits warnings on using absolute paths to modules
@@ -178,12 +191,12 @@ def main():
178
191
# writing funny lines at the head of each file.
179
192
cythonize_args ['language' ] = 'c++'
180
193
181
- cythonize_wrapper (modules , ** cythonize_args )
194
+ cythonize_wrapper (modules , args . force_optimized_lib , ** cythonize_args )
182
195
183
196
# build standalone executables that embed the py interpreter
184
197
Options .embed = "main"
185
198
186
- cythonize_wrapper (embedded_modules , ** cythonize_args )
199
+ cythonize_wrapper (embedded_modules , args . force_optimized_lib , ** cythonize_args )
187
200
188
201
# verify depends
189
202
from Cython .Build .Dependencies import _dep_tree
0 commit comments