diff --git a/mypyc/build.py b/mypyc/build.py index 64772c924dc54..a6822b655bf6f 100644 --- a/mypyc/build.py +++ b/mypyc/build.py @@ -53,11 +53,22 @@ class ModDesc(NamedTuple): LIBRT_MODULES = [ - ModDesc("librt.internal", ["internal/librt_internal.c"], [], ["internal"]), - ModDesc("librt.strings", ["strings/librt_strings.c"], [], ["strings"]), + ModDesc( + "librt.internal", + ["internal/librt_internal_static.c", "internal/librt_internal.c"], + [], + ["internal"], + ), + ModDesc( + "librt.strings", + ["strings/librt_strings_static.c", "strings/librt_strings.c"], + [], + ["strings"], + ), ModDesc( "librt.base64", [ + "base64/librt_base64_static.c", "base64/librt_base64.c", "base64/lib.c", "base64/codec_choose.c", @@ -107,6 +118,7 @@ class ModDesc(NamedTuple): ModDesc( "librt.vecs", [ + "vecs/librt_vecs_static.c", "vecs/librt_vecs.c", "vecs/vec_i64.c", "vecs/vec_i32.c", @@ -120,7 +132,9 @@ class ModDesc(NamedTuple): ["vecs/librt_vecs.h", "vecs/vec_template.c"], ["vecs"], ), - ModDesc("librt.time", ["time/librt_time.c"], ["time/librt_time.h"], []), + ModDesc( + "librt.time", ["time/librt_time_static.c", "time/librt_time.c"], ["time/librt_time.h"], [] + ), ] try: @@ -357,6 +371,7 @@ def build_using_shared_lib( deps: list[str], build_dir: str, extra_compile_args: list[str], + extra_include_dirs: list[str], ) -> list[Extension]: """Produce the list of extension modules when a shared library is needed. @@ -373,7 +388,7 @@ def build_using_shared_lib( get_extension()( shared_lib_name(group_name), sources=cfiles, - include_dirs=[include_dir(), build_dir], + include_dirs=[include_dir(), build_dir] + extra_include_dirs, depends=deps, extra_compile_args=extra_compile_args, ) @@ -399,7 +414,10 @@ def build_using_shared_lib( def build_single_module( - sources: list[BuildSource], cfiles: list[str], extra_compile_args: list[str] + sources: list[BuildSource], + cfiles: list[str], + extra_compile_args: list[str], + extra_include_dirs: list[str], ) -> list[Extension]: """Produce the list of extension modules for a standalone extension. @@ -409,7 +427,7 @@ def build_single_module( get_extension()( sources[0].module, sources=cfiles, - include_dirs=[include_dir()], + include_dirs=[include_dir()] + extra_include_dirs, extra_compile_args=extra_compile_args, ) ] @@ -513,7 +531,9 @@ def mypyc_build( *, separate: bool | list[tuple[list[str], str | None]] = False, only_compile_paths: Iterable[str] | None = None, - skip_cgen_input: tuple[list[list[tuple[str, str]]], list[str]] | None = None, + skip_cgen_input: ( + tuple[list[list[tuple[str, str]]], list[tuple[str, bool, list[str]]]] | None + ) = None, always_use_shared_lib: bool = False, ) -> tuple[emitmodule.Groups, list[tuple[list[str], list[str]]], list[SourceDep]]: """Do the front and middle end of mypyc building, producing and writing out C source.""" @@ -547,7 +567,10 @@ def mypyc_build( write_file(os.path.join(compiler_options.target_dir, "ops.txt"), ops_text) else: group_cfiles = skip_cgen_input[0] - source_deps = [SourceDep(d) for d in skip_cgen_input[1]] + source_deps = [ + SourceDep(path, has_header=hdr, include_dirs=dirs) + for (path, hdr, dirs) in skip_cgen_input[1] + ] # Write out the generated C and collect the files for each group # Should this be here?? @@ -664,7 +687,9 @@ def mypycify( strip_asserts: bool = False, multi_file: bool = False, separate: bool | list[tuple[list[str], str | None]] = False, - skip_cgen_input: tuple[list[list[tuple[str, str]]], list[str]] | None = None, + skip_cgen_input: ( + tuple[list[list[tuple[str, str]]], list[tuple[str, bool, list[str]]]] | None + ) = None, target_dir: str | None = None, include_runtime_files: bool | None = None, strict_dunder_typing: bool = False, @@ -781,12 +806,15 @@ def mypycify( # runtime library in. Otherwise it just gets #included to save on # compiler invocations. shared_cfilenames = [] + include_dirs = set() if not compiler_options.include_runtime_files: # Collect all files to copy: runtime files + conditional source files files_to_copy = list(RUNTIME_C_FILES) for source_dep in source_deps: files_to_copy.append(source_dep.path) - files_to_copy.append(source_dep.get_header()) + if header := source_dep.get_header(): + files_to_copy.append(header) + include_dirs.update(source_dep.include_dirs) # Copy all files for name in files_to_copy: @@ -797,6 +825,7 @@ def mypycify( shared_cfilenames.append(rt_file) extensions = [] + extra_include_dirs = [os.path.join(include_dir(), dir) for dir in include_dirs] for (group_sources, lib_name), (cfilenames, deps) in zip(groups, group_cfilenames): if lib_name: extensions.extend( @@ -807,11 +836,14 @@ def mypycify( deps, build_dir, cflags, + extra_include_dirs, ) ) else: extensions.extend( - build_single_module(group_sources, cfilenames + shared_cfilenames, cflags) + build_single_module( + group_sources, cfilenames + shared_cfilenames, cflags, extra_include_dirs + ) ) if install_librt: diff --git a/mypyc/codegen/emitmodule.py b/mypyc/codegen/emitmodule.py index cb79a25a552d4..ced8d592e483c 100644 --- a/mypyc/codegen/emitmodule.py +++ b/mypyc/codegen/emitmodule.py @@ -443,6 +443,8 @@ def collect_source_dependencies(modules: dict[str, ModuleIR]) -> set[SourceDep]: for dep in module.dependencies: if isinstance(dep, SourceDep): source_deps.add(dep) + else: + source_deps.add(dep.static_data_dep()) return source_deps @@ -585,6 +587,8 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]: source_deps = collect_source_dependencies(self.modules) for source_dep in sorted(source_deps, key=lambda d: d.path): base_emitter.emit_line(f'#include "{source_dep.path}"') + if self.compiler_options.depends_on_librt_internal: + base_emitter.emit_line("#include ") base_emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"') base_emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"') emitter = base_emitter @@ -634,26 +638,29 @@ def generate_c_for_modules(self) -> list[tuple[str, str]]: ext_declarations.emit_line(f"#define MYPYC_NATIVE{self.group_suffix}_H") ext_declarations.emit_line("#include ") ext_declarations.emit_line("#include ") + + declarations = Emitter(self.context) + declarations.emit_line(f"#ifndef MYPYC_LIBRT_INTERNAL{self.group_suffix}_H") + declarations.emit_line(f"#define MYPYC_LIBRT_INTERNAL{self.group_suffix}_H") + declarations.emit_line("#include ") + declarations.emit_line("#include ") + if self.compiler_options.depends_on_librt_internal: - ext_declarations.emit_line("#include ") + declarations.emit_line("#include ") if any(LIBRT_BASE64 in mod.dependencies for mod in self.modules.values()): - ext_declarations.emit_line("#include ") + declarations.emit_line("#include ") if any(LIBRT_STRINGS in mod.dependencies for mod in self.modules.values()): - ext_declarations.emit_line("#include ") + declarations.emit_line("#include ") if any(LIBRT_TIME in mod.dependencies for mod in self.modules.values()): - ext_declarations.emit_line("#include