capstone: Convert Makefile bits to meson bits

There are better ways to do this, e.g. meson cmake subproject,
but that requires cmake 3.7 and some of our CI environments
only provide cmake 3.5.

Nor can we add a meson.build file to capstone/, because the git
submodule would then always report "untracked files".  Fixing that
would require creating our own branch on the qemu git mirror, at
which point we could just as easily create a native meson subproject.

Instead, build the library via the main meson.build.

This improves the current state of affairs in that we will re-link
the qemu executables against a changed libcapstone.a, which we wouldn't
do before-hand.  In addition, the use of the configuration header file
instead of command-line -DEFINES means that we will rebuild the
capstone objects with changes to meson.build.

Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Alex Bennée <alex.bennee@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2020-09-13 12:19:25 -07:00
parent dd8c1e808f
commit 8b18cdbfd6
4 changed files with 120 additions and 80 deletions

View File

@ -156,21 +156,11 @@ dtc/all: .git-submodule-status dtc/libfdt
dtc/%: .git-submodule-status
@mkdir -p $@
# Overriding CFLAGS causes us to lose defines added in the sub-makefile.
# Not overriding CFLAGS leads to mis-matches between compilation modes.
# Therefore we replicate some of the logic in the sub-makefile.
# Remove all the extra -Warning flags that QEMU uses that Capstone doesn't;
# no need to annoy QEMU developers with such things.
CAP_CFLAGS = $(patsubst -W%,,$(CFLAGS) $(QEMU_CFLAGS)) $(CAPSTONE_CFLAGS)
CAP_CFLAGS += -DCAPSTONE_USE_SYS_DYN_MEM
CAP_CFLAGS += -DCAPSTONE_HAS_ARM
CAP_CFLAGS += -DCAPSTONE_HAS_ARM64
CAP_CFLAGS += -DCAPSTONE_HAS_POWERPC
CAP_CFLAGS += -DCAPSTONE_HAS_X86
# Retain for a while so that incremental build across this patch
# does not raise an error for missing target "capstone/all", which
# comes from the saved SUBDIRS value.
.PHONY: capstone/all
capstone/all: .git-submodule-status
$(call quiet-command,$(MAKE) -C $(SRC_PATH)/capstone CAPSTONE_SHARED=no BUILDDIR="$(BUILD_DIR)/capstone" CC="$(CC)" AR="$(AR)" LD="$(LD)" RANLIB="$(RANLIB)" CFLAGS="$(CAP_CFLAGS)" $(SUBDIR_MAKEFLAGS) $(BUILD_DIR)/capstone/$(LIBCAPSTONE))
capstone/all:
.PHONY: slirp/all
slirp/all: .git-submodule-status

68
configure vendored
View File

