diff options
6 files changed, 33 insertions, 21 deletions
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index f2ca665ff..077535a8d 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -331,10 +331,9 @@ Cargo subprojects automatically call `override_dependency` with the name * `0.0.x` -> '0' It allows to make different dependencies for incompatible versions of the same crate. -- the suffix is `-rs` for `rlib` and `dylib` crate types, otherwise it is the - crate type (e.g. `staticlib` or `cdylib`). The suffix is added to distinguish - Rust crates from regular system dependencies; for example `gstreamer-1.0` is a - system pkg-config dependency and `gstreamer-0.22-rs` is a Cargo dependency. +- the suffix is `-rs` for `rlib` and `dylib` crate types. The suffix is added to + distinguish Rust crates from C-ABI dependencies; for example `gstreamer-1.0` + is a system pkg-config dependency and `gstreamer-0.22-rs` is a Cargo dependency. That means the `.wrap` file should have `dependency_names = foo-1-rs` in their `[provide]` section when `Cargo.toml` has package name `foo` and version `1.2`. diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index fe0a2a591..02fe9d3b4 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -32,8 +32,10 @@ if T.TYPE_CHECKING: from ..interpreterbase import SubProject from ..compilers.rust import RustCompiler + from typing_extensions import Literal + def _dependency_name(package_name: str, api: str, suffix: str = '-rs') -> str: - basename = package_name[:-len(suffix)] if package_name.endswith(suffix) else package_name + basename = package_name[:-len(suffix)] if suffix and package_name.endswith(suffix) else package_name return f'{basename}-{api}{suffix}' @@ -139,8 +141,19 @@ class Interpreter: ast += self._create_meson_subdir(build) if pkg.manifest.lib: - for crate_type in pkg.manifest.lib.crate_type: - ast.extend(self._create_lib(pkg, build, crate_type)) + crate_type = pkg.manifest.lib.crate_type + if 'dylib' in crate_type and 'cdylib' in crate_type: + raise MesonException('Cannot build both dylib and cdylib due to file name conflict') + if 'proc-macro' in crate_type: + ast.extend(self._create_lib(pkg, build, 'proc-macro', shared=True)) + if any(x in crate_type for x in ['lib', 'rlib', 'dylib']): + ast.extend(self._create_lib(pkg, build, 'rust', + static=('lib' in crate_type or 'rlib' in crate_type), + shared='dylib' in crate_type)) + if any(x in crate_type for x in ['staticlib', 'cdylib']): + ast.extend(self._create_lib(pkg, build, 'c', + static='staticlib' in crate_type, + shared='cdylib' in crate_type)) return ast @@ -560,7 +573,9 @@ class Interpreter: build.block([build.function('subdir', [build.string('meson')])])) ] - def _create_lib(self, pkg: PackageState, build: builder.Builder, crate_type: raw.CRATE_TYPE) -> T.List[mparser.BaseNode]: + def _create_lib(self, pkg: PackageState, build: builder.Builder, + lib_type: Literal['rust', 'c', 'proc-macro'], + static: bool = False, shared: bool = False) -> T.List[mparser.BaseNode]: dependencies: T.List[mparser.BaseNode] = [] dependency_map: T.Dict[mparser.BaseNode, mparser.BaseNode] = {} for name in pkg.required_deps: @@ -593,21 +608,19 @@ class Interpreter: 'rust_args': build.array(rust_args), } - depname_suffix = '-rs' if crate_type in {'lib', 'rlib', 'proc-macro'} else f'-{crate_type}' + depname_suffix = '' if lib_type == 'c' else '-rs' depname = _dependency_name(pkg.manifest.package.name, pkg.manifest.package.api, depname_suffix) lib: mparser.BaseNode - if crate_type == 'proc-macro': + if lib_type == 'proc-macro': lib = build.method('proc_macro', build.identifier('rust'), posargs, kwargs) else: - if crate_type in {'lib', 'rlib', 'staticlib'}: - target_type = 'static_library' - elif crate_type in {'dylib', 'cdylib'}: - target_type = 'shared_library' + if static and shared: + target_type = 'both_libraries' else: - raise MesonException(f'Unsupported crate type {crate_type}') - if crate_type in {'staticlib', 'cdylib'}: - kwargs['rust_abi'] = build.string('c') + target_type = 'shared_library' if shared else 'static_library' + + kwargs['rust_abi'] = build.string(lib_type) lib = build.function(target_type, posargs, kwargs) features_args: T.List[mparser.BaseNode] = [] diff --git a/test cases/rust/22 cargo subproject/meson.build b/test cases/rust/22 cargo subproject/meson.build index 7e2c66288..3a79bc8a6 100644 --- a/test cases/rust/22 cargo subproject/meson.build +++ b/test cases/rust/22 cargo subproject/meson.build @@ -1,6 +1,6 @@ project('cargo subproject', 'c') -foo_dep = dependency('foo-0-cdylib') +foo_dep = dependency('foo-0') exe = executable('app', 'main.c', dependencies: foo_dep, ) diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap index d12172bf3..c39970188 100644 --- a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap +++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs.wrap @@ -2,4 +2,4 @@ method = cargo [provide] -dependency_names = foo-0-cdylib +dependency_names = foo-0 diff --git a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml index dd8525b54..acbd56efe 100644 --- a/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml +++ b/test cases/rust/22 cargo subproject/subprojects/foo-0-rs/Cargo.toml @@ -4,7 +4,7 @@ version = "0.0.1" edition = "2021" [lib] -crate-type = ["cdylib"] +crate-type = ["staticlib", "cdylib"] path = "lib.rs" # This dependency does not exist, verify optional works. diff --git a/test cases/rust/30 cargo workspace/meson.build b/test cases/rust/30 cargo workspace/meson.build index fab1954c6..4d69fdfc0 100644 --- a/test cases/rust/30 cargo workspace/meson.build +++ b/test cases/rust/30 cargo workspace/meson.build @@ -6,7 +6,7 @@ e = executable('test-foo-1-rs', 'test_foo_1.rs', ) test('test-foo-1-rs', e) -foo_cdylib = dependency('foo-1-cdylib') +foo_cdylib = dependency('foo-1') e = executable('test-foo-1-cdylib', 'test_foo_1.c', dependencies: [foo_cdylib], ) |
