summaryrefslogtreecommitdiff
path: root/upstream-layers/openembedded-core/meta/classes/create-spdx-3.0.bbclass
blob: 56fd01fd533bcfc56ba9acc809ca535095c8c5fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: GPL-2.0-only
#

inherit spdx-common

SPDX_VERSION = "3.0.1"

# The list of SPDX profiles generated documents will conform to
SPDX_PROFILES ?= "core build software simpleLicensing security"

SPDX_INCLUDE_BUILD_VARIABLES ??= "0"
SPDX_INCLUDE_BUILD_VARIABLES[doc] = "If set to '1', the bitbake variables for a \
    recipe will be included in the Build object. This will most likely result \
    in non-reproducible SPDX output"

SPDX_INCLUDE_BITBAKE_PARENT_BUILD ??= "0"
SPDX_INCLUDE_BITBAKE_PARENT_BUILD[doc] = "Report the parent invocation of bitbake \
    for each Build object. This allows you to know who invoked bitbake to perform \
    a build, but will result in non-reproducible SPDX output."

SPDX_PACKAGE_ADDITIONAL_PURPOSE ?= ""
SPDX_PACKAGE_ADDITIONAL_PURPOSE[doc] = "The list of additional purposes to assign to \
    the generated packages for a recipe. The primary purpose is always `install`. \
    Packages overrides are allowed to override the additional purposes for \
    individual packages."

SPDX_IMAGE_PURPOSE ?= "filesystemImage"
SPDX_IMAGE_PURPOSE[doc] = "The list of purposes to assign to the generated images. \
    The first listed item will be the Primary Purpose and all additional items will \
    be added as additional purposes"

SPDX_SDK_PURPOSE ?= "install"
SPDX_SDK_PURPOSE[doc] = "The list of purposes to assign to the generate SDK installer. \
    The first listed item will be the Primary Purpose and all additional items will \
    be added as additional purposes"

SPDX_INCLUDE_VEX ??= "current"
SPDX_INCLUDE_VEX[doc] = "Controls what VEX information is in the output. Set to \
    'none' to disable all VEX data. Set to 'current' to only include VEX data \
    for vulnerabilities not already fixed in the upstream source code \
    (recommended). Set  to 'all' to get all known historical vulnerabilities, \
    including those already fixed upstream (warning: This can be large and \
    slow)."

SPDX_INCLUDE_TIMESTAMPS ?= "0"
SPDX_INCLUDE_TIMESTAMPS[doc] = "Include time stamps in SPDX output. This is \
    useful if you want to know when artifacts were produced and when builds \
    occurred, but will result in non-reproducible SPDX output"

SPDX_INCLUDE_KERNEL_CONFIG ??= "0"
SPDX_INCLUDE_KERNEL_CONFIG[doc] = "If set to '1', the .config file for the kernel will be parsed \
and each CONFIG_* value will be included in the Build.build_parameter list as DictionaryEntry \
items. Set to '0' to disable exporting kernel configuration to improve performance or reduce \
SPDX document size."

SPDX_INCLUDE_PACKAGECONFIG ??= "0"
SPDX_INCLUDE_PACKAGECONFIG[doc] = "If set to '1', each PACKAGECONFIG feature is recorded in the \
build_Build object's build_parameter list as a DictionaryEntry with key \
'PACKAGECONFIG:<feature>' and value 'enabled' or 'disabled'"

SPDX_IMPORTS ??= ""
SPDX_IMPORTS[doc] = "SPDX_IMPORTS is the base variable that describes how to \
    reference external SPDX ids. Each import is defined as a key in this \
    variable with a suffix to describe to as a suffix to look up more \
    information about the import. Each key can have the following variables: \
        SPDX_IMPORTS_<key>_spdxid: The Fully qualified SPDX ID of the object \
        SPDX_IMPORTS_<key>_uri: The URI where the SPDX Document that contains \
            the external object can be found. Optional but recommended \
        SPDX_IMPORTS_<key>_hash_<hash>: The Checksum of the SPDX Document that \
            contains the External ID. <hash> must be one the valid SPDX hashing \
            algorithms, as described by the HashAlgorithm vocabulary in the\
            SPDX 3 spec. Optional but recommended"

# Agents
#   Bitbake variables can be used to describe an SPDX Agent that may be used
#   during the build. An Agent is specified using a set of variables which all
#   start with some common base name:
#
#   <BASE>_name: The name of the Agent (required)
#   <BASE>_type: The type of Agent. Must be one of "person", "organization",
#       "software", or "agent" (the default if not specified)
#   <BASE>_comment: The comment for the Agent (optional)
#   <BASE>_id_<ID>: And External Identifier for the Agent. <ID> must be a valid
#       ExternalIdentifierType from the SPDX 3 spec. Commonly, an E-mail address
#       can be specified with <BASE>_id_email
#
#   Alternatively, an Agent can be an external reference by referencing a key
#   in SPDX_IMPORTS like so:
#
#   <BASE>_import = "<key>"
#
#   Finally, the same agent described by another set of agent variables can be
#   referenced by specifying the basename of the variable that should be
#   referenced:
#
#   SPDX_PACKAGE_SUPPLIER_ref = "SPDX_AUTHORS_openembedded"

