diff options
author | Sebastian Dröge <sebastian@centricular.com> | 2023-04-13 23:04:51 +0300 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2023-04-21 15:35:06 -0400 |
commit | 01420bf8fc1ee6c1466e2fa4c9805267192dce26 (patch) | |
tree | c419d8b14d4a4144a4a3ce093f853e0c7d385875 | |
parent | 474e3ea8afd170ae86cc5c3a547caee65f97ecb8 (diff) | |
download | meson-01420bf8fc1ee6c1466e2fa4c9805267192dce26.zip meson-01420bf8fc1ee6c1466e2fa4c9805267192dce26.tar.gz meson-01420bf8fc1ee6c1466e2fa4c9805267192dce26.tar.bz2 |
rust: Add new `rust_dependency_map` target configuration
This allows changing the crate name with which a library ends up being
available inside the Rust code, similar to cargo's dependency renaming
feature or `extern crate foo as bar` inside Rust code.
-rw-r--r-- | docs/markdown/snippets/rust_dependency_map.md | 18 | ||||
-rw-r--r-- | docs/yaml/functions/_build_target_base.yaml | 10 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 20 | ||||
-rw-r--r-- | mesonbuild/build.py | 9 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 1 | ||||
-rw-r--r-- | test cases/rust/17 staticlib link staticlib/branch.rs | 2 | ||||
-rw-r--r-- | test cases/rust/17 staticlib link staticlib/meson.build | 2 |
7 files changed, 48 insertions, 14 deletions
diff --git a/docs/markdown/snippets/rust_dependency_map.md b/docs/markdown/snippets/rust_dependency_map.md new file mode 100644 index 0000000..62c9dae --- /dev/null +++ b/docs/markdown/snippets/rust_dependency_map.md @@ -0,0 +1,18 @@ +## Support for defining crate names of Rust dependencies in Rust targets + +Rust supports defining a different crate name for a dependency than what the +actual crate name during compilation of that dependency was. + +This allows using multiple versions of the same crate at once, or simply using +a shorter name of the crate for convenience. + +```meson +a_dep = dependency('some-very-long-name') + +my_executable = executable('my-executable', 'src/main.rs', + rust_dependency_map : { + 'some_very_long_name' : 'a', + }, + dependencies : [a_dep], +) +``` diff --git a/docs/yaml/functions/_build_target_base.yaml b/docs/yaml/functions/_build_target_base.yaml index 8b169c8..abc5bf9 100644 --- a/docs/yaml/functions/_build_target_base.yaml +++ b/docs/yaml/functions/_build_target_base.yaml @@ -302,3 +302,13 @@ kwargs: "proc-macro" is a special rust procedural macro crate. "proc-macro" is new in 0.62.0. + + rust_dependency_map: + type: dict[str] + since: 1.2.0 + description: | + On rust targets this provides a map of library names to the crate name + with which it would be available inside the rust code. + + This allows renaming similar to the dependency renaming feature of cargo + or `extern crate foo as bar` inside rust code. diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 4d367ed..edf9c1f 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -50,7 +50,7 @@ if T.TYPE_CHECKING: from typing_extensions import Literal from .._typing import ImmutableListProtocol - from ..build import ExtractedObjects + from ..build import ExtractedObjects, LibTypes from ..interpreter import Interpreter from ..linkers import DynamicLinker, StaticLinker from ..compilers.cs import CsCompiler @@ -1830,6 +1830,12 @@ class NinjaBackend(backends.Backend): self.rust_crates[name] = crate + def _get_rust_dependency_name(self, target: build.BuildTarget, dependency: LibTypes) -> str: + # Convert crate names with dashes to underscores by default like + # cargo does as dashes can't be used as parts of identifiers + # 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'] # Rust compiler takes only the main file as input and @@ -1936,11 +1942,7 @@ class NinjaBackend(backends.Backend): # specify `extern CRATE_NAME=OUTPUT_FILE` for each Rust # dependency, so that collisions with libraries in rustc's # sysroot don't cause ambiguity - # - # Also convert crate names with dashes to underscores like - # cargo does as dashes can't be used as parts of identifiers - # in Rust - d_name = d.name.replace('-', '_') + d_name = self._get_rust_dependency_name(target, d) args += ['--extern', '{}={}'.format(d_name, os.path.join(d.subdir, d.filename))] project_deps.append(RustDep(d_name, self.rust_crates[d.name].order)) elif isinstance(d, build.StaticLibrary): @@ -1979,11 +1981,7 @@ class NinjaBackend(backends.Backend): # specify `extern CRATE_NAME=OUTPUT_FILE` for each Rust # dependency, so that collisions with libraries in rustc's # sysroot don't cause ambiguity - # - # Also convert crate names with dashes to underscores like - # cargo does as dashes can't be used as parts of identifiers - # in Rust - d_name = d.name.replace('-', '_') + d_name = self._get_rust_dependency_name(target, d) args += ['--extern', '{}={}'.format(d_name, os.path.join(d.subdir, d.filename))] project_deps.append(RustDep(d_name, self.rust_crates[d.name].order)) else: diff --git a/mesonbuild/build.py b/mesonbuild/build.py index d32296b..0c4326a 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -74,7 +74,7 @@ lang_arg_kwargs |= { } vala_kwargs = {'vala_header', 'vala_gir', 'vala_vapi'} -rust_kwargs = {'rust_crate_type'} +rust_kwargs = {'rust_crate_type', 'rust_dependency_map'} cs_kwargs = {'resources', 'cs_args'} buildtarget_kwargs = { @@ -1239,6 +1239,13 @@ class BuildTarget(Target): if self.gnu_symbol_visibility not in permitted: raise InvalidArguments('GNU symbol visibility arg {} not one of: {}'.format(self.gnu_symbol_visibility, ', '.join(permitted))) + rust_dependency_map = kwargs.get('rust_dependency_map', {}) + if not isinstance(rust_dependency_map, dict): + raise InvalidArguments(f'Invalid rust_dependency_map "{rust_dependency_map}": must be a dictionary.') + if any(not isinstance(v, str) for v in rust_dependency_map.values()): + raise InvalidArguments(f'Invalid rust_dependency_map "{rust_dependency_map}": must be a dictionary with string values.') + self.rust_dependency_map = rust_dependency_map + def validate_win_subsystem(self, value: str) -> str: value = value.lower() if re.fullmatch(r'(boot_application|console|efi_application|efi_boot_service_driver|efi_rom|efi_runtime_driver|native|posix|windows)(,\d+(\.\d+)?)?', value) is None: diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 48c7d1f..e51910e 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -3183,6 +3183,7 @@ class Interpreter(InterpreterBase, HoldableObject): raise InterpreterException(f'Unknown default_library value: {default_library}.') def build_target(self, node: mparser.BaseNode, args, kwargs, targetclass): + @FeatureNewKwargs('build target', '1.2.0', ['rust_dependency_map']) @FeatureNewKwargs('build target', '0.42.0', ['rust_crate_type', 'build_rpath', 'implicit_include_directories']) @FeatureNewKwargs('build target', '0.41.0', ['rust_args']) @FeatureNewKwargs('build target', '0.38.0', ['build_by_default']) diff --git a/test cases/rust/17 staticlib link staticlib/branch.rs b/test cases/rust/17 staticlib link staticlib/branch.rs index 29e1cd0..ea97647 100644 --- a/test cases/rust/17 staticlib link staticlib/branch.rs +++ b/test cases/rust/17 staticlib link staticlib/branch.rs @@ -1,4 +1,4 @@ #[no_mangle] pub extern "C" fn what_have_we_here() -> i32 { - leaf::HOW_MANY * leaf::HOW_MANY + myleaf::HOW_MANY * myleaf::HOW_MANY } diff --git a/test cases/rust/17 staticlib link staticlib/meson.build b/test cases/rust/17 staticlib link staticlib/meson.build index 68d08f3..4a01c05 100644 --- a/test cases/rust/17 staticlib link staticlib/meson.build +++ b/test cases/rust/17 staticlib link staticlib/meson.build @@ -3,6 +3,6 @@ project('staticlib link staticlib', 'c', 'rust') leaf = static_library('leaf', 'leaf.rs', rust_crate_type : 'rlib') # Even though leaf is linked using link_with, this gets implicitly promoted to link_whole because # it is an internal Rust project. -branch = static_library('branch', 'branch.rs', link_with: leaf, rust_crate_type : 'staticlib', install : true) +branch = static_library('branch', 'branch.rs', link_with: leaf, rust_crate_type : 'staticlib', rust_dependency_map : { 'leaf' : 'myleaf' }, install : true) e = executable('prog', 'prog.c', link_with : branch, install : true) test('linktest', e) |