From f895998e3f80b4cac40e8ef018110025a153c11c Mon Sep 17 00:00:00 2001 From: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Date: Wed, 3 May 2023 15:41:32 +1200 Subject: [PATCH] Add configure script to set up a light-weight build environment (#26154) * Add configure script to set up a light-weight build environment ... and optionally configure a GN build from environment variables and command line options. This simplifies building a CHIP app as a component within an existing buildroot style build system. Make the custom_toolchain build arg easier to use by interpreting relative paths as relative to ${build_root}/toolchain. Also move the declare_args statements for the 'custom' toolchain into a gni file so they can be discovered correctly. * Factor out python code into configure.utils.py Ensure //build_overrides/pigweed_environment.gni exists. Install wheel in the venv before installing dependencies. * Add chip-build-minimal docker image and minimal-build workflow The chip-build-minimal contains only the minimal build tools for compiling a CHIP app on Linux (c++ toolchain, python3, gn, ninja) and minimal library dependencies (openssl, glib). * Nits from code review * Update with latest zap version from master --- .github/workflows/minimal-build.yaml | 45 +++ build/config/BUILDCONFIG.gn | 11 +- build/toolchain/custom/BUILD.gn | 12 +- build/toolchain/custom/custom.gni | 27 ++ .../build_overrides/pigweed_environment.gni | 25 +- .../images/chip-build-minimal/Dockerfile | 27 ++ .../docker/images/chip-build-minimal/build.sh | 1 + .../docker/images/chip-build-minimal/run.sh | 1 + .../docker/images/chip-build-minimal/version | 1 + scripts/configure | 276 ++++++++++++++++++ scripts/configure.impl.py | 157 ++++++++++ scripts/setup/requirements.build.txt | 13 + scripts/setup/requirements.txt | 11 +- scripts/setup/zap.version | 1 + scripts/tools/zap/version_update.py | 1 + 15 files changed, 581 insertions(+), 28 deletions(-) create mode 100644 .github/workflows/minimal-build.yaml create mode 100644 build/toolchain/custom/custom.gni create mode 100644 integrations/docker/images/chip-build-minimal/Dockerfile create mode 120000 integrations/docker/images/chip-build-minimal/build.sh create mode 120000 integrations/docker/images/chip-build-minimal/run.sh create mode 120000 integrations/docker/images/chip-build-minimal/version create mode 100755 scripts/configure create mode 100644 scripts/configure.impl.py create mode 100644 scripts/setup/requirements.build.txt create mode 100644 scripts/setup/zap.version diff --git a/.github/workflows/minimal-build.yaml b/.github/workflows/minimal-build.yaml new file mode 100644 index 00000000000000..e6215890be1dda --- /dev/null +++ b/.github/workflows/minimal-build.yaml @@ -0,0 +1,45 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +name: Minimal Build (Linux / configure) + +on: + push: + pull_request: + merge_group: + +concurrency: + group: ${{ github.ref }}-${{ github.workflow }}-${{ (github.event_name == 'pull_request' && github.event.number) || (github.event_name == 'workflow_dispatch' && github.run_number) || github.sha }} + cancel-in-progress: true + +jobs: + minimal: + name: Linux / configure build of all-clusters-app + timeout-minutes: 60 + + if: github.actor != 'restyled-io[bot]' + runs-on: ubuntu-latest + + container: + image: connectedhomeip/chip-build-minimal:0.7.2 + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Checkout submodules + run: scripts/checkout_submodules.py --allow-changing-global-git-config --shallow --platform linux + - name: Configure and build All Clusters App + timeout-minutes: 10 + run: | + CC=gcc CXX=g++ scripts/configure --project=examples/all-clusters-app/linux && ./ninja-build diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn index 13a13f804c3248..9d2f17d1acf86e 100644 --- a/build/config/BUILDCONFIG.gn +++ b/build/config/BUILDCONFIG.gn @@ -57,8 +57,17 @@ if (host_toolchain == "") { } } +_custom_toolchain = { + import("${_build_overrides.build_root}/toolchain/custom/custom.gni") +} + if (_chip_defaults.custom_toolchain != "") { - _default_toolchain = _chip_defaults.custom_toolchain + if (filter_include([ _chip_defaults.custom_toolchain ], [ "/*" ]) == []) { + # Interpret relative toolchain names relative to ${build_root}/toolchain/ + _default_toolchain = "${_build_overrides.build_root}/toolchain/${_chip_defaults.custom_toolchain}" + } else { + _default_toolchain = _chip_defaults.custom_toolchain + } } else if (target_os == "all") { _default_toolchain = "${_pigweed_overrides.dir_pw_toolchain}/default" } else if (target_os == "linux") { diff --git a/build/toolchain/custom/BUILD.gn b/build/toolchain/custom/BUILD.gn index f0ee798e9db194..bb8433ada6a246 100644 --- a/build/toolchain/custom/BUILD.gn +++ b/build/toolchain/custom/BUILD.gn @@ -14,19 +14,9 @@ import("//build_overrides/build.gni") import("${build_root}/config/compiler/compiler.gni") +import("${build_root}/toolchain/custom/custom.gni") import("${build_root}/toolchain/gcc_toolchain.gni") -declare_args() { - # C compiler to use for target build. - target_cc = "" - - # C++ compiler to use for target build. - target_cxx = "" - - # Archive tool to use for target build. - target_ar = "" -} - gcc_toolchain("custom") { if (target_cc == "" || target_cxx == "" || target_ar == "") { assert(false, diff --git a/build/toolchain/custom/custom.gni b/build/toolchain/custom/custom.gni new file mode 100644 index 00000000000000..890801a1c647df --- /dev/null +++ b/build/toolchain/custom/custom.gni @@ -0,0 +1,27 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # C compiler to use for target build. + # Only relevant with custom_toolchain = "custom". + target_cc = "" + + # C++ compiler to use for target build. + # Only relevant with custom_toolchain = "custom". + target_cxx = "" + + # Archive tool to use for target build. + # Only relevant with custom_toolchain = "custom". + target_ar = "" +} diff --git a/examples/build_overrides/pigweed_environment.gni b/examples/build_overrides/pigweed_environment.gni index 7fc8bb96532351..a35e7843f84885 100644 --- a/examples/build_overrides/pigweed_environment.gni +++ b/examples/build_overrides/pigweed_environment.gni @@ -20,11 +20,20 @@ _bootstrap_root = "//third_party/connectedhomeip" import("${_bootstrap_root}/build_overrides/pigweed_environment.gni") # Rebase paths to our root. -pw_env_setup_CIPD_ARM = - get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_ARM}", "abspath") -pw_env_setup_CIPD_PIGWEED = - get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_PIGWEED}", "abspath") -pw_env_setup_CIPD_PYTHON = - get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_PYTHON}", "abspath") -pw_env_setup_VIRTUAL_ENV = - get_path_info("${_bootstrap_root}/${pw_env_setup_VIRTUAL_ENV}", "abspath") +if (defined(pw_env_setup_CIPD_ARM)) { + pw_env_setup_CIPD_ARM = + get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_ARM}", "abspath") +} +if (defined(pw_env_setup_CIPD_PIGWEED)) { + pw_env_setup_CIPD_PIGWEED = + get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_PIGWEED}", + "abspath") +} +if (defined(pw_env_setup_CIPD_PYTHON)) { + pw_env_setup_CIPD_PYTHON = + get_path_info("${_bootstrap_root}/${pw_env_setup_CIPD_PYTHON}", "abspath") +} +if (defined(pw_env_setup_VIRTUAL_ENV)) { + pw_env_setup_VIRTUAL_ENV = + get_path_info("${_bootstrap_root}/${pw_env_setup_VIRTUAL_ENV}", "abspath") +} diff --git a/integrations/docker/images/chip-build-minimal/Dockerfile b/integrations/docker/images/chip-build-minimal/Dockerfile new file mode 100644 index 00000000000000..093943d03a1d3a --- /dev/null +++ b/integrations/docker/images/chip-build-minimal/Dockerfile @@ -0,0 +1,27 @@ +# This minimal build image is intentionally not based on chip-build +FROM ubuntu:focal + +# ARG NINJA_VERSION=v1.11.1 +ARG GN_HASH=5a004f9427a050c6c393c07ddb85cba8ff3849fa + +RUN set -x \ + && apt-get update \ + && DEBIAN_FRONTEND=noninteractive apt-get upgrade -y \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + build-essential ca-certificates git pkg-config python3-venv ninja-build \ + && git config --global advice.detachedHead false + +# RUN set -x && cd /var/tmp \ +# && git clone --branch "$NINJA_VERSION" https://github.com/ninja-build/ninja.git \ +# && ( cd ninja && ./configure.py --bootstrap && install -m 0755 ninja /usr/local/bin/ ) \ +# && rm -rf ninja + +RUN set -x && cd /var/tmp \ + && git clone https://gn.googlesource.com/gn \ + && ( cd gn && git checkout "$GN_HASH" && CXX=g++ build/gen.py && ninja -C out && install -m 0755 out/gn /usr/local/bin/ ) \ + && rm -rf gn + +# CHIP build dependencies +RUN set -x \ + && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + libssl-dev libglib2.0-dev diff --git a/integrations/docker/images/chip-build-minimal/build.sh b/integrations/docker/images/chip-build-minimal/build.sh new file mode 120000 index 00000000000000..fcb4d4ee75d531 --- /dev/null +++ b/integrations/docker/images/chip-build-minimal/build.sh @@ -0,0 +1 @@ +../../build.sh \ No newline at end of file diff --git a/integrations/docker/images/chip-build-minimal/run.sh b/integrations/docker/images/chip-build-minimal/run.sh new file mode 120000 index 00000000000000..ccbd3501b330d9 --- /dev/null +++ b/integrations/docker/images/chip-build-minimal/run.sh @@ -0,0 +1 @@ +../../run.sh \ No newline at end of file diff --git a/integrations/docker/images/chip-build-minimal/version b/integrations/docker/images/chip-build-minimal/version new file mode 120000 index 00000000000000..a4280acd348e7f --- /dev/null +++ b/integrations/docker/images/chip-build-minimal/version @@ -0,0 +1 @@ +../chip-build/version \ No newline at end of file diff --git a/scripts/configure b/scripts/configure new file mode 100755 index 00000000000000..84203e71043b3e --- /dev/null +++ b/scripts/configure @@ -0,0 +1,276 @@ +#!/bin/bash -e + +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Usage: configure [OPTIONS] [--project=... [PROJECT OPTIONS]] +# +# Configures a stand-alone build for a CHIP application in the current +# directory and creates a `ninja-build` wrapper script to build it. Should +# generally be run from an empty build directory (i.e. out-of-tree). +# +# This is intended to be used in the context of an external build system and +# represents a light-weight alternative to bootstrapping the full Pigweed build +# environment (via scripts/activate.sh). The pigweed git sub-module must still +# be present though. +# +# External tool dependencies: bash, python3, gn, ninja +# +# The zap-cli code generator and a small number of Python modules are +# downloaded if necessary (see scripts/setup/requirements.build.txt) and +# installed in a build environment directory. By default this is local to +# the build directory, but an external directory can be specified using the +# --build-env-dir option. The build environment directory can be shared by any +# number of build directories, independently of target / tool chain. +# +# Project options can be passed in the usual GNU configure style (--enable-foo, +# --foo-bar=value) and are translated into GN build arguments. By default, +# configure will override the toolchain for the GN build using a 'custom' +# toolchain assembled from the usual environment variables (CC, CXX, AR, CFLAGS, +# CXXFLAGS, ...). + +function usage() { + info "Usage: $0 [OPTIONS] [--project=... [PROJECT OPTIONS]]" + info "Options:" + info " --build-env-dir=DIR Directory to create (host) build environment in" + info " --project=DIR Sub-directory to build, e.g. examples/lighting-app/linux" + exit 0 +} + +function main() { # ... + set -o pipefail + CHIP_ROOT=$(cd "$(dirname "$0")/.." && pwd) + BUILD_ENV_DEPS=( + "${CHIP_ROOT}/scripts/setup/requirements.build.txt" + "${CHIP_ROOT}/scripts/setup/constraints.txt" + "${CHIP_ROOT}/scripts/setup/zap.version" + ) + + if [[ "$PWD" == "$CHIP_ROOT" ]]; then + BUILD_DIR="out/configured" + BUILD_ROOT="${CHIP_ROOT}/${BUILD_DIR}" + BUILD_ENV_DIR=".venv" + info "Configuring in-tree, will build in $BUILD_DIR using environment $BUILD_ENV_DIR" + else + BUILD_DIR="." + BUILD_ROOT="$PWD" + BUILD_ENV_DIR="build-env" + fi + PROJECT= + + # Parse main options but leave project options in $@ + while [[ $# -gt 0 && -z "$PROJECT" ]]; do + case "$1" in + --help) usage ;; + --build-env-dir=*) BUILD_ENV_DIR="${1#*=}" ;; + --project=*) PROJECT="${1#*=}" ;; + *) fail "Invalid argument: '$1'" ;; + esac + shift + done + + if [[ -n "$PROJECT" ]]; then + local subdir="$(cd "${CHIP_ROOT}/${PROJECT}" 2>/dev/null && pwd)" + [[ -n "$subdir" && -r "${subdir}/.gn" ]] || fail "Invalid project '${PROJECT}'" + PROJECT="${subdir#${CHIP_ROOT}/}" + [[ "$subdir" == "${CHIP_ROOT}/${PROJECT}" ]] || fail "Unable to determine project path" + fi + + check_binary gn GN + check_binary ninja NINJA + if ! activate_build_env; then + check_python + configure_python_env + if ! check_binary zap-cli; then + download_zap + fi + finalize_build_env + fi + + if [[ -z "$PROJECT" ]]; then + info "Build environment created. (Specify --project=DIR to configure a build.)" + return + fi + + create_empty_pw_env + gn_generate "$@" + create_ninja_wrapper + info "You can now run ./ninja-build" +} + +function create_empty_pw_env() { + # The Pigweed environment ("//build_overrides/pigweed_environment.gni") is + # imported unconditionally in various build files, so ensure it exists. + local gni="build_overrides/pigweed_environment.gni" + if [[ -d "${CHIP_ROOT}/$(dirname "$gni")" ]]; then + if safe_to_clobber "$gni"; then + info "Creating empty $gni in source tree" + echo "# ${CONFIGURE_MARKER}" >"${CHIP_ROOT}/${gni}" + else + info "Warning: Leaving existing $gni in place, this might affect the build configuration." + fi + fi +} + +function gn_generate() { # [project options] + mkdir -p "${BUILD_ROOT}" + ensure_no_clobber "${BUILD_ROOT}/args.gn" + ( + cd "${CHIP_ROOT}/${PROJECT}" # --root= doesn't work for gn args! + + # Run gn gen with an empty args.gn first so we can list all arguments + info "Configuring gn build arguments (see $BUILD_DIR/args.configured for full list)" + echo "# ${CONFIGURE_MARKER}" >"${BUILD_ROOT}/args.gn" + gn -q gen "$BUILD_ROOT" + + # Use the argument list to drive the mapping of our command line options to GN args + call_impl process_project_args <(gn args "$BUILD_ROOT" --list --json) "$@" >>"${BUILD_ROOT}/args.gn" + gn args "$BUILD_ROOT" --list >"${BUILD_ROOT}/args.configured" + + # Now gn gen with the arguments we have configured. + info "Running gn gen to generate ninja files" + gn -q gen "$BUILD_ROOT" + ) +} + +function create_ninja_wrapper() { + # Note: "." != $BUILD_DIR for in-tree builds + local wrapper="ninja-build" + ensure_no_clobber "$wrapper" + cat >"$wrapper" <"${BUILD_ENV_DIR}/.cksum" + source "${BUILD_ENV_DIR}/bin/activate" + PYTHON="python" +} + +function download_zap() { + local version platform + read -r version <"${CHIP_ROOT}/scripts/setup/zap.version" + case "$OSTYPE" in + linux*) platform=linux ;; + darwin*) platform=mac ;; + *) fail "Unable to determine zap platform for OSTYPE='$OSTYPE'" ;; + esac + local url="https://github.com/project-chip/zap/releases/download/${version}/zap-${platform}.zip" + + progress "Installing zap-cli from $url" + call_impl download_and_extract_zip "$url" "${BUILD_ENV_DIR}/bin" zap-cli + chmod a+x "${BUILD_ENV_DIR}/bin/zap-cli" # ZipFile.extract() does not handle permissions + info "ok" +} + +function call_impl() { # func ... + "$PYTHON" "${CHIP_ROOT}/scripts/configure.impl.py" "$@" +} + +function check_python() { + progress "Checking for Python 3" + if have_binary python3; then + PYTHON="$(hash -t python3)" + elif have_binary python; then + PYTHON="$(hash -t python)" + local ver="$("$PYTHON" --version)" + if [[ "$ver" != "Python 3."* ]]; then + info "need Python 3 but found $ver" + return 1 + fi + else + info "not found" + return 1 + fi + info "$PYTHON" +} + +function check_binary() { # binary [VAR] + progress "Checking for $1" + if ! have_binary "$1"; then + info "not found" + return 1 + fi + local path="$(hash -t "$1")" + [[ -n "$2" ]] && eval "$2=\$path" + info "$path" +} + +function have_binary() { # binary + hash "$1" 2>/dev/null +} + +function ensure_no_clobber() { # file + safe_to_clobber "$1" || fail "Won't overwrite file not generated by configure: $1" +} + +function safe_to_clobber() { # file + CONFIGURE_MARKER="Auto-generated by configure, do not edit" + [[ -s "$1" ]] || return 0 + read -r -n 512 -d '' <"$1" || true + [[ "${REPLY/$CONFIGURE_MARKER/}" != "$REPLY" ]] && return 0 + return 1 +} + +function info() { # message + echo "$*" >&2 +} + +function progress() { # message + echo -n "$*... " >&2 +} + +function fail() { # message + echo "Error: $*" >&2 + exit 1 +} + +main "$@" diff --git a/scripts/configure.impl.py b/scripts/configure.impl.py new file mode 100644 index 00000000000000..b51e40fa00cf55 --- /dev/null +++ b/scripts/configure.impl.py @@ -0,0 +1,157 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# This file contains private utilities for use by the `configure` script. +# It is self-contained and depends only on the Python 3 standard library. + +import collections +import json +import os +import re +import sys +import urllib.request +import zipfile + + +def download_and_extract_zip(url, dest_dir, *member_names): + file, *_ = urllib.request.urlretrieve(url) + with zipfile.ZipFile(file) as zip: + for member in zip.infolist(): + if member.filename in member_names: + zip.extract(member, dest_dir) + + +def process_project_args(gn_args_json_file, *params): + processor = ProjectArgProcessor(gn_args_json_file) + processor.process_defaults() + processor.process_env() + processor.process_parameters(params) + for arg, value in processor.args.items(): + info(" - %s = %s" % (arg, value)) + print("%s = %s" % (arg, value)) + + +class ProjectArgProcessor: + # Prefixes to try when mapping parameters to GN arguments + BOOL_ARG_PREFIXES = ('is_', 'enable_', 'use_', 'chip_', 'chip_enable', 'chip_use_', 'chip_config_') + GENERIC_ARG_PREFIXES = ('chip_', 'chip_config_') + + gn_args = {} # GN arg -> type ('s'tring, 'b'ool, 'i'integer, '[' list, '{' struct) + args = collections.OrderedDict() # collected arguments + + def __init__(self, gn_args_json_file): + # Parse `gn args --list --json` output and derive arg types from default values + argtype = str.maketrans('"tf0123456789', 'sbbiiiiiiiiii') + with open(gn_args_json_file) as fh: + for arg in json.load(fh): + self.gn_args[arg['name']] = arg['default']['value'][0].translate(argtype) + + def process_defaults(self): + self.add_default('custom_toolchain', 'custom') + + def process_env(self): + self.add_env_arg('target_cc', 'CC', 'cc') + self.add_env_arg('target_cxx', 'CXX', 'cxx') + self.add_env_arg('target_ar', 'AR', 'ar') + self.add_env_arg('target_cflags', 'CPPFLAGS', list=True) + self.add_env_arg('target_cflags_c', 'CFLAGS', list=True) + self.add_env_arg('target_cflags_cc', 'CXXFLAGS', list=True) + self.add_env_arg('target_cflags_objc', 'OBJCFLAGS', list=True) + self.add_env_arg('target_ldflags', 'LDFLAGS', list=True) + + def add_arg(self, arg, value): + # format strings and booleans as JSON, otherwise pass through as is + self.args[arg] = (json.dumps(value) if self.gn_args.get(arg, 's') in 'sb' else value) + + def add_default(self, arg, value): + """Add an argument, if supported by the GN build""" + if arg in self.gn_args: + self.add_arg(arg, value) + + def add_env_arg(self, arg, envvar, default=None, list=False): + """Add an argument from an environment variable""" + value = os.environ.get(envvar, default) + if not value: + return + if not (type := self.gn_args.get(arg, None)): + info("Warning: Not propagating %s, project has no build arg '%s'" % (envvar, arg)) + return + self.args[arg] = json.dumps(value if type != '[' else value.split() if list else [value]) + + def gn_arg(self, name, prefixes=(), type=None): + """Finds the GN argument corresponding to a parameter name""" + arg = name.translate(str.maketrans('-', '_')) + candidates = [p + arg for p in (('',) + prefixes) if (p + arg) in self.gn_args] + preferred = [c for c in candidates if self.gn_args[c] == type] if type else [] + if not (match := next(iter(preferred + candidates), None)): + info("Warning: Project has no build arg '%s'" % arg) + return match + + def process_triplet_parameter(self, name, value): + if value is None: + fail("Project option --%s requires an argument" % name) + triplet = value.split('-') + if len(triplet) not in (2, 3, 4): + fail("Project option --%s argument must be a cpu-vendor-os[-abi] triplet" % name) + prefix = 'host_' if name == 'build' else 'target_' # "host" has different meanings in GNU and GN! + self.add_arg(prefix + 'cpu', triplet[0]) + self.add_arg(prefix + 'os', triplet[1 if len(triplet) == 2 else 2]) + + def process_enable_parameter(self, name, value): + if not (arg := self.gn_arg(name[len('enable-'):], self.BOOL_ARG_PREFIXES, 'b')): + return + if self.gn_args[arg] != 'b': + fail("Project build arg '%s' is not a boolean" % arg) + if value != 'no' and value is not None: + fail("Invalid argument for --%s, must be absent or 'no'" % name) + self.add_arg(arg, value is None) + + def process_generic_parameter(self, name, value): + if not (arg := self.gn_arg(name, self.GENERIC_ARG_PREFIXES)): + return + if self.gn_args[arg] == 'b': + fail("Project build arg '%s' is a boolean, use --enable-..." % arg) + if value is None: + fail("Project option --%s requires an argument" % name) + self.add_arg(arg, value) + + def process_parameter(self, name, value): + if name in ('build', 'host', 'target'): + self.process_triplet_parameter(name, value) + elif name.startswith('enable-'): + self.process_enable_parameter(name, value) + else: + self.process_generic_parameter(name, value) + + def process_parameters(self, args): + """Process GNU-style configure command line parameters""" + for arg in args: + if not (m := re.fullmatch(r'--([a-z][a-z0-9-]*)(?:=(.*))?', arg)): + fail("Invalid argument: '%s'" % arg) + self.process_parameter(m.group(1), m.group(2)) + + +def info(message): + print(message, file=sys.stderr) + + +def fail(message): + info("Error: " + message) + sys.exit(1) + + +# `configure` invokes the top-level functions in this file by +# passing the function name and arguments on the command line. +[_, func, *args] = sys.argv +globals()[func](*args) diff --git a/scripts/setup/requirements.build.txt b/scripts/setup/requirements.build.txt new file mode 100644 index 00000000000000..82fe4cc08cea50 --- /dev/null +++ b/scripts/setup/requirements.build.txt @@ -0,0 +1,13 @@ +# Minimal requirements for building stand-alone CHIP applications. +# +# The list of Python packages required to perform a minimal CHIP +# application build should be kept as small as possible. Ideally, +# core build scripts should depend only on the standard library. + +# scripts/build +click + +# scripts/py_matter_idl/matter_idl +jinja2 +lark +stringcase diff --git a/scripts/setup/requirements.txt b/scripts/setup/requirements.txt index 53d0037d6634f3..2a5c57c1eef574 100644 --- a/scripts/setup/requirements.txt +++ b/scripts/setup/requirements.txt @@ -1,6 +1,9 @@ pip-tools virtualenv +# core build requirements +-r requirements.build.txt + # esp-idf -c constraints.esp32.txt -r requirements.esp32.txt @@ -67,14 +70,6 @@ ghapi pandas ; platform_machine != 'aarch64' and platform_machine != 'arm64' tabulate -# scripts/build -click - -# scripts/py_matter_idl/matter_idl -lark -# scripts/py_matter_idl/matter_idl and scripts/py_matter_yamtests/matter_yamltests -stringcase - cryptography # python unit tests diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version new file mode 100644 index 00000000000000..70fb1c57a67ad8 --- /dev/null +++ b/scripts/setup/zap.version @@ -0,0 +1 @@ +v2023.04.27-nightly diff --git a/scripts/tools/zap/version_update.py b/scripts/tools/zap/version_update.py index 394e2048b17646..ba40ca575c53f2 100755 --- a/scripts/tools/zap/version_update.py +++ b/scripts/tools/zap/version_update.py @@ -51,6 +51,7 @@ USAGE_FILES_DEPENDING_ON_ZAP_VERSION = [ 'integrations/docker/images/chip-cert-bins/Dockerfile', 'scripts/setup/zap.json', + 'scripts/setup/zap.version', ]