SPDX_AUTHORS ??= "openembedded"
SPDX_AUTHORS[doc] = "A space separated list of the document authors. Each item \
    is used to name a base variable like SPDX_AUTHORS_<AUTHOR> that \
    describes the author."

SPDX_AUTHORS_openembedded_name = "OpenEmbedded"
SPDX_AUTHORS_openembedded_type = "organization"

SPDX_BUILD_HOST[doc] = "The base variable name to describe the build host on \
    which a build is running. Must be an SPDX_IMPORTS key. Requires \
    SPDX_INCLUDE_BITBAKE_PARENT_BUILD. NOTE: Setting this will result in \
    non-reproducible SPDX output"

SPDX_INVOKED_BY[doc] = "The base variable name to describe the Agent that \
    invoked the build, which builds will link to if specified. Requires \
    SPDX_INCLUDE_BITBAKE_PARENT_BUILD. NOTE: Setting this will likely result in \
    non-reproducible SPDX output"

SPDX_ON_BEHALF_OF[doc] = "The base variable name to describe the Agent on who's \
    behalf the invoking Agent (SPDX_INVOKED_BY) is running the build. Requires \
    SPDX_INCLUDE_BITBAKE_PARENT_BUILD. NOTE: Setting this will likely result in \
    non-reproducible SPDX output"

SPDX_PACKAGE_SUPPLIER[doc] = "The base variable name to describe the Agent who \
    is supplying artifacts produced by the build"

SPDX_IMAGE_SUPPLIER[doc] = "The base variable name to describe the Agent who \
    is supplying the image SBOM. The supplier will be set on all root elements \
    of the image SBOM using the suppliedBy property. If not set, no supplier \
    information will be added to the image SBOM."

SPDX_SDK_SUPPLIER[doc] = "The base variable name to describe the Agent who \
    is supplying the SDK SBOM. The supplier will be set on all root elements \
    of the SDK SBOM using the suppliedBy property. If not set, no supplier \
    information will be added to the SDK SBOM."

SPDX_PACKAGE_VERSION ??= "${PV}"
SPDX_PACKAGE_VERSION[doc] = "The version of a package, software_packageVersion \
    in software_Package"

SPDX_PACKAGE_URL ??= ""
SPDX_PACKAGE_URL[doc] = "Provides a place for the SPDX data creator to record \
the package URL string (in accordance with the Package URL specification) for \
a software Package. DEPRECATED - use SPDX_PACKAGE_URLS instead"

SPDX_PACKAGE_URLS ?= "${SPDX_PACKAGE_URL} ${@oe.purl.get_base_purl(d)}"
SPDX_PACKAGE_URLS[doc] = "A space separated list of Package URLs (purls) for \
    the software Package. The first item in this list will be listed as the \
    packageUrl property of the packages, and all purls (including the first \
    one) will be listed as external references. The default value is an auto \
    generated pkg:yocto purl based on the recipe name, version, and layer name. \
    Override this variable to replace the default, otherwise append or prepend \
    to add additional purls."

SPDX_RECIPE_SBOM_NAME ?= "${PN}-recipe-sbom"
SPDX_RECIPE_SBOM_NAME[doc] = "The name of output recipe SBoM when using \
    create_recipe_sbom"

SPDX_GIT_PURL_MAPPINGS ??= ""
SPDX_GIT_PURL_MAPPINGS[doc] = "A space separated list of domain:purl_type \
    mappings to configure PURL generation for Git source downloads. \
    For example, 'gitlab.example.com:pkg:gitlab' maps repositories hosted \
    on gitlab.example.com to the pkg:gitlab PURL type. \
    github.com is always mapped to pkg:github by default."

IMAGE_CLASSES:append = " create-spdx-image-3.0"
SDK_CLASSES += "create-spdx-sdk-3.0"

oe.spdx30_tasks.set_timestamp_now[vardepsexclude] = "SPDX_INCLUDE_TIMESTAMPS"
oe.spdx30_tasks.get_package_sources_from_debug[vardepsexclude] += "STAGING_KERNEL_DIR"
oe.spdx30_tasks.collect_dep_objsets[vardepsexclude] = "SPDX_MULTILIB_SSTATE_ARCHS"


# SPDX library code makes heavy use of classes, which bitbake cannot easily
# parse out dependencies. As such, the library code files that make use of
# classes are explicitly added as file checksum dependencies.
SPDX3_DEP_FILES = "\
    ${COREBASE}/meta/lib/oe/sbom30.py:True \
    ${COREBASE}/meta/lib/oe/spdx30/model.py:True \
    ${SPDX_LICENSES}:True \
    "

SPDX3_VAR_DEPS = "\
    SPDX_INCLUDE_BITBAKE_PARENT_BUILD \
    SPDX_PACKAGE_ADDITIONAL_PURPOSE \
    SPDX_PROFILES \
    SPDX_NAMESPACE_PREFIX \
    SPDX_UUID_NAMESPACE \
    "

