|  | # Copyright 2020 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("//build/config/clang/clang.gni") | 
|  | import("//build/rust/config.gni") | 
|  | import("//build/toolchain/zircon/clang.gni") | 
|  |  | 
|  | # NOTE: Keep in sync with //zircon/public/gn/toolchain/toolchain_runtime_deps.gni | 
|  | # until build unification completes. | 
|  |  | 
|  | # ## runtime.json | 
|  | # | 
|  | # Each toolchain (i.e. Clang or rustc) provides a "runtime.json" file | 
|  | # in its top-level lib/ sub-directory. | 
|  | # | 
|  | # This file is provided by the toolchain to describe the runtime | 
|  | # dependencies implied by linking a binary based on --target and other | 
|  | # compiler switches.  The file contains a JSON array of objects that map to | 
|  | # the following GN schema.  Each entry matches a single compilation mode | 
|  | # and yields all the runtime dependencies implied by that mode. | 
|  | # | 
|  | # Type: list(scope) | 
|  | # | 
|  | # * target | 
|  | #   - Required: --target tuple a la `${toolchain.target_tuple}`. | 
|  | #   - Type: string | 
|  | # | 
|  | # * cflags | 
|  | #   - Optional: List of compilation flags that select this mode, | 
|  | #     e.g. `"-fsanitizer=..."` and the like. | 
|  | #     If not specified, cflags are ignored during selection. | 
|  | #   - Type: list(string) | 
|  | # | 
|  | # * ldflags | 
|  | #   - Optional: Link-time flags that select this mode. | 
|  | #     This is usually either `[ "-static-libstdc++" ]` or `[]`. | 
|  | #     If not specified, ldflags are ignored during selection. | 
|  | #   - Type: list(string) | 
|  | # | 
|  | # * runtime | 
|  | #   - Required: List of runtime files needed by binaries in this mode. | 
|  | #   - Type: list(scope) | 
|  | # | 
|  | #     * name | 
|  | #       - Optional: A stable name for the library to use when publishing a | 
|  | #         zx_manifest. If omitted, soname is used. | 
|  | #       - Type: string | 
|  | # | 
|  | #     * soname | 
|  | #       - Required: `DT_SONAME` string in the ELF shared library. | 
|  | #       - Type: string | 
|  | # | 
|  | #     * dist | 
|  | #       - Required: File to load to satisfy $soname `DT_NEEDED` entries. | 
|  | #       - Type: path relative to `${toolchain_spec.lib_dir}` | 
|  | # | 
|  | #     * debug | 
|  | #       - Optional: Unstripped or separate debug file matching $dist. | 
|  | #       - Type: path relative to `${toolchain_spec.lib_dir}` | 
|  | # | 
|  | #     * breakpad | 
|  | #       - Required if `debug` is present and `toolchain.use_breakpad` is true: | 
|  | #         Path to breakpad .sym file. | 
|  | #       - Type: path relative to `${toolchain_spec.lib_dir}` | 
|  | # | 
|  | _clang_lib_dir = rebase_path("$clang_prefix/../lib", ".", root_build_dir) | 
|  | _clang_runtime_file = "$_clang_lib_dir/runtime.json" | 
|  | _clang_runtime = read_file(_clang_runtime_file, "json") | 
|  |  | 
|  | _rustc_lib_dir = rebase_path("$rustc_prefix/../lib", ".", root_build_dir) | 
|  | _rustc_runtime_file = "$_rustc_lib_dir/runtime.json" | 
|  | _rustc_runtime = read_file(_rustc_runtime_file, "json") | 
|  |  | 
|  | # ## Toolchain specifications | 
|  | # | 
|  | # Each <runtime>_toolchain_spec below is a scope with the following keys: | 
|  | # | 
|  | #     * runtime | 
|  | #       - Required: The contents of the runtimes manifest (runtime.json). | 
|  | #         See above for the schema. | 
|  | #       - Type: scope | 
|  | # | 
|  | #     * runtime_file | 
|  | #       - Required: The path to runtime.json from which `runtime` was read. | 
|  | #       - Type: file | 
|  | # | 
|  | #     * flag_vars | 
|  | #       - Required: The set of flags to match on in the runtimes manifest. | 
|  | #       - Example: `[ "cflags", "ldflags" ]` | 
|  | #       - Type: list(string) | 
|  | # | 
|  | #     * lib_dir | 
|  | #       - Required: The base path for all libraries in runtime.json. | 
|  | #       - Type: string | 
|  | # | 
|  | #     * version_string | 
|  | #       - Required: A string that changes every time the toolchain is updated, | 
|  | #         so we know when to force a recompile. | 
|  | #       - Type: string | 
|  | # | 
|  | #     * version_description | 
|  | #       - Required: Something that can lead a human to find the specific toolchain, | 
|  | #         such as a source repository URL and revision identifier. If not available, | 
|  | #         supply an empty string. | 
|  | #       - Type: string | 
|  | # | 
|  | # Clang toolchain spec for use with toolchain_runtime_deps(). | 
|  | clang_toolchain_spec = { | 
|  | runtime = _clang_runtime | 
|  | runtime_file = _clang_runtime_file | 
|  | lib_dir = _clang_lib_dir | 
|  | version_string = clang_version_string | 
|  | version_description = clang_version_description | 
|  | flag_vars = [ | 
|  | "cflags", | 
|  | "ldflags", | 
|  | ] | 
|  | } | 
|  |  | 
|  | # Rust toolchain spec for use with toolchain_runtime_deps(). | 
|  | rustc_toolchain_spec = { | 
|  | runtime = _rustc_runtime | 
|  | runtime_file = _rustc_runtime_file | 
|  | lib_dir = _rustc_lib_dir | 
|  | version_string = rustc_version_string | 
|  | version_description = rustc_version_description | 
|  | flag_vars = [ "rustflags" ] | 
|  | } | 
|  |  | 
|  | # Provide deps required by toolchain-provided runtime libraries. | 
|  | # | 
|  | # Every linking target, such as executable(), shared_library(), or | 
|  | # loadable_module(), needs this in deps to represent the link-time and | 
|  | # runtime dependencies of support code the compiler links in implicitly. | 
|  | # The parameters indicate the compilation mode in terms of the link-time | 
|  | # and compile-time flags used.  These must exactly match lists supplied by | 
|  | # the toolchain in $clang_runtime to select for things like instrumentation | 
|  | # and shared vs static linking of the standard C++ library. | 
|  | # | 
|  | # ## Parameters | 
|  | # | 
|  | # * toolchain_spec | 
|  | #   - Required: Path information about the compiler runtimes. | 
|  | #   - Type: scope with the following: | 
|  | # | 
|  | # * <flag variables> | 
|  | #   - Required: Flags to match in the runtimes manifest. Should have a value for | 
|  | #     every flag in toolchain_spec.flag_vars. | 
|  | #   - Example: `cflags = [] ldflags = [ "-static-libstdc++" ]` | 
|  | #   - Type: list(string) | 
|  | # | 
|  | # * libraries | 
|  | #   - Optional: List of library names to include in this target. If not specific | 
|  | #     all libraries matching the flag variables in the toolchain spec for the | 
|  | #     current variant will be added. | 
|  | #   - Type: list(string) | 
|  | # | 
|  | template("toolchain_runtime_deps") { | 
|  | not_needed(invoker, [ "libraries" ]) | 
|  | group(target_name) { | 
|  | forward_variables_from(invoker, | 
|  | [ | 
|  | "testonly", | 
|  | "visibility", | 
|  | ]) | 
|  |  | 
|  | toolchain_spec = invoker.toolchain_spec | 
|  |  | 
|  | # This information comes out the same in the main and the shlib | 
|  | # toolchains.  But we don't want two copies to appear in the metadata | 
|  | # collection, so we always redirect to the shlib toolchain (when there | 
|  | # is one).  Note that multiple toolchains (variants that aren't that | 
|  | # different, e.g. uninstrumented variants) may produce identical | 
|  | # manifest entries because they match the same entries in the | 
|  | # clang_runtime and use the same ${toolchain.libprefix} string.  That | 
|  | # is less than ideal but it does no harm since the tools like zbi that | 
|  | # consume manifests accept redundant entries if they are identical. | 
|  | if (toolchain_variant.with_shared && current_toolchain != shlib_toolchain) { | 
|  | public_deps = [ ":$target_name($shlib_toolchain)" ] | 
|  | not_needed(invoker, toolchain_spec.flag_vars) | 
|  | } else { | 
|  | if (toolchain_variant.with_shared && defined(visibility)) { | 
|  | visibility += [ ":$target_name" ] | 
|  | } | 
|  |  | 
|  | match = false | 
|  | match_flags = { | 
|  | forward_variables_from(invoker, toolchain_spec.flag_vars) | 
|  | } | 
|  | foreach(config, toolchain_spec.runtime) { | 
|  | # Clear value from last iteration. | 
|  | config_flags = { | 
|  | } | 
|  | config_flags = { | 
|  | forward_variables_from(config, toolchain_spec.flag_vars) | 
|  | } | 
|  | if (config_flags == match_flags && config.target + [ clang_target ] - | 
|  | [ clang_target ] != config.target) { | 
|  | assert(match == false, | 
|  | "${toolchain_spec.runtime_file} has multiple matches for" + | 
|  | " --target=${clang_target} + $invoker") | 
|  | match = config | 
|  | } | 
|  | } | 
|  | assert(match != false, | 
|  | "${toolchain_spec.runtime_file} has no match for" + | 
|  | " --target=${clang_target} + $invoker") | 
|  |  | 
|  | metadata = { | 
|  | binaries = [] | 
|  | distribution_entries = [] | 
|  | } | 
|  |  | 
|  | _label = get_label_info(":$target_name", "label_with_toolchain") | 
|  |  | 
|  | # The installation path prefix for runtime libraries depends on the variant. | 
|  | # Note that fuzzer variants use the base variant name, i.e. without the -fuzzer | 
|  | # suffix for this prefix. | 
|  | _libprefix = "" | 
|  | if (toolchain_variant.instrumented) { | 
|  | _libprefix = string_replace(toolchain_variant.name, "-fuzzer", "") + "/" | 
|  | } | 
|  |  | 
|  | # In many cases, the loop below will be empty. | 
|  | not_needed([ | 
|  | "_label", | 
|  | "_libprefix", | 
|  | ]) | 
|  |  | 
|  | foreach(lib, match.runtime) { | 
|  | if (!defined(invoker.libraries) || invoker.libraries + [ lib.name ] - | 
|  | [ lib.name ] != invoker.libraries) { | 
|  | _dist_file = | 
|  | rebase_path(lib.dist, root_build_dir, toolchain_spec.lib_dir) | 
|  |  | 
|  | if (defined(lib.soname)) { | 
|  | _soname = lib.soname | 
|  | } else { | 
|  | _soname = get_path_info(lib.dist, "file") | 
|  | } | 
|  |  | 
|  | # Used by the distribution_manifest() template. | 
|  | metadata.distribution_entries += [ | 
|  | { | 
|  | destination = "lib/${_libprefix}${_soname}" | 
|  | label = _label | 
|  | source = _dist_file | 
|  | }, | 
|  | ] | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | } |