From 6ff8889d41bdec143b87040ae13969c3918fd245 Mon Sep 17 00:00:00 2001 From: ajohns Date: Tue, 17 Dec 2019 11:32:50 +1100 Subject: [PATCH] -added test -updated wiki --- src/rez/build_system.py | 11 +++++ .../data/builds/packages/foo/1.0.0/package.py | 3 ++ .../builds/packages/foo/1.0.0/rezbuild.py | 5 +++ wiki/pages/Package-Commands.md | 41 +++++++++++++++++++ wiki/pages/Package-Definition-Guide.md | 9 ++++ 5 files changed, 69 insertions(+) diff --git a/src/rez/build_system.py b/src/rez/build_system.py index 8ade6953f..4b95708b3 100644 --- a/src/rez/build_system.py +++ b/src/rez/build_system.py @@ -256,6 +256,7 @@ def add_standard_build_actions(cls, executor, context, variant, build_type, - Setting a standard list on env-vars; - Executing pre_build_commands(), if the package has one. """ + from rez.utils.data_utils import RO_AttrDictWrapper # set env vars env_vars = cls.get_standard_vars( @@ -270,12 +271,22 @@ def add_standard_build_actions(cls, executor, context, variant, build_type, for var, value in env_vars.items(): executor.env[var] = value + # bind build-related values into a 'build' namespace + build_ns = { + "build_type": build_type.name, + "install": install, + "build_path": build_path, + "install_path": install_path + } + # execute pre_build_commands() pre_build_commands = getattr(variant, "pre_build_commands") if pre_build_commands: with executor.reset_globals(): executor.bind("this", variant) + executor.bind("build", RO_AttrDictWrapper(build_ns)) + executor.execute_code(pre_build_commands) diff --git a/src/rez/tests/data/builds/packages/foo/1.0.0/package.py b/src/rez/tests/data/builds/packages/foo/1.0.0/package.py index 39854c41e..70a68da94 100644 --- a/src/rez/tests/data/builds/packages/foo/1.0.0/package.py +++ b/src/rez/tests/data/builds/packages/foo/1.0.0/package.py @@ -8,6 +8,9 @@ private_build_requires = ["build_util"] +def pre_build_commands(): + env.FOO_TEST_VAR = "hello" + def commands(): env.PYTHONPATH.append('{root}/python') diff --git a/src/rez/tests/data/builds/packages/foo/1.0.0/rezbuild.py b/src/rez/tests/data/builds/packages/foo/1.0.0/rezbuild.py index f654721ec..0285aa85c 100644 --- a/src/rez/tests/data/builds/packages/foo/1.0.0/rezbuild.py +++ b/src/rez/tests/data/builds/packages/foo/1.0.0/rezbuild.py @@ -2,6 +2,7 @@ from build_util import build_directory_recurse, check_visible import os.path +import os def build(source_path, build_path, install_path, targets): @@ -11,6 +12,10 @@ def build(source_path, build_path, install_path, targets): import floob print(floob.hello()) + # env var should have been set in pre_build_commands + if os.getenv("FOO_TEST_VAR") != "hello": + raise RuntimeError("Expected $FOO_TEST_VAR to be set") + # do the build if "install" not in (targets or []): install_path = None diff --git a/wiki/pages/Package-Commands.md b/wiki/pages/Package-Commands.md index 92e999a4a..b1fcabfc7 100644 --- a/wiki/pages/Package-Commands.md +++ b/wiki/pages/Package-Commands.md @@ -151,6 +151,17 @@ The order of command execution is: * Then, all package *commands* are executed, in standard execution order; * Then, all package *post_commands* are executed, in standard execution order. +## Pre Build Commands + +If a package is being built, that package's commands are not run, simply because that package is +not present in its own build environment! However, sometimes there is a need to run commands +specifically for the package being built. For example, you may wish to set some environment +variables to pass information along to the build system. + +The *pre_build_commands* function does just this. It is called prior to the build. Note that info +about the current build (such as the installation path) is available in a +(build)[Package-Commands#build] object (other commands functions do not have this object visible). + ## A Largish Example Here is an example of a package definition with a fairly lengthy *commands* section: @@ -214,6 +225,36 @@ Create a command alias. See [this.base](#thisbase). +### build +*Dict-like object* + + if build.install: + info("An installation is taking place") + +This object is only available in the (pre_build_commands)[Package-Commands#pre-build-commands] +function. It has the following fields: + +#### build.build_type +*String* + +One of 'local', 'central'. The type is _central_ if a package _release_ is occurring, and _local_ +otherwise. + +#### build.install +*Boolean* + +True if an installation is taking place, False otherwise. + +#### build.build_path +*String* + +Path to the build directory (not the installation path). This will typically reside somewhere +within the `./build` subdirectory of the package being built. + +#### build.install_path +Installation directory. Note that this will be set, even if an installation is _not_ taking place. +Do not check this variable to detect if an installation is occurring - see `build.install` instead. + ### building *Boolean* diff --git a/wiki/pages/Package-Definition-Guide.md b/wiki/pages/Package-Definition-Guide.md index 64302ecb6..3ef70775e 100644 --- a/wiki/pages/Package-Definition-Guide.md +++ b/wiki/pages/Package-Definition-Guide.md @@ -762,6 +762,15 @@ variable. Specify the build system used to build this package. If not set, it is detected automatically when a build occurs (or the user specifies it using the `--build-system` option). +### pre_build_commands +*Function* + + def pre_build_commands(): + env.FOO_BUILT_BY_REZ = 1 + +This is similar to *commands*, except that it is run _prior to the current package being built_. +See [here](Package-Commands#pre-build-commands) for more details. + ### preprocess *Function*