blob: a0fa849561384c17c0c93fddf04d3b6a35765c2f [file] [log] [blame] [edit]
#!/usr/bin/env python3.8
#
# Copyright 2018 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.
import hashlib
import os
from pathlib import Path
import platform
import re
ROOT_PATH = Path(os.environ.get("FUCHSIA_DIR", ""))
FX_PATH = ROOT_PATH / "scripts" / "fx"
FUCHSIA_BUILD_DIR = Path(os.environ.get("FUCHSIA_BUILD_DIR", ""))
PREBUILT_DIR = ROOT_PATH / "prebuilt"
PREBUILT_THIRD_PARTY_DIR = PREBUILT_DIR / "third_party"
HOST_PLATFORM = (
platform.system().lower().replace("darwin", "mac")
+ "-"
+ {"x86_64": "x64", "aarch64": "arm64"}[platform.machine()]
)
class GnTarget:
def __init__(self, gn_target, fuchsia_dir=None):
# [\w-] is a valid GN name. We also accept '/' and '.' in paths.
# For the toolchain suffix, we take the whole label name at once, so we allow ':'.
match = re.match(
r"([\w/.-]*)" + r"(:([\w.-]+))?" + r"(\(([\w./:+-]+)\))?$", gn_target
)
if match is None:
print(f"Invalid GN label '{gn_target}'")
raise ValueError(gn_target)
path, name, toolchain = match.group(1, 3, 5)
if fuchsia_dir is None:
fuchsia_dir = ROOT_PATH
if path.startswith("//"):
path = fuchsia_dir / Path(path[2:])
else:
path = Path(path).resolve()
if name is None:
name = path.name
self.label_path = path.relative_to(fuchsia_dir)
self.label_name = name
self.explicit_toolchain = toolchain
def __str__(self):
return self.gn_target
@property
def ninja_target(self):
"""The canonical GN label of this target, minus the leading '//'."""
return str(self.label_path) + ":" + self.label_name + self.toolchain_suffix
@property
def gn_target(self):
"""The canonical GN label of this target, including the leading '//'."""
return "//" + self.ninja_target
@property
def toolchain_suffix(self):
"""The GN path suffix for this target's toolchain, if it is not the default."""
if self.explicit_toolchain is None or "fuchsia" in self.explicit_toolchain:
return ""
return "({})".format(self.explicit_toolchain)
@property
def src_path(self):
"""The path to the directory containing this target's BUILD.gn file."""
return ROOT_PATH / self.label_path
def gen_dir(self, build_dir=None):
"""The path to the directory containing this target's generated files.
Note: this function uses a heuristic to differentiate between default and
non-default toolchains. The gen_dir for the default toolchain is
<build_dir>/gen but otherwise it's <build_dir>/<toolchain>/gen. For the
purpose of most rust targets, saying that a toolchain that includes "fuchsia"
is default is usually good enough for finding generated_files, however this
could result in incorrect paths for any toolchain that contains "fuchsia" but
doesn't happen to be the default.
"""
tc = self.explicit_toolchain
return (
(build_dir or FUCHSIA_BUILD_DIR)
/ (tc.split(":")[-1] if tc and "fuchsia" not in tc else "")
/ "gen"
/ self.label_path
)
def manifest_path(self, build_dir=None):
"""The path to Cargo.toml for this target."""
if build_dir is None:
build_dir = FUCHSIA_BUILD_DIR
hashed_gn_path = hashlib.sha1(self.ninja_target.encode("utf-8")).hexdigest()
return Path(build_dir) / "cargo" / hashed_gn_path / "Cargo.toml"