@ -478,7 +478,7 @@ opengl=""
opengl_dmabuf="no"
cpuid_h="no"
avx2_opt=""
capstone=""
capstone="auto"
lzo=""
snappy=""
bzip2=""
@ -1575,11 +1575,11 @@ for opt do
;;
--enable-vhost-kernel) vhost_kernel="yes"
;;
--disable-capstone) capstone="no"
--disable-capstone) capstone="disabled"
;;
--enable-capstone) capstone="yes"
--enable-capstone) capstone="enabled"
;;
--enable-capstone=git) capstone="git"
--enable-capstone=git) capstone="internal"
;;
--enable-capstone=system) capstone="system"
;;
@ -5017,51 +5017,11 @@ fi
# capstone
case "$capstone" in
"" | yes)
if $pkg_config capstone; then
capstone=system
elif test -e "${source_path}/.git" && test $git_update = 'yes' ; then
capstone=git
elif test -e "${source_path}/capstone/Makefile" ; then
capstone=internal
elif test -z "$capstone" ; then
capstone=no
else
feature_not_found "capstone" "Install capstone devel or git submodule"
fi
;;
system)
if ! $pkg_config capstone; then
feature_not_found "capstone" "Install capstone devel"
fi
;;
esac
case "$capstone" in
git | internal)
if test "$capstone" = git; then
auto | enabled | internal)
# Simpler to always update submodule, even if not needed.
if test -e "${source_path}/.git" && test $git_update = 'yes' ; then
git_submodules="${git_submodules} capstone"
fi
mkdir -p capstone
if test "$mingw32" = "yes"; then
LIBCAPSTONE=capstone.lib
else
LIBCAPSTONE=libcapstone.a
fi
capstone_libs="-Lcapstone -lcapstone"
capstone_cflags="-I${source_path}/capstone/include"
;;
system)
capstone_libs="$($pkg_config --libs capstone)"
capstone_cflags="$($pkg_config --cflags capstone)"
;;
no)
;;
*)
error_exit "Unknown state for capstone: $capstone"
;;
esac
@ -7142,11 +7102,6 @@ fi
if test "$ivshmem" = "yes" ; then
echo "CONFIG_IVSHMEM=y" >> $config_host_mak
fi
if test "$capstone" != "no" ; then
echo "CONFIG_CAPSTONE=y" >> $config_host_mak
echo "CAPSTONE_CFLAGS=$capstone_cflags" >> $config_host_mak
echo "CAPSTONE_LIBS=$capstone_libs" >> $config_host_mak
fi
if test "$debug_mutex" = "yes" ; then
echo "CONFIG_DEBUG_MUTEX=y" >> $config_host_mak
fi
@ -7664,13 +7619,7 @@ done # for target in $targets
if [ "$fdt" = "git" ]; then
subdirs="$subdirs dtc"
fi
if [ "$capstone" = "git" -o "$capstone" = "internal" ]; then
subdirs="$subdirs capstone"
fi
echo "SUBDIRS=$subdirs" >> $config_host_mak
if test -n "$LIBCAPSTONE"; then
echo "LIBCAPSTONE=$LIBCAPSTONE" >> $config_host_mak
fi
if test "$numa" = "yes"; then
echo "CONFIG_NUMA=y" >> $config_host_mak
@ -7846,7 +7795,8 @@ NINJA=${ninja:-$PWD/ninjatool} $meson setup \
-Dmalloc=$malloc -Dmalloc_trim=$malloc_trim \
-Dcocoa=$cocoa -Dmpath=$mpath -Dsdl=$sdl -Dsdl_image=$sdl_image \
-Dvnc=$vnc -Dvnc_sasl=$vnc_sasl -Dvnc_jpeg=$vnc_jpeg -Dvnc_png=$vnc_png \
-Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f\
-Dgettext=$gettext -Dxkbcommon=$xkbcommon -Du2f=$u2f \
-Dcapstone=$capstone \
$cross_arg \
"$PWD" "$source_path"

View File