python do_create_recipe_spdx() {
    import oe.spdx30_tasks
    oe.spdx30_tasks.create_recipe_spdx(d)
}
addtask do_create_recipe_spdx

SSTATETASKS += "do_create_recipe_spdx"
do_create_recipe_spdx[sstate-inputdirs] = "${SPDXRECIPEDEPLOY}"
do_create_recipe_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}"
do_create_recipe_spdx[file-checksums] += "${SPDX3_DEP_FILES}"
do_create_recipe_spdx[cleandirs] = "${SPDXRECIPEDEPLOY}"
do_create_recipe_spdx[deptask] += "do_create_recipe_spdx"
do_create_recipe_spdx[vardeps] += "${SPDX3_VAR_DEPS}"
do_create_recipe_spdx[file-checksums] = "${@bb.fetch.get_checksum_file_list(d)}"

python do_create_recipe_spdx_setscene () {
    sstate_setscene(d)
}
addtask do_create_recipe_spdx_setscene

python do_create_spdx() {
    import oe.spdx30_tasks
    oe.spdx30_tasks.create_spdx(d)
}
addtask do_create_spdx after \
    do_unpack \
    do_patch \
    do_create_recipe_spdx \
    do_deploy_source_date_epoch \
    do_populate_sysroot do_package do_packagedata \
    before do_populate_sdk do_populate_sdk_ext do_build do_rm_work

SSTATETASKS += "do_create_spdx"
do_create_spdx[sstate-inputdirs] = "${SPDXDEPLOY}"
do_create_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}"
do_create_spdx[file-checksums] += "${SPDX3_DEP_FILES}"
do_create_spdx[deptask] += "do_create_spdx"
do_create_spdx[dirs] = "${SPDXWORK}"
do_create_spdx[cleandirs] = "${SPDXDEPLOY} ${SPDXWORK}"
do_create_spdx[depends] += " \
    ${PATCHDEPENDENCY} \
    ${@create_spdx_source_deps(d)} \
"
do_create_spdx[vardeps] += "${SPDX3_VAR_DEPS}"

python do_create_spdx_setscene () {
    sstate_setscene(d)
}
addtask do_create_spdx_setscene

python do_create_package_spdx() {
    import oe.spdx30_tasks
    oe.spdx30_tasks.create_package_spdx(d)
}
oe.spdx30_tasks.create_package_spdx[vardepsexclude] = "OVERRIDES"

addtask do_create_package_spdx after do_create_spdx before do_build do_rm_work
SSTATETASKS += "do_create_package_spdx"
do_create_package_spdx[sstate-inputdirs] = "${SPDXRUNTIMEDEPLOY}"
do_create_package_spdx[sstate-outputdirs] = "${DEPLOY_DIR_SPDX}"
do_create_package_spdx[file-checksums] += "${SPDX3_DEP_FILES}"
do_create_package_spdx[dirs] = "${SPDXRUNTIMEDEPLOY}"
do_create_package_spdx[cleandirs] = "${SPDXRUNTIMEDEPLOY}"
do_create_package_spdx[deptask] = "do_create_spdx"
do_create_package_spdx[rdeptask] = "do_create_spdx"
do_create_package_spdx[vardeps] += "${SPDX3_VAR_DEPS}"

python do_create_package_spdx_setscene () {
    sstate_setscene(d)
}
addtask do_create_package_spdx_setscene

addtask do_create_recipe_sbom after create_recipe_spdx
python do_create_recipe_sbom() {
    import oe.spdx30_tasks
    from pathlib import Path
    deploydir = Path(d.getVar("SPDXRECIPESBOMDEPLOY"))
    oe.spdx30_tasks.create_recipe_sbom(d, deploydir)
}

SSTATETASKS += "do_create_recipe_sbom"
do_create_recipe_sbom[recrdeptask] = "do_create_recipe_spdx"
do_create_recipe_sbom[nostamp] = "1"
do_create_recipe_sbom[sstate-inputdirs] = "${SPDXRECIPESBOMDEPLOY}"
do_create_recipe_sbom[sstate-outputdirs] = "${DEPLOY_DIR_IMAGE}"
do_create_recipe_sbom[file-checksums] += "${SPDX3_DEP_FILES}"
do_create_recipe_sbom[cleandirs] = "${SPDXRECIPESBOMDEPLOY}"
do_create_recipe_sbom[vardeps] += "${SPDX3_VAR_DEPS}"

python do_create_recipe_sbom_setscene () {
    sstate_setscene(d)
}
addtask do_create_recipe_sbom_setscene

python spdx30_build_started_handler () {
    import oe.spdx30_tasks
    d = e.data.createCopy()
    oe.spdx30_tasks.write_bitbake_spdx(d)
}

addhandler spdx30_build_started_handler
spdx30_build_started_handler[eventmask] = "bb.event.BuildStarted"