meson: move sparse detection to Meson and rewrite check_sparse.py

Pass the path to the program to scripts/check_sparse.py, which
previously was not included in config-host.mak.  Change
scripts/check_sparse.py to work with cgcc, which seems to
work better with sparse 0.6.x.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Paolo Bonzini 2020-09-01 07:51:16 -04:00
parent fa73168b08
commit deb62371fe
4 changed files with 57 additions and 35 deletions

View file

@ -1,25 +1,59 @@
#! /usr/bin/env python3
# Invoke sparse based on the contents of compile_commands.json
# 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 extract_cflags(shcmd):
cflags = shlex.split(shcmd)
return [x for x in cflags
if x.startswith('-D') or x.startswith('-I') or x.startswith('-W')
or x.startswith('-std=')]
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
cflags = sys.argv[1:-1]
with open(sys.argv[-1], 'r') as fd:
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:
cmd = ['sparse'] + cflags + extract_cflags(cmd['command']) + [cmd['file']]
print(' '.join((shlex.quote(x) for x in cmd)))
r = subprocess.run(cmd)
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)