From de93962c009782bd6ec5ee3ca5425a4cc096dd31 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 | 14 +++++++++++--- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/mesonbuild/cargo/interpreter.py b/mesonbuild/cargo/interpreter.py index b3783ca1c5a3..ea5d5e9542ab 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 c7f850f7c1ff..d6d235ecc3fd 100644 --- a/mesonbuild/modules/rust.py +++ b/mesonbuild/modules/rust.py @@ -61,6 +61,7 @@ class FuncBindgen(TypedDict): class FuncCargoCfg(TypedDict): skip_build_rs: bool + info: T.Dict[str, str] class RustModule(ExtensionModule): @@ -326,7 +327,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 env = os.environ.copy() def conv(k: str) -> str: @@ -341,6 +342,7 @@ def conv(k: str) -> str: rustc_cmd = rustc.get_exelist(ccache=False) env['RUSTC'] = rustc_cmd[0] env['TARGET'] = rustc.get_target_triplet() + env.update(info) return env CARGO_CFG_PREFIX = 'cargo:rustc-cfg=' @@ -350,6 +352,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)) @@ -360,9 +363,14 @@ 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) + try: + orig_env = os.environ + os.environ = env + res = rustc.run(build_rs_file, state.environment, run_cwd=cwd) + finally: + os.environ = orig_env if res.returncode == 0: compiler_args: T.List[str] = [] for line in res.stdout.splitlines():