aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2021-01-20 18:59:25 +0000
committerGitHub <noreply@github.com>2021-01-20 18:59:25 +0000
commit3c304bbb79ac5562ad401c722801a7d9ad4de0c6 (patch)
treecdb373bb3acd901952d22a1969ec8d8ad0ad928d
parent8133a7b9a4b8f0686fbc479aa2d64e41c85a979b (diff)
parentcaa6d5e16b6b12f64269246e83d29e2189bb5e92 (diff)
downloadmeson-3c304bbb79ac5562ad401c722801a7d9ad4de0c6.zip
meson-3c304bbb79ac5562ad401c722801a7d9ad4de0c6.tar.gz
meson-3c304bbb79ac5562ad401c722801a7d9ad4de0c6.tar.bz2
Merge pull request #8158 from dcbaker/submit/rust-generated-main
rust: Accept generated sources for main.rs
-rw-r--r--mesonbuild/backend/ninjabackend.py29
-rw-r--r--mesonbuild/build.py29
-rw-r--r--mesonbuild/modules/unstable_rust.py2
-rw-r--r--test cases/rust/11 generated main/gen.py16
-rw-r--r--test cases/rust/11 generated main/meson.build16
5 files changed, 70 insertions, 22 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index d66708c..c1c4c93 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -45,7 +45,7 @@ from ..mesonlib import (
)
from ..mesonlib import get_compiler_for_source, has_path_sep, OptionKey
from .backends import CleanTrees
-from ..build import InvalidArguments
+from ..build import GeneratedList, InvalidArguments
from ..interpreter import Interpreter
if T.TYPE_CHECKING:
@@ -691,13 +691,6 @@ int dummy;
src_block['sources'] += sources
src_block['generated_sources'] += generated_sources
- def is_rust_target(self, target):
- if len(target.sources) > 0:
- first_file = target.sources[0]
- if first_file.fname.endswith('.rs'):
- return True
- return False
-
def generate_target(self, target):
try:
if isinstance(target, build.BuildTarget):
@@ -723,7 +716,7 @@ int dummy;
if isinstance(target, build.Jar):
self.generate_jar_target(target)
return
- if self.is_rust_target(target):
+ if target.uses_rust():
self.generate_rust_target(target)
return
if 'cs' in target.compilers:
@@ -1588,12 +1581,27 @@ int dummy;
args = rustc.compiler_args()
# Compiler args for compiling this target
args += compilers.get_base_compile_args(base_proxy, rustc)
+ self.generate_generator_list_rules(target)
+
+ orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets]
+
main_rust_file = None
for i in target.get_sources():
if not rustc.can_compile(i):
raise InvalidArguments('Rust target {} contains a non-rust source file.'.format(target.get_basename()))
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('Rust target {} contains a non-rust source file.'.format(target.get_basename()))
+ if isinstance(g, GeneratedList):
+ fname = os.path.join(self.get_target_private_dir(target), i)
+ else:
+ fname = i
+ 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')
target_name = os.path.join(target.subdir, target.get_filename())
@@ -1631,7 +1639,6 @@ int dummy;
args += target.get_extra_args('rust')
args += rustc.get_output_args(os.path.join(target.subdir, target.get_filename()))
args += self.environment.coredata.get_external_args(target.for_machine, rustc.language)
- orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets]
linkdirs = OrderedDict()
for d in target.link_targets:
linkdirs[d.subdir] = True
@@ -1678,7 +1685,7 @@ int dummy;
args += ['-C', 'link-arg=' + rpath_arg + ':' + os.path.join(rustc.get_sysroot(), 'lib')]
compiler_name = self.get_compiler_rule_name('rust', target.for_machine)
element = NinjaBuildElement(self.all_outputs, target_name, compiler_name, main_rust_file)
- if len(orderdeps) > 0:
+ if orderdeps:
element.add_orderdep(orderdeps)
element.add_item('ARGS', args)
element.add_item('targetdep', depfile)
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 017b0f0..13783d1 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -569,7 +569,7 @@ class BuildTarget(Target):
unity_opt = environment.coredata.get_option(OptionKey('unity'))
self.is_unity = unity_opt == 'on' or (unity_opt == 'subprojects' and subproject != '')
self.environment = environment
- self.sources = []
+ self.sources: T.List[File] = []
self.compilers = OrderedDict() # type: OrderedDict[str, Compiler]
self.objects = []
self.external_deps = []
@@ -588,7 +588,7 @@ class BuildTarget(Target):
self.need_install = False
self.pch = {}
self.extra_args: T.Dict[str, T.List['FileOrString']] = {}
- self.generated = []
+ self.generated: T.Sequence[T.Union[GeneratedList, CustomTarget, CustomTargetIndex]] = []
self.d_features = {}
self.pic = False
self.pie = False
@@ -1412,9 +1412,16 @@ You probably should put it in link_with instead.''')
m = 'Could not get a dynamic linker for build target {!r}'
raise AssertionError(m.format(self.name))
- def get_using_rustc(self) -> bool:
+ def uses_rust(self) -> bool:
"""Is this target a rust target."""
- return self.sources and self.sources[0].fname.endswith('.rs')
+ if self.sources:
+ first_file = self.sources[0]
+ if first_file.fname.endswith('.rs'):
+ return True
+ elif self.generated:
+ if self.generated[0].get_outputs()[0].endswith('.rs'):
+ return True
+ return False
def get_using_msvc(self):
'''
@@ -1434,11 +1441,13 @@ You probably should put it in link_with instead.''')
2. If the target contains only objects, process_compilers guesses and
picks the first compiler that smells right.
'''
- compiler, _ = self.get_clink_dynamic_linker_and_stdlibs()
+ # Rustc can use msvc style linkers
+ if self.uses_rust():
+ compiler = self.environment.coredata.compilers[self.for_machine]['rust']
+ else:
+ compiler, _ = self.get_clink_dynamic_linker_and_stdlibs()
# Mixing many languages with MSVC is not supported yet so ignore stdlibs.
- if compiler and compiler.get_linker_id() in {'link', 'lld-link', 'xilink', 'optlink'}:
- return True
- return False
+ return compiler and compiler.get_linker_id() in {'link', 'lld-link', 'xilink', 'optlink'}
def check_module_linking(self):
'''
@@ -1687,7 +1696,7 @@ class Executable(BuildTarget):
self.import_filename = self.gcc_import_filename
if m.is_windows() and ('cs' in self.compilers or
- self.get_using_rustc() or
+ self.uses_rust() or
self.get_using_msvc()):
self.debug_filename = self.name + '.pdb'
@@ -1877,7 +1886,7 @@ class SharedLibrary(BuildTarget):
suffix = 'dll'
self.vs_import_filename = '{0}{1}.lib'.format(self.prefix if self.prefix is not None else '', self.name)
self.gcc_import_filename = '{0}{1}.dll.a'.format(self.prefix if self.prefix is not None else 'lib', self.name)
- if self.get_using_rustc():
+ if self.uses_rust():
# Shared library is of the form foo.dll
prefix = ''
# Import library is called foo.dll.lib
diff --git a/mesonbuild/modules/unstable_rust.py b/mesonbuild/modules/unstable_rust.py
index 02369b6..d215376 100644
--- a/mesonbuild/modules/unstable_rust.py
+++ b/mesonbuild/modules/unstable_rust.py
@@ -85,7 +85,7 @@ class RustModule(ExtensionModule):
base_target: BuildTarget = unholder(args[1])
if not isinstance(base_target, BuildTarget):
raise InterpreterException('Second positional argument to rustmod.test() must be a library or executable')
- if not base_target.get_using_rustc():
+ if not base_target.uses_rust():
raise InterpreterException('Second positional argument to rustmod.test() must be a rust based target')
extra_args = stringlistify(kwargs.get('args', []))
diff --git a/test cases/rust/11 generated main/gen.py b/test cases/rust/11 generated main/gen.py
new file mode 100644
index 0000000..ebbc2a7
--- /dev/null
+++ b/test cases/rust/11 generated main/gen.py
@@ -0,0 +1,16 @@
+#!/usr/bin/env python3
+
+import argparse
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('out')
+ args = parser.parse_args()
+
+ with open(args.out, 'w') as f:
+ f.write('fn main() { println!("I prefer tarnish, actually.") }')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/test cases/rust/11 generated main/meson.build b/test cases/rust/11 generated main/meson.build
new file mode 100644
index 0000000..4749816
--- /dev/null
+++ b/test cases/rust/11 generated main/meson.build
@@ -0,0 +1,16 @@
+project('generated rust main', 'rust')
+
+gen = find_program('gen.py')
+
+c = custom_target(
+ 'custom_target',
+ command : [gen, '@OUTPUT@'],
+ output : ['main.rs'],
+)
+
+executable('custom_target_main', c)
+executable('custom_target_index_main', c[0])
+
+gen = generator(gen, arguments : ['@OUTPUT@'], output : '@BASENAME@.rs')
+# Doesn't actually use gen.py as input, just a limitation of generators
+executable('generator_main', gen.process(['gen.py']))