summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesonbuild/backend/ninjabackend.py73
-rw-r--r--mesonbuild/compilers/rust.py2
2 files changed, 49 insertions, 26 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 9ca092c5a..a3bc89c49 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -1931,24 +1931,12 @@ class NinjaBackend(backends.Backend):
# in Rust
return target.rust_dependency_map.get(dependency.name, dependency.name).replace('-', '_')
- def generate_rust_target(self, target: build.BuildTarget) -> None:
- rustc = target.compilers['rust']
+ def generate_rust_sources(self, target: build.BuildTarget) -> T.Tuple[T.List[str], str]:
+ orderdeps: T.List[str] = []
+
# Rust compiler takes only the main file as input and
# figures out what other files are needed via import
# statements and magic.
- args = rustc.compiler_args()
- # Compiler args for compiling this target
- args += compilers.get_base_compile_args(target, rustc, self.environment)
- self.generate_generator_list_rules(target)
-
- # dependencies need to cause a relink, they're not just for ordering
- deps: T.List[str] = []
-
- # Dependencies for rust-project.json
- project_deps: T.List[RustDep] = []
-
- orderdeps: T.List[str] = []
-
main_rust_file = None
if target.structured_sources:
if target.structured_sources.needs_copy():
@@ -1978,14 +1966,10 @@ class NinjaBackend(backends.Backend):
orderdeps.extend(_ods)
for i in target.get_sources():
- if not rustc.can_compile(i):
- raise InvalidArguments(f'Rust target {target.get_basename()} contains a non-rust source file.')
if main_rust_file is None:
main_rust_file = i.rel_to_builddir(self.build_to_src)
for g in target.get_generated_sources():
for i in g.get_outputs():
- if not rustc.can_compile(i):
- raise InvalidArguments(f'Rust target {target.get_basename()} contains a non-rust source file.')
if isinstance(g, GeneratedList):
fname = os.path.join(self.get_target_private_dir(target), i)
else:
@@ -1993,26 +1977,35 @@ class NinjaBackend(backends.Backend):
if main_rust_file is None:
main_rust_file = fname
orderdeps.append(fname)
- if main_rust_file is None:
- raise RuntimeError('A Rust target has no Rust sources. This is weird. Also a bug. Please report')
+
+ return orderdeps, main_rust_file
+
+ def get_rust_compiler_args(self, target: build.BuildTarget, rustc: Compiler,
+ depfile: T.Optional[str] = None) -> T.List[str]:
+ # Compiler args for compiling this target
+ args = compilers.get_base_compile_args(target, rustc, self.environment)
+
target_name = self.get_target_filename(target)
args.extend(['--crate-type', target.rust_crate_type])
# If we're dynamically linking, add those arguments
- #
- # Rust is super annoying, calling -C link-arg foo does not work, it has
- # to be -C link-arg=foo
if target.rust_crate_type in {'bin', 'dylib'}:
args.extend(rustc.get_linker_always_args())
args += self.generate_basic_compiler_args(target, rustc)
# Rustc replaces - with _. spaces or dots are not allowed, so we replace them with underscores
args += ['--crate-name', target.name.replace('-', '_').replace(' ', '_').replace('.', '_')]
- depfile = os.path.join(self.get_target_private_dir(target), target.name + '.d')
- args += rustc.get_dependency_gen_args(target_name, depfile)
+ if depfile:
+ args += rustc.get_dependency_gen_args(target_name, depfile)
args += rustc.get_output_args(target_name)
args += ['-C', 'metadata=' + target.get_id()]
args += target.get_extra_args('rust')
+ return args
+
+ def get_rust_compiler_deps_and_args(self, target: build.BuildTarget, rustc: Compiler) -> T.Tuple[T.List[str], T.List[RustDep], T.List[str]]:
+ deps: T.List[str] = []
+ project_deps: T.List[RustDep] = []
+ args: T.List[str] = []
# Rustc always use non-debug Windows runtime. Inject the one selected
# by Meson options instead.
@@ -2126,6 +2119,33 @@ class NinjaBackend(backends.Backend):
if isinstance(target, build.SharedLibrary) or has_shared_deps:
args += self.get_build_rpath_args(target, rustc)
+ return deps, project_deps, args
+
+ def generate_rust_target(self, target: build.BuildTarget) -> None:
+ rustc = target.compilers['rust']
+ self.generate_generator_list_rules(target)
+
+ for i in target.get_sources():
+ if not rustc.can_compile(i):
+ raise InvalidArguments(f'Rust target {target.get_basename()} contains a non-rust source file.')
+ for g in target.get_generated_sources():
+ for i in g.get_outputs():
+ if not rustc.can_compile(i):
+ raise InvalidArguments(f'Rust target {target.get_basename()} contains a non-rust source file.')
+
+ orderdeps, main_rust_file = self.generate_rust_sources(target)
+ target_name = self.get_target_filename(target)
+ if main_rust_file is None:
+ raise RuntimeError('A Rust target has no Rust sources. This is weird. Also a bug. Please report')
+
+ args = rustc.compiler_args()
+
+ depfile = os.path.join(self.get_target_private_dir(target), target.name + '.d')
+ args += self.get_rust_compiler_args(target, rustc, depfile)
+
+ deps, project_deps, deps_args = self.get_rust_compiler_deps_and_args(target, rustc)
+ args += deps_args
+
proc_macro_dylib_path = None
if target.rust_crate_type == 'proc-macro':
proc_macro_dylib_path = self.get_target_filename_abs(target)
@@ -2142,6 +2162,7 @@ class NinjaBackend(backends.Backend):
if orderdeps:
element.add_orderdep(orderdeps)
if deps:
+ # dependencies need to cause a relink, they're not just for ordering
element.add_dep(deps)
element.add_item('ARGS', args)
element.add_item('targetdep', depfile)
diff --git a/mesonbuild/compilers/rust.py b/mesonbuild/compilers/rust.py
index 011c28f1d..210544ed8 100644
--- a/mesonbuild/compilers/rust.py
+++ b/mesonbuild/compilers/rust.py
@@ -279,6 +279,8 @@ class RustCompiler(Compiler):
def get_linker_always_args(self) -> T.List[str]:
args: T.List[str] = []
+ # Rust is super annoying, calling -C link-arg foo does not work, it has
+ # to be -C link-arg=foo
for a in super().get_linker_always_args():
args.extend(['-C', f'link-arg={a}'])
return args