99from Cython .Build import cythonize
1010
1111
12+ def parse_env_bool (name : str ) -> bool | None :
13+ """Return a boolean override from an environment variable."""
14+ value = os .getenv (name )
15+ if value is None :
16+ return None
17+
18+ normalized = value .strip ().lower ()
19+ if normalized in {"1" , "true" , "yes" , "on" }:
20+ return True
21+ if normalized in {"0" , "false" , "no" , "off" }:
22+ return False
23+
24+ raise ValueError (
25+ f"Environment variable { name !r} must be one of 1/0, true/false, yes/no, on/off"
26+ )
27+
28+
1229class BuildConfig :
1330 """Centralized build configuration management for itzi package.
1431
@@ -22,16 +39,25 @@ def __init__(self):
2239 self .is_wheel_build = os .getenv ("ITZI_BDIST_WHEEL" ) is not None
2340 self .platform = self .detect_platform ()
2441 self .architecture = self .detect_architecture ()
42+ self .openmp_override = parse_env_bool ("ITZI_USE_OPENMP" )
43+ self .use_openmp = self .detect_openmp_usage ()
2544 self .compiler_type = None # Set during build
45+ self .base_compile_args_plain = ["-O3" , "-w" ]
2646 self .base_compile_args_unix = ["-O3" , "-w" , "-fopenmp" ]
27- self .base_compile_args_macos = [
28- "-O3" ,
29- "-w" ,
30- "-Xpreprocessor" ,
31- "-fopenmp" ,
32- ]
47+ self .base_compile_args_macos = ["-O3" , "-w" , "-Xpreprocessor" , "-fopenmp" ]
3348 self .base_compile_args_msvc = ["/openmp" , "/Ox" ]
34- self .base_link_args_unix = ["-lgomp" , "-fopenmp" ]
49+ self .base_compile_args_msvc_plain = ["/Ox" ]
50+ self .base_link_args_unix = ["-lgomp" ]
51+
52+ def detect_openmp_usage (self ) -> bool :
53+ """Return whether OpenMP should be enabled for this build."""
54+ if self .openmp_override is not None :
55+ return self .openmp_override
56+
57+ if self .is_wheel_build and self .platform == "macos" and self .architecture == "arm64" :
58+ return False
59+
60+ return True
3561
3662 def detect_platform (self ):
3763 """Detect current platform (Linux, Windows, macOS)"""
@@ -73,20 +99,39 @@ def _get_source_optimization_flags(self):
7399
74100 if self .compiler_type == "msvc" :
75101 # Conservative MSVC flags for source builds
76- compile_args = self .base_compile_args_msvc
102+ if self .use_openmp :
103+ compile_args = self .base_compile_args_msvc .copy ()
104+ else :
105+ compile_args = self .base_compile_args_msvc_plain .copy ()
77106 link_args = []
78107 elif self .compiler_type == "mingw32" :
79- compile_args = self .base_compile_args_unix + ["-lgomp" , "-lpthread" , "-march=native" ]
80- link_args = ["-lgomp" , "-lpthread" ]
108+ if self .use_openmp :
109+ compile_args = self .base_compile_args_unix + [
110+ "-lgomp" ,
111+ "-lpthread" ,
112+ "-march=native" ,
113+ ]
114+ link_args = ["-lgomp" , "-lpthread" ]
115+ else :
116+ compile_args = self .base_compile_args_plain + ["-lpthread" , "-march=native" ]
117+ link_args = ["-lpthread" ]
81118 elif self .compiler_type == "unix" :
82119 if self .platform == "macos" :
83120 # macOS specific handling
84- compile_args = self .base_compile_args_macos + ["-march=native" ]
85- link_args = ["-lomp" ]
121+ if self .use_openmp :
122+ compile_args = self .base_compile_args_macos + ["-march=native" ]
123+ link_args = ["-lomp" ]
124+ else :
125+ compile_args = self .base_compile_args_plain + ["-march=native" ]
126+ link_args = []
86127 else :
87128 # Linux and other Unix systems
88- compile_args = self .base_compile_args_unix + ["-march=native" ]
89- link_args = self .base_link_args_unix
129+ if self .use_openmp :
130+ compile_args = self .base_compile_args_unix + ["-march=native" ]
131+ link_args = self .base_link_args_unix
132+ else :
133+ compile_args = self .base_compile_args_plain + ["-march=native" ]
134+ link_args = []
90135
91136 return compile_args , link_args
92137
@@ -96,55 +141,76 @@ def _get_wheel_optimization_flags(self):
96141 link_args = []
97142
98143 if self .compiler_type == "msvc" :
144+ if self .use_openmp :
145+ compile_args = self .base_compile_args_msvc .copy ()
146+ else :
147+ compile_args = self .base_compile_args_msvc_plain .copy ()
99148 if self .architecture == "x86_64" :
100- compile_args = self . base_compile_args_msvc + [ "/arch:AVX2" ]
149+ compile_args . append ( "/arch:AVX2" )
101150 elif self .architecture == "arm64" :
102- compile_args = self .base_compile_args_msvc + ["/arch:armv8.2" ]
103- else :
104- compile_args = self .base_compile_args_msvc
151+ compile_args .append ("/arch:armv8.2" )
105152 link_args = []
106153
107154 elif self .compiler_type == "mingw32" :
108155 if self .architecture == "x86_64" :
109- compile_args = self .base_compile_args_unix + [
110- "-lgomp" ,
111- "-lpthread" ,
112- "-march=x86-64-v3" ,
113- ]
156+ if self .use_openmp :
157+ compile_args = self .base_compile_args_unix + [
158+ "-lgomp" ,
159+ "-lpthread" ,
160+ "-march=x86-64-v3" ,
161+ ]
162+ else :
163+ compile_args = self .base_compile_args_plain + ["-lpthread" , "-march=x86-64-v3" ]
114164 elif self .architecture == "arm64" :
115- compile_args = self .base_compile_args_unix + ["-march=armv8-a+simd" ]
165+ if self .use_openmp :
166+ compile_args = self .base_compile_args_unix + ["-march=armv8-a+simd" ]
167+ else :
168+ compile_args = self .base_compile_args_plain + ["-march=armv8-a+simd" ]
169+ else :
170+ if self .use_openmp :
171+ compile_args = self .base_compile_args_unix + ["-lgomp" , "-lpthread" ]
172+ else :
173+ compile_args = self .base_compile_args_plain + ["-lpthread" ]
174+ if self .use_openmp :
175+ link_args = ["-lgomp" , "-lpthread" ]
116176 else :
117- compile_args = self .base_compile_args_unix
118- link_args = ["-lgomp" , "-lpthread" ]
177+ link_args = ["-lpthread" ]
119178
120179 elif self .compiler_type == "unix" :
121180 if self .platform == "macos" :
122181 if self .architecture == "arm64" :
123- compile_args = self .base_compile_args_macos + ["-march=armv8-a+simd" ]
182+ if self .use_openmp :
183+ compile_args = self .base_compile_args_macos + ["-march=armv8-a+simd" ]
184+ else :
185+ compile_args = self .base_compile_args_plain + ["-march=armv8-a+simd" ]
124186 else :
125- compile_args = self .base_compile_args_macos
126- link_args = ["-lomp" ]
187+ if self .use_openmp :
188+ compile_args = self .base_compile_args_macos
189+ else :
190+ compile_args = self .base_compile_args_plain .copy ()
191+ link_args = ["-lomp" ] if self .use_openmp else []
127192 else :
128193 # Linux and other Unix systems
129194 if self .architecture == "x86_64" :
130- compile_args = self .base_compile_args_unix + ["-march=x86-64-v3" ]
195+ if self .use_openmp :
196+ compile_args = self .base_compile_args_unix + ["-march=x86-64-v3" ]
197+ else :
198+ compile_args = self .base_compile_args_plain + ["-march=x86-64-v3" ]
131199 elif self .architecture == "arm64" :
132- compile_args = self .base_compile_args_unix + ["-march=armv8-a+simd" ]
200+ if self .use_openmp :
201+ compile_args = self .base_compile_args_unix + ["-march=armv8-a+simd" ]
202+ else :
203+ compile_args = self .base_compile_args_plain + ["-march=armv8-a+simd" ]
133204 else :
134- compile_args = self .base_compile_args_unix
135- link_args = self .base_link_args_unix
205+ if self .use_openmp :
206+ compile_args = self .base_compile_args_unix .copy ()
207+ else :
208+ compile_args = self .base_compile_args_plain .copy ()
209+ link_args = self .base_link_args_unix if self .use_openmp else []
136210
137211 return compile_args , link_args
138212
139213
140- # Legacy compiler options for backward compatibility
141- copt = {
142- "msvc" : ["/openmp" , "/Ox" ],
143- "mingw32" : ["-O3" , "-w" , "-fopenmp" , "-lgomp" , "-lpthread" ],
144- "unix" : ["-O3" , "-w" , "-fopenmp" ],
145- }
146- lopt = {"mingw32" : ["-lgomp" , "-lpthread" ], "unix" : ["-lgomp" , "-fopenmp" ]}
147-
148214macos_includes = [
149215 "/opt/homebrew/include" ,
150216 "/usr/local/include" ,
@@ -167,6 +233,7 @@ def build_extensions(self):
167233 print (f"Build mode: { 'wheel' if build_config .is_wheel_build else 'source' } " )
168234 print (f"Platform: { build_config .platform } " )
169235 print (f"Architecture: { build_config .architecture } " )
236+ print (f"OpenMP enabled: { build_config .use_openmp } " )
170237
171238 # Get optimization flags from BuildConfig
172239 try :
@@ -181,7 +248,11 @@ def build_extensions(self):
181248 ext .extra_link_args = link_args
182249
183250 # Add macOS-specific include and library paths if needed
184- if compiler == "unix" and platform .system () == "Darwin" :
251+ if (
252+ compiler == "unix"
253+ and platform .system () == "Darwin"
254+ and build_config .use_openmp
255+ ):
185256 for path in macos_includes :
186257 if os .path .exists (path ):
187258 ext .include_dirs .append (path )
@@ -197,22 +268,45 @@ def build_extensions(self):
197268 )
198269 # Fallback to legacy system
199270 for ext in self .extensions :
200- if compiler in ["msvc" , "mingw32" ]:
201- ext .extra_compile_args = copt [compiler ]
202- ext .extra_link_args = lopt .get (compiler )
203- if compiler in ["unix" ]:
271+ if compiler == "msvc" :
272+ if build_config .use_openmp :
273+ ext .extra_compile_args = build_config .base_compile_args_msvc .copy ()
274+ else :
275+ ext .extra_compile_args = build_config .base_compile_args_msvc_plain .copy ()
276+ ext .extra_link_args = []
277+ elif compiler == "mingw32" :
278+ if build_config .use_openmp :
279+ ext .extra_compile_args = build_config .base_compile_args_unix + [
280+ "-lgomp" ,
281+ "-lpthread" ,
282+ ]
283+ ext .extra_link_args = ["-lgomp" , "-lpthread" ]
284+ else :
285+ ext .extra_compile_args = build_config .base_compile_args_plain + [
286+ "-lpthread"
287+ ]
288+ ext .extra_link_args = ["-lpthread" ]
289+ elif compiler == "unix" :
204290 if platform .system () == "Darwin" :
205- ext .extra_compile_args .extend (["-Xpreprocessor" , "-fopenmp" ])
206- ext .extra_link_args .append ("-lomp" )
207- for path in macos_includes :
208- if os .path .exists (path ):
209- ext .include_dirs .append (path )
210- for path in macos_libs :
211- if os .path .exists (path ):
212- ext .library_dirs .append (path )
291+ if build_config .use_openmp :
292+ ext .extra_compile_args = build_config .base_compile_args_macos .copy ()
293+ ext .extra_link_args = ["-lomp" ]
294+ for path in macos_includes :
295+ if os .path .exists (path ):
296+ ext .include_dirs .append (path )
297+ for path in macos_libs :
298+ if os .path .exists (path ):
299+ ext .library_dirs .append (path )
300+ else :
301+ ext .extra_compile_args = build_config .base_compile_args_plain .copy ()
302+ ext .extra_link_args = []
213303 else :
214- ext .extra_compile_args = copt [compiler ]
215- ext .extra_link_args = lopt [compiler ]
304+ if build_config .use_openmp :
305+ ext .extra_compile_args = build_config .base_compile_args_unix .copy ()
306+ ext .extra_link_args = build_config .base_link_args_unix
307+ else :
308+ ext .extra_compile_args = build_config .base_compile_args_plain .copy ()
309+ ext .extra_link_args = []
216310
217311 build_ext .build_extensions (self )
218312
0 commit comments