blob: acb078032afb632c09cbdf86c6f33a5b841a2a04 [file] [log] [blame]
# Copyright 2023 The Chromium 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/python/python_action.gni")
declare_args() {
# When true, generated_licenses_spdx template will generate stub SPDX files
# with placeholder license. License gathering will be skipped.
# Since license gathering is resource intensive, this is useful for non-production
# builds that would run faster.
# The global configuration can be overwritten in specific `generated_licenses_spdx`
# template invocation via the `generate_stub` parameter.
generate_licenses_spdx_stubs = true
}
# Generates a stub license SPDX json file. See `generate_licenses_spdx_stubs` arg.
#
# Parameters:
#
# spdx_root_package_name (required)
# Same as in the generated_licenses_spdx rule.
# output (required)
# The name of the output file. E.g. `foo.spdx.json`.
template("_generated_licenses_spdx_stub") {
assert(defined(invoker.spdx_root_package_name),
"Must specify `spdx_root_package_name`")
assert(defined(invoker.output), "Must specify `output`")
generated_file(target_name) {
outputs = [ invoker.output ]
output_conversion = "json"
# Stub SPDX 2.3 content.
contents = {
spdxVersion = "SPDX-2.3"
SPDXID = "SPDXRef-DOCUMENT"
name = invoker.spdx_root_package_name
documentNamespace = ""
creationInfo = {
creators = [ "Tool: generated_licenses_spdx.gni" ]
}
dataLicense = "CC0-1.0"
documentDescribes = [ "SPDXRef-Package-main" ]
packages = [
{
name = invoker.spdx_root_package_name
SPDXID = "SPDXRef-Package-main"
licenseConcluded = "License-0"
},
]
hasExtractedLicensingInfos = [
{
licenseId = "License-0"
extractedText = "This is not a license. This is a generated placeholder. \nPlease build with gn arg `generate_licenses_spdx_stubs=false`."
name = "License Placeholder"
},
]
}
}
}
# Collects license metadata and generates a license SPDX json file for a given target.
#
# When `generate_licenses_spdx_stubs=true`, will generate a stub spdx instead.
#
# Parameters:
#
# target (required)
# The GN target to analyze and produce the SPDX for.
#
# output (required)
# The name of the output file. E.g. `foo.spdx.json`.
#
# spdx_root_package_name (required)
# The name to use for the main package in the SPDX document.
# This is used in debugging and license reviews, and should
# correspond with a stable, developer-friendly, short name of
# the target.
#
# compare_with_legacy_spdx (resource, optional)
# Compares the output to reference spdx file.
#
# ignore_comparison_errors (bool, optional)
# Ignores comparison errors when comparing with a legacy spdx file.
#
# debug_hints (bool, optional)
# Will add "_hint" elements to output spdx for debugging purposes.
# Default is false.
#
# log_level (str, optional)
# Tool logging level. Defaults to WARN.
#
# include_host_tools (bool, optional)
# Include host tools' licenses. Defaults to false as these tools don't ship with most software.
# Set to true when generating spdx for the tools themselves.
#
# ignore_collection_errors (bool, optional)
# When true, generation will ignore license collection errors
# and only log them as warnings.
#
# additional_licenses (list of labels, optional)
# Labels of additional license.gni targets to include in the SPDX.
#
# generate_stub (bool, optional)
# When true, will generate an SPDX placeholder. Defaults to the global
# `generate_licenses_spdx_stubs` gn arg.
#
template("generated_licenses_spdx") {
assert(defined(invoker.target), "Must specify `target`")
assert(defined(invoker.spdx_root_package_name),
"Must specify `spdx_root_package_name`")
assert(defined(invoker.output), "Must specify `output`")
_generate_stub = generate_licenses_spdx_stubs
if (defined(invoker.generate_stub)) {
_generate_stub = invoker.generate_stub
}
if (_generate_stub) {
_generated_licenses_spdx_stub(target_name) {
output = invoker.output
spdx_root_package_name = invoker.spdx_root_package_name
}
not_needed(invoker,
"*",
[
"spdx_root_package_name",
"output",
])
} else {
_targets = {
main = target_name
generated_metadata = "${target_name}.licenses_metadata"
additional_licenses = "${target_name}.additional_licenses"
}
_files = {
generated_metadata =
"${target_out_dir}/${target_name}.licenses_metadata.json"
generated_spdx = invoker.output
generated_depfile = "${target_gen_dir}/${target_name}.d"
}
_include_host_tools = false
if (defined(invoker.include_host_tools)) {
_include_host_tools = invoker.include_host_tools
}
if (defined(invoker.additional_licenses)) {
group(_targets.additional_licenses) {
applicable_licenses = invoker.additional_licenses
}
}
generated_file(_targets.generated_metadata) {
outputs = [ _files.generated_metadata ]
data_keys = [
"license",
"applicable_licenses",
]
if (!_include_host_tools) {
walk_keys = [ "applicable_licenses_host_barrier" ]
}
deps = [ invoker.target ]
if (defined(invoker.additional_licenses)) {
deps += [ ":${_targets.additional_licenses}" ]
}
output_conversion = "json"
}
python_action(_targets.main) {
forward_variables_from(invoker,
[
"deps",
"testonly",
"visibility",
])
binary_label = "//build/licenses/python:generated_licenses_spdx_tool(${host_toolchain})"
inputs = [ _files.generated_metadata ]
outputs = [ _files.generated_spdx ]
# Depsfile is generated for all the read licenses files listed in
# generated_metadata_target.
depfile = _files.generated_depfile
args = [
"--generated-license-metadata",
rebase_path(_files.generated_metadata, root_build_dir),
"--fuchsia-source-path",
rebase_path("//", root_build_dir),
"--spdx-root-package-name",
invoker.spdx_root_package_name,
"--spdx-output",
rebase_path(_files.generated_spdx, root_build_dir),
"--dep-file",
rebase_path(_files.generated_depfile, root_build_dir),
]
if (defined(invoker.compare_with_legacy_spdx)) {
args += [
"--compare-with-legacy-spdx",
rebase_path(invoker.compare_with_legacy_spdx, root_build_dir),
]
}
if (defined(invoker.ignore_comparison_errors) &&
invoker.ignore_comparison_errors) {
args += [ "--ignore-comparison-errors" ]
}
if (defined(invoker.debug_hints) && invoker.debug_hints) {
args += [ "--debug-hints" ]
}
if (_include_host_tools) {
args += [ "--include-host-tools" ]
}
if (defined(invoker.ignore_collection_errors) &&
invoker.ignore_collection_errors) {
args += [ "--ignore-collection-errors" ]
}
if (defined(invoker.log_level)) {
args += [
"--log-level",
invoker.log_level,
]
}
if (!defined(deps)) {
deps = []
}
deps += [ ":${_targets.generated_metadata}" ]
}
}
}