From 7c3a0f81dfd77007ce207d1dc57ce3d12b0e3e84 Mon Sep 17 00:00:00 2001 From: Xavier Claessens Date: Fri, 24 Nov 2023 12:22:05 -0500 Subject: [PATCH] cargo: Set CARGO_PKG_* in env when building and running build.rs --- mesonbuild/cargo/interpreter.py | 28 +++++++++++++++++++++++++--- mesonbuild/modules/rust.py | 7 +++++-- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index 3cf945fd8cb8..bb1476e30dbb 100644 --- a/mesonbuild/cargo/interpreter.py +++ b/mesonbuild/cargo/interpreter.py @@ -522,7 +522,7 @@ def _create_features(cargo: Manifest, build: builder.Builder) -> T.List[mparser. def _create_cfg(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseNode]: # Allow Cargo subprojects to add extra Rust args in meson/meson.build file. # This is used to replace build.rs logic. - + # cargo_info = {'CARGO_...': 'value', ...} # extra_args = [] # extra_deps = [] # fs = import('fs') @@ -530,8 +530,29 @@ def _create_cfg(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseN # if has_meson_build # subdir('meson') # endif - # cfg = rust.cargo_cfg(features, skip_build_rs: has_meson_build) + # cfg = rust.cargo_cfg(features, skip_build_rs: has_meson_build, info: cargo_info) + version_arr = cargo.package.version.split('.') + version_arr += ['' * (4 - len(version_arr))] return [ + build.assign(build.dict({ + # https://doc.rust-lang.org/cargo/reference/environment-variables.html + build.string('CARGO_MANIFEST_DIR'): build.string(os.path.join(cargo.subdir, cargo.path)), + build.string('CARGO_PKG_VERSION'): build.string(cargo.package.version), + build.string('CARGO_PKG_VERSION_MAJOR'): build.string(version_arr[0]), + build.string('CARGO_PKG_VERSION_MINOR'): build.string(version_arr[1]), + build.string('CARGO_PKG_VERSION_PATCH'): build.string(version_arr[2]), + build.string('CARGO_PKG_VERSION_PRE'): build.string(version_arr[3]), + build.string('CARGO_PKG_AUTHORS'): build.string(','.join(cargo.package.authors)), + build.string('CARGO_PKG_NAME'): build.string(cargo.package.name), + build.string('CARGO_PKG_DESCRIPTION'): build.string(cargo.package.description or ''), + build.string('CARGO_PKG_HOMEPAGE'): build.string(cargo.package.homepage or ''), + build.string('CARGO_PKG_REPOSITORY'): build.string(cargo.package.repository or ''), + build.string('CARGO_PKG_LICENSE'): build.string(cargo.package.license or ''), + build.string('CARGO_PKG_LICENSE_FILE'): build.string(cargo.package.license_file or ''), + build.string('CARGO_PKG_RUST_VERSION'): build.string(cargo.package.rust_version or ''), + build.string('CARGO_PKG_README'): build.string(cargo.package.readme or ''), + }), + 'cargo_info'), build.assign(build.array([]), _extra_args_varname()), build.assign(build.array([]), _extra_deps_varname()), build.assign(build.function('import', [build.string('fs')]), 'fs'), @@ -543,7 +564,8 @@ def _create_cfg(cargo: Manifest, build: builder.Builder) -> T.List[mparser.BaseN 'cargo_cfg', build.identifier('rust'), [build.method('keys', build.identifier('features'))], - {'skip_build_rs': build.identifier('has_meson_build')}, + {'skip_build_rs': build.identifier('has_meson_build'), + 'info': build.identifier('cargo_info')}, ), 'cfg'), ] diff --git a/mesonbuild/modules/rust.py b/mesonbuild/modules/rust.py index b290ffb08449..952d2d8358b5 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -55,6 +55,7 @@ class FuncBindgen(TypedDict): class FuncCargoCfg(TypedDict): skip_build_rs: bool + info: T.Dict[str, str] class RustModule(ExtensionModule): @@ -376,7 +377,7 @@ def _split_cfg(cfg: str) -> T.Tuple[str, str]: return pair[0], value @staticmethod - def _get_build_rs_env(state: ModuleState, cfgs: T.Dict[str, str], features: T.List[str]) -> T.Dict[str, str]: + def _get_build_rs_env(state: ModuleState, cfgs: T.Dict[str, str], features: T.List[str], info: T.Dict[str, str]) -> T.Dict[str, str]: # https://doc.rust-lang.org/cargo/reference/environment-variables.html#environment-variables-cargo-sets-for-build-scripts out_dir = os.path.join(state.environment.build_dir, state.subdir, 'build.rs.p') rustc = T.cast('T.Optional[RustCompiler]', state.get_compiler('rust', MachineChoice.HOST)) @@ -392,6 +393,7 @@ def conv(k: str) -> str: env[f'CARGO_CFG_{conv(k)}'] = v for f in features: env[f'CARGO_FEATURE_{conv(f)}'] = '' + env.update(info) return env CARGO_CFG_PREFIX = 'cargo:rustc-cfg=' @@ -401,6 +403,7 @@ def conv(k: str) -> str: @typed_kwargs( 'rust.cargo_cfg', KwargInfo('skip_build_rs', bool, default=False), + KwargInfo('info', ContainerTypeInfo(dict, str), default={}), ) def cargo_cfg(self, state: ModuleState, args: T.Tuple[T.List[str]], kwargs: FuncCargoCfg) -> T.Dict[str, str]: cfgs = dict(self._split_cfg(i) for i in self._get_cfgs(state, MachineChoice.HOST)) @@ -411,7 +414,7 @@ def cargo_cfg(self, state: ModuleState, args: T.Tuple[T.List[str]], kwargs: Func rustc = state.get_compiler('rust', MachineChoice.BUILD) if not rustc: raise InterpreterException(f'build.rs file requires rust language for build machine') - env = self._get_build_rs_env(state, cfgs, args[0]) + env = self._get_build_rs_env(state, cfgs, args[0], kwargs['info']) cwd = os.path.join(state.environment.source_dir, state.subdir) res = rustc.run(build_rs_file, state.environment, run_env=env, run_cwd=cwd) if res.returncode == 0: