mirror of
https://github.com/mesonbuild/meson.git
synced 2026-06-30 19:57:45 +00:00
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.
This commit is contained in:
committed by
Xavier Claessens
parent
474e3ea8af
commit
01420bf8fc
18
docs/markdown/snippets/rust_dependency_map.md
Normal file
18
docs/markdown/snippets/rust_dependency_map.md
Normal file
@@ -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],
|
||||
)
|
||||
```
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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'])
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user