blob: 01dfa07d518310c461256fe7c17397f90df8a063 [file] [log] [blame]
# 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
)