aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian Dröge <sebastian@centricular.com>2023-04-13 23:04:51 +0300
committerXavier Claessens <xclaesse@gmail.com>2023-04-21 15:35:06 -0400
commit01420bf8fc1ee6c1466e2fa4c9805267192dce26 (patch)
treec419d8b14d4a4144a4a3ce093f853e0c7d385875
parent474e3ea8afd170ae86cc5c3a547caee65f97ecb8 (diff)
downloadmeson-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.md18
-rw-r--r--docs/yaml/functions/_build_target_base.yaml10
-rw-r--r--mesonbuild/backend/ninjabackend.py20
-rw-r--r--mesonbuild/build.py9
-rw-r--r--mesonbuild/interpreter/interpreter.py1
-rw-r--r--test cases/rust/17 staticlib link staticlib/branch.rs2
-rw-r--r--test cases/rust/17 staticlib link staticlib/meson.build2
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)