diff options
| author | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-11-09 17:40:44 +0200 |
|---|---|---|
| committer | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-11-23 16:04:33 +0200 |
| commit | 35193dd8e4f2a24ae689eeb8d01a2c3bcca11025 (patch) | |
| tree | e0fd24bf10aaec8eb0af74c5421ed5cf56d4a151 | |
| parent | 50471c0b843afc0173a9807b676d3c076b695305 (diff) | |
| download | meson-35193dd8e4f2a24ae689eeb8d01a2c3bcca11025.tar.gz | |
Add basic import std support for GCC.
| -rw-r--r-- | mesonbuild/backend/ninjabackend.py | 54 | ||||
| -rw-r--r-- | test cases/common/286 importstd/useistd.cpp | 2 |
2 files changed, 55 insertions, 1 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 00db7a206..fb7ac5b01 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -477,6 +477,12 @@ class RustCrate: return ret +@dataclass +class ImportStdInfo: + gen_target: NinjaBuildElement + gen_module_file: str + gen_objects: T.List[str] + class NinjaBackend(backends.Backend): def __init__(self, build: T.Optional[build.Build]): @@ -500,6 +506,7 @@ class NinjaBackend(backends.Backend): # - https://github.com/mesonbuild/meson/pull/9453 # - https://github.com/mesonbuild/meson/issues/9479#issuecomment-953485040 self.allow_thin_archives = PerMachine[bool](True, True) + self.import_std: T.Optional[ImportStdInfo] = None def create_phony_target(self, dummy_outfile: str, rulename: str, phony_infilename: str) -> NinjaBuildElement: ''' @@ -3241,6 +3248,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) rel_obj) self.add_build(depelem) commands += compiler.get_module_outdir_args(self.get_target_private_dir(target)) + + # C++ import std is complicated enough to get its own method. + istd_args, istd_dep = self.handle_cpp_import_std(target, compiler) + commands.extend(istd_args) + header_deps += istd_dep if extra_args is not None: commands.extend(extra_args) @@ -3290,6 +3302,41 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) assert isinstance(rel_src, str) return (rel_obj, rel_src.replace('\\', '/')) + def target_uses_import_std(self, target: build.BuildTarget) -> bool: + if 'cpp' not in target.compilers: + return False + if 'cpp_importstd' not in self.environment.coredata.optstore: + return False + if self.environment.coredata.get_option_for_target(target, 'cpp_importstd') == 'false': + return False + return True + + def handle_cpp_import_std(self, target: build.BuildTarget, compiler): + istd_args = [] + istd_dep = [] + if not self.target_uses_import_std(target): + return istd_args, istd_dep + mlog.warning('Import std support is experimental and might break compatibility in the future.') + # At the time of writing, all three major compilers work + # wildly differently. Keep this isolated here until things + # consolidate. + if compiler.id == 'gcc': + if self.import_std is None: + mod_file = 'gcm.cache/std.gcm' + mod_obj_file = 'std.o' + elem = NinjaBuildElement(self.all_outputs, [mod_file, mod_obj_file], 'CUSTOM_COMMAND', []) + compile_args = compiler.get_option_compile_args(target, self.environment) + compile_args += compiler.get_option_std_args(target, self.environment) + compile_args += ['-c', '-fmodules', '-fsearch-include-path', 'bits/std.cc'] + elem.add_item('COMMAND', compiler.exelist + compile_args) + self.add_build(elem) + self.import_std = ImportStdInfo(elem, mod_file, [mod_obj_file]) + istd_args = ['-fmodules'] + istd_dep = [File(True, '', self.import_std.gen_module_file)] + return istd_args, istd_dep + else: + raise MesonException(f'Import std not supported on compiler {compiler.id} yet.') + def add_dependency_scanner_entries_to_element(self, target: build.BuildTarget, compiler, element, src) -> None: if not self.should_use_dyndeps_for_target(target): return @@ -3763,6 +3810,8 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) dep_targets = [] dep_targets.extend(self.guess_external_link_dependencies(linker, target, commands, internal)) + obj_list += self.get_import_std_object(target) + # Add libraries generated by custom targets custom_target_libraries = self.get_custom_target_provided_libraries(target) commands += extra_args @@ -3791,6 +3840,11 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485''')) self.create_target_linker_introspection(target, linker, commands) return elem + def get_import_std_object(self, target: build.BuildTarget) -> T.List[File]: + if not self.target_uses_import_std(target): + return [] + return self.import_std.gen_objects + def get_dependency_filename(self, t) -> str: if isinstance(t, build.SharedLibrary): if t.uses_rust() and t.rust_crate_type == 'proc-macro': diff --git a/test cases/common/286 importstd/useistd.cpp b/test cases/common/286 importstd/useistd.cpp index d8d707a8b..70f62ec3b 100644 --- a/test cases/common/286 importstd/useistd.cpp +++ b/test cases/common/286 importstd/useistd.cpp @@ -1,4 +1,4 @@ -#include<print> +import std; int main(int, char**) { std::print("Import STD is working.\n"); |
