blob: 96627c5b7157b7d5757b424850cc66752f3f9954 [file] [log] [blame]
# Copyright 2017 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.
"""Recipe for building Clang toolchain."""
from contextlib import contextmanager
from recipe_engine.recipe_api import Property
from PB.go.chromium.org.luci.common.proto.srcman.manifest import Manifest
from google.protobuf import json_format
import re
DEPS = [
"fuchsia/git",
"fuchsia/gitiles",
"fuchsia/goma",
"fuchsia/macos_sdk",
"fuchsia/toolchain",
"fuchsia/upload",
"fuchsia/windows_sdk",
"recipe_engine/buildbucket",
"recipe_engine/cipd",
"recipe_engine/context",
"recipe_engine/file",
"recipe_engine/isolated",
"recipe_engine/path",
"recipe_engine/platform",
"recipe_engine/properties",
"recipe_engine/python",
"recipe_engine/raw_io",
"recipe_engine/scheduler",
"recipe_engine/step",
]
TARGET_TO_ARCH = {
"x64": "x86_64",
"arm64": "aarch64",
}
TARGETS = TARGET_TO_ARCH.keys()
PLATFORM_TO_TRIPLE = {
"linux-amd64": "x86_64-linux-gnu",
"linux-arm64": "aarch64-linux-gnu",
"mac-amd64": "x86_64-apple-darwin",
"windows-amd64": "x86_64-pc-windows-msvc",
}
PLATFORMS = PLATFORM_TO_TRIPLE.keys()
# TODO(fxbug.dev/27210): remove this and switch to normalized triples.
TRIPLE_TO_NORMALIZED_TRIPLE = {
"x86_64-linux-gnu": "x86_64-unknown-linux-gnu",
"aarch64-linux-gnu": "aarch64-unknown-linux-gnu",
"x86_64-apple-darwin": "x86_64-apple-darwin",
"x86_64-pc-windows-msvc": "x86_64-pc-windows-msvc",
}
LIBXML2_GIT = "https://fuchsia.googlesource.com/third_party/libxml2"
ZLIB_GIT = "https://fuchsia.googlesource.com/third_party/zlib"
CIPD_SERVER_HOST = "chrome-infra-packages.appspot.com"
PROPERTIES = {
"repository": Property(
kind=str,
help="Git repository URL",
default="https://fuchsia.googlesource.com/third_party/llvm-project",
),
"revision": Property(kind=str, help="Git revision", default=None),
"platform": Property(kind=str, help="CIPD platform for the target", default=None),
}
def slashes(api, path):
return path.replace("\\", "/") if api.platform.is_win else path
def build_zlib(api, options, arguments, destdir, ninja_jobs, cipd_dir, manifest):
zlib_dir = api.path["start_dir"].join("zlib")
src_dir = zlib_dir.join("src")
revision = api.git.checkout(ZLIB_GIT, src_dir, ref="upstream/master")
git_checkout = manifest.directories[str(src_dir)].git_checkout
git_checkout.repo_url = ZLIB_GIT
git_checkout.revision = revision
build_dir = zlib_dir.join("build")
api.file.ensure_directory("make build dir", build_dir)
with api.context(cwd=build_dir):
api.step(
"configure",
[cipd_dir.join("bin", "cmake")]
+ [slashes(api, option.format(**arguments)) for option in options]
+ ["-DAMD64=ON", src_dir],
)
api.step(
"build", [cipd_dir.join("ninja"), "-j%d" % ninja_jobs,],
)
with api.context(env={"DESTDIR": destdir}):
api.step(
"install", [cipd_dir.join("ninja"), "install",],
)
def build_libxml2(api, options, arguments, destdir, ninja_jobs, cipd_dir, manifest):
libxml2_dir = api.path["start_dir"].join("libxml2")
src_dir = libxml2_dir.join("src")
revision = api.git.checkout(LIBXML2_GIT, src_dir, ref="upstream/master")
git_checkout = manifest.directories[str(src_dir)].git_checkout
git_checkout.repo_url = LIBXML2_GIT
git_checkout.revision = revision
build_dir = libxml2_dir.join("build")
api.file.ensure_directory("make build dir", build_dir)
with api.context(cwd=build_dir):
api.step(
"configure",
[cipd_dir.join("bin", "cmake")]
+ [slashes(api, option.format(**arguments)) for option in options]
+ [
"-DBUILD_SHARED_LIBS=OFF",
"-DLIBXML2_WITH_ICU=OFF",
"-DLIBXML2_WITH_LZMA=OFF",
"-DLIBXML2_WITH_PYTHON=OFF",
# TODO(phosek): lld only links libxml2 and not zlib, so when
# zlib support in libxml2 is enabled, this fails in the case of
# static linking.
"-DLIBXML2_WITH_ZLIB=OFF",
]
+ [src_dir],
)
api.step(
"build", [cipd_dir.join("ninja"), "-j%d" % ninja_jobs,],
)
with api.context(env={"DESTDIR": destdir}):
api.step(
"install", [cipd_dir.join("ninja"), "install",],
)
# //zircon/public/gn/toolchain/clang.gni:clang_runtime sets the JSON schema.
#
# This function makes the prototype spec; debug and breakpad info is added by
# runtimes.py.
def make_runtimes_spec(clang_version):
# TODO(fxbug.dev/27110): Ideally this would be done by the cmake build itself.
runtimes = []
for arch in TARGET_TO_ARCH.itervalues():
target_triple = "{arch}-unknown-fuchsia".format(arch=arch)
target = [target_triple, "{arch}-fuchsia".format(arch=arch)]
runtime_dir = "clang/{version}/lib/{target}".format(
version=clang_version, target=target_triple
)
cxx_lib_dir = "{target}/c++".format(target=target_triple)
for mode_ldflags in [[], ["-static-libstdc++"]]:
for mode_cflags, mode_multilib, mode_runtimes in [
([], "", []),
(["-fsanitize=address"], "asan/", ["libclang_rt.asan.so"]),
(["-fsanitize=undefined"], "", ["libclang_rt.ubsan_standalone.so"]),
]:
runtime = [
{"dist": runtime_dir + "/" + soname} for soname in mode_runtimes
]
if not mode_ldflags:
cxx_lib = [
{
"dist": cxx_lib_dir + "/" + mode_multilib + soname,
"name": soname.split(".")[0],
}
for soname in [
"libc++.so.2",
"libc++abi.so.1",
"libunwind.so.1",
]
]
runtime.extend(cxx_lib)
runtimes.append(
{
"target": target,
"cflags": mode_cflags,
"ldflags": mode_ldflags,
"runtime": runtime,
}
)
return runtimes
def RunSteps(api, repository, revision, platform):
use_goma = (
not api.platform.arch == "arm" and api.platform.bits == 64
) and not api.platform.is_win
if use_goma:
api.goma.ensure()
ninja_jobs = api.goma.jobs
goma_context = lambda: api.goma.build_with_goma()
else:
ninja_jobs = api.platform.cpu_count
@contextmanager
def null_context():
yield
goma_context = null_context
prod = api.buildbucket.builder_id.bucket == "prod"
ci = api.buildbucket.builder_id.bucket == "ci"
gitiles_commit = api.buildbucket.build_input.gitiles_commit
if gitiles_commit.host and gitiles_commit.project and gitiles_commit.id:
repository = "https://%s/%s" % (gitiles_commit.host, gitiles_commit.project)
revision = gitiles_commit.id
# TODO: factor this out into a host_build recipe module.
host_platform = "%s-%s" % (
api.platform.name.replace("win", "windows"),
{"intel": {32: "386", 64: "amd64",}, "arm": {32: "armv6", 64: "arm64",},}[
api.platform.arch
][api.platform.bits],
)
target_platform = platform or host_platform
use_breakpad = host_platform == "linux-amd64"
manifest = Manifest()
with api.step.nest("ensure_packages"):
with api.context(infra_steps=True):
cipd_dir = api.path["start_dir"].join("cipd")
pkgs = api.cipd.EnsureFile()
# We don't have SDK for linux-arm64 or win, but we only need sysroot.
if (
api.platform.arch == "arm" and api.platform.bits == 64
) or api.platform.is_win:
pkgs.add_package("fuchsia/sdk/core/linux-amd64", "latest", "sdk")
else:
pkgs.add_package("fuchsia/sdk/core/${platform}", "latest", "sdk")
if api.platform.name == "win":
pkgs.add_package("infra/cmake/${platform}", "version:3.16.1")
pkgs.add_package("infra/ninja/${platform}", "version:1.9.0")
# TODO(phosek): Switch to CIPD package once we have it.
api.isolated.download(
"msys",
isolated_hash="7b23533856ac8a1a2fec614e71df22cc065c7448",
output_dir=cipd_dir.join("msys"),
)
api.isolated.download(
"clang",
isolated_hash="fd47a7ec0e608bfc7d08714fdb3ef48585cec60d",
output_dir=cipd_dir,
)
else:
pkgs.add_package("fuchsia/third_party/clang/${platform}", "integration")
if api.platform.arch == "arm" and api.platform.bits == 64:
pkgs.add_package(
"fuchsia/third_party/cmake/${platform}",
"git_revision:4f90fef85f6391e63dfae26bd6f290c59ea48e95",
)
else:
# TODO(phosek): Switch to fuchsia/third_party/cmake when 3.19 is out.
pkgs.add_package(
"infra/cmake/${platform}", "version:3.14.6",
)
pkgs.add_package(
"fuchsia/third_party/ninja/${platform}",
"git_revision:0ccc7886fd4694ae1372d29b4954e2dd3be118be",
)
pkgs.add_package("fuchsia/sysroot/linux-386", "latest", "linux-i386")
pkgs.add_package("fuchsia/sysroot/linux-amd64", "latest", "linux-amd64")
pkgs.add_package("fuchsia/sysroot/linux-arm64", "latest", "linux-arm64")
pkgs.add_package("fuchsia/sysroot/linux-armv6l", "latest", "linux-armhf")
if use_breakpad:
pkgs.add_package(
"fuchsia/tools/breakpad/${platform}", "latest", "breakpad"
)
ensured = api.cipd.ensure(cipd_dir, pkgs)
for subdir, pins in ensured.iteritems():
directory = manifest.directories[str(cipd_dir.join(subdir))]
directory.cipd_server_host = CIPD_SERVER_HOST
for pin in pins:
directory.cipd_package[pin.package].instance_id = pin.instance_id
staging_dir = api.path["start_dir"].join("staging")
pkg_dir = staging_dir.join("llvm_install")
api.file.ensure_directory("create pkg dir", pkg_dir)
with api.context(infra_steps=True):
llvm_dir = api.path["start_dir"].join("llvm-project")
revision = api.git.checkout(
repository,
path=llvm_dir,
ref=revision,
step_test_data=lambda: api.raw_io.test_api.stream_output(revision),
)
git_checkout = manifest.directories[str(llvm_dir)].git_checkout
git_checkout.repo_url = repository
git_checkout.revision = revision
target_triple = PLATFORM_TO_TRIPLE[target_platform]
host_triple = PLATFORM_TO_TRIPLE[host_platform]
with api.macos_sdk(kind="ios"), api.windows_sdk(), goma_context():
if api.platform.name == "linux":
host_sysroot = cipd_dir.join(host_platform)
target_sysroot = cipd_dir.join(target_platform)
elif api.platform.name == "mac":
# TODO(fxbug.dev/3043): Eventually use our own hermetic sysroot as for Linux.
step_result = api.step(
"xcrun",
["xcrun", "--sdk", "macosx", "--show-sdk-path"],
stdout=api.raw_io.output(name="sdk-path", add_output_log=True),
step_test_data=lambda: api.raw_io.test_api.stream_output(
"/some/xcode/path"
),
)
target_sysroot = host_sysroot = step_result.stdout.strip()
elif api.platform.name == "win":
target_sysroot = host_sysroot = api.windows_sdk.sdk_dir
else: # pragma: no cover
assert False, "unsupported platform"
arguments = {
"target_triple": TRIPLE_TO_NORMALIZED_TRIPLE[target_triple],
"host_triple": host_triple,
"target_sysroot": target_sysroot,
"host_sysroot": host_sysroot,
"linux_arm64_sysroot": cipd_dir.join("linux-arm64"),
"linux_armhf_sysroot": cipd_dir.join("linux-armhf"),
"linux_i386_sysroot": cipd_dir.join("linux-i386"),
"linux_amd64_sysroot": cipd_dir.join("linux-amd64"),
"fuchsia_sdk": cipd_dir.join("sdk"),
}
if api.platform.is_win:
arguments.update(
{
"cc": cipd_dir.join("bin", "clang-cl.exe"),
"cxx": cipd_dir.join("bin", "clang-cl.exe"),
"ar": cipd_dir.join("bin", "llvm-ar.exe"),
"ld": cipd_dir.join("bin", "lld-link.exe"),
"mt": cipd_dir.join("bin", "llvm-mt.exe"),
"nm": cipd_dir.join("bin", "llvm-nm.exe"),
"objcopy": cipd_dir.join("bin", "llvm-objcopy.exe"),
"objdump": cipd_dir.join("bin", "llvm-objdump.exe"),
"ranlib": cipd_dir.join("bin", "llvm-ranlib.exe"),
"rc": cipd_dir.join("bin", "llvm-rc.exe"),
"readelf": cipd_dir.join("bin", "llvm-readelf.exe"),
"strip": cipd_dir.join("bin", "llvm-strip.exe"),
"ninja": cipd_dir.join("ninja.exe"),
}
)
else:
arguments.update(
{
"cc": cipd_dir.join("bin", "clang"),
"cxx": cipd_dir.join("bin", "clang++"),
"ar": cipd_dir.join("bin", "llvm-ar"),
"ld": cipd_dir.join("bin", "ld.lld"),
"lipo": cipd_dir.join("bin", "llvm-lipo"),
"nm": cipd_dir.join("bin", "llvm-nm"),
"objcopy": cipd_dir.join("bin", "llvm-objcopy"),
"objdump": cipd_dir.join("bin", "llvm-objdump"),
"ranlib": cipd_dir.join("bin", "llvm-ranlib"),
"readelf": cipd_dir.join("bin", "llvm-readelf"),
"strip": cipd_dir.join("bin", "llvm-strip"),
"ninja": cipd_dir.join("ninja"),
}
)
if use_goma:
arguments.update(
{"gomacc": api.goma.goma_dir.join("gomacc"),}
)
options = [
"-GNinja",
"-DCMAKE_MAKE_PROGRAM={ninja}",
"-DCMAKE_INSTALL_PREFIX=",
"-DCMAKE_C_COMPILER={cc}",
"-DCMAKE_CXX_COMPILER={cxx}",
"-DCMAKE_ASM_COMPILER={cc}",
]
if use_goma:
options.extend(
[
"-DCMAKE_C_COMPILER_LAUNCHER={gomacc}",
"-DCMAKE_CXX_COMPILER_LAUNCHER={gomacc}",
"-DCMAKE_ASM_COMPILER_LAUNCHER={gomacc}",
]
)
options.extend(
{
"linux": [
"-DCMAKE_AR={ar}",
"-DCMAKE_LINKER={ld}",
"-DCMAKE_NM={nm}",
"-DCMAKE_OBJCOPY={objcopy}",
"-DCMAKE_OBJDUMP={objdump}",
"-DCMAKE_RANLIB={ranlib}",
"-DCMAKE_READELF={readelf}",
"-DCMAKE_STRIP={strip}",
],
"mac": ["-DCMAKE_LIPO={lipo}",],
"win": [
"-DCMAKE_AR={ar}",
"-DCMAKE_LINKER={ld}",
"-DCMAKE_NM={nm}",
"-DCMAKE_OBJCOPY={objcopy}",
"-DCMAKE_OBJDUMP={objdump}",
"-DCMAKE_RANLIB={ranlib}",
"-DCMAKE_READELF={readelf}",
"-DCMAKE_STRIP={strip}",
# TODO(phosek): reenable once we update the host toolchain
# "-DCMAKE_RC_COMPILER={rc}",
# "-DCMAKE_MT={mt}",
],
}[api.platform.name]
)
options.extend(["-DCMAKE_SYSROOT={target_sysroot}"])
if not api.platform.is_win:
# TODO(phosek): Build these even for Windows.
with api.step.nest("zlib"):
zlib_install_dir = staging_dir.join("zlib_install")
api.file.ensure_directory("create zlib_install_dir", zlib_install_dir)
build_zlib(
api,
options
+ [
"-DCMAKE_%s_FLAGS=-O3 -fPIC --target=%s" % (lang, target_triple)
for lang in ["C", "CXX"]
],
arguments,
zlib_install_dir,
ninja_jobs,
cipd_dir,
manifest,
)
with api.step.nest("libxml2"):
libxml2_install_dir = staging_dir.join("libxml2_install")
api.file.ensure_directory(
"create libxml2_install_dir", libxml2_install_dir
)
build_libxml2(
api,
options
+ [
"-DCMAKE_%s_FLAGS=-O3 -fPIC --target=%s" % (lang, target_triple)
for lang in ["C", "CXX"]
],
arguments,
libxml2_install_dir,
ninja_jobs,
cipd_dir,
manifest,
)
json_manifest = json_format.MessageToJson(
manifest, preserving_proto_field_name=True
)
api.file.write_text(
"source manifest", pkg_dir.join("source_manifest.json"), json_manifest
)
# build clang+llvm
build_dir = staging_dir.join("llvm_build")
api.file.ensure_directory("create llvm build dir", build_dir)
arguments.update(
{
"BOOTSTRAP_": "BOOTSTRAP_",
"STAGE2_": "STAGE2_",
"stage2_": "stage2-",
"_stage2": "",
}
if prod
else {"BOOTSTRAP_": "", "STAGE2_": "", "stage2_": "", "_stage2": "-stage2",}
)
llvm_projects = ["clang", "clang-tools-extra", "lld", "llvm"]
llvm_runtimes = ["compiler-rt", "libcxx", "libcxxabi", "libunwind"]
if not api.platform.is_win:
options.extend(
[
"-D{BOOTSTRAP_}ZLIB_INCLUDE_DIR=%s"
% zlib_install_dir.join("include"),
"-D{BOOTSTRAP_}ZLIB_LIBRARY=%s"
% zlib_install_dir.join("lib", "libz.a"),
"-D{BOOTSTRAP_}LIBXML2_INCLUDE_DIR=%s"
% libxml2_install_dir.join("include", "libxml2"),
"-D{BOOTSTRAP_}LIBXML2_LIBRARY=%s"
% libxml2_install_dir.join("lib", "libxml2.a"),
]
)
if prod:
options.extend(
[
"-DZLIB_INCLUDE_DIR=%s" % zlib_install_dir.join("include"),
"-DZLIB_LIBRARY=%s" % zlib_install_dir.join("lib", "libz.a"),
"-DLIBXML2_INCLUDE_DIR=%s"
% libxml2_install_dir.join("include", "libxml2"),
"-DLIBXML2_LIBRARY=%s"
% libxml2_install_dir.join("lib", "libxml2.a"),
]
)
if api.platform.name == "linux":
if prod:
options.extend(
["-D{BOOTSTRAP_}CMAKE_SYSROOT={target_sysroot}"]
+ [
# BOOTSTRAP_ prefixed flags are passed to the second stage compiler.
"-D{BOOTSTRAP_}CMAKE_%s_LINKER_FLAGS=-static-libstdc++" % mode
for mode in ["SHARED", "MODULE", "EXE"]
]
+ [
# Unprefixed flags are used by the first stage compiler.
"-DCMAKE_%s_LINKER_FLAGS=-static-libstdc++" % mode
for mode in ["SHARED", "MODULE", "EXE"]
]
)
else:
options.extend(
[
# BOOTSTRAP_ prefixed flags are passed to the second stage compiler.
"-D{BOOTSTRAP_}CMAKE_%s_LINKER_FLAGS=-static-libstdc++" % mode
for mode in ["SHARED", "MODULE", "EXE"]
]
+ ["-DLLVM_ENABLE_LTO=OFF",]
)
if host_triple != target_triple: # pragma: no cover
options.extend(
[
"-D{BOOTSTRAP_}CMAKE_SYSTEM_NAME=Linux",
"-D{BOOTSTRAP_}CMAKE_C_COMPILER_TARGET={target_triple}",
"-D{BOOTSTRAP_}CMAKE_CXX_COMPILER_TARGET={target_triple}",
"-D{BOOTSTRAP_}LLVM_DEFAULT_TARGET_TRIPLE={target_triple}",
]
)
elif api.platform.name == "mac":
if prod:
options.extend(
["-D{BOOTSTRAP_}CMAKE_SYSROOT={target_sysroot}"]
+ [
# BOOTSTRAP_ prefixed flags are passed to the second stage compiler.
"-D{BOOTSTRAP_}CMAKE_%s_LINKER_FLAGS=-nostdlib++ %s"
% (mode, build_dir.join("lib", "libc++.a"))
for mode in ["SHARED", "MODULE", "EXE"]
]
+ [
# Unprefixed flags are used by the first stage compiler.
"-DCMAKE_%s_LINKER_FLAGS=-nostdlib++ %s"
% (mode, cipd_dir.join("lib", "libc++.a"))
for mode in ["SHARED", "MODULE", "EXE"]
]
)
else:
options.extend(
[
# BOOTSTRAP_ prefixed flags are passed to the second stage compiler.
"-D{BOOTSTRAP_}CMAKE_%s_LINKER_FLAGS=-nostdlib++ %s"
% (mode, cipd_dir.join("lib", "libc++.a"))
for mode in ["SHARED", "MODULE", "EXE"]
]
+ ["-DLLVM_ENABLE_LTO=OFF"]
)
elif api.platform.name == "win":
if not prod:
options.extend(["-DLLVM_ENABLE_LTO=OFF"])
# STAGE2_ prefixed flags are passed to the second stage by the first stage build.
if ci:
options.extend(
["-D{STAGE2_}LLVM_ENABLE_ASSERTIONS=ON",]
)
options.extend(
[
"-D{STAGE2_}LINUX_aarch64-unknown-linux-gnu_SYSROOT={linux_arm64_sysroot}",
"-D{STAGE2_}LINUX_armv7-unknown-linux-gnueabihf_SYSROOT={linux_armhf_sysroot}",
"-D{STAGE2_}LINUX_i386-unknown-linux-gnu_SYSROOT={linux_i386_sysroot}",
"-D{STAGE2_}LINUX_x86_64-unknown-linux-gnu_SYSROOT={linux_amd64_sysroot}",
"-D{STAGE2_}FUCHSIA_SDK={fuchsia_sdk}",
]
)
if api.platform.is_win:
env_prefixes = {"PATH": [cipd_dir.join("msys")]}
else:
env_prefixes = {}
with api.step.nest("clang"), api.context(
cwd=build_dir, env_prefixes=env_prefixes
):
api.step(
"configure",
[cipd_dir.join("bin", "cmake")]
+ [slashes(api, option.format(**arguments)) for option in options]
+ [
"-C",
llvm_dir.join(
"clang",
"cmake",
"caches",
"Fuchsia{_stage2}.cmake".format(**arguments),
),
llvm_dir.join("llvm"),
],
)
# Build the full (two-stage) distribution.
api.step(
"build",
[
cipd_dir.join("ninja"),
# This only applies to the first stage, second stage is invoked by
# CMake as a subprocess and will use Ninja's default.
"-j%d" % ninja_jobs,
"{stage2_}distribution".format(**arguments),
],
)
# Run the tests.
projects = ["llvm", "clang", "lld"]
# TODO(phosek): run runtime tests
# + [(runtime + '-{target_triple}').format(**arguments)
# for runtime in ['unwind', 'cxxabi', 'cxx']]
api.step(
"test",
[cipd_dir.join("ninja"), "-j%d" % api.goma.jobs]
+ [
("{stage2_}check-" + project).format(**arguments)
for project in projects
],
)
with api.context(env={"DESTDIR": pkg_dir}):
api.step(
"install",
[
cipd_dir.join("ninja"),
"{stage2_}install-distribution-stripped".format(**arguments),
],
)
step_result = api.file.read_text(
"Version.inc",
build_dir.join(
*(
(["tools", "clang", "stage2-bins"] if prod else [])
+ ["tools", "clang", "include", "clang", "Basic", "Version.inc"]
)
),
test_data='#define CLANG_VERSION_STRING "8.0.0"',
)
m = re.search(r'CLANG_VERSION_STRING "([a-zA-Z0-9.-]+)"', step_result)
assert m, "Cannot determine Clang version"
clang_version = m.group(1)
api.toolchain.strip_runtimes(
"generate runtime.json",
spec=make_runtimes_spec(clang_version),
path=pkg_dir.join("lib"),
build_id_subpath="debug/.build-id",
readelf=cipd_dir.join("bin", "llvm-readelf"),
dump_syms=(
cipd_dir.join("breakpad", "dump_syms", "dump_syms")
if use_breakpad
else None
),
)
api.python(
"generate license",
api.resource("generate_license.py"),
args=["--include"]
+ [
llvm_dir.join(project, "LICENSE.TXT")
for project in llvm_projects + llvm_runtimes
]
+ (
[
"--extract",
api.path["start_dir"].join("libxml2", "src", "Copyright"),
"-",
"--extract",
api.path["start_dir"].join("zlib", "src", "zlib.h"),
"4-22",
]
if not api.platform.is_win
else []
),
stdout=api.raw_io.output(leak_to=pkg_dir.join("LICENSE")),
)
isolated = api.upload.upload_isolated(pkg_dir)
if prod:
# The published package has the same name for every platform.
api.upload.cipd_package(
"fuchsia/third_party/clang/%s" % target_platform,
pkg_dir,
[api.upload.DirectoryPath(pkg_dir)],
{"git_revision": revision},
repository=repository,
extra_tags={"version": clang_version},
)
# TODO(phosek): move this logic to clang_trigger.py recipe.
if not target_platform in ["linux-arm64", "windows-amd64"]:
host = "fuchsia.googlesource.com"
project = "fuchsia"
refs = api.gitiles.refs("https://%s/%s" % (host, project))
ref = "refs/heads/master"
fuchsia_rev = refs.get(ref, "HEAD")
# Do a full integration build. This will use the just-built toolchain
# to build all of Fuchsia to check whether there are any regressions.
api.scheduler.emit_trigger(
api.scheduler.BuildbucketTrigger(
properties={
"clang_toolchain": {
# Purely for informational purposes; not consumed by
# any recipe or recipe module.
"git_repository": repository,
"git_revision": revision,
},
"build.clang_toolchain": {
"type": "isolated",
"instance": isolated,
},
"checkout.buildset": "commit/gitiles/%s/%s/+/%s"
% (host, project, fuchsia_rev),
},
tags={
"buildset": "commit/gitiles/%s/+/%s"
% (repository.split("://")[1], revision),
"gitiles_ref": ref,
},
),
project="fuchsia",
jobs={
"linux-amd64": (
"clang_toolchain.fuchsia-arm64-debug",
"clang_toolchain.fuchsia-arm64-release",
"clang_toolchain.fuchsia-x64-debug",
"clang_toolchain.fuchsia-x64-release",
),
"mac-amd64": ("clang_toolchain.fuchsia-host-mac",),
}[target_platform],
)
def GenTests(api):
for os in ("linux", "mac"):
yield (
api.test("ci-%s-x64" % os)
+ api.buildbucket.ci_build(
project="fuchsia",
bucket="ci",
git_repo="https://fuchsia.googlesource.com/third_party/llvm-project",
revision="a" * 40,
)
+ api.platform.name(os)
+ api.properties(platform=os + "-amd64")
)
yield (
api.test("prod-%s-x64" % os)
+ api.buildbucket.ci_build(
project="fuchsia",
bucket="prod",
git_repo="https://fuchsia.googlesource.com/third_party/llvm-project",
revision="a" * 40,
)
+ api.platform.name(os)
+ api.properties(platform=os + "-amd64")
+ api.gitiles.refs("refs", ("refs/heads/master", "b" * 40))
)
yield (
api.test("windows-amd64")
+ api.buildbucket.ci_build(
project="fuchsia",
bucket="ci",
git_repo="https://fuchsia.googlesource.com/third_party/llvm-project",
revision="a" * 40,
)
+ api.platform.name("win")
+ api.properties(platform="windows-amd64")
)
yield (
api.test("linux-arm64")
+ api.buildbucket.ci_build(
project="fuchsia",
bucket="ci",
git_repo="https://fuchsia.googlesource.com/third_party/llvm-project",
revision="a" * 40,
)
+ api.platform.name("linux")
+ api.platform.arch("arm")
+ api.platform.bits(64)
+ api.properties(platform="linux-arm64")
)