summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Bettis <jbettis@google.com>2022-02-04 08:50:45 -0700
committerCommit Bot <commit-bot@chromium.org>2022-02-19 04:42:07 +0000
commit2d653eea9c0c70bd41cc8459885d9b0c13f2d27e (patch)
treec4016c6bc9d2603c3bb17b5bdf5b44e3a0d930f0
parent88307eb2bf53f6324eb3c9a609993139880b0f7c (diff)
downloadchrome-ec-2d653eea9c0c70bd41cc8459885d9b0c13f2d27e.tar.gz
zmake: Implement zmake configure for multi-project.
Change zmake configure to work as described in go/zmake-cli-v2. BRANCH=None BUG=b:217788621 TEST=Various zmake configure cmds. Cq-Include-Trybots: luci.chromeos.cq:cq-orchestrator Cq-Depend: chromium:3462900 Change-Id: I58fa4d8427efff64c5764eac6ba4752a71785127 Signed-off-by: Jeremy Bettis <jbettis@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3445105 Reviewed-by: Jack Rosenthal <jrosenth@chromium.org> Commit-Queue: Jeremy Bettis <jbettis@chromium.org> Tested-by: Jeremy Bettis <jbettis@chromium.org>
-rw-r--r--.gitlab-ci.yml4
-rw-r--r--docs/code_coverage.md4
-rw-r--r--docs/reducing_ec_image_size.md4
-rw-r--r--docs/zephyr/zephyr_build.md6
-rw-r--r--zephyr/zmake/README.md12
-rw-r--r--zephyr/zmake/tests/test_zmake.py4
-rw-r--r--zephyr/zmake/zmake/__main__.py94
-rw-r--r--zephyr/zmake/zmake/zmake.py168
8 files changed, 193 insertions, 103 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index f36cc8b743..cb4e82fcba 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -72,7 +72,7 @@ seed_cache:
script:
- zmake --zephyr-base "${ZEPHYR_BASE}"
--modules-dir "${MODULES_DIR}" -l DEBUG configure -b
- -B "${BUILD_DIR}/${PROJECT}" -t ${TOOLCHAIN:-zephyr}
+ -B "${BUILD_DIR}" -t ${TOOLCHAIN:-zephyr}
"${PROJECT}"
- for b in "${BUILD_DIR}/${PROJECT}"/build-* ; do
bdir=$(basename ${b}) ;
@@ -98,7 +98,7 @@ seed_cache:
script:
- zmake --zephyr-base "${ZEPHYR_BASE}"
--modules-dir "${MODULES_DIR}" -l DEBUG configure -b --coverage
- -B "${BUILD_DIR}/${PROJECT}" -t ${TOOLCHAIN:-zephyr}
+ -B "${BUILD_DIR}" -t ${TOOLCHAIN:-zephyr}
"${PROJECT}"
- lcov --rc lcov_branch_coverage=1 -o "${BUILD_DIR}/${PROJECT}/output/merged_twister.info" -a "${BUILD_DIR}/${PROJECT}/output/zephyr.info" -a "${BUILD_DIR}/zephyr_codecov/fixed.info"
- lcov --rc lcov_branch_coverage=1 -o "${BUILD_DIR}/${PROJECT}/output/merged_twister_no_ec.info" -e "${BUILD_DIR}/${PROJECT}/output/merged_twister.info" "${ZEPHYR_BASE}/**" "${MODULES_DIR}/**"
diff --git a/docs/code_coverage.md b/docs/code_coverage.md
index cddc7b671d..93637ac019 100644
--- a/docs/code_coverage.md
+++ b/docs/code_coverage.md
@@ -50,8 +50,8 @@ The coverage report top-level page is
`build/ztest-coverage/coverage_rpt/index.html`.
For manual coverage report you can run:
-`zmake configure --test --coverage <PATH>`
+`zmake configure --test --coverage <TESTNAME>`
Example:
-`zmake configure --test --coverage zephyr/test/drivers/`
+`zmake configure --test --coverage test-drivers`
`genhtml -q -o build/ztest-coverage/coverage_rpt/ build/zephyr/test-drivers/output/zephyr.info`
diff --git a/docs/reducing_ec_image_size.md b/docs/reducing_ec_image_size.md
index e7df161bca..d93d0b4840 100644
--- a/docs/reducing_ec_image_size.md
+++ b/docs/reducing_ec_image_size.md
@@ -122,10 +122,10 @@ images outside chroot before running the commands below.
$ zmake configure -B /tmp/zephyr-volteer volteer
# Build the RO image
-$ ninja -C /tmp/zephyr-volteer/build-ro
+$ ninja -C /tmp/zephyr-volteer/volteer/build-ro
# Generate the ROM report, report sent to stdout
-$ ninja -C /tmp/zephyr-volteer/build-ro rom_report
+$ ninja -C /tmp/zephyr-volteer/volteer/build-ro rom_report
```
Please refer to the [Zephyr Optimization Tools][3] documentation for details on
diff --git a/docs/zephyr/zephyr_build.md b/docs/zephyr/zephyr_build.md
index b49e2ec4b1..c20d4f25e7 100644
--- a/docs/zephyr/zephyr_build.md
+++ b/docs/zephyr/zephyr_build.md
@@ -114,13 +114,13 @@ a rough guide.
First configure the build with the project you want:
```bash
-zmake configure -B /tmp/z/vol volteer
+zmake configure -B /tmp/z volteer
```
Then build with just the target directory:
```
-zmake build /tmp/z/vol
+zmake build /tmp/z/volteer
```
The output is in that directory:
@@ -146,7 +146,7 @@ as well.
It should be possible to do this with:
```bash
-ninja -C /tmp/z/vol/build-ro menuconfig
+ninja -C /tmp/z/volteer/build-ro menuconfig
```
However at present this does not work [b/184662866](http://b/184662866).
diff --git a/zephyr/zmake/README.md b/zephyr/zmake/README.md
index 6eb573154c..697daaab06 100644
--- a/zephyr/zmake/README.md
+++ b/zephyr/zmake/README.md
@@ -35,27 +35,29 @@ Chromium OS's meta-build tool for Zephyr
### zmake configure
-**Usage:** `zmake configure [-h] [-t TOOLCHAIN] [--bringup] [--clobber] [--allow-warnings] [-B BUILD_DIR] [-b] [--test] project_name [-c]`
+**Usage:** `zmake configure [-h] [-b] [--test] [-t TOOLCHAIN] [--bringup] [--clobber] [--allow-warnings] [-B BUILD_DIR] [-c] (-a | --host-tests-only | project_name [project_name ...])`
#### Positional Arguments
| | |
|---|---|
-| `project_name` | Name of the project to setup |
+| `project_name` | Name(s) of the project(s) to build |
#### Optional Arguments
| | |
|---|---|
| `-h`, `--help` | show this help message and exit |
+| `-b`, `--build` | Run the build after configuration |
+| `--test` | Test the .elf file after building |
| `-t TOOLCHAIN`, `--toolchain TOOLCHAIN` | Name of toolchain to use |
| `--bringup` | Enable bringup debugging features |
| `--clobber` | Delete existing build directories, even if configuration is unchanged |
| `--allow-warnings` | Do not treat warnings as errors |
-| `-B BUILD_DIR`, `--build-dir BUILD_DIR` | Build directory |
-| `-b`, `--build` | Run the build after configuration |
-| `--test` | Test the .elf file after configuration |
+| `-B BUILD_DIR`, `--build-dir BUILD_DIR` | Root build directory, project files will be in ${build_dir}/${project_name} |
| `-c`, `--coverage` | Enable CONFIG_COVERAGE Kconfig. |
+| `-a`, `--all` | Select all projects |
+| `--host-tests-only` | Select all test projects |
### zmake build
diff --git a/zephyr/zmake/tests/test_zmake.py b/zephyr/zmake/tests/test_zmake.py
index f2759e5af3..33f51b7221 100644
--- a/zephyr/zmake/tests/test_zmake.py
+++ b/zephyr/zmake/tests/test_zmake.py
@@ -156,7 +156,9 @@ EXTRAVERSION =
):
if use_configure:
zmk.configure(
- "fakeproject", build_dir=pathlib.Path("build"), clobber=True
+ ["fakeproject"],
+ build_dir=pathlib.Path("build"),
+ clobber=True,
)
else:
with patch("zmake.version.write_version_header", autospec=True):
diff --git a/zephyr/zmake/zmake/__main__.py b/zephyr/zmake/zmake/__main__.py
index ab60a00657..e8700bda3a 100644
--- a/zephyr/zmake/zmake/__main__.py
+++ b/zephyr/zmake/zmake/__main__.py
@@ -180,28 +180,6 @@ def get_argparser():
"configure",
help="Set up a build directory to be built later by the build subcommand",
)
- configure.add_argument("-t", "--toolchain", help="Name of toolchain to use")
- configure.add_argument(
- "--bringup",
- action="store_true",
- dest="bringup",
- help="Enable bringup debugging features",
- )
- configure.add_argument(
- "--clobber",
- action="store_true",
- dest="clobber",
- help="Delete existing build directories, even if configuration is unchanged",
- )
- configure.add_argument(
- "--allow-warnings",
- action="store_true",
- default=False,
- help="Do not treat warnings as errors",
- )
- configure.add_argument(
- "-B", "--build-dir", type=pathlib.Path, help="Build directory"
- )
configure.add_argument(
"-b",
"--build",
@@ -213,19 +191,9 @@ def get_argparser():
"--test",
action="store_true",
dest="test_after_configure",
- help="Test the .elf file after configuration",
- )
- configure.add_argument(
- "project_name",
- help="Name of the project to setup",
- )
- configure.add_argument(
- "-c",
- "--coverage",
- action="store_true",
- dest="coverage",
- help="Enable CONFIG_COVERAGE Kconfig.",
+ help="Test the .elf file after building",
)
+ add_common_configure_args(configure)
build = sub.add_parser(
"build",
@@ -329,6 +297,64 @@ def get_argparser():
return parser, sub
+def add_common_configure_args(sub_parser: argparse.ArgumentParser):
+ """Adds common arguments used by configure-like subcommands."""
+ sub_parser.add_argument("-t", "--toolchain", help="Name of toolchain to use")
+ sub_parser.add_argument(
+ "--bringup",
+ action="store_true",
+ dest="bringup",
+ help="Enable bringup debugging features",
+ )
+ sub_parser.add_argument(
+ "--clobber",
+ action="store_true",
+ dest="clobber",
+ help="Delete existing build directories, even if configuration is unchanged",
+ )
+ sub_parser.add_argument(
+ "--allow-warnings",
+ action="store_true",
+ default=False,
+ help="Do not treat warnings as errors",
+ )
+ sub_parser.add_argument(
+ "-B",
+ "--build-dir",
+ type=pathlib.Path,
+ help="Root build directory, project files will be in "
+ "${build_dir}/${project_name}",
+ )
+ sub_parser.add_argument(
+ "-c",
+ "--coverage",
+ action="store_true",
+ dest="coverage",
+ help="Enable CONFIG_COVERAGE Kconfig.",
+ )
+ group = sub_parser.add_mutually_exclusive_group(required=True)
+ group.add_argument(
+ "-a",
+ "--all",
+ action="store_true",
+ dest="all_projects",
+ help="Select all projects",
+ )
+ group.add_argument(
+ "--host-tests-only",
+ action="store_true",
+ dest="host_tests_only",
+ help="Select all test projects",
+ )
+ group.add_argument(
+ "project_names",
+ nargs="*",
+ metavar="project_name",
+ help="Name(s) of the project(s) to build",
+ default=[],
+ )
+
+
def main(argv=None):
"""The main function.
diff --git a/zephyr/zmake/zmake/zmake.py b/zephyr/zmake/zmake/zmake.py
index 4b5d6feacb..c175c0b90b 100644
--- a/zephyr/zmake/zmake/zmake.py
+++ b/zephyr/zmake/zmake/zmake.py
@@ -190,9 +190,30 @@ class Zmake:
self._checkout = util.locate_cros_checkout()
return self._checkout.resolve()
+ def _resolve_projects(
+ self, project_names, all_projects=False, host_tests_only=False
+ ):
+ """Finds all projects for the specified command line flags.
+
+ Returns a list of projects.
+ """
+ found_projects = zmake.project.find_projects(self.module_paths["ec"] / "zephyr")
+ if all_projects:
+ projects = found_projects.values()
+ elif host_tests_only:
+ projects = [p for p in found_projects.values() if p.config.is_test]
+ else:
+ projects = []
+ for project_name in project_names:
+ try:
+ projects.append(found_projects[project_name])
+ except KeyError as e:
+ raise KeyError("No project named {}".format(project_name)) from e
+ return projects
+
def configure(
self,
- project_name,
+ project_names,
build_dir=None,
toolchain=None,
build_after_configure=False,
@@ -201,25 +222,57 @@ class Zmake:
bringup=False,
coverage=False,
allow_warnings=False,
+ all_projects=False,
+ host_tests_only=False,
):
- """Locate a project by name or directory and then call _configure."""
- root_dir = self.module_paths["ec"] / "zephyr"
- found_projects = zmake.project.find_projects(root_dir)
- try:
- project = found_projects[project_name]
- except KeyError as e:
- raise KeyError(f"No project named {project_name}") from e
- return self._configure(
- project=project,
- build_dir=build_dir,
- toolchain=toolchain,
- build_after_configure=build_after_configure,
- test_after_configure=test_after_configure,
- clobber=clobber,
- bringup=bringup,
- coverage=coverage,
- allow_warnings=allow_warnings,
+ """Locate and configure the specified projects."""
+ # Resolve build_dir if needed.
+ if not build_dir:
+ build_dir = self.module_paths["ec"] / "build" / "zephyr"
+
+ projects = self._resolve_projects(
+ project_names, all_projects=all_projects, host_tests_only=host_tests_only
)
+ for project in projects:
+ project_build_dir = pathlib.Path(build_dir) / project.config.project_name
+ self.executor.append(
+ func=functools.partial(
+ self._configure,
+ project=project,
+ build_dir=project_build_dir,
+ toolchain=toolchain,
+ build_after_configure=build_after_configure,
+ test_after_configure=test_after_configure,
+ clobber=clobber,
+ bringup=bringup,
+ coverage=coverage,
+ allow_warnings=allow_warnings,
+ )
+ )
+ if self._sequential:
+ rv = self.executor.wait()
+ if rv:
+ return rv
+ rv = self.executor.wait()
+ if rv:
+ return rv
+ if len(projects) > 1 and coverage and test_after_configure:
+ rv = self._merge_lcov_files(
+ projects=[p for p in projects if p.config.is_test],
+ build_dir=build_dir,
+ output_file=build_dir / "all_tests.info",
+ )
+ if rv:
+ return rv
+ if len(projects) > 1 and coverage and build_after_configure:
+ rv = self._merge_lcov_files(
+ projects=[p for p in projects if not p.config.is_test],
+ build_dir=build_dir,
+ output_file=build_dir / "all_builds.info",
+ )
+ if rv:
+ return rv
+ return 0
def _configure(
self,
@@ -383,7 +436,7 @@ class Zmake:
(build_dir / "project_name.txt").write_text(project.config.project_name)
util.update_symlink(project.config.project_dir, build_dir / "project")
- if test_after_configure:
+ if test_after_configure and project.config.is_test:
return self.test(
build_dir=build_dir,
coverage=coverage,
@@ -400,6 +453,7 @@ class Zmake:
)
else:
return self.build(build_dir=build_dir)
+ return 0
def build(self, build_dir, output_files_out=None, fail_on_warnings=False):
"""Build a pre-configured build directory."""
@@ -763,46 +817,18 @@ class Zmake:
with self.jobserver.get_job():
return self._run_lcov(build_dir, lcov_file, initial=True, gcov=gcov)
- def coverage(self, build_dir, clobber=False):
- """Builds all targets with coverage enabled, and then runs the tests."""
+ def _merge_lcov_files(self, projects, build_dir, output_file):
all_lcov_files = []
- root_dir = self.module_paths["ec"] / "zephyr"
- for project in zmake.project.find_projects(root_dir).values():
- is_test = project.config.is_test
+ for project in projects:
project_build_dir = pathlib.Path(build_dir) / project.config.project_name
- if is_test:
- # Configure and run the test.
- all_lcov_files.append(project_build_dir / "output" / "zephyr.info")
- self.executor.append(
- func=functools.partial(
- self._configure,
- project=project,
- build_dir=project_build_dir,
- build_after_configure=True,
- test_after_configure=is_test,
- coverage=True,
- clobber=clobber,
- )
- )
- else:
- # Don't build non-test projects
- self.logger.info("Skipping project %s", project.config.project_name)
- if self._sequential:
- rv = self.executor.wait()
- if rv:
- return rv
-
- rv = self.executor.wait()
- if rv:
- return rv
-
+ all_lcov_files.append(project_build_dir / "output" / "zephyr.info")
with self.jobserver.get_job():
# Merge info files into a single lcov.info
- self.logger.info("Merging coverage data into %s.", build_dir / "lcov.info")
+ self.logger.info("Merging coverage data into %s.", output_file)
cmd = [
"/usr/bin/lcov",
"-o",
- build_dir / "lcov.info",
+ output_file,
"--rc",
"lcov_branch_coverage=1",
]
@@ -823,7 +849,41 @@ class Zmake:
)
if proc.wait():
raise OSError(get_process_failure_msg(proc))
+ return 0
+ def coverage(self, build_dir, clobber=False):
+ """Builds all targets with coverage enabled, and then runs the tests."""
+ root_dir = self.module_paths["ec"] / "zephyr"
+ projects = [
+ p
+ for p in zmake.project.find_projects(root_dir).values()
+ if p.config.is_test
+ ]
+ for project in projects:
+ project_build_dir = pathlib.Path(build_dir) / project.config.project_name
+ # Configure and run the test.
+ self.executor.append(
+ func=functools.partial(
+ self._configure,
+ project=project,
+ build_dir=project_build_dir,
+ build_after_configure=True,
+ test_after_configure=True,
+ coverage=True,
+ clobber=clobber,
+ )
+ )
+ if self._sequential:
+ rv = self.executor.wait()
+ if rv:
+ return rv
+
+ rv = self.executor.wait()
+ if rv:
+ return rv
+
+ self._merge_lcov_files(projects, build_dir, build_dir / "lcov.info")
+ with self.jobserver.get_job():
# Find the common root dir
prefixdir = os.path.commonprefix(list(self.module_paths.values()))
@@ -841,8 +901,8 @@ class Zmake:
prefixdir,
"-s",
"--branch-coverage",
- ]
- + all_lcov_files,
+ build_dir / "lcov.info",
+ ],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding="utf-8",