| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- # Part of the Carbon Language project, under the Apache License v2.0 with LLVM
- # Exceptions. See /LICENSE for license information.
- # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- """Rules for constructing install information."""
- load("@rules_pkg//pkg:mappings.bzl", "pkg_attributes", "pkg_filegroup", "pkg_files", "pkg_mklink", "strip_prefix")
- load("//toolchain/base:llvm_tools.bzl", "LLVM_MAIN_TOOLS", "LLVM_TOOL_ALIASES")
- _clang_aliases = [
- "clang",
- "clang++",
- "clang-cl",
- "clang-cpp",
- ]
- # TODO: Add remaining aliases of LLD for Windows and WASM when we have support
- # for them wired up through the busybox.
- _lld_aliases = [
- "ld.lld",
- "ld64.lld",
- ]
- _llvm_binaries = _clang_aliases + _lld_aliases + [
- tool.bin_name
- for tool in LLVM_MAIN_TOOLS.values()
- ] + [
- "llvm-" + alias
- for (_, aliases) in LLVM_TOOL_ALIASES.items()
- for alias in aliases
- ]
- def _toolchain_llvm_binaries_impl(ctx):
- outputs = []
- for bin in _llvm_binaries:
- out = ctx.actions.declare_file(ctx.attr.prefix + "llvm/bin/" + bin)
- ctx.actions.symlink(
- output = out,
- target_file = ctx.files.carbon_binary[0],
- )
- outputs.append(out)
- return [DefaultInfo(files = depset(direct = outputs))]
- toolchain_llvm_binaries = rule(
- doc = "Creates symlinks for LLVM binaries pointing to a single Carbon binary.",
- implementation = _toolchain_llvm_binaries_impl,
- attrs = {
- "carbon_binary": attr.label(
- allow_single_file = True,
- #executable = True,
- mandatory = True,
- #cfg = None,
- ),
- "prefix": attr.string(default = ""),
- },
- )
- def _removeprefix_or_fail(s, prefix):
- if prefix == "":
- return s
- new_s = s.removeprefix(prefix)
- if new_s == s:
- fail("Unable to remove prefix '{0}' from '{1}'".format(prefix, s))
- return new_s
- def _get_pkg_relative_path(file):
- path = file.path
- if file.root.path != "":
- path = _removeprefix_or_fail(path, file.root.path + "/")
- if file.owner.workspace_root != "":
- path = _removeprefix_or_fail(path, file.owner.workspace_root + "/")
- return _removeprefix_or_fail(path, file.owner.package + "/")
- def _toolchain_files_impl(ctx):
- prefix = ctx.attr.prefix
- outputs = []
- for src in ctx.files.srcs:
- rel_path = _get_pkg_relative_path(src)
- rel_path = _removeprefix_or_fail(rel_path, ctx.attr.remove_prefix)
- if rel_path in ctx.attr.renames:
- rel_path = ctx.attr.renames[rel_path]
- out = ctx.actions.declare_file("{0}{1}".format(prefix, rel_path))
- ctx.actions.symlink(output = out, target_file = src)
- outputs.append(out)
- return [DefaultInfo(files = depset(outputs))]
- toolchain_files = rule(
- doc = "Arranges files into a directory structure by symlinking them with prefix removal and renames.",
- implementation = _toolchain_files_impl,
- attrs = {
- "prefix": attr.string(default = ""),
- "remove_prefix": attr.string(default = ""),
- "renames": attr.string_dict(default = {}),
- "srcs": attr.label_list(allow_files = True),
- },
- )
- def _filtered_files_impl(ctx):
- include_set = set()
- for filter_src in ctx.files.filter_to_srcs:
- rel_path = _get_pkg_relative_path(filter_src)
- include_set.add(_removeprefix_or_fail(rel_path, ctx.attr.filter_to_srcs_prefix))
- outputs = []
- for src in ctx.files.srcs:
- rel_path = _get_pkg_relative_path(src)
- if _removeprefix_or_fail(rel_path, ctx.attr.srcs_prefix) in include_set:
- outputs.append(src)
- return [DefaultInfo(files = depset(outputs))]
- filtered_files = rule(
- doc = "Filters a set of files based on their relative paths matching another set of files.",
- implementation = _filtered_files_impl,
- attrs = {
- "filter_to_srcs": attr.label_list(),
- "filter_to_srcs_prefix": attr.string(default = ""),
- "srcs": attr.label_list(),
- "srcs_prefix": attr.string(default = ""),
- },
- )
- def filtered_toolchain_files(name, prefix, remove_prefix, srcs_groups):
- """A collection of filtered toolchain files from overlapping `srcs`."""
- name_base = name.removesuffix("_srcs")
- if name_base == "" or name_base == name:
- fail("Invalid name for building a set of filtered toolchain files.")
- toolchain_files(
- name = name_base + "_all_srcs",
- srcs = srcs_groups,
- prefix = prefix,
- remove_prefix = remove_prefix,
- )
- for srcs in srcs_groups:
- suffix = srcs.partition(":")[2].removeprefix(name_base)
- filtered_files(
- name = name_base + suffix,
- srcs = [":" + name_base + "_all_srcs"],
- srcs_prefix = prefix,
- filter_to_srcs = [srcs],
- filter_to_srcs_prefix = remove_prefix,
- )
- def toolchain_pkg_filegroup(name, carbon_busybox, srcs, tags = []):
- """Given a CMake-style install prefix[1], the hierarchy looks like:
- - prefix/bin: Binaries intended for direct use.
- - prefix/lib/carbon: Private data and files.
- - prefix/lib/carbon/core: The `Core` package files.
- - prefix/lib/carbon/llvm/bin: LLVM binaries.
- This will be how installs are provided on Unix-y platforms, and is loosely
- based on the FHS (Filesystem Hierarchy Standard). See the CMake install prefix
- documentation[1] for more details.
- [1]: https://cmake.org/cmake/help/latest/variable/CMAKE_INSTALL_PREFIX.html
- """
- pkg_srcs = []
- # Separately handle the busybox so that we can set its attributes.
- pkg_files(
- name = name + "_busybox",
- srcs = [carbon_busybox],
- prefix = "lib/carbon",
- attributes = pkg_attributes(mode = "0755"),
- tags = tags,
- )
- pkg_srcs.append(":" + name + "_busybox")
- pkg_files(
- name = name + "_srcs",
- srcs = srcs,
- prefix = "lib/carbon",
- strip_prefix = strip_prefix.from_pkg(),
- tags = tags,
- )
- pkg_srcs.append(":" + name + "_srcs")
- for bin in _llvm_binaries:
- pkg_mklink(
- name = name + "_llvm_symlink_" + bin,
- link_name = "lib/carbon/llvm/bin/" + bin,
- target = "../../carbon-busybox",
- tags = tags,
- )
- pkg_srcs.append(":" + name + "_llvm_symlink_" + bin)
- pkg_mklink(
- name = name + "_bin_symlink",
- link_name = "bin/carbon",
- target = "../lib/carbon/carbon-busybox",
- tags = tags,
- )
- pkg_srcs.append(":" + name + "_bin_symlink")
- pkg_filegroup(name = name, srcs = pkg_srcs, tags = tags)
|