blob: bc78b35183d37f66e5d0dce48e356b09f79b82e3 [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/banjo/toolchain.gni")
import("//build/compiled_action.gni")
import("//build/sdk/sdk_atom.gni")
# Private template to generate an SDK Atom for banjo_library and
# banjo_dummy_library targets.
#
template("_banjo_library_sdk") {
library_name = target_name
if (defined(invoker.name)) {
library_name = invoker.name
}
# Process sources.
file_base = "banjo/$library_name"
all_files = []
sdk_sources = []
foreach(source, invoker.sources) {
relative_source = rebase_path(source, ".")
if (string_replace(relative_source, "..", "bogus") != relative_source) {
# If the source file is not within the same directory, just use the file
# name.
relative_source = get_path_info(source, "file")
}
destination = "$file_base/$relative_source"
sdk_sources += [ destination ]
all_files += [
{
source = rebase_path(source)
dest = destination
},
]
}
# Identify metadata for dependencies.
sdk_metas = []
sdk_deps = []
all_deps = []
if (defined(invoker.deps)) {
all_deps = invoker.deps
}
foreach(dep, all_deps) {
full_label = get_label_info(dep, "label_no_toolchain")
sdk_dep = "${full_label}_sdk"
sdk_deps += [ sdk_dep ]
gen_dir = get_label_info(sdk_dep, "target_gen_dir")
name = get_label_info(sdk_dep, "name")
sdk_metas += [ rebase_path("$gen_dir/$name.meta.json") ]
}
# Generate the library metadata.
meta_file = "$target_gen_dir/${target_name}.sdk_meta.json"
meta_target_name = "${target_name}_meta"
action(meta_target_name) {
script = "//build/banjo/gen_sdk_meta.py"
inputs = sdk_metas
outputs = [
meta_file,
]
args = [
"--out",
rebase_path(meta_file),
"--name",
library_name,
"--root",
file_base,
"--specs",
] + sdk_metas + [ "--sources" ] + sdk_sources
deps = sdk_deps
}
sdk_atom("${target_name}_sdk") {
id = "sdk://banjo/$library_name"
category = invoker.sdk_category
meta = {
source = meta_file
dest = "$file_base/meta.json"
schema = "banjo_library"
}
files = all_files
non_sdk_deps = [ ":$meta_target_name" ]
deps = []
foreach(dep, all_deps) {
label = get_label_info(dep, "label_no_toolchain")
deps += [ "${label}_sdk" ]
}
}
}
# Generates some representation of a Banjo library that's consumable by Language
# bindings generators.
#
# The parameters for this template are defined in //build/banjo/banjo.gni. The
# relevant parameters in this template are:
# - name;
# - sources;
# - sdk_category.
template("banjo_library") {
assert(
current_toolchain == banjo_toolchain,
"This template can only be used in the Banjo toolchain $banjo_toolchain.")
assert(defined(invoker.sources), "A Banjo library requires some sources.")
library_name = target_name
if (defined(invoker.name)) {
library_name = invoker.name
}
c_response_file = "$target_gen_dir/c/$target_name.args"
cpp_response_file = "$target_gen_dir/cpp/$target_name.args"
cpp_i_response_file = "$target_gen_dir/cpp_i/$target_name.args"
rust_response_file = "$target_gen_dir/rust/$target_name.args"
cpp_mock_response_file = "$target_gen_dir/cpp_mock/$target_name.args"
ddk_root = string_replace(string_replace(library_name, ".", "/"), "_", "-")
ddktl_root = string_replace(ddk_root, "ddk", "ddktl")
ddk_header = "$root_gen_dir/$ddk_root.h"
ddktl_header = "$root_gen_dir/$ddktl_root.h"
ddktl_internal_header = "$root_gen_dir/$ddktl_root-internal.h"
rust_file = "banjo_" + string_replace(library_name, ".", "_") + ".rs"
rust_internal_header = "$target_gen_dir/$rust_file"
ddktl_mock_header = "$root_gen_dir/mock/$ddktl_root.h"
main_target_name = target_name
c_response_file_target_name = "${target_name}_c_response_file"
cpp_response_file_target_name = "${target_name}_cpp_response_file"
cpp_i_response_file_target_name = "${target_name}_cpp_i_response_file"
rust_response_file_target_name = "${target_name}_rust_response_file"
cpp_mock_response_file_target_name = "${target_name}_cpp_mock_response_file"
c_compile_target_name = "${target_name}_c_compile"
cpp_compile_target_name = "${target_name}_cpp_compile"
cpp_i_compile_target_name = "${target_name}_cpp_i_compile"
rust_compile_target_name = "${target_name}_rust_compile"
cpp_mock_target_name = "${target_name}_cpp_mock"
targets = [
[
c_response_file_target_name,
c_compile_target_name,
c_response_file,
"c",
ddk_header,
],
[
cpp_response_file_target_name,
cpp_compile_target_name,
cpp_response_file,
"cpp",
ddktl_header,
],
[
cpp_i_response_file_target_name,
cpp_i_compile_target_name,
cpp_i_response_file,
"cpp_i",
ddktl_internal_header,
],
[
rust_response_file_target_name,
rust_compile_target_name,
rust_response_file,
"rust",
rust_internal_header,
],
[
cpp_mock_response_file_target_name,
cpp_mock_target_name,
cpp_mock_response_file,
"cpp_mock",
ddktl_mock_header,
],
]
all_deps = []
if (defined(invoker.deps)) {
all_deps += invoker.deps
}
if (defined(invoker.public_deps)) {
all_deps += invoker.public_deps
}
foreach(target, targets) {
target_name = target[0]
response_file = target[2]
backend = target[3]
output = target[4]
action(target_name) {
visibility = [ ":*" ]
script = "//build/banjo/gen_response_file.py"
forward_variables_from(invoker,
[
"deps",
"public_deps",
"sources",
"testonly",
])
libraries = "$target_gen_dir/$backend/$main_target_name.libraries"
outputs = [
response_file,
libraries,
]
args = [
"--out-response-file",
rebase_path(response_file, root_build_dir),
"--out-libraries",
rebase_path(libraries, root_build_dir),
"--backend",
backend,
"--output",
rebase_path(output, root_build_dir),
"--name",
library_name,
"--sources",
] + rebase_path(sources, root_build_dir)
if (all_deps != []) {
dep_libraries = []
foreach(dep, all_deps) {
gen_dir = get_label_info(dep, "target_gen_dir")
name = get_label_info(dep, "name")
dep_libraries += [ "$gen_dir/c/$name.libraries" ]
}
inputs = dep_libraries
args +=
[ "--dep-libraries" ] + rebase_path(dep_libraries, root_build_dir)
}
}
}
foreach(target, targets) {
target_name = target[1]
response_target_name = target[0]
response_file = target[2]
backend = target[3]
output = target[4]
if (backend != "rust") {
action(target_name) {
forward_variables_from(invoker, [ "testonly" ])
visibility = [ ":*" ]
script = "//prebuilt/tools/banjo/${host_platform}/banjo_bin"
inputs = [
response_file,
]
outputs = [
output,
]
rebased_response_file = rebase_path(response_file, root_build_dir)
args = [ "@$rebased_response_file" ]
deps = [
":$response_target_name",
]
}
}
}
group(main_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public_deps = [
":$c_compile_target_name",
":$c_response_file_target_name",
":$cpp_compile_target_name",
":$cpp_i_compile_target_name",
":$cpp_i_response_file_target_name",
":$cpp_mock_response_file_target_name",
":$cpp_mock_target_name",
":$cpp_response_file_target_name",
":$rust_response_file_target_name",
]
}
if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
_banjo_library_sdk("$main_target_name") {
forward_variables_from(invoker, "*")
}
}
}
template("banjo_dummy_library") {
assert(
current_toolchain == banjo_toolchain,
"This template can only be used in the Banjo toolchain $banjo_toolchain.")
assert(defined(invoker.sources),
"A Banjo dummy library requires some sources.")
library_name = target_name
if (defined(invoker.name)) {
library_name = invoker.name
}
main_target_name = target_name
c_response_file_target_name = "${target_name}_rust_response_file"
rust_response_file_target_name = "${target_name}_c_response_file"
ddk_root = string_replace(string_replace(library_name, ".", "/"), "_", "-")
rust_file = "banjo_" + string_replace(library_name, ".", "_") + ".rs"
ddk_header = "$target_gen_dir/$ddk_root.h"
rust_internal_header = "$target_gen_dir/$rust_file"
targets = [
[
c_response_file_target_name,
"c",
ddk_header,
],
[
rust_response_file_target_name,
"rust",
rust_internal_header,
],
]
foreach(target, targets) {
response_target_name = target[0]
backend = target[1]
output = target[2]
action(response_target_name) {
visibility = [ ":*" ]
script = "//build/banjo/gen_response_file.py"
forward_variables_from(invoker,
[
"deps",
"public_deps",
"sources",
"testonly",
])
response_file = "$target_gen_dir/$backend/$main_target_name.args"
libraries = "$target_gen_dir/$backend/$main_target_name.libraries"
outputs = [
response_file,
libraries,
]
args = [
"--output",
rebase_path(output, root_build_dir),
"--backend",
backend,
"--out-response-file",
rebase_path(response_file, root_build_dir),
"--out-libraries",
rebase_path(libraries, root_build_dir),
"--name",
library_name,
"--sources",
] + rebase_path(sources, root_build_dir)
}
}
group(main_target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
public_deps = [
":$c_response_file_target_name",
":$rust_response_file_target_name",
]
}
if (defined(invoker.sdk_category) && invoker.sdk_category != "excluded") {
_banjo_library_sdk("$target_name") {
forward_variables_from(invoker, "*")
}
}
}