blob: 75b8aec88768fc97517470baea9713adb6c1c9c7 [file] [log] [blame]
# Copyright 2019 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/unification/zn_build/public/gn/config/globals.gni")
set_defaults("library") {
configs =
default_common_binary_configs + [
"//build/unification/zn_build/public/gn/config:default_include_dirs",
"//build/unification/zn_build/public/gn/config:default_warnings",
"//build/unification/zn_build/public/gn/config:user",
]
}
template("library") {
main_target_name = target_name
if (main_target_name == "c" || main_target_name == "zircon") {
# For now, libc and libzircon are still built by ZN and available in the GN
# build via the sysroot. This assert ensure we never try to directly build
# these libraries.
assert(false, "Dependencies on 'c' and 'zircon' should not be needed")
}
# These parameters are applicable to the "library" instance and not to the
# target(s) it generates.
# This includes "deps" and "public_deps" which are pre-processed before being
# passed on.
template_params = [
"deps",
"host",
"kernel",
"no_implicit_deps",
"public_deps",
"sdk",
"sdk_headers",
"sdk_publishable",
"shared",
"static",
]
is_shared = defined(invoker.shared) && invoker.shared
is_publishable = defined(invoker.sdk_publishable) && invoker.sdk_publishable
# Gather all dependencies in a single list.
# The loop below will process that list and break it down into private and
# public deps.
all_deps = []
if (defined(invoker.public_deps)) {
foreach(label, invoker.public_deps) {
# "public_deps" should only contain header dependencies: ignore other
# types.
if (get_label_info(label, "name") == "headers" || get_path_info(
get_label_info(
label,
"name"),
"extension") ==
"headers" ||
get_path_info(get_label_info(label, "dir"), "dir") ==
"$zx/system/banjo") {
all_deps += [ label ]
}
if (get_label_info(label, "name") == "trace-engine-headers-for-handler") {
# The trace-* libraries have very intricate dependency structures which
# require this special case...
all_deps += [ label ]
}
}
}
if (defined(invoker.deps)) {
all_deps += invoker.deps
}
# Translate and classify dependencies.
# This loop transforms ZN-style labels into GN-style labels depending on
# their types, which it infers from the shape of the labels.
target_deps = []
target_public_deps = []
foreach(dep, all_deps) {
if (dep == "//zircon/system/ulib/zircon" ||
dep == "//zircon/system/ulib/zircon:headers" ||
dep == "//zircon/system/ulib/c" ||
dep == "//zircon/system/ulib/c:headers") {
# These fundamental libraries are already available via the sysroot, no
# need for further action.
} else if (get_label_info(dep, "name") == "c") {
# Private dependency on the C bindings of a FIDL library.
dep = get_label_info(dep, "dir")
assert(get_path_info(dep, "dir") == "$zx/system/fidl")
dep = get_label_info(dep, "name")
target_deps += [ "//zircon/system/fidl/${dep}:${dep}_c" ]
} else if (get_label_info(dep, "name") == "c.headers") {
# Public dependency on the C bindings of a FIDL library.
dep = get_label_info(dep, "dir")
assert(get_path_info(dep, "dir") == "$zx/system/fidl")
dep = get_label_info(dep, "name")
target_public_deps += [ "//zircon/system/fidl/${dep}:${dep}_c" ]
} else if (get_label_info(dep, "name") == "llcpp") {
# Private dependency on the LLCPP bindings of a FIDL library.
dep = get_label_info(dep, "dir")
assert(get_path_info(dep, "dir") == "$zx/system/fidl")
dep = get_label_info(dep, "name")
target_deps += [ "//zircon/system/fidl/${dep}:${dep}_llcpp" ]
} else if (get_label_info(dep, "name") == "llcpp.headers") {
# Public dependency on the LLCPP bindings of a FIDL library.
dep = get_label_info(dep, "dir")
assert(get_path_info(dep, "dir") == "$zx/system/fidl")
dep = get_label_info(dep, "name")
target_public_deps += [ "//zircon/system/fidl/${dep}:${dep}_llcpp" ]
} else if (get_label_info(dep, "name") == "headers") {
# Public dependency on another C/C++ library.
base_label = get_label_info(dep, "dir")
target_public_deps += [ base_label ]
} else if (get_path_info(get_label_info(dep, "name"), "extension") ==
"headers") {
# Public dependency on another C/C++ library.
base_label = get_label_info(dep, "dir")
# This call returns the target name without its extension.
name = get_path_info(get_label_info(dep, "name"), "name")
target_public_deps += [ "$base_label:$name" ]
} else if (get_path_info(get_label_info(dep, "dir"), "dir") ==
"$zx/system/banjo") {
# Private dependency on a Banjo library.
dep = get_path_info(get_label_info(dep, "dir"), "file")
target_deps += [ "//zircon/system/banjo/$dep" ]
} else if (get_label_info(dep, "name") == "static" ||
get_label_info(dep, "name") == "shared") {
# Private dependency on another C/C++ library.
base_label = get_label_info(dep, "dir")
target_deps += [ base_label ]
} else if (get_path_info(get_label_info(dep, "name"), "extension") ==
"static" || get_path_info(get_label_info(dep, "name"),
"extension") == "shared") {
# Private dependency on another C/C++ library.
base_label = get_label_info(dep, "dir")
# This call returns the target name without its extension.
name = get_path_info(get_label_info(dep, "name"), "name")
target_deps += [ "$base_label:$name" ]
} else {
target_deps += [ dep ]
}
}
# A set of additional parameters to be passed to the resulting target.
target_extra_params = {
}
# Add SDK-related information to targets destined for public glory.
if (is_publishable) {
target_extra_params.category = "partner"
target_extra_params.api = "//sdk/lib/$target_name/$target_name.api"
if (defined(invoker.sdk_headers)) {
target_extra_params.public = []
foreach(header, invoker.sdk_headers) {
target_extra_params.public += [ "include/$header" ]
}
}
}
# The type of target to generate.
target_type = ""
# The file declaring the target type, if applicable.
target_import = ""
if (is_shared) {
if (is_publishable) {
target_type = "sdk_shared_library"
target_import = "//build/cpp/sdk_shared_library.gni"
# Libraries published in SDKs must always link libc++ statically.
target_extra_params.libcxx_linkage = "static"
target_extra_params.include_base = "include"
target_extra_params.symbols_api = "//sdk/lib/$target_name/$target_name.symbols.api"
# Add runtime dependencies.
# There is no way to express these dependencies with ZN's "library"
# template, so they are being manually added here.
target_extra_params.runtime_deps = []
if (target_name == "syslog") {
target_extra_params.runtime_deps += [
"//zircon/system/ulib/fdio:fdio_sdk",
]
}
if (target_name == "memfs") {
target_extra_params.runtime_deps += [
"//zircon/system/ulib/fdio:fdio_sdk",
"//zircon/system/ulib/trace-engine:trace-engine_sdk",
]
}
if (target_name == "trace-provider-so") {
target_extra_params.runtime_deps += [
"//zircon/system/ulib/fdio:fdio_sdk",
]
}
} else {
target_type = "shared_library"
}
} else {
if (is_publishable) {
target_type = "sdk_source_set"
target_import = "//build/cpp/sdk_source_set.gni"
target_extra_params.sdk_name = target_name
} else {
target_type = "source_set"
}
}
if (target_import != "") {
import(target_import)
}
# This config will allow compilation units depending on this library to find
# its headers.
config("${main_target_name}_config") {
include_dirs = [ "include" ]
}
# Declare the main target.
target(target_type, main_target_name) {
forward_variables_from(invoker, "*", template_params)
forward_variables_from(target_extra_params, "*")
if (!defined(public_configs)) {
public_configs = []
}
public_configs += [ ":${main_target_name}_config" ]
deps = target_deps
public_deps = target_public_deps
}
if (!is_shared) {
# Some of the source libraries are depended on by Rust binaries, which
# cannot depend on .o files. For every source library, we generate a
# matching static library tagged with the config and metadata needed by the
# Rust build to identify and use that library.
out_dir = rebase_path(target_out_dir)
config("$main_target_name.static_config") {
if (is_fuchsia) {
libs = [ "zircon" ]
rustflags = [
"-Lnative=$out_dir",
"-l$main_target_name",
]
}
}
static_library("$main_target_name.static") {
forward_variables_from(invoker, [ "testonly" ])
output_name = main_target_name
public_configs = [ ":$main_target_name.static_config" ]
public_deps = [ ":$main_target_name" ]
metadata = {
zircon_lib_dirs = [ out_dir ]
}
}
}
}