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

24
configure vendored
View File

@ -303,7 +303,7 @@ sdl_image="auto"
virtfs="" virtfs=""
mpath="auto" mpath="auto"
vnc="enabled" vnc="enabled"
sparse="no" sparse="auto"
vde="" vde=""
vnc_sasl="auto" vnc_sasl="auto"
vnc_jpeg="auto" vnc_jpeg="auto"
@ -1040,9 +1040,9 @@ for opt do
;; ;;
--disable-tsan) tsan="no" --disable-tsan) tsan="no"
;; ;;
--enable-sparse) sparse="yes" --enable-sparse) sparse="enabled"
;; ;;
--disable-sparse) sparse="no" --disable-sparse) sparse="disabled"
;; ;;
--disable-strip) strip_opt="no" --disable-strip) strip_opt="no"
;; ;;
@ -2875,19 +2875,6 @@ if test "$gettext" != "false" ; then
fi fi
fi fi
##########################################
# Sparse probe
if test "$sparse" != "no" ; then
if has sparse; then
sparse=yes
else
if test "$sparse" = "yes" ; then
feature_not_found "sparse" "Install sparse binary"
fi
sparse=no
fi
fi
########################################## ##########################################
# X11 probe # X11 probe
if $pkg_config --exists "x11"; then if $pkg_config --exists "x11"; then
@ -7127,9 +7114,6 @@ echo "QEMU_CXXFLAGS=$QEMU_CXXFLAGS" >> $config_host_mak
echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak echo "QEMU_INCLUDES=$QEMU_INCLUDES" >> $config_host_mak
echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak echo "GLIB_CFLAGS=$glib_cflags" >> $config_host_mak
echo "GLIB_LIBS=$glib_libs" >> $config_host_mak echo "GLIB_LIBS=$glib_libs" >> $config_host_mak
if test "$sparse" = "yes" ; then
echo "SPARSE_CFLAGS = -Wbitwise -Wno-transparent-union -Wno-old-initializer -Wno-non-pointer-null" >> $config_host_mak
fi
echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak echo "QEMU_LDFLAGS=$QEMU_LDFLAGS" >> $config_host_mak
echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak echo "LDFLAGS_NOPIE=$LDFLAGS_NOPIE" >> $config_host_mak
echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak echo "LD_I386_EMULATION=$ld_i386_emulation" >> $config_host_mak
@ -7382,7 +7366,7 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \
-Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \ -Dstrip=$(if test "$strip_opt" = yes; then echo true; else echo false; fi) \
-Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \ -Db_pie=$(if test "$pie" = yes; then echo true; else echo false; fi) \
-Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \ -Db_coverage=$(if test "$gcov" = yes; then echo true; else echo false; fi) \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim \ -Dmalloc=$malloc -Dmalloc_trim=$malloc_trim -Dsparse=$sparse \
-Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \ -Dkvm=$kvm -Dhax=$hax -Dwhpx=$whpx -Dhvf=$hvf \
-Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \ -Dxen=$xen -Dxen_pci_passthrough=$xen_pci_passthrough -Dtcg=$tcg \
-Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \ -Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \

View File

@ -102,11 +102,13 @@ if host_machine.system() == 'darwin'
add_languages('objc', required: false, native: false) add_languages('objc', required: false, native: false)
endif endif
if 'SPARSE_CFLAGS' in config_host sparse = find_program('cgcc', required: get_option('sparse'))
if sparse.found()
run_target('sparse', run_target('sparse',
command: [find_program('scripts/check_sparse.py'), command: [find_program('scripts/check_sparse.py'),
config_host['SPARSE_CFLAGS'].split(), 'compile_commands.json', sparse.full_path(), '-Wbitwise',
'compile_commands.json']) '-Wno-transparent-union', '-Wno-old-initializer',
'-Wno-non-pointer-null'])
endif endif
########################################### ###########################################
@ -1557,7 +1559,7 @@ summary_info += {'host CPU': cpu}
summary_info += {'host endianness': build_machine.endian()} summary_info += {'host endianness': build_machine.endian()}
summary_info += {'target list': ' '.join(target_dirs)} summary_info += {'target list': ' '.join(target_dirs)}
summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')} summary_info += {'gprof enabled': config_host.has_key('CONFIG_GPROF')}
summary_info += {'sparse enabled': meson.get_compiler('c').cmd_array().contains('cgcc')} summary_info += {'sparse enabled': sparse.found()}
summary_info += {'strip binaries': get_option('strip')} summary_info += {'strip binaries': get_option('strip')}
summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')} summary_info += {'profiler': config_host.has_key('CONFIG_PROFILER')}
summary_info += {'static build': config_host.has_key('CONFIG_STATIC')} summary_info += {'static build': config_host.has_key('CONFIG_STATIC')}

View File

@ -5,6 +5,8 @@ option('docdir', type : 'string', value : 'doc',
option('gettext', type : 'boolean', value : true, option('gettext', type : 'boolean', value : true,
description: 'Localization of the GTK+ user interface') description: 'Localization of the GTK+ user interface')
option('sparse', type : 'feature', value : 'auto',
description: 'sparse checker')
option('malloc_trim', type : 'feature', value : 'auto', option('malloc_trim', type : 'feature', value : 'auto',
description: 'enable libc malloc_trim() for memory optimization') description: 'enable libc malloc_trim() for memory optimization')

View File

@ -1,25 +1,59 @@
#! /usr/bin/env python3 #! /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 json
import subprocess import subprocess
import os
import sys import sys
import shlex import shlex
def extract_cflags(shcmd): def cmdline_for_sparse(sparse, cmdline):
cflags = shlex.split(shcmd) # Do not include the C compiler executable
return [x for x in cflags skip = True
if x.startswith('-D') or x.startswith('-I') or x.startswith('-W') arg = False
or x.startswith('-std=')] 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] root_path = os.getenv('MESON_BUILD_ROOT')
with open(sys.argv[-1], 'r') as fd: 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) compile_commands = json.load(fd)
sparse = sys.argv[2:]
sparse_env = os.environ.copy()
for cmd in compile_commands: for cmd in compile_commands:
cmd = ['sparse'] + cflags + extract_cflags(cmd['command']) + [cmd['file']] cmdline = shlex.split(cmd['command'])
print(' '.join((shlex.quote(x) for x in cmd))) cmd = cmdline_for_sparse(sparse, cmdline)
r = subprocess.run(cmd) 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: if r.returncode != 0:
sys.exit(r.returncode) sys.exit(r.returncode)