# Copyright (c) 2021 The Linux Foundation # # SPDX-License-Identifier: Apache-2.0 from subprocess import run, PIPE from west import log # Given a path to the applicable C compiler, a C source file, and the # corresponding TargetCompileGroup, determine which include files would # be used. # Arguments: # 1) path to applicable C compiler # 2) C source file being analyzed # 3) TargetCompileGroup for the current target # Returns: list of paths to include files, or [] on error or empty findings. def getCIncludes(compilerPath, srcFile, tcg): log.dbg(f" - getting includes for {srcFile}") # prepare fragments fragments = [fr for fr in tcg.compileCommandFragments if fr.strip() != ""] # prepare include arguments includes = ["-I" + incl.path for incl in tcg.includes] # prepare defines defines = ["-D" + d.define for d in tcg.defines] # prepare command invocation cmd = [compilerPath, "-E", "-H"] + fragments + includes + defines + [srcFile] cp = run(cmd, stdout=PIPE, stderr=PIPE, universal_newlines=True) if cp.returncode != 0: log.dbg(f" - calling {compilerPath} failed with error code {cp.returncode}") return [] else: # response will be in cp.stderr, not cp.stdout return extractIncludes(cp.stderr) # Parse the response from the CC -E -H call, to extract the include file paths def extractIncludes(resp): includes = set() # lines we want will start with one or more periods, followed by # a space and then the include file path, e.g.: # .... /home/steve/programming/zephyr/zephyrproject/zephyr/include/kernel.h # the number of periods indicates the depth of nesting (for transitively- # included files), but here we aren't going to care about that. We'll # treat everything as tied to the corresponding source file. # once we hit the line "Multiple include guards may be useful for:", # we're done; ignore everything after that for rline in resp.splitlines(): if rline.startswith("Multiple include guards"): break if rline[0] == ".": sline = rline.split(" ", maxsplit=1) if len(sline) != 2: continue includes.add(sline[1]) includesList = list(includes) includesList.sort() return includesList