@@ -57,6 +57,12 @@ class _Target(typing.Generic[_S, _R]):
5757 known_symbols : dict [str , int ] = dataclasses .field (default_factory = dict )
5858 pyconfig_dir : pathlib .Path = pathlib .Path .cwd ().resolve ()
5959
60+ def _compile_args (self ) -> list [str ]:
61+ return list (self .args )
62+
63+ def _shim_compile_args (self ) -> list [str ]:
64+ return []
65+
6066 def _get_nop (self ) -> bytes :
6167 if re .fullmatch (r"aarch64-.*" , self .triple ):
6268 nop = b"\x1f \x20 \x03 \xd5 "
@@ -139,7 +145,7 @@ def _handle_relocation(
139145 ) -> _stencils .Hole :
140146 raise NotImplementedError (type (self ))
141147
142- def _common_clang_args (self , opname : str , tempdir : pathlib .Path ) -> list [str ]:
148+ def _base_clang_args (self , opname : str , tempdir : pathlib .Path ) -> list [str ]:
143149 return [
144150 f"--target={ self .triple } " ,
145151 "-DPy_BUILD_CORE_MODULE" ,
@@ -179,20 +185,22 @@ async def _build_stencil_group(
179185 ) -> _stencils .StencilGroup :
180186 s = tempdir / f"{ opname } .s"
181187 o = tempdir / f"{ opname } .o"
182- args_s = self ._common_clang_args (opname , tempdir )
188+ args_s = self ._base_clang_args (opname , tempdir )
183189 args_s += [
184190 "-S" ,
185- # This debug info isn't necessary, and bloats out the JIT'ed code.
186- # We *may* be able to re-enable this, process it, and JIT it for a
187- # nicer debugging experience... but that needs a lot more research:
191+ # Stencils do not need unwind info, and the optimizer does not
192+ # preserve .cfi_* directives correctly. On Darwin,
193+ # -fno-asynchronous-unwind-tables alone still leaves synchronous
194+ # unwind directives in the assembly, so disable both forms here.
195+ "-fno-unwind-tables" ,
188196 "-fno-asynchronous-unwind-tables" ,
189197 "-o" ,
190198 f"{ s } " ,
191199 f"{ c } " ,
192200 ]
193201 if self .frame_pointers :
194202 args_s += ["-Xclang" , "-mframe-pointer=reserved" ]
195- args_s += self .args
203+ args_s += self ._compile_args ()
196204 # Allow user-provided CFLAGS to override any defaults
197205 args_s += shlex .split (self .cflags )
198206 await _llvm .run (
@@ -222,13 +230,8 @@ async def _build_stencil_group(
222230 async def _build_shim_object (self , output : pathlib .Path ) -> None :
223231 with tempfile .TemporaryDirectory () as tempdir :
224232 work = pathlib .Path (tempdir ).resolve ()
225- args_o = self ._common_clang_args ("shim" , work )
226- if self .triple .endswith ("-windows-msvc" ):
227- # The linked shim is part of pythoncore, not a shared extension.
228- # On Windows, Py_BUILD_CORE_MODULE makes public APIs import from
229- # pythonXY.lib, which creates a self-dependency when linking
230- # pythoncore.dll. Build the shim with builtin/core semantics.
231- args_o += ["-UPy_BUILD_CORE_MODULE" , "-DPy_BUILD_CORE_BUILTIN" ]
233+ args_o = self ._base_clang_args ("shim" , work )
234+ args_o += self ._shim_compile_args ()
232235 args_o += [
233236 "-c" ,
234237 # The linked shim is a real function in the final binary, so
@@ -237,7 +240,7 @@ async def _build_shim_object(self, output: pathlib.Path) -> None:
237240 ]
238241 if self .frame_pointers :
239242 args_o += ["-Xclang" , "-mframe-pointer=all" ]
240- args_o += self .args
243+ args_o += self ._compile_args ()
241244 args_o += shlex .split (self .cflags )
242245 args_o += ["-o" , f"{ output } " , f"{ TOOLS_JIT / 'shim.c' } " ]
243246 await _llvm .run (
@@ -328,6 +331,13 @@ def build(
328331class _COFF (
329332 _Target [_schema .COFFSection , _schema .COFFRelocation ]
330333): # pylint: disable = too-few-public-methods
334+ def _shim_compile_args (self ) -> list [str ]:
335+ # The linked shim is part of pythoncore, not a shared extension.
336+ # On Windows, Py_BUILD_CORE_MODULE makes public APIs import from
337+ # pythonXY.lib, which creates a self-dependency when linking
338+ # pythoncore.dll. Build the shim with builtin/core semantics.
339+ return ["-UPy_BUILD_CORE_MODULE" , "-DPy_BUILD_CORE_BUILTIN" ]
340+
331341 def _handle_section (
332342 self , section : _schema .COFFSection , group : _stencils .StencilGroup
333343 ) -> None :
@@ -428,6 +438,10 @@ class _COFF64(_COFF):
428438 symbol_prefix = ""
429439 re_global = re .compile (r'\s*\.def\s+(?P<label>[\w."$?@]+);' )
430440
441+ def _compile_args (self ) -> list [str ]:
442+ runtime = "-fms-runtime-lib=dll_dbg" if self .debug else "-fms-runtime-lib=dll"
443+ return [runtime , * self .args ]
444+
431445
432446class _ELF (
433447 _Target [_schema .ELFSection , _schema .ELFRelocation ]
@@ -639,9 +653,8 @@ def get_target(host: str) -> _COFF32 | _COFF64 | _ELF | _MachO:
639653 elif re .fullmatch (r"aarch64-pc-windows-msvc" , host ):
640654 host = "aarch64-pc-windows-msvc"
641655 condition = "defined(_M_ARM64)"
642- args = ["-fms-runtime-lib=dll" ]
643656 optimizer = _optimizers .OptimizerAArch64
644- target = _COFF64 (host , condition , args = args , optimizer = optimizer )
657+ target = _COFF64 (host , condition , optimizer = optimizer )
645658 elif re .fullmatch (r"aarch64-.*-linux-gnu" , host ):
646659 host = "aarch64-unknown-linux-gnu"
647660 condition = "defined(__aarch64__) && defined(__linux__)"
@@ -668,9 +681,8 @@ def get_target(host: str) -> _COFF32 | _COFF64 | _ELF | _MachO:
668681 elif re .fullmatch (r"x86_64-pc-windows-msvc" , host ):
669682 host = "x86_64-pc-windows-msvc"
670683 condition = "defined(_M_X64)"
671- args = ["-fms-runtime-lib=dll" ]
672684 optimizer = _optimizers .OptimizerX86
673- target = _COFF64 (host , condition , args = args , optimizer = optimizer )
685+ target = _COFF64 (host , condition , optimizer = optimizer )
674686 elif re .fullmatch (r"x86_64-.*-linux-gnu" , host ):
675687 host = "x86_64-unknown-linux-gnu"
676688 condition = "defined(__x86_64__) && defined(__linux__)"
0 commit comments