diff options
author | Xavier Claessens <xavier.claessens@collabora.com> | 2023-06-02 12:11:45 -0400 |
---|---|---|
committer | Xavier Claessens <xclaesse@gmail.com> | 2023-10-09 21:13:58 -0400 |
commit | dc329f0f04d917da5bf295e013f393caed4a85fc (patch) | |
tree | 00ec4bd14f1af655fa049ec102649dad9e53f0f7 | |
parent | ea42d2d01999c00c7fe7846de38416b8693bfb79 (diff) | |
download | meson-dc329f0f04d917da5bf295e013f393caed4a85fc.zip meson-dc329f0f04d917da5bf295e013f393caed4a85fc.tar.gz meson-dc329f0f04d917da5bf295e013f393caed4a85fc.tar.bz2 |
interpreter: Add support for cargo subproject
-rw-r--r-- | docs/markdown/Wrap-dependency-system-manual.md | 21 | ||||
-rw-r--r-- | docs/markdown/snippets/wrap.md | 3 | ||||
-rw-r--r-- | mesonbuild/cargo/__init__.py | 5 | ||||
-rw-r--r-- | mesonbuild/cargo/interpreter.py | 8 | ||||
-rw-r--r-- | mesonbuild/interpreter/interpreter.py | 25 | ||||
-rw-r--r-- | mesonbuild/wrap/wrap.py | 3 | ||||
-rw-r--r-- | test cases/cmake/26 dependency fallback/meson.build | 2 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/main.c | 5 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/meson.build | 7 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/bar-rs.wrap | 2 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/bar-rs/Cargo.toml | 3 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/bar-rs/src/lib.rs | 1 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/foo-rs.wrap | 2 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/foo-rs/Cargo.toml | 10 | ||||
-rw-r--r-- | test cases/rust/21 cargo subproject/subprojects/foo-rs/src/lib.rs | 4 |
15 files changed, 91 insertions, 10 deletions
diff --git a/docs/markdown/Wrap-dependency-system-manual.md b/docs/markdown/Wrap-dependency-system-manual.md index 9000c40..e1e9474 100644 --- a/docs/markdown/Wrap-dependency-system-manual.md +++ b/docs/markdown/Wrap-dependency-system-manual.md @@ -91,6 +91,7 @@ previously reserved to `wrap-file`: Supported methods: - `meson` requires `meson.build` file. - `cmake` requires `CMakeLists.txt` file. [See details](#cmake-wraps). + - `cargo` requires `Cargo.toml` file. [See details](#cargo-wraps). ### Specific to wrap-file - `source_url` - download url to retrieve the wrap-file source archive @@ -313,6 +314,26 @@ method = cmake [provide] foo-bar-1.0 = foo_bar_dep ``` +### Cargo wraps + +Cargo subprojects automatically override the `<package_name>-rs` dependency name. +`package_name` is defined in `[package] name = ...` section of the `Cargo.toml` +and `-rs` suffix is added. That means the `.wrap` file should have +`dependency_names = foo-rs` in their `[provide]` section when `Cargo.toml` has +package name `foo`. + +Cargo subprojects require a toml parser. Python >= 3.11 have one built-in, older +Python versions require either the external `tomli` module or `toml2json` program. + +For example, a Cargo project with the package name `foo-bar` would have a wrap +file like that: +```ini +[wrap-file] +... +method = cargo +[provide] +dependency_names = foo-bar-rs +``` ## Using wrapped projects diff --git a/docs/markdown/snippets/wrap.md b/docs/markdown/snippets/wrap.md index 6e03c2e..3a5521e 100644 --- a/docs/markdown/snippets/wrap.md +++ b/docs/markdown/snippets/wrap.md @@ -1,4 +1,4 @@ -## Automatic fallback to `cmake` subproject +## Automatic fallback to `cmake` and `cargo` subproject CMake subprojects have been supported for a while using the `cmake.subproject()` module method. However until now it was not possible to use a CMake subproject @@ -10,3 +10,4 @@ key in the wrap file's first section. The method defaults to `meson`. Supported methods: - `meson` requires `meson.build` file. - `cmake` requires `CMakeLists.txt` file. [See details](Wrap-dependency-system-manual.md#cmake-wraps). +- `cargo` requires `Cargo.toml` file. [See details](Wrap-dependency-system-manual.md#cargo-wraps). diff --git a/mesonbuild/cargo/__init__.py b/mesonbuild/cargo/__init__.py index e69de29..0007b9d 100644 --- a/mesonbuild/cargo/__init__.py +++ b/mesonbuild/cargo/__init__.py @@ -0,0 +1,5 @@ +__all__ = [ + 'interpret' +] + +from .interpreter import interpret diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 68517ba..12365bb 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -457,7 +457,13 @@ def _create_lib(cargo: Manifest, build: builder.Builder, crate_type: manifest.CR ] -def interpret(cargo: Manifest, env: Environment) -> mparser.CodeBlockNode: +def interpret(subp_name: str, subdir: str, env: Environment) -> mparser.CodeBlockNode: + package_name = subp_name[:-3] if subp_name.endswith('-rs') else subp_name + manifests = _load_manifests(os.path.join(env.source_dir, subdir)) + cargo = manifests.get(package_name) + if not cargo: + raise MesonException(f'Cargo package {package_name!r} not found in {subdir}') + filename = os.path.join(cargo.subdir, cargo.path, 'Cargo.toml') build = builder.Builder(filename) diff --git a/mesonbuild/interpreter/interpreter.py b/mesonbuild/interpreter/interpreter.py index 23ce146..cc83cbd 100644 --- a/mesonbuild/interpreter/interpreter.py +++ b/mesonbuild/interpreter/interpreter.py @@ -930,13 +930,14 @@ class Interpreter(InterpreterBase, HoldableObject): m += ['method', mlog.bold(method)] mlog.log(*m, '\n', nested=False) + methods_map: T.Dict[wrap.Method, T.Callable[[str, str, T.Dict[OptionKey, str, kwtypes.DoSubproject]], SubprojectHolder]] = { + 'meson': self._do_subproject_meson, + 'cmake': self._do_subproject_cmake, + 'cargo': self._do_subproject_cargo, + } + try: - if method == 'meson': - return self._do_subproject_meson(subp_name, subdir, default_options, kwargs) - elif method == 'cmake': - return self._do_subproject_cmake(subp_name, subdir, default_options, kwargs) - else: - raise mesonlib.MesonBugException(f'The method {method} is invalid for the subproject {subp_name}') + return methods_map[method](subp_name, subdir, default_options, kwargs) # Invalid code is always an error except InvalidCode: raise @@ -1038,6 +1039,18 @@ class Interpreter(InterpreterBase, HoldableObject): result.cm_interpreter = cm_int return result + def _do_subproject_cargo(self, subp_name: str, subdir: str, + default_options: T.Dict[OptionKey, str], + kwargs: kwtypes.DoSubproject) -> SubprojectHolder: + from .. import cargo + FeatureNew.single_use('Cargo subproject', '1.3.0', self.subproject, location=self.current_node) + with mlog.nested(subp_name): + ast = cargo.interpret(subp_name, subdir, self.environment) + return self._do_subproject_meson( + subp_name, subdir, default_options, kwargs, ast, + # FIXME: Are there other files used by cargo interpreter? + [os.path.join(subdir, 'Cargo.toml')]) + def get_option_internal(self, optname: str) -> coredata.UserOption: key = OptionKey.from_string(optname).evolve(subproject=self.subproject) diff --git a/mesonbuild/wrap/wrap.py b/mesonbuild/wrap/wrap.py index 21a5c5d..a5b4dc8 100644 --- a/mesonbuild/wrap/wrap.py +++ b/mesonbuild/wrap/wrap.py @@ -47,7 +47,7 @@ if T.TYPE_CHECKING: import http.client from typing_extensions import Literal - Method = Literal['meson', 'cmake'] + Method = Literal['meson', 'cmake', 'cargo'] try: # Importing is just done to check if SSL exists, so all warnings @@ -450,6 +450,7 @@ class Resolver: methods_map: T.Dict[Method, str] = { 'meson': 'meson.build', 'cmake': 'CMakeLists.txt', + 'cargo': 'Cargo.toml', } # Check if this wrap forces a specific method, use meson otherwise. diff --git a/test cases/cmake/26 dependency fallback/meson.build b/test cases/cmake/26 dependency fallback/meson.build index b36aaac..871d70c 100644 --- a/test cases/cmake/26 dependency fallback/meson.build +++ b/test cases/cmake/26 dependency fallback/meson.build @@ -9,7 +9,7 @@ test('test1', exe1) # to meson but wrap force cmake. subproject('force_cmake') -testcase expect_error('Wrap method \'notfound\' is not supported, must be one of: meson, cmake') +testcase expect_error('Wrap method \'notfound\' is not supported, must be one of: meson, cmake, cargo') subproject('broken_method') endtestcase diff --git a/test cases/rust/21 cargo subproject/main.c b/test cases/rust/21 cargo subproject/main.c new file mode 100644 index 0000000..5daec64 --- /dev/null +++ b/test cases/rust/21 cargo subproject/main.c @@ -0,0 +1,5 @@ +int rust_func(void); + +int main(int argc, char *argv[]) { + return rust_func(); +} diff --git a/test cases/rust/21 cargo subproject/meson.build b/test cases/rust/21 cargo subproject/meson.build new file mode 100644 index 0000000..420e6e3 --- /dev/null +++ b/test cases/rust/21 cargo subproject/meson.build @@ -0,0 +1,7 @@ +project('cargo subproject', 'c') + +foo_dep = dependency('foo-rs') +exe = executable('app', 'main.c', + dependencies: foo_dep, +) +test('cargo-test', exe) diff --git a/test cases/rust/21 cargo subproject/subprojects/bar-rs.wrap b/test cases/rust/21 cargo subproject/subprojects/bar-rs.wrap new file mode 100644 index 0000000..99686e9 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/bar-rs.wrap @@ -0,0 +1,2 @@ +[wrap-file] +method = cargo diff --git a/test cases/rust/21 cargo subproject/subprojects/bar-rs/Cargo.toml b/test cases/rust/21 cargo subproject/subprojects/bar-rs/Cargo.toml new file mode 100644 index 0000000..232b4d7 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/bar-rs/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "bar" +version = "0.1" diff --git a/test cases/rust/21 cargo subproject/subprojects/bar-rs/src/lib.rs b/test cases/rust/21 cargo subproject/subprojects/bar-rs/src/lib.rs new file mode 100644 index 0000000..5b64db8 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/bar-rs/src/lib.rs @@ -0,0 +1 @@ +pub const VALUE: i32 = 0; diff --git a/test cases/rust/21 cargo subproject/subprojects/foo-rs.wrap b/test cases/rust/21 cargo subproject/subprojects/foo-rs.wrap new file mode 100644 index 0000000..99686e9 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/foo-rs.wrap @@ -0,0 +1,2 @@ +[wrap-file] +method = cargo diff --git a/test cases/rust/21 cargo subproject/subprojects/foo-rs/Cargo.toml b/test cases/rust/21 cargo subproject/subprojects/foo-rs/Cargo.toml new file mode 100644 index 0000000..214c327 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/foo-rs/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "foo" +version = "0.0.1" +edition = "2021" + +[lib] +crate-type = ["cdylib"] + +[dependencies] +mybar = { version = "0.1", package = "bar" } diff --git a/test cases/rust/21 cargo subproject/subprojects/foo-rs/src/lib.rs b/test cases/rust/21 cargo subproject/subprojects/foo-rs/src/lib.rs new file mode 100644 index 0000000..732d7d2 --- /dev/null +++ b/test cases/rust/21 cargo subproject/subprojects/foo-rs/src/lib.rs @@ -0,0 +1,4 @@ +#[no_mangle] +pub extern "C" fn rust_func() -> i32 { + mybar::VALUE +} |