123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- # Copyright (c) 2020, 2021 The Linux Foundation
- #
- # SPDX-License-Identifier: Apache-2.0
- import os
- from west import log
- from zspdx.walker import WalkerConfig, Walker
- from zspdx.scanner import ScannerConfig, scanDocument
- from zspdx.writer import writeSPDX
- # SBOMConfig contains settings that will be passed along to the various
- # SBOM maker subcomponents.
- class SBOMConfig:
- def __init__(self):
- super(SBOMConfig, self).__init__()
- # prefix for Document namespaces; should not end with "/"
- self.namespacePrefix = ""
- # location of build directory
- self.buildDir = ""
- # location of SPDX document output directory
- self.spdxDir = ""
- # should also analyze for included header files?
- self.analyzeIncludes = False
- # should also add an SPDX document for the SDK?
- self.includeSDK = False
- # create Cmake file-based API directories and query file
- # Arguments:
- # 1) build_dir: build directory
- def setupCmakeQuery(build_dir):
- # check that query dir exists as a directory, or else create it
- cmakeApiDirPath = os.path.join(build_dir, ".cmake", "api", "v1", "query")
- if os.path.exists(cmakeApiDirPath):
- if not os.path.isdir(cmakeApiDirPath):
- log.err(f'cmake api query directory {cmakeApiDirPath} exists and is not a directory')
- return False
- # directory exists, we're good
- else:
- # create the directory
- os.makedirs(cmakeApiDirPath, exist_ok=False)
- # check that codemodel-v2 exists as a file, or else create it
- queryFilePath = os.path.join(cmakeApiDirPath, "codemodel-v2")
- if os.path.exists(queryFilePath):
- if not os.path.isfile(queryFilePath):
- log.err(f'cmake api query file {queryFilePath} exists and is not a directory')
- return False
- # file exists, we're good
- return True
- else:
- # file doesn't exist, let's create it
- os.mknod(queryFilePath)
- return True
- # main entry point for SBOM maker
- # Arguments:
- # 1) cfg: SBOMConfig
- def makeSPDX(cfg):
- # report any odd configuration settings
- if cfg.analyzeIncludes and not cfg.includeSDK:
- log.wrn(f"config: requested to analyze includes but not to generate SDK SPDX document;")
- log.wrn(f"config: will proceed but will discard detected includes for SDK header files")
- # set up walker configuration
- walkerCfg = WalkerConfig()
- walkerCfg.namespacePrefix = cfg.namespacePrefix
- walkerCfg.buildDir = cfg.buildDir
- walkerCfg.analyzeIncludes = cfg.analyzeIncludes
- walkerCfg.includeSDK = cfg.includeSDK
- # make and run the walker
- w = Walker(walkerCfg)
- retval = w.makeDocuments()
- if not retval:
- log.err("SPDX walker failed; bailing")
- return False
- # set up scanner configuration
- scannerCfg = ScannerConfig()
- # scan each document from walker
- if cfg.includeSDK:
- scanDocument(scannerCfg, w.docSDK)
- scanDocument(scannerCfg, w.docApp)
- scanDocument(scannerCfg, w.docZephyr)
- scanDocument(scannerCfg, w.docBuild)
- # write each document, in this particular order so that the
- # hashes for external references are calculated
- # write SDK document, if we made one
- if cfg.includeSDK:
- retval = writeSPDX(os.path.join(cfg.spdxDir, "sdk.spdx"), w.docSDK)
- if not retval:
- log.err("SPDX writer failed for SDK document; bailing")
- return False
- # write app document
- retval = writeSPDX(os.path.join(cfg.spdxDir, "app.spdx"), w.docApp)
- if not retval:
- log.err("SPDX writer failed for app document; bailing")
- return False
- # write zephyr document
- writeSPDX(os.path.join(cfg.spdxDir, "zephyr.spdx"), w.docZephyr)
- if not retval:
- log.err("SPDX writer failed for zephyr document; bailing")
- return False
- # write build document
- writeSPDX(os.path.join(cfg.spdxDir, "build.spdx"), w.docBuild)
- if not retval:
- log.err("SPDX writer failed for build document; bailing")
- return False
- return True
|