| # Copyright 2022 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from recipe_engine import config_types |
| from recipe_engine import recipe_api |
| |
| |
| class CMakeApi(recipe_api.RecipeApi): |
| """APIs for interacting with CMake.""" |
| |
| def build_with_ninja( |
| self, |
| src_dir, |
| build_type=None, |
| cache=None, |
| cache_entries=(), |
| extra_args=(), |
| build_args=(), |
| install_cmd="install", |
| ninja_jobs=None, |
| build_dir=None, |
| install_dir=None, |
| ): |
| """ |
| Build with CMake and Ninja. |
| |
| Args: |
| build_args (seq(str)): Passed to ninja build. |
| install_args (seq(str)): Passed to ninja install. |
| ninja_jobs (int): Ninja jobs. Defaults to `api.platform.cpu_count`. |
| extra_args (seq(str)): Args to pass to cmake. |
| build_dir (Path): Path to build dir. If not specified, use a |
| temporary directory. |
| install_dir (Path): Path to install dir. |
| |
| Returns: |
| Path: Path to install dir. |
| """ |
| build_dir = build_dir or self.m.path.mkdtemp(prefix="build") |
| self( |
| step_name="configure", |
| src_dir=src_dir, |
| build_dir=build_dir, |
| build_type=build_type, |
| cache=cache, |
| cache_entries=cache_entries, |
| extra_args=extra_args, |
| ) |
| self.m.ninja( |
| "build", |
| ninja_args=build_args, |
| build_dir=build_dir, |
| ninja_jobs=ninja_jobs or self.m.platform.cpu_count, |
| ) |
| with self.m.context(env={"DESTDIR": install_dir} if install_dir else None): |
| self.m.ninja( |
| "install", |
| [install_cmd], |
| build_dir=build_dir, |
| ) |
| return install_dir |
| |
| # TODO(fxbug.dev/122100): Consider replacing all direct cmake invocations |
| # with self.build_with_ninja(), then remove this function. |
| def __call__( |
| self, |
| src_dir, |
| build_dir, |
| build_type=None, |
| generator="Ninja", |
| cache=None, |
| cache_entries=(), |
| extra_args=(), |
| step_name="cmake", |
| ): |
| base_cmd = [ |
| self.path / "bin" / "cmake", |
| "-S", |
| src_dir, |
| "-B", |
| build_dir, |
| ] |
| |
| args = [] |
| if generator: |
| args.extend(["-G", generator]) |
| if cache: |
| args.extend(["-C", cache]) |
| if build_type: |
| args.extend([f"-DCMAKE_BUILD_TYPE={build_type}"]) |
| for entry in cache_entries: |
| args.extend(["-D", entry]) |
| args.extend(extra_args) |
| return self.m.step( |
| step_name, |
| base_cmd + [self._normalize(arg) for arg in args], |
| ) |
| |
| @property |
| def path(self): |
| return self.m.cipd_ensure( |
| self.resource("cipd.ensure"), |
| "fuchsia/third_party/cmake/${platform}", |
| executable_path="", |
| ) |
| |
| def _normalize(self, path): |
| # CMake only accept '/' as path delimiter, even on Windows. |
| # This helper function replaces '\' with '/' on Windows platform. |
| # Do not normalize recipe engine Path objects as they are already |
| # normalized on Windows. |
| return ( |
| path.replace("\\", "/") |
| if self.m.platform.is_win and not isinstance(path, config_types.Path) |
| else path |
| ) |