You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
2.3 KiB
67 lines
2.3 KiB
# Copyright (c) 2021 The Linux Foundation |
|
# |
|
# SPDX-License-Identifier: Apache-2.0 |
|
|
|
from subprocess import run |
|
|
|
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, capture_output=True, text=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
|
|
|