@ -10,6 +10,7 @@ else
keyval = import('unstable-keyval')
endif
ss = import('sourceset')
fs = import('fs')
sh = find_program('sh')
cc = meson.get_compiler('c')
@ -495,11 +496,6 @@ if 'CONFIG_USB_LIBUSB' in config_host
libusb = declare_dependency(compile_args: config_host['LIBUSB_CFLAGS'].split(),
link_args: config_host['LIBUSB_LIBS'].split())
endif
capstone = not_found
if 'CONFIG_CAPSTONE' in config_host
capstone = declare_dependency(compile_args: config_host['CAPSTONE_CFLAGS'].split(),
link_args: config_host['CAPSTONE_LIBS'].split())
endif
libpmem = not_found
if 'CONFIG_LIBPMEM' in config_host
libpmem = declare_dependency(compile_args: config_host['LIBPMEM_CFLAGS'].split(),
@ -581,7 +577,6 @@ foreach k, v: config_host
config_host_data.set(k, v == 'y' ? 1 : v)
endif
endforeach
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
minikconf = find_program('scripts/minikconf.py')
config_all = {}
@ -736,6 +731,107 @@ config_all += {
'CONFIG_ALL': true,
}
# Submodules
capstone = not_found
capstone_opt = get_option('capstone')
if capstone_opt in ['enabled', 'auto', 'system']
have_internal = fs.exists(meson.current_source_dir() / 'capstone/Makefile')
capstone = dependency('capstone', static: enable_static,
method: 'pkg-config',
required: capstone_opt == 'system' or
capstone_opt == 'enabled' and not have_internal)
if capstone.found()
capstone_opt = 'system'
elif have_internal
capstone_opt = 'internal'
else
capstone_opt = 'disabled'
endif
endif
if capstone_opt == 'internal'
capstone_data = configuration_data()
capstone_data.set('CAPSTONE_USE_SYS_DYN_MEM', '1')
capstone_files = files(
'capstone/cs.c',
'capstone/MCInst.c',
'capstone/MCInstrDesc.c',
'capstone/MCRegisterInfo.c',
'capstone/SStream.c',
'capstone/utils.c'
)
if 'CONFIG_ARM_DIS' in config_all_disas
capstone_data.set('CAPSTONE_HAS_ARM', '1')
capstone_files += files(
'capstone/arch/ARM/ARMDisassembler.c',
'capstone/arch/ARM/ARMInstPrinter.c',
'capstone/arch/ARM/ARMMapping.c',
'capstone/arch/ARM/ARMModule.c'
)
endif
# FIXME: This config entry currently depends on a c++ compiler.
# Which is needed for building libvixl, but not for capstone.
if 'CONFIG_ARM_A64_DIS' in config_all_disas
capstone_data.set('CAPSTONE_HAS_ARM64', '1')
capstone_files += files(
'capstone/arch/AArch64/AArch64BaseInfo.c',
'capstone/arch/AArch64/AArch64Disassembler.c',
'capstone/arch/AArch64/AArch64InstPrinter.c',
'capstone/arch/AArch64/AArch64Mapping.c',
'capstone/arch/AArch64/AArch64Module.c'
)
endif
if 'CONFIG_PPC_DIS' in config_all_disas
capstone_data.set('CAPSTONE_HAS_POWERPC', '1')
capstone_files += files(
'capstone/arch/PowerPC/PPCDisassembler.c',
'capstone/arch/PowerPC/PPCInstPrinter.c',
'capstone/arch/PowerPC/PPCMapping.c',
'capstone/arch/PowerPC/PPCModule.c'
)
endif
if 'CONFIG_I386_DIS' in config_all_disas
capstone_data.set('CAPSTONE_HAS_X86', 1)
capstone_files += files(
'capstone/arch/X86/X86Disassembler.c',
'capstone/arch/X86/X86DisassemblerDecoder.c',
'capstone/arch/X86/X86ATTInstPrinter.c',
'capstone/arch/X86/X86IntelInstPrinter.c',
'capstone/arch/X86/X86Mapping.c',
'capstone/arch/X86/X86Module.c'
)
endif
configure_file(output: 'capstone-defs.h', configuration: capstone_data)
capstone_cargs = [
# FIXME: There does not seem to be a way to completely replace the c_args
# that come from add_project_arguments() -- we can only add to them.
# So: disable all warnings with a big hammer.
'-Wno-error', '-w',
# Include all configuration defines via a header file, which will wind up
# as a dependency on the object file, and thus changes here will result
# in a rebuild.
'-include', 'capstone-defs.h'
]
libcapstone = static_library('capstone',
sources: capstone_files,
c_args: capstone_cargs,
include_directories: 'capstone/include')
capstone = declare_dependency(link_with: libcapstone,
include_directories: 'capstone/include')
endif
config_host_data.set('CONFIG_CAPSTONE', capstone.found())
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
# Generators
hxtool = find_program('scripts/hxtool')
@ -1566,7 +1662,7 @@ summary_info += {'vvfat support': config_host.has_key('CONFIG_VVFAT')}
summary_info += {'qed support': config_host.has_key('CONFIG_QED')}
summary_info += {'parallels support': config_host.has_key('CONFIG_PARALLELS')}
summary_info += {'sheepdog support': config_host.has_key('CONFIG_SHEEPDOG')}
summary_info += {'capstone': config_host.has_key('CONFIG_CAPSTONE')}
summary_info += {'capstone': capstone_opt == 'disabled' ? false : capstone_opt}
summary_info += {'libpmem support': config_host.has_key('CONFIG_LIBPMEM')}
summary_info += {'libdaxctl support': config_host.has_key('CONFIG_LIBDAXCTL')}
summary_info += {'libudev': libudev.found()}

View File

@ -31,3 +31,7 @@ option('vnc_sasl', type : 'feature', value : 'auto',
description: 'SASL authentication for VNC server')
option('xkbcommon', type : 'feature', value : 'auto',
description: 'xkbcommon support')
option('capstone', type: 'combo', value: 'auto',
choices: ['disabled', 'enabled', 'auto', 'system', 'internal'],
description: 'Whether and how to find the capstone library')