(self)
| 636 | return "_" + exported_name(self.group_name.split(".")[-1]) if self.group_name else "" |
| 637 | |
| 638 | def generate_c_for_modules(self) -> list[tuple[str, str]]: |
| 639 | file_contents = [] |
| 640 | multi_file = self.use_shared_lib and self.multi_file |
| 641 | |
| 642 | # Collect all literal refs in IR. |
| 643 | for module in self.modules.values(): |
| 644 | for fn in module.functions: |
| 645 | collect_literals(fn, self.context.literals) |
| 646 | |
| 647 | base_emitter = Emitter(self.context) |
| 648 | # Optionally just include the runtime library c files to |
| 649 | # reduce the number of compiler invocations needed. |
| 650 | # Use <> form (only -I paths) so a shim file with the same |
| 651 | # basename as a runtime file can't shadow it. Triggered by |
| 652 | # mypyc/lower/int_ops.py vs lib-rt/int_ops.c on mypy self-compile. |
| 653 | if self.compiler_options.include_runtime_files: |
| 654 | for name in RUNTIME_C_FILES: |
| 655 | base_emitter.emit_line(f"#include <{name}>") |
| 656 | # Include conditional source files |
| 657 | source_deps = collect_source_dependencies(self.modules) |
| 658 | for source_dep in sorted(source_deps, key=lambda d: d.path): |
| 659 | base_emitter.emit_line(f"#include <{source_dep.path}>") |
| 660 | if self.compiler_options.depends_on_librt_internal: |
| 661 | base_emitter.emit_line("#include <internal/librt_internal_api.c>") |
| 662 | base_emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"') |
| 663 | base_emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"') |
| 664 | emitter = base_emitter |
| 665 | |
| 666 | self.generate_literal_tables() |
| 667 | |
| 668 | for module_name, module in self.modules.items(): |
| 669 | if multi_file: |
| 670 | emitter = Emitter(self.context, filepath=self.source_paths[module_name]) |
| 671 | emitter.emit_line(f'#include "__native{self.short_group_suffix}.h"') |
| 672 | emitter.emit_line(f'#include "__native_internal{self.short_group_suffix}.h"') |
| 673 | |
| 674 | self.declare_module(module_name, emitter) |
| 675 | self.declare_internal_globals(module_name, emitter) |
| 676 | self.declare_imports(module.imports, emitter) |
| 677 | |
| 678 | for cl in module.classes: |
| 679 | if cl.is_ext_class: |
| 680 | generate_class(cl, module_name, emitter) |
| 681 | |
| 682 | # Generate Python extension module definitions and module initialization functions. |
| 683 | self.generate_module_def(emitter, module_name, module) |
| 684 | |
| 685 | for fn in module.functions: |
| 686 | emitter.emit_line() |
| 687 | generate_native_function(fn, emitter, self.source_paths[module_name], module_name) |
| 688 | if fn.name != TOP_LEVEL_NAME and not fn.internal: |
| 689 | emitter.emit_line() |
| 690 | if is_fastcall_supported(fn, emitter.capi_version): |
| 691 | generate_wrapper_function( |
| 692 | fn, emitter, self.source_paths[module_name], module_name |
| 693 | ) |
| 694 | else: |
| 695 | generate_legacy_wrapper_function( |
no test coverage detected