60 lines
1.6 KiB
Python
60 lines
1.6 KiB
Python
#! /usr/bin/env python3
|
|
|
|
# Invoke sparse based on the contents of compile_commands.json,
|
|
# also working around several deficiencies in cgcc's command line
|
|
# parsing
|
|
|
|
import json
|
|
import subprocess
|
|
import os
|
|
import sys
|
|
import shlex
|
|
|
|
def cmdline_for_sparse(sparse, cmdline):
|
|
# Do not include the C compiler executable
|
|
skip = True
|
|
arg = False
|
|
out = sparse + ['-no-compile']
|
|
for x in cmdline:
|
|
if arg:
|
|
out.append(x)
|
|
arg = False
|
|
continue
|
|
if skip:
|
|
skip = False
|
|
continue
|
|
# prevent sparse from treating output files as inputs
|
|
if x == '-MF' or x == '-MQ' or x == '-o':
|
|
skip = True
|
|
continue
|
|
# cgcc ignores -no-compile if it sees -M or -MM?
|
|
if x.startswith('-M'):
|
|
continue
|
|
# sparse does not understand these!
|
|
if x == '-iquote' or x == '-isystem':
|
|
x = '-I'
|
|
if x == '-I':
|
|
arg = True
|
|
out.append(x)
|
|
return out
|
|
|
|
root_path = os.getenv('MESON_BUILD_ROOT')
|
|
def build_path(s):
|
|
return s if not root_path else os.path.join(root_path, s)
|
|
|
|
ccjson_path = build_path(sys.argv[1])
|
|
with open(ccjson_path, 'r') as fd:
|
|
compile_commands = json.load(fd)
|
|
|
|
sparse = sys.argv[2:]
|
|
sparse_env = os.environ.copy()
|
|
for cmd in compile_commands:
|
|
cmdline = shlex.split(cmd['command'])
|
|
cmd = cmdline_for_sparse(sparse, cmdline)
|
|
print('REAL_CC=%s' % shlex.quote(cmdline[0]),
|
|
' '.join((shlex.quote(x) for x in cmd)))
|
|
sparse_env['REAL_CC'] = cmdline[0]
|
|
r = subprocess.run(cmd, env=sparse_env, cwd=root_path)
|
|
if r.returncode != 0:
|
|
sys.exit(r.returncode)
|