summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py54
-rw-r--r--test cases/common/286 importstd/useistd.cpp2
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");