3939from mypyc .codegen import emitmodule
4040from mypyc .common import IS_FREE_THREADED , RUNTIME_C_FILES , shared_lib_name
4141from mypyc .errors import Errors
42+ from mypyc .ir .deps import SourceDep
4243from mypyc .ir .pprint import format_modules
4344from mypyc .namegen import exported_name
4445from mypyc .options import CompilerOptions
@@ -282,14 +283,14 @@ def generate_c(
282283 groups : emitmodule .Groups ,
283284 fscache : FileSystemCache ,
284285 compiler_options : CompilerOptions ,
285- ) -> tuple [list [list [tuple [str , str ]]], str ]:
286+ ) -> tuple [list [list [tuple [str , str ]]], str , list [ SourceDep ] ]:
286287 """Drive the actual core compilation step.
287288
288289 The groups argument describes how modules are assigned to C
289290 extension modules. See the comments on the Groups type in
290291 mypyc.emitmodule for details.
291292
292- Returns the C source code and (for debugging) the pretty printed IR.
293+ Returns the C source code, (for debugging) the pretty printed IR, and list of SourceDeps .
293294 """
294295 t0 = time .time ()
295296
@@ -325,7 +326,10 @@ def generate_c(
325326 if options .mypyc_annotation_file :
326327 generate_annotated_html (options .mypyc_annotation_file , result , modules , mapper )
327328
328- return ctext , "\n " .join (format_modules (modules ))
329+ # Collect SourceDep dependencies
330+ source_deps = sorted (emitmodule .collect_source_dependencies (modules ), key = lambda d : d .path )
331+
332+ return ctext , "\n " .join (format_modules (modules )), source_deps
329333
330334
331335def build_using_shared_lib (
@@ -486,9 +490,9 @@ def mypyc_build(
486490 * ,
487491 separate : bool | list [tuple [list [str ], str | None ]] = False ,
488492 only_compile_paths : Iterable [str ] | None = None ,
489- skip_cgen_input : Any | None = None ,
493+ skip_cgen_input : tuple [ list [ list [ tuple [ str , str ]]], list [ str ]] | None = None ,
490494 always_use_shared_lib : bool = False ,
491- ) -> tuple [emitmodule .Groups , list [tuple [list [str ], list [str ]]]]:
495+ ) -> tuple [emitmodule .Groups , list [tuple [list [str ], list [str ]]], list [ SourceDep ] ]:
492496 """Do the front and middle end of mypyc building, producing and writing out C source."""
493497 fscache = FileSystemCache ()
494498 mypyc_sources , all_sources , options = get_mypy_config (
@@ -511,14 +515,16 @@ def mypyc_build(
511515
512516 # We let the test harness just pass in the c file contents instead
513517 # so that it can do a corner-cutting version without full stubs.
518+ source_deps : list [SourceDep ] = []
514519 if not skip_cgen_input :
515- group_cfiles , ops_text = generate_c (
520+ group_cfiles , ops_text , source_deps = generate_c (
516521 all_sources , options , groups , fscache , compiler_options = compiler_options
517522 )
518523 # TODO: unique names?
519524 write_file (os .path .join (compiler_options .target_dir , "ops.txt" ), ops_text )
520525 else :
521- group_cfiles = skip_cgen_input
526+ group_cfiles = skip_cgen_input [0 ]
527+ source_deps = [SourceDep (d ) for d in skip_cgen_input [1 ]]
522528
523529 # Write out the generated C and collect the files for each group
524530 # Should this be here??
@@ -535,7 +541,7 @@ def mypyc_build(
535541 deps = [os .path .join (compiler_options .target_dir , dep ) for dep in get_header_deps (cfiles )]
536542 group_cfilenames .append ((cfilenames , deps ))
537543
538- return groups , group_cfilenames
544+ return groups , group_cfilenames , source_deps
539545
540546
541547def mypycify (
@@ -548,7 +554,7 @@ def mypycify(
548554 strip_asserts : bool = False ,
549555 multi_file : bool = False ,
550556 separate : bool | list [tuple [list [str ], str | None ]] = False ,
551- skip_cgen_input : Any | None = None ,
557+ skip_cgen_input : tuple [ list [ list [ tuple [ str , str ]]], list [ str ]] | None = None ,
552558 target_dir : str | None = None ,
553559 include_runtime_files : bool | None = None ,
554560 strict_dunder_typing : bool = False ,
@@ -633,7 +639,7 @@ def mypycify(
633639 )
634640
635641 # Generate all the actual important C code
636- groups , group_cfilenames = mypyc_build (
642+ groups , group_cfilenames , source_deps = mypyc_build (
637643 paths ,
638644 only_compile_paths = only_compile_paths ,
639645 compiler_options = compiler_options ,
@@ -708,11 +714,19 @@ def mypycify(
708714 # compiler invocations.
709715 shared_cfilenames = []
710716 if not compiler_options .include_runtime_files :
711- for name in RUNTIME_C_FILES :
717+ # Collect all files to copy: runtime files + conditional source files
718+ files_to_copy = list (RUNTIME_C_FILES )
719+ for source_dep in source_deps :
720+ files_to_copy .append (source_dep .path )
721+ files_to_copy .append (source_dep .get_header ())
722+
723+ # Copy all files
724+ for name in files_to_copy :
712725 rt_file = os .path .join (build_dir , name )
713726 with open (os .path .join (include_dir (), name ), encoding = "utf-8" ) as f :
714727 write_file (rt_file , f .read ())
715- shared_cfilenames .append (rt_file )
728+ if name .endswith (".c" ):
729+ shared_cfilenames .append (rt_file )
716730
717731 extensions = []
718732 for (group_sources , lib_name ), (cfilenames , deps ) in zip (groups , group_cfilenames ):
0 commit comments