blob: 6b597917c7720421d02d1d4c33828bf03adab2e5 [file] [log] [blame]
# 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("//build/sdk/sdk_atom.gni")
# A shared library that can be exported to an SDK in binary form.
#
# Parameters
#
# category (required)
# Publication level of the library in SDKs.
# See //build/sdk/sdk_atom.gni.
#
# no_headers (optional)
# Whether to include the library's headers in the SDK.
# Defaults to false.
#
# sdk_name (optional)
# Name of the library in the SDK.
# If not specified, a name is inferred from the target's label.
#
# include_base (optional)
# Path to the root directory for includes.
# Defaults to ".".
#
# runtime_deps (optional)
# List of labels representing the library's runtime dependencies. This is
# only needed for runtime dependencies inherited from private dependencies.
# Note that these labels should represent SDK targets.
# The defaults for a prebuilt_shared_library should match that of a shared_library.
set_defaults("prebuilt_shared_library") {
configs = default_shared_library_configs
}
template("prebuilt_shared_library") {
assert(defined(invoker.category), "Must define an SDK category")
main_target_name = target_name
manifest_target_name = "${target_name}_sdk_manifest"
sdk_target_name = "${target_name}_sdk"
shared_library(main_target_name) {
forward_variables_from(invoker,
"*",
[
"category",
"include_base",
"no_headers",
"runtime_deps",
"sdk_name",
])
if (defined(visibility)) {
visibility += [ ":$manifest_target_name" ]
}
# Request that the runtime deps be written out to a file. This file will be
# used later to verify that all runtime deps are available in the SDK.
write_runtime_deps = "$target_out_dir/$target_name.runtime_deps"
}
compute_name = false
if (defined(invoker.sdk_name)) {
atom_name = invoker.sdk_name
} else if (defined(invoker.output_name)) {
atom_name = invoker.output_name
} else {
compute_name = true
name_target_name = "${target_name}_name"
default_name = target_name
target_label = get_label_info(":$target_name", "label_no_toolchain")
atom_name_file = "$target_gen_dir/${target_name}_sdk_name.txt"
action(name_target_name) {
script = "//build/cpp/compute_sdk_name.py"
outputs = [
atom_name_file,
]
args = [
"--out",
rebase_path(atom_name_file),
"--default-name",
default_name,
"--label",
target_label,
]
}
}
sdk_manifest_file = "$target_gen_dir/$sdk_target_name.sdk"
output_name = target_name
if (defined(invoker.output_name)) {
output_name = invoker.output_name
}
sdk_atom(manifest_target_name) {
forward_variables_from(invoker,
"*",
[
"headers_only",
"include_base",
"prebuilt",
"sdk_name",
])
# Specify the path to the generated manifest file so that it matches the
# label of the SDK (group) target below. This way the file will be found in
# the location that the build system expects.
manifest_file = sdk_manifest_file
domain = "cpp"
if (compute_name) {
name_file = atom_name_file
} else {
name = atom_name
}
tags = [ "type:compiled_shared" ]
category = invoker.category
if (is_fuchsia) {
tags += [ "arch:target" ]
} else {
tags += [ "arch:host" ]
}
no_headers = defined(invoker.no_headers) && invoker.no_headers
files = []
if ((defined(invoker.public) || defined(invoker.sources)) && !no_headers) {
headers = []
if (defined(invoker.public)) {
headers += invoker.public
} else {
foreach(source_file, invoker.sources) {
extension = get_path_info(source_file, "extension")
if (extension == "h") {
headers += [ source_file ]
}
}
}
foreach(header, headers) {
include_base = "include"
if (defined(invoker.include_base)) {
include_base = invoker.include_base
}
destination = rebase_path(header, include_base)
files += [
{
source = header
dest = "include/$destination"
},
]
}
}
shared_out_dir = get_label_info(":bogus($shlib_toolchain)", "root_out_dir")
lib_name = "lib$output_name.so"
# TODO(TO-791): put ABI stubs under lib/, not the full thing.
files += [
{
source = "$shared_out_dir/$lib_name"
dest = "dist/$lib_name"
packaged = true
},
{
source = "$shared_out_dir/$lib_name"
dest = "lib/$lib_name"
},
{
source = "$shared_out_dir/lib.unstripped/$lib_name"
dest = "debug/$lib_name"
},
]
deps = []
# If a prebuilt library is only provided for packaging purposes (by not
# exposing headers) then its dependencies need not be included in an SDK.
if (defined(invoker.public_deps) && !no_headers) {
foreach(dep, invoker.public_deps) {
full_label = get_label_info(dep, "label_no_toolchain")
deps += [ "${full_label}_sdk" ]
}
}
if (defined(invoker.runtime_deps)) {
package_deps = invoker.runtime_deps
}
non_sdk_deps = [ ":$main_target_name" ]
if (compute_name) {
non_sdk_deps += [ ":$name_target_name" ]
}
# Explicitly add non-public dependencies, in case some of the source files
# are generated.
if (defined(invoker.deps)) {
non_sdk_deps += invoker.deps
}
}
shared_gen_dir = get_label_info(":bogus($shlib_toolchain)", "target_out_dir")
runtime_deps_file = "$shared_gen_dir/$target_name.runtime_deps"
verify_target_name = "${target_name}_verify"
# Verify that the SDK manifest for this target includes all of the expected
# runtime dependencies.
# TODO(pylaligand): also check that everything in there is either prebuilt or
# headers only.
action(verify_target_name) {
script = "//build/cpp/verify_runtime_deps.py"
inputs = [
sdk_manifest_file,
runtime_deps_file,
]
stamp_file = "$target_gen_dir/$target_name.stamp"
outputs = [
stamp_file,
]
args = [
"--stamp",
rebase_path(stamp_file),
"--manifest",
rebase_path(sdk_manifest_file),
"--runtime-deps-file",
rebase_path(runtime_deps_file),
"--root-out-dir",
rebase_path(root_out_dir),
]
deps = [
":$main_target_name",
":$manifest_target_name",
]
}
group(sdk_target_name) {
public_deps = [
":$manifest_target_name",
]
deps = [
":$verify_target_name",
]
}
}