mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/bonzini-gitlab/tags/for-upstream' into staging
meson related: * convert unit tests * bugfixes for mtest2make * miscellaneous bugfixes * dead code removal and configure cleanups * oss-fuzz fixes * msys fixes # gpg: Signature made Tue 08 Sep 2020 10:43:27 BST # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini-gitlab/tags/for-upstream: (45 commits) docs: update build system documentation meson: remove linkage of sdl to baum meson: Convert undefsym.sh to undefsym.py fuzz: Add support for custom fuzzing library meson: specify fuzz linker script as a project arg oss-fuzz: fix rpath configure: update dtc submodule docs: suggest Meson replacements for various configure functions configure: drop dead variables and functions configure: do not include dependency flags in QEMU_CFLAGS and LIBS meson: get opengl compilation flags from OPENGL_CFLAGS meson: get glib compilation flags from GLIB_CFLAGS configure: do not look for install(1) configure: remove unnecessary libm test configure: move -ldl test to meson meson: keep all compiler flags detection together configure: move disassembler configuration to meson Makefile: inline the relevant parts of rules.mak Makefile: remove dead variables and includes meson: compute config_all_devices directly ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -2,8 +2,6 @@
|
||||
/build/
|
||||
/.doctrees
|
||||
/config-devices.*
|
||||
/config-all-devices.*
|
||||
/config-all-disas.*
|
||||
/config-host.*
|
||||
/config-target.*
|
||||
/config.status
|
||||
|
||||
@@ -10,6 +10,20 @@ BUILD_DIR=$(CURDIR)
|
||||
# Before including a proper config-host.mak, assume we are in the source tree
|
||||
SRC_PATH=.
|
||||
|
||||
# Don't use implicit rules or variables
|
||||
# we have explicit rules for everything
|
||||
MAKEFLAGS += -rR
|
||||
|
||||
# Usage: $(call quiet-command,command and args,"NAME","args to print")
|
||||
# This will run "command and args", and either:
|
||||
# if V=1 just print the whole command and args
|
||||
# otherwise print the 'quiet' output in the format " NAME args to print"
|
||||
# NAME should be a short name of the command, 7 letters or fewer.
|
||||
# If called with only a single argument, will print nothing in quiet mode.
|
||||
quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1
|
||||
quiet-@ = $(if $(V),,@)
|
||||
quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
|
||||
|
||||
UNCHECKED_GOALS := %clean TAGS cscope ctags dist \
|
||||
help check-help print-% \
|
||||
docker docker-% vm-help vm-test vm-build-%
|
||||
@@ -64,10 +78,11 @@ ${ninja-targets-c_COMPILER} ${ninja-targets-cpp_COMPILER}: .var.command += -MP
|
||||
# reread (and MESON won't be empty anymore).
|
||||
ifneq ($(MESON),)
|
||||
Makefile.mtest: build.ninja scripts/mtest2make.py
|
||||
$(MESON) introspect --tests | $(PYTHON) scripts/mtest2make.py > $@
|
||||
$(MESON) introspect --tests --benchmarks | $(PYTHON) scripts/mtest2make.py > $@
|
||||
-include Makefile.mtest
|
||||
endif
|
||||
|
||||
Makefile: .git-submodule-status
|
||||
.git-submodule-status: git-submodule-update config-host.mak
|
||||
|
||||
# Check that we're not trying to do an out-of-tree build from
|
||||
@@ -80,13 +95,6 @@ seems to have been used for an in-tree build. You can fix this by running \
|
||||
endif
|
||||
endif
|
||||
|
||||
CONFIG_SOFTMMU := $(if $(filter %-softmmu,$(TARGET_DIRS)),y)
|
||||
CONFIG_USER_ONLY := $(if $(filter %-user,$(TARGET_DIRS)),y)
|
||||
CONFIG_XEN := $(CONFIG_XEN_BACKEND)
|
||||
CONFIG_ALL=y
|
||||
-include config-all-devices.mak
|
||||
-include config-all-disas.mak
|
||||
|
||||
config-host.mak: $(SRC_PATH)/configure $(SRC_PATH)/pc-bios $(SRC_PATH)/VERSION
|
||||
@echo $@ is out-of-date, running configure
|
||||
@if test -f meson-private/coredata.dat; then \
|
||||
@@ -115,13 +123,6 @@ ninja-clean::
|
||||
ninja-distclean::
|
||||
build.ninja: config-host.mak
|
||||
|
||||
include $(SRC_PATH)/rules.mak
|
||||
|
||||
# lor is defined in rules.mak
|
||||
CONFIG_BLOCK := $(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS))
|
||||
|
||||
generated-files-y += .git-submodule-status
|
||||
|
||||
# Don't try to regenerate Makefile or configure
|
||||
# We don't generate any of them
|
||||
Makefile: ;
|
||||
@@ -130,15 +131,7 @@ configure: ;
|
||||
.PHONY: all clean cscope distclean install \
|
||||
recurse-all dist msi FORCE
|
||||
|
||||
$(call set-vpath, $(SRC_PATH))
|
||||
|
||||
LIBS+=-lz $(LIBS_TOOLS)
|
||||
|
||||
SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet) BUILD_DIR=$(BUILD_DIR)
|
||||
|
||||
ifneq ($(wildcard config-host.mak),)
|
||||
include $(SRC_PATH)/Makefile.objs
|
||||
endif
|
||||
SUBDIR_MAKEFLAGS=$(if $(V),,--no-print-directory --quiet)
|
||||
|
||||
include $(SRC_PATH)/tests/Makefile.include
|
||||
|
||||
@@ -162,7 +155,7 @@ dtc/%: .git-submodule-status
|
||||
# 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))
|
||||
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
|
||||
@@ -205,7 +198,6 @@ clean: recurse-clean ninja-clean clean-ctlist
|
||||
-exec rm {} +
|
||||
rm -f TAGS cscope.* *.pod *~ */*~
|
||||
rm -f fsdev/*.pod scsi/*.pod
|
||||
rm -f $(foreach f,$(generated-files-y),$(f) $(f)-timestamp)
|
||||
|
||||
VERSION = $(shell cat $(SRC_PATH)/VERSION)
|
||||
|
||||
@@ -248,18 +240,6 @@ cscope:
|
||||
# Needed by "meson install"
|
||||
export DESTDIR
|
||||
|
||||
# Add a dependency on the generated files, so that they are always
|
||||
# rebuilt before other object files
|
||||
ifneq ($(wildcard config-host.mak),)
|
||||
ifneq ($(filter-out $(UNCHECKED_GOALS),$(MAKECMDGOALS)),$(if $(MAKECMDGOALS),,fail))
|
||||
Makefile: $(generated-files-y)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Include automatically generated dependency files
|
||||
# Dependencies in Makefile.objs files come from our recursive subdir rules
|
||||
-include $(wildcard *.d tests/*.d)
|
||||
|
||||
include $(SRC_PATH)/tests/docker/Makefile.include
|
||||
include $(SRC_PATH)/tests/vm/Makefile.include
|
||||
|
||||
@@ -283,6 +263,7 @@ help:
|
||||
@echo ''
|
||||
@echo 'Test targets:'
|
||||
$(call print-help,check,Run all tests (check-help for details))
|
||||
$(call print-help,bench,Run all benchmarks)
|
||||
$(call print-help,docker,Help about targets running tests inside containers)
|
||||
$(call print-help,vm-help,Help about targets running tests inside VM)
|
||||
@echo ''
|
||||
@@ -299,3 +280,9 @@ endif
|
||||
endif
|
||||
$(call print-help,$(MAKE) [targets],(quiet build, default))
|
||||
$(call print-help,$(MAKE) V=1 [targets],(verbose build))
|
||||
|
||||
# will delete the target of a rule if commands exit with a nonzero exit status
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
#######################################################################
|
||||
# Common libraries for tools and emulators
|
||||
qom-obj-y = qom/libqom.fa
|
||||
|
||||
#######################################################################
|
||||
# code used by both qemu system emulation and qemu-img
|
||||
|
||||
ifeq ($(call lor,$(CONFIG_SOFTMMU),$(CONFIG_TOOLS)),y)
|
||||
|
||||
authz-obj-y = authz/libauthz.fa
|
||||
authz/libauthz.fa-libs = $(if $(CONFIG_AUTH_PAM),-lpam)
|
||||
|
||||
block-obj-y += libblock.fa
|
||||
|
||||
libblock.fa-libs = $(ZSTD_LIBS)
|
||||
libblock.fa-libs += $(LIBNFS_LIBS)
|
||||
libblock.fa-libs += $(LIBISCSI_LIBS)
|
||||
libblock.fa-libs += $(CURL_LIBS)
|
||||
libblock.fa-libs += $(RBD_LIBS)
|
||||
libblock.fa-libs += $(GLUSTERFS_LIBS)
|
||||
libblock.fa-libs += $(VXHS_LIBS)
|
||||
libblock.fa-libs += $(LIBSSH_LIBS)
|
||||
libblock.fa-libs += $(BZIP2_LIBS)
|
||||
libblock.fa-libs += $(LZFSE_LIBS)
|
||||
libblock.fa-libs += $(if $(CONFIG_LINUX_AIO),-laio)
|
||||
libblock.fa-libs += $(LIBXML2_LIBS)
|
||||
|
||||
chardev-obj-y = chardev/libchardev.fa
|
||||
|
||||
crypto-obj-y = crypto/libcrypto.fa
|
||||
|
||||
io-obj-y = io/libio.fa
|
||||
|
||||
endif # CONFIG_SOFTMMU or CONFIG_TOOLS
|
||||
@@ -9,7 +9,7 @@ tcg_ss.add(files(
|
||||
))
|
||||
tcg_ss.add(when: 'CONFIG_USER_ONLY', if_true: files('user-exec.c'))
|
||||
tcg_ss.add(when: 'CONFIG_SOFTMMU', if_false: files('user-exec-stub.c'))
|
||||
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: files('plugin-gen.c'))
|
||||
tcg_ss.add(when: 'CONFIG_PLUGIN', if_true: [files('plugin-gen.c'), libdl])
|
||||
specific_ss.add_all(when: 'CONFIG_TCG', if_true: tcg_ss)
|
||||
|
||||
specific_ss.add(when: ['CONFIG_SOFTMMU', 'CONFIG_TCG'], if_true: files('tcg-all.c', 'cputlb.c'))
|
||||
|
||||
+2
-2
@@ -36,9 +36,9 @@ softmmu_ss.add(when: ['CONFIG_SPICE', spice], if_true: files('spice.c'))
|
||||
|
||||
chardev_modules = {}
|
||||
|
||||
if config_host.has_key('CONFIG_BRLAPI') and sdl.found()
|
||||
if config_host.has_key('CONFIG_BRLAPI')
|
||||
module_ss = ss.source_set()
|
||||
module_ss.add(when: [sdl, brlapi], if_true: [files('baum.c'), pixman])
|
||||
module_ss.add(when: [brlapi], if_true: [files('baum.c'), pixman])
|
||||
chardev_modules += { 'baum': module_ss }
|
||||
endif
|
||||
|
||||
|
||||
+1
-3
@@ -22,6 +22,4 @@ common_ss.add(when: 'CONFIG_SH4_DIS', if_true: files('sh4.c'))
|
||||
common_ss.add(when: 'CONFIG_SPARC_DIS', if_true: files('sparc.c'))
|
||||
common_ss.add(when: 'CONFIG_XTENSA_DIS', if_true: files('xtensa.c'))
|
||||
|
||||
# TODO: As long as the TCG interpreter and its generated code depend
|
||||
# on the QEMU target, we cannot compile the disassembler here.
|
||||
#common_ss.add(when: 'CONFIG_TCI_DIS', if_true: files('tci.c'))
|
||||
specific_ss.add(when: 'CONFIG_TCG_INTERPRETER', if_true: files('tci.c'))
|
||||
|
||||
+18
-97
@@ -125,27 +125,27 @@ developers in checking for system features:
|
||||
`compile_object $CFLAGS`
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS. The test program must have been previously written to a file
|
||||
called $TMPC.
|
||||
called $TMPC. The replacement in Meson is the compiler object `cc`,
|
||||
which has methods such as `cc.compiles()`,
|
||||
`cc.check_header()`, `cc.has_function()`.
|
||||
|
||||
`compile_prog $CFLAGS $LDFLAGS`
|
||||
Attempt to compile a test program with the system C compiler using
|
||||
$CFLAGS and link it with the system linker using $LDFLAGS. The test
|
||||
program must have been previously written to a file called $TMPC.
|
||||
The replacement in Meson is `cc.find_library()` and `cc.links()`.
|
||||
|
||||
`has $COMMAND`
|
||||
Determine if $COMMAND exists in the current environment, either as a
|
||||
shell builtin, or executable binary, returning 0 on success.
|
||||
|
||||
`path_of $COMMAND`
|
||||
Return the fully qualified path of $COMMAND, printing it to stdout,
|
||||
and returning 0 on success.
|
||||
shell builtin, or executable binary, returning 0 on success. The
|
||||
replacement in Meson is `find_program()`.
|
||||
|
||||
`check_define $NAME`
|
||||
Determine if the macro $NAME is defined by the system C compiler
|
||||
|
||||
`check_include $NAME`
|
||||
Determine if the include $NAME file is available to the system C
|
||||
compiler
|
||||
compiler. The replacement in Meson is `cc.has_header()`.
|
||||
|
||||
`write_c_skeleton`
|
||||
Write a minimal C program main() function to the temporary file
|
||||
@@ -179,7 +179,7 @@ process for:
|
||||
|
||||
- Userspace emulators - qemu-$ARCH
|
||||
|
||||
- Some (but not all) unit tests
|
||||
- Unit tests
|
||||
|
||||
2) documentation
|
||||
|
||||
@@ -204,8 +204,9 @@ are then turned into static libraries as follows::
|
||||
|
||||
chardev = declare_dependency(link_whole: libchardev)
|
||||
|
||||
The special `.fa` suffix is needed as long as unit tests are built with
|
||||
the older Makefile infrastructure, and will go away later.
|
||||
As of Meson 0.55.1, the special `.fa` suffix should be used for everything
|
||||
that is used with `link_whole`, to ensure that the link flags are placed
|
||||
correctly in the command line.
|
||||
|
||||
Files linked into emulator targets there can be split into two distinct groups
|
||||
of files, those which are independent of the QEMU emulation target and
|
||||
@@ -221,7 +222,8 @@ only in system emulators, `user_ss` only in user-mode emulators.
|
||||
|
||||
In the target-dependent set lives CPU emulation, device emulation and
|
||||
much glue code. This sometimes also has to be compiled multiple times,
|
||||
once for each target being built.
|
||||
once for each target being built. Target-dependent files are included
|
||||
in the `specific_ss` sourceset.
|
||||
|
||||
All binaries link with a static library `libqemuutil.a`, which is then
|
||||
linked to all the binaries. `libqemuutil.a` is built from several
|
||||
@@ -300,84 +302,9 @@ The resulting build system is largely non-recursive in nature, in
|
||||
contrast to common practices seen with automake.
|
||||
|
||||
Tests are also ran by the Makefile with the traditional `make check`
|
||||
phony target. Meson test suites such as `unit` can be ran with `make
|
||||
check-unit` too. It is also possible to run tests defined in meson.build
|
||||
with `meson test`.
|
||||
|
||||
The following text is only relevant for unit tests which still have to
|
||||
be converted to Meson.
|
||||
|
||||
All binaries should link to `libqemuutil.a`, e.g.:
|
||||
|
||||
qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a
|
||||
|
||||
On Windows, all binaries have the suffix `.exe`, so all Makefile rules
|
||||
which create binaries must include the $(EXESUF) variable on the binary
|
||||
name. e.g.
|
||||
|
||||
qemu-img$(EXESUF): qemu-img.o ..snip..
|
||||
|
||||
This expands to `.exe` on Windows, or an empty string on other platforms.
|
||||
|
||||
Variable naming
|
||||
---------------
|
||||
|
||||
The QEMU convention is to define variables to list different groups of
|
||||
object files. These are named with the convention $PREFIX-obj-y. The
|
||||
Meson `chardev` variable in the previous example corresponds to a
|
||||
variable 'chardev-obj-y'.
|
||||
|
||||
Likewise, tests that are executed by `make check-unit` are grouped into
|
||||
a variable check-unit-y, like this:
|
||||
|
||||
check-unit-y += tests/test-visitor-serialization$(EXESUF)
|
||||
check-unit-y += tests/test-iov$(EXESUF)
|
||||
check-unit-y += tests/test-bitmap$(EXESUF)
|
||||
|
||||
When a test or object file which needs to be conditionally built based
|
||||
on some characteristic of the host system, the configure script will
|
||||
define a variable for the conditional. For example, on Windows it will
|
||||
define $(CONFIG_POSIX) with a value of 'n' and $(CONFIG_WIN32) with a
|
||||
value of 'y'. It is now possible to use the config variables when
|
||||
listing object files. For example,
|
||||
|
||||
check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
|
||||
|
||||
On Windows this expands to
|
||||
|
||||
check-unit-n += tests/vmstate.exe
|
||||
|
||||
Since the `check-unit` target only runs tests included in `$(check-unit-y)`,
|
||||
POSIX specific tests listed in `$(util-obj-n)` are ignored on the Windows
|
||||
platform builds.
|
||||
|
||||
|
||||
CFLAGS / LDFLAGS / LIBS handling
|
||||
--------------------------------
|
||||
|
||||
There are many different binaries being built with differing purposes,
|
||||
and some of them might even be 3rd party libraries pulled in via git
|
||||
submodules. As such the use of the global CFLAGS variable is generally
|
||||
avoided in QEMU, since it would apply to too many build targets.
|
||||
|
||||
Flags that are needed by any QEMU code (i.e. everything *except* GIT
|
||||
submodule projects) are put in $(QEMU_CFLAGS) variable. For linker
|
||||
flags the $(LIBS) variable is sometimes used, but a couple of more
|
||||
targeted variables are preferred.
|
||||
|
||||
In addition to these variables, it is possible to provide cflags and
|
||||
libs against individual source code files, by defining variables of the
|
||||
form $FILENAME-cflags and $FILENAME-libs. For example, the test
|
||||
test-crypto-tlscredsx509 needs to link to the libtasn1 library,
|
||||
so tests/Makefile.include defines some variables:
|
||||
|
||||
tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
|
||||
tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
|
||||
|
||||
The scope is a little different between the two variables. The libs get
|
||||
used when linking any target binary that includes the curl.o object
|
||||
file, while the cflags get used when compiling the curl.c file only.
|
||||
|
||||
phony target, while benchmarks are run with `make bench`. Meson test
|
||||
suites such as `unit` can be ran with `make check-unit` too. It is also
|
||||
possible to run tests defined in meson.build with `meson test`.
|
||||
|
||||
Important files for the build system
|
||||
====================================
|
||||
@@ -401,15 +328,9 @@ number of dynamically created files listed later.
|
||||
executables. Build rules for various subdirectories are included in
|
||||
other meson.build files spread throughout the QEMU source tree.
|
||||
|
||||
`rules.mak`
|
||||
This file provides the generic helper rules for invoking build tools, in
|
||||
particular the compiler and linker.
|
||||
|
||||
`tests/Makefile.include`
|
||||
Rules for building the unit tests. This file is included directly by the
|
||||
top level Makefile, so anything defined in this file will influence the
|
||||
entire build system. Care needs to be taken when writing rules for tests
|
||||
to ensure they only apply to the unit test execution / build.
|
||||
Rules for external test harnesses. These include the TCG tests,
|
||||
`qemu-iotests` and the Avocado-based acceptance tests.
|
||||
|
||||
`tests/docker/Makefile.include`
|
||||
Rules for Docker tests. Like tests/Makefile, this file is included
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
arm_ss = ss.source_set()
|
||||
arm_ss.add(files('boot.c'))
|
||||
arm_ss.add(files('boot.c'), fdt)
|
||||
arm_ss.add(when: 'CONFIG_PLATFORM_BUS', if_true: files('sysbus-fdt.c'))
|
||||
arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c'))
|
||||
arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c'))
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ mips_ss.add(when: 'CONFIG_FULOONG', if_true: files('fuloong2e.c'))
|
||||
mips_ss.add(when: 'CONFIG_JAZZ', if_true: files('jazz.c'))
|
||||
mips_ss.add(when: 'CONFIG_MALTA', if_true: files('gt64xxx_pci.c', 'malta.c'))
|
||||
mips_ss.add(when: 'CONFIG_MIPSSIM', if_true: files('mipssim.c'))
|
||||
mips_ss.add(when: 'CONFIG_MIPS_BOSTON', if_true: files('boston.c'))
|
||||
mips_ss.add(when: 'CONFIG_MIPS_BOSTON', if_true: [files('boston.c'), fdt])
|
||||
mips_ss.add(when: 'CONFIG_MIPS_CPS', if_true: files('cps.c'))
|
||||
mips_ss.add(when: 'CONFIG_R4K', if_true: files('r4k.c'))
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
riscv_ss = ss.source_set()
|
||||
riscv_ss.add(files('boot.c'))
|
||||
riscv_ss.add(files('boot.c'), fdt)
|
||||
riscv_ss.add(files('numa.c'))
|
||||
riscv_ss.add(when: 'CONFIG_HART', if_true: files('riscv_hart.c'))
|
||||
riscv_ss.add(when: 'CONFIG_OPENTITAN', if_true: files('opentitan.c'))
|
||||
|
||||
+94
-33
@@ -1,6 +1,6 @@
|
||||
project('qemu', ['c'], meson_version: '>=0.55.0',
|
||||
default_options: ['warning_level=1', 'c_std=gnu99', 'cpp_std=gnu++11',
|
||||
'b_lundef=false','b_colorout=auto'],
|
||||
'b_colorout=auto'],
|
||||
version: run_command('head', meson.source_root() / 'VERSION').stdout().strip())
|
||||
|
||||
not_found = dependency('', required: false)
|
||||
@@ -14,7 +14,6 @@ ss = import('sourceset')
|
||||
sh = find_program('sh')
|
||||
cc = meson.get_compiler('c')
|
||||
config_host = keyval.load(meson.current_build_dir() / 'config-host.mak')
|
||||
config_all_disas = keyval.load(meson.current_build_dir() / 'config-all-disas.mak')
|
||||
enable_modules = 'CONFIG_MODULES' in config_host
|
||||
enable_static = 'CONFIG_STATIC' in config_host
|
||||
build_docs = 'BUILD_DOCS' in config_host
|
||||
@@ -33,6 +32,23 @@ endforeach
|
||||
have_tools = 'CONFIG_TOOLS' in config_host
|
||||
have_block = have_system or have_tools
|
||||
|
||||
python = import('python').find_installation()
|
||||
|
||||
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
|
||||
supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
|
||||
'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
|
||||
|
||||
cpu = host_machine.cpu_family()
|
||||
targetos = host_machine.system()
|
||||
|
||||
configure_file(input: files('scripts/ninjatool.py'),
|
||||
output: 'ninjatool',
|
||||
configuration: config_host)
|
||||
|
||||
##################
|
||||
# Compiler flags #
|
||||
##################
|
||||
|
||||
add_project_arguments(config_host['QEMU_CFLAGS'].split(),
|
||||
native: false, language: ['c', 'objc'])
|
||||
add_project_arguments(config_host['QEMU_CXXFLAGS'].split(),
|
||||
@@ -42,7 +58,13 @@ add_project_link_arguments(config_host['QEMU_LDFLAGS'].split(),
|
||||
add_project_arguments(config_host['QEMU_INCLUDES'].split(),
|
||||
language: ['c', 'cpp', 'objc'])
|
||||
|
||||
python = import('python').find_installation()
|
||||
# Specify linker-script with add_project_link_arguments so that it is not placed
|
||||
# within a linker --start-group/--end-group pair
|
||||
if 'CONFIG_FUZZ' in config_host
|
||||
add_project_link_arguments(['-Wl,-T,',
|
||||
(meson.current_source_dir() / 'tests/qtest/fuzz/fork_fuzz.ld')],
|
||||
native: false, language: ['c', 'cpp', 'objc'])
|
||||
endif
|
||||
|
||||
link_language = meson.get_external_property('link_language', 'cpp')
|
||||
if link_language == 'cpp'
|
||||
@@ -59,17 +81,6 @@ if 'SPARSE_CFLAGS' in config_host
|
||||
'compile_commands.json'])
|
||||
endif
|
||||
|
||||
configure_file(input: files('scripts/ninjatool.py'),
|
||||
output: 'ninjatool',
|
||||
configuration: config_host)
|
||||
|
||||
supported_oses = ['windows', 'freebsd', 'netbsd', 'openbsd', 'darwin', 'sunos', 'linux']
|
||||
supported_cpus = ['ppc', 'ppc64', 's390x', 'sparc64', 'riscv32', 'riscv64', 'x86', 'x86_64',
|
||||
'arm', 'aarch64', 'mips', 'mips64', 'sparc', 'sparc64']
|
||||
|
||||
cpu = host_machine.cpu_family()
|
||||
targetos = host_machine.system()
|
||||
|
||||
m = cc.find_library('m', required: false)
|
||||
util = cc.find_library('util', required: false)
|
||||
winmm = []
|
||||
@@ -101,8 +112,11 @@ elif targetos == 'haiku'
|
||||
cc.find_library('network'),
|
||||
cc.find_library('bsd')]
|
||||
endif
|
||||
glib = declare_dependency(compile_args: config_host['GLIB_CFLAGS'].split(),
|
||||
link_args: config_host['GLIB_LIBS'].split())
|
||||
# The path to glib.h is added to all compilation commands. This was
|
||||
# grandfathered in from the QEMU Makefiles.
|
||||
add_project_arguments(config_host['GLIB_CFLAGS'].split(),
|
||||
native: false, language: ['c', 'cpp', 'objc'])
|
||||
glib = declare_dependency(link_args: config_host['GLIB_LIBS'].split())
|
||||
gio = not_found
|
||||
if 'CONFIG_GIO' in config_host
|
||||
gio = declare_dependency(compile_args: config_host['GIO_CFLAGS'].split(),
|
||||
@@ -208,6 +222,10 @@ libmpathpersist = not_found
|
||||
if config_host.has_key('CONFIG_MPATH')
|
||||
libmpathpersist = cc.find_library('mpathpersist')
|
||||
endif
|
||||
libdl = not_found
|
||||
if 'CONFIG_PLUGIN' in config_host
|
||||
libdl = cc.find_library('dl', required: true)
|
||||
endif
|
||||
libiscsi = not_found
|
||||
if 'CONFIG_LIBISCSI' in config_host
|
||||
libiscsi = declare_dependency(compile_args: config_host['LIBISCSI_CFLAGS'].split(),
|
||||
@@ -297,7 +315,8 @@ if 'CONFIG_AUDIO_COREAUDIO' in config_host
|
||||
endif
|
||||
opengl = not_found
|
||||
if 'CONFIG_OPENGL' in config_host
|
||||
opengl = declare_dependency(link_args: config_host['OPENGL_LIBS'].split())
|
||||
opengl = declare_dependency(compile_args: config_host['OPENGL_CFLAGS'].split(),
|
||||
link_args: config_host['OPENGL_LIBS'].split())
|
||||
else
|
||||
endif
|
||||
gtk = not_found
|
||||
@@ -410,6 +429,15 @@ libdaxctl = not_found
|
||||
if 'CONFIG_LIBDAXCTL' in config_host
|
||||
libdaxctl = declare_dependency(link_args: config_host['LIBDAXCTL_LIBS'].split())
|
||||
endif
|
||||
tasn1 = not_found
|
||||
if 'CONFIG_TASN1' in config_host
|
||||
tasn1 = declare_dependency(compile_args: config_host['TASN1_CFLAGS'].split(),
|
||||
link_args: config_host['TASN1_LIBS'].split())
|
||||
endif
|
||||
keyutils = dependency('libkeyutils', required: false,
|
||||
method: 'pkg-config', static: enable_static)
|
||||
|
||||
has_gettid = cc.has_function('gettid')
|
||||
|
||||
# Create config-host.h
|
||||
|
||||
@@ -420,6 +448,8 @@ config_host_data.set('CONFIG_VNC_JPEG', jpeg.found())
|
||||
config_host_data.set('CONFIG_VNC_PNG', png.found())
|
||||
config_host_data.set('CONFIG_VNC_SASL', sasl.found())
|
||||
config_host_data.set('CONFIG_XKBCOMMON', xkbcommon.found())
|
||||
config_host_data.set('CONFIG_KEYUTILS', keyutils.found())
|
||||
config_host_data.set('CONFIG_GETTID', has_gettid)
|
||||
config_host_data.set('QEMU_VERSION', '"@0@"'.format(meson.project_version()))
|
||||
config_host_data.set('QEMU_VERSION_MAJOR', meson.project_version().split('.')[0])
|
||||
config_host_data.set('QEMU_VERSION_MINOR', meson.project_version().split('.')[1])
|
||||
@@ -449,10 +479,45 @@ endforeach
|
||||
genh += configure_file(output: 'config-host.h', configuration: config_host_data)
|
||||
|
||||
minikconf = find_program('scripts/minikconf.py')
|
||||
config_all_devices = {}
|
||||
config_all_disas = {}
|
||||
config_devices_mak_list = []
|
||||
config_devices_h = {}
|
||||
config_target_h = {}
|
||||
config_target_mak = {}
|
||||
|
||||
disassemblers = {
|
||||
'alpha' : ['CONFIG_ALPHA_DIS'],
|
||||
'arm' : ['CONFIG_ARM_DIS'],
|
||||
'avr' : ['CONFIG_AVR_DIS'],
|
||||
'cris' : ['CONFIG_CRIS_DIS'],
|
||||
'hppa' : ['CONFIG_HPPA_DIS'],
|
||||
'i386' : ['CONFIG_I386_DIS'],
|
||||
'x86_64' : ['CONFIG_I386_DIS'],
|
||||
'x32' : ['CONFIG_I386_DIS'],
|
||||
'lm32' : ['CONFIG_LM32_DIS'],
|
||||
'm68k' : ['CONFIG_M68K_DIS'],
|
||||
'microblaze' : ['CONFIG_MICROBLAZE_DIS'],
|
||||
'mips' : ['CONFIG_MIPS_DIS'],
|
||||
'moxie' : ['CONFIG_MOXIE_DIS'],
|
||||
'nios2' : ['CONFIG_NIOS2_DIS'],
|
||||
'or1k' : ['CONFIG_OPENRISC_DIS'],
|
||||
'ppc' : ['CONFIG_PPC_DIS'],
|
||||
'riscv' : ['CONFIG_RISCV_DIS'],
|
||||
'rx' : ['CONFIG_RX_DIS'],
|
||||
's390' : ['CONFIG_S390_DIS'],
|
||||
'sh4' : ['CONFIG_SH4_DIS'],
|
||||
'sparc' : ['CONFIG_SPARC_DIS'],
|
||||
'xtensa' : ['CONFIG_XTENSA_DIS'],
|
||||
}
|
||||
if link_language == 'cpp'
|
||||
disassemblers += {
|
||||
'aarch64' : [ 'CONFIG_ARM_A64_DIS'],
|
||||
'arm' : [ 'CONFIG_ARM_DIS', 'CONFIG_ARM_A64_DIS'],
|
||||
'mips' : [ 'CONFIG_MIPS_DIS', 'CONFIG_NANOMIPS_DIS'],
|
||||
}
|
||||
endif
|
||||
|
||||
kconfig_external_symbols = [
|
||||
'CONFIG_KVM',
|
||||
'CONFIG_XEN',
|
||||
@@ -468,9 +533,19 @@ kconfig_external_symbols = [
|
||||
'CONFIG_PVRDMA',
|
||||
]
|
||||
ignored = ['TARGET_XML_FILES', 'TARGET_ABI_DIR', 'TARGET_DIRS']
|
||||
|
||||
foreach target : target_dirs
|
||||
config_target = keyval.load(meson.current_build_dir() / target / 'config-target.mak')
|
||||
|
||||
foreach k, v: disassemblers
|
||||
if config_host['ARCH'].startswith(k) or config_target['TARGET_BASE_ARCH'].startswith(k)
|
||||
foreach sym: v
|
||||
config_target += { sym: 'y' }
|
||||
config_all_disas += { sym: 'y' }
|
||||
endforeach
|
||||
endif
|
||||
endforeach
|
||||
|
||||
config_target_data = configuration_data()
|
||||
foreach k, v: config_target
|
||||
if not k.startswith('TARGET_') and not k.startswith('CONFIG_')
|
||||
@@ -517,11 +592,11 @@ foreach target : target_dirs
|
||||
config_devices_h += {target: configure_file(output: target + '-config-devices.h',
|
||||
configuration: config_devices_data)}
|
||||
config_target += config_devices
|
||||
config_all_devices += config_devices
|
||||
endif
|
||||
config_target_mak += {target: config_target}
|
||||
endforeach
|
||||
|
||||
grepy = find_program('scripts/grepy.sh')
|
||||
# This configuration is used to build files that are shared by
|
||||
# multiple binaries, and then extracted out of the "common"
|
||||
# static_library target.
|
||||
@@ -531,17 +606,6 @@ grepy = find_program('scripts/grepy.sh')
|
||||
# targets that are not built for this compilation. The CONFIG_ALL
|
||||
# pseudo symbol replaces it.
|
||||
|
||||
if have_system
|
||||
config_all_devices_mak = configure_file(
|
||||
output: 'config-all-devices.mak',
|
||||
input: config_devices_mak_list,
|
||||
capture: true,
|
||||
command: [grepy, '@INPUT@'],
|
||||
)
|
||||
config_all_devices = keyval.load(config_all_devices_mak)
|
||||
else
|
||||
config_all_devices = {}
|
||||
endif
|
||||
config_all = config_all_devices
|
||||
config_all += config_host
|
||||
config_all += config_all_disas
|
||||
@@ -868,7 +932,7 @@ foreach d, list : modules
|
||||
endforeach
|
||||
|
||||
nm = find_program('nm')
|
||||
undefsym = find_program('scripts/undefsym.sh')
|
||||
undefsym = find_program('scripts/undefsym.py')
|
||||
block_syms = custom_target('block.syms', output: 'block.syms',
|
||||
input: [libqemuutil, block_mods],
|
||||
capture: true,
|
||||
@@ -1028,7 +1092,6 @@ foreach target : target_dirs
|
||||
'gui': false,
|
||||
'sources': specific_fuzz.sources(),
|
||||
'dependencies': specific_fuzz.dependencies(),
|
||||
'link_depends': [files('tests/qtest/fuzz/fork_fuzz.ld')],
|
||||
}]
|
||||
endif
|
||||
else
|
||||
@@ -1102,7 +1165,6 @@ if have_tools
|
||||
dependencies: [block, qemuutil], install: true)
|
||||
qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
|
||||
dependencies: [block, qemuutil], install: true)
|
||||
qemu_block_tools += [qemu_img, qemu_io, qemu_nbd]
|
||||
|
||||
subdir('storage-daemon')
|
||||
subdir('contrib/rdmacm-mux')
|
||||
@@ -1293,7 +1355,6 @@ summary_info += {'CFLAGS': config_host['CFLAGS']}
|
||||
summary_info += {'QEMU_CFLAGS': config_host['QEMU_CFLAGS']}
|
||||
summary_info += {'QEMU_LDFLAGS': config_host['QEMU_LDFLAGS']}
|
||||
summary_info += {'make': config_host['MAKE']}
|
||||
summary_info += {'install': config_host['INSTALL']}
|
||||
summary_info += {'python': '@0@ (version: @1@)'.format(python.full_path(), python.language_version())}
|
||||
summary_info += {'sphinx-build': config_host['SPHINX_BUILD']}
|
||||
summary_info += {'genisoimage': config_host['GENISOIMAGE']}
|
||||
|
||||
+1
-1
@@ -6,4 +6,4 @@ softmmu_ss.add(files(
|
||||
'qmp-cmds.c',
|
||||
))
|
||||
|
||||
specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: files('misc.c'))
|
||||
specific_ss.add(when: 'CONFIG_SOFTMMU', if_true: [files('misc.c'), spice])
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
|
||||
# These are used when we want to do substitutions without confusing Make
|
||||
NULL :=
|
||||
SPACE := $(NULL) #
|
||||
COMMA := ,
|
||||
|
||||
# Don't use implicit rules or variables
|
||||
# we have explicit rules for everything
|
||||
MAKEFLAGS += -rR
|
||||
|
||||
# Files with this suffixes are final, don't try to generate them
|
||||
# using implicit rules
|
||||
%/trace-events:
|
||||
%.hx:
|
||||
%.py:
|
||||
%.objs:
|
||||
%.d:
|
||||
%.h:
|
||||
%.c:
|
||||
%.cc:
|
||||
%.cpp:
|
||||
%.m:
|
||||
%.mak:
|
||||
|
||||
# Flags for dependency generation
|
||||
QEMU_DGFLAGS += -MMD -MP -MT $@ -MF $(@D)/$(*F).d
|
||||
|
||||
# Compiler searches the source file dir first, but in vpath builds
|
||||
# we need to make it search the build dir too, before any other
|
||||
# explicit search paths. There are two search locations in the build
|
||||
# dir, one absolute and the other relative to the compiler working
|
||||
# directory. These are the same for target-independent files, but
|
||||
# different for target-dependent ones.
|
||||
QEMU_LOCAL_INCLUDES = -iquote $(BUILD_DIR) -iquote $(BUILD_DIR)/$(@D) -iquote $(@D)
|
||||
|
||||
WL := -Wl,
|
||||
ifdef CONFIG_DARWIN
|
||||
whole-archive = $(WL)-force_load,$1
|
||||
else
|
||||
whole-archive = $(WL)--whole-archive $1 $(WL)--no-whole-archive
|
||||
endif
|
||||
|
||||
extract-libs = $(strip $(foreach o,$1,$($o-libs)))
|
||||
|
||||
%.o: %.c
|
||||
@mkdir -p $(dir $@)
|
||||
$(call quiet-command,$(CC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
|
||||
$(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) \
|
||||
-c -o $@ $<,"CC","$(TARGET_DIR)$@")
|
||||
|
||||
# If we have a CXX we might have some C++ objects, in which case we
|
||||
# must link with the C++ compiler, not the plain C compiler.
|
||||
LINKPROG = $(or $(CXX),$(CC))
|
||||
|
||||
LINK = $(call quiet-command, $(LINKPROG) $(CFLAGS) $(QEMU_LDFLAGS) -o $@ \
|
||||
$(filter-out %.a %.fa,$1) \
|
||||
$(foreach l,$(filter %.fa,$1),$(call whole-archive,$l)) \
|
||||
$(filter %.a,$1) \
|
||||
$(call extract-libs,$1) $(LIBS),"LINK","$(TARGET_DIR)$@")
|
||||
|
||||
%.o: %.S
|
||||
$(call quiet-command,$(CCAS) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
|
||||
$(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) \
|
||||
-c -o $@ $<,"CCAS","$(TARGET_DIR)$@")
|
||||
|
||||
%.o: %.cc
|
||||
$(call quiet-command,$(CXX) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
|
||||
$(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CXXFLAGS) $($@-cflags) \
|
||||
-c -o $@ $<,"CXX","$(TARGET_DIR)$@")
|
||||
|
||||
%.o: %.cpp
|
||||
$(call quiet-command,$(CXX) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
|
||||
$(QEMU_CXXFLAGS) $(QEMU_DGFLAGS) $(CXXFLAGS) $($@-cflags) \
|
||||
-c -o $@ $<,"CXX","$(TARGET_DIR)$@")
|
||||
|
||||
%.o: %.m
|
||||
$(call quiet-command,$(OBJCC) $(QEMU_LOCAL_INCLUDES) $(QEMU_INCLUDES) \
|
||||
$(QEMU_CFLAGS) $(QEMU_DGFLAGS) $(CFLAGS) $($@-cflags) \
|
||||
-c -o $@ $<,"OBJC","$(TARGET_DIR)$@")
|
||||
|
||||
%.o: %.dtrace
|
||||
$(call quiet-command,dtrace -o $@ -G -s $<,"GEN","$(TARGET_DIR)$@")
|
||||
|
||||
.PHONY: modules
|
||||
modules:
|
||||
|
||||
%$(EXESUF): %.o
|
||||
$(call LINK,$(filter %.o %.a %.fa, $^))
|
||||
|
||||
%.a:
|
||||
$(call quiet-command,rm -f $@ && $(AR) rcs $@ $^,"AR","$(TARGET_DIR)$@")
|
||||
|
||||
# Usage: $(call quiet-command,command and args,"NAME","args to print")
|
||||
# This will run "command and args", and either:
|
||||
# if V=1 just print the whole command and args
|
||||
# otherwise print the 'quiet' output in the format " NAME args to print"
|
||||
# NAME should be a short name of the command, 7 letters or fewer.
|
||||
# If called with only a single argument, will print nothing in quiet mode.
|
||||
quiet-command-run = $(if $(V),,$(if $2,printf " %-7s %s\n" $2 $3 && ))$1
|
||||
quiet-@ = $(if $(V),,@)
|
||||
quiet-command = $(quiet-@)$(call quiet-command-run,$1,$2,$3)
|
||||
|
||||
# cc-option
|
||||
# Usage: CFLAGS+=$(call cc-option, -falign-functions=0, -malign-functions=0)
|
||||
|
||||
cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
|
||||
>/dev/null 2>&1 && echo OK), $2, $3)
|
||||
cc-c-option = $(if $(shell $(CC) $1 $2 -c -o /dev/null -xc /dev/null \
|
||||
>/dev/null 2>&1 && echo OK), $2, $3)
|
||||
|
||||
VPATH_SUFFIXES = %.c %.h %.S %.cc %.cpp %.m %.mak %.texi %.sh %.rc Kconfig% %.json.in
|
||||
set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
|
||||
|
||||
# install-prog list, dir
|
||||
define install-prog
|
||||
$(INSTALL_DIR) "$2"
|
||||
$(INSTALL_PROG) $1 "$2"
|
||||
$(if $(STRIP),$(STRIP) $(foreach T,$1,"$2/$(notdir $T)"),)
|
||||
endef
|
||||
|
||||
# Logical functions (for operating on y/n values like CONFIG_FOO vars)
|
||||
# Inputs to these must be either "y" (true) or "n" or "" (both false)
|
||||
# Output is always either "y" or "n".
|
||||
# Usage: $(call land,$(CONFIG_FOO),$(CONFIG_BAR))
|
||||
# Logical NOT
|
||||
lnot = $(if $(subst n,,$1),n,y)
|
||||
# Logical AND
|
||||
land = $(if $(findstring yy,$1$2),y,n)
|
||||
# Logical OR
|
||||
lor = $(if $(findstring y,$1$2),y,n)
|
||||
# Logical XOR (note that this is the inverse of leqv)
|
||||
lxor = $(if $(filter $(call lnot,$1),$(call lnot,$2)),n,y)
|
||||
# Logical equivalence (note that leqv "","n" is true)
|
||||
leqv = $(if $(filter $(call lnot,$1),$(call lnot,$2)),y,n)
|
||||
# Logical if: like make's $(if) but with an leqv-like test
|
||||
lif = $(if $(subst n,,$1),$2,$3)
|
||||
|
||||
# String testing functions: inputs to these can be any string;
|
||||
# the output is always either "y" or "n". Leading and trailing whitespace
|
||||
# is ignored when comparing strings.
|
||||
# String equality
|
||||
eq = $(if $(subst $2,,$1)$(subst $1,,$2),n,y)
|
||||
# String inequality
|
||||
ne = $(if $(subst $2,,$1)$(subst $1,,$2),y,n)
|
||||
# Emptiness/non-emptiness tests:
|
||||
isempty = $(if $1,n,y)
|
||||
notempty = $(if $1,y,n)
|
||||
|
||||
.PHONY: clean-timestamp
|
||||
clean-timestamp:
|
||||
rm -f *.timestamp
|
||||
clean: clean-timestamp
|
||||
|
||||
# will delete the target of a rule if commands exit with a nonzero exit status
|
||||
.DELETE_ON_ERROR:
|
||||
|
||||
print-%:
|
||||
@echo '$*=$($*)'
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
grep -h '=y$' "$@" | sort -u
|
||||
+54
-44
@@ -19,38 +19,25 @@ class Suite(object):
|
||||
print('''
|
||||
SPEED = quick
|
||||
|
||||
# $1 = test command, $2 = test name
|
||||
.test-human-tap = $1 < /dev/null | ./scripts/tap-driver.pl --test-name="$2" $(if $(V),,--show-failures-only)
|
||||
.test-human-exitcode = $1 < /dev/null
|
||||
.test-tap-tap = $1 < /dev/null | sed "s/^[a-z][a-z]* [0-9]*/& $2/" || true
|
||||
.test-tap-exitcode = printf "%s\\n" 1..1 "`$1 < /dev/null > /dev/null || echo "not "`ok 1 $2"
|
||||
.test.print = echo $(if $(V),'$1','Running test $2') >&3
|
||||
# $1 = environment, $2 = test command, $3 = test name, $4 = dir
|
||||
.test-human-tap = $1 $(if $4,(cd $4 && $2),$2) < /dev/null | ./scripts/tap-driver.pl --test-name="$3" $(if $(V),,--show-failures-only)
|
||||
.test-human-exitcode = $1 $(PYTHON) scripts/test-driver.py $(if $4,-C$4) $(if $(V),--verbose) -- $2 < /dev/null
|
||||
.test-tap-tap = $1 $(if $4,(cd $4 && $2),$2) < /dev/null | sed "s/^[a-z][a-z]* [0-9]*/& $3/" || true
|
||||
.test-tap-exitcode = printf "%s\\n" 1..1 "`$1 $(if $4,(cd $4 && $2),$2) < /dev/null > /dev/null || echo "not "`ok 1 $3"
|
||||
.test.human-print = echo $(if $(V),'$1 $2','Running test $3') &&
|
||||
.test.env = MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$(( $${RANDOM:-0} % 255 + 1))}
|
||||
|
||||
# $1 = test name, $2 = test target (human or tap)
|
||||
.test.run = $(call .test.print,$(.test.cmd.$1),$(.test.name.$1)) && $(call .test-$2-$(.test.driver.$1),$(.test.cmd.$1),$(.test.name.$1))
|
||||
.test.run = $(call .test.$2-print,$(.test.env.$1),$(.test.cmd.$1),$(.test.name.$1)) $(call .test-$2-$(.test.driver.$1),$(.test.env.$1),$(.test.cmd.$1),$(.test.name.$1),$(.test.dir.$1))
|
||||
|
||||
define .test.human_k
|
||||
@exec 3>&1; rc=0; $(foreach TEST, $1, $(call .test.run,$(TEST),human) || rc=$$?;) \\
|
||||
exit $$rc
|
||||
endef
|
||||
define .test.human_no_k
|
||||
$(foreach TEST, $1, @exec 3>&1; $(call .test.run,$(TEST),human)
|
||||
)
|
||||
endef
|
||||
.test.human = \\
|
||||
$(if $(findstring k, $(MAKEFLAGS)), $(.test.human_k), $(.test.human_no_k))
|
||||
|
||||
define .test.tap
|
||||
@exec 3>&1; { $(foreach TEST, $1, $(call .test.run,$(TEST),tap); ) } \\
|
||||
| ./scripts/tap-merge.pl | tee "$@" \\
|
||||
| ./scripts/tap-driver.pl $(if $(V),, --show-failures-only)
|
||||
endef
|
||||
.test.output-format = human
|
||||
''')
|
||||
|
||||
suites = defaultdict(Suite)
|
||||
introspect = json.load(sys.stdin)
|
||||
i = 0
|
||||
for test in json.load(sys.stdin):
|
||||
|
||||
def process_tests(test, suites):
|
||||
global i
|
||||
env = ' '.join(('%s=%s' % (shlex.quote(k), shlex.quote(v))
|
||||
for k, v in test['env'].items()))
|
||||
executable = test['cmd'][0]
|
||||
@@ -65,15 +52,19 @@ for test in json.load(sys.stdin):
|
||||
test['cmd'][0] = executable
|
||||
else:
|
||||
test['cmd'][0] = executable
|
||||
cmd = '$(.test.env) %s %s' % (env, ' '.join((shlex.quote(x) for x in test['cmd'])))
|
||||
if test['workdir'] is not None:
|
||||
cmd = '(cd %s && %s)' % (shlex.quote(test['workdir']), cmd)
|
||||
cmd = ' '.join((shlex.quote(x) for x in test['cmd']))
|
||||
driver = test['protocol'] if 'protocol' in test else 'exitcode'
|
||||
|
||||
i += 1
|
||||
if test['workdir'] is not None:
|
||||
print('.test.dir.%d := %s' % (i, shlex.quote(test['workdir'])))
|
||||
print('.test.name.%d := %s' % (i, test['name']))
|
||||
print('.test.driver.%d := %s' % (i, driver))
|
||||
print('.test.env.%d := $(.test.env) %s' % (i, env))
|
||||
print('.test.cmd.%d := %s' % (i, cmd))
|
||||
print('.PHONY: run-test-%d' % (i,))
|
||||
print('run-test-%d: all' % (i,))
|
||||
print('\t@$(call .test.run,%d,$(.test.output-format))' % (i,))
|
||||
|
||||
test_suites = test['suite'] or ['default']
|
||||
is_slow = any(s.endswith('-slow') for s in test_suites)
|
||||
@@ -88,22 +79,41 @@ for test in json.load(sys.stdin):
|
||||
suites[s].tests.append(i)
|
||||
suites[s].executables.add(executable)
|
||||
|
||||
print('.PHONY: check check-report.tap')
|
||||
print('check:')
|
||||
print('check-report.tap:')
|
||||
print('\t@cat $^ | scripts/tap-merge.pl >$@')
|
||||
for name, suite in suites.items():
|
||||
def emit_prolog(suites, prefix):
|
||||
all_tap = ' '.join(('%s-report-%s.tap' % (prefix, k) for k in suites.keys()))
|
||||
print('.PHONY: %s %s-report.tap %s' % (prefix, prefix, all_tap))
|
||||
print('%s: run-tests' % (prefix,))
|
||||
print('%s-report.tap %s: %s-report%%.tap: all' % (prefix, all_tap, prefix))
|
||||
print('''\t$(MAKE) .test.output-format=tap --quiet -Otarget V=1 %s$* | ./scripts/tap-merge.pl | tee "$@" \\
|
||||
| ./scripts/tap-driver.pl $(if $(V),, --show-failures-only)''' % (prefix, ))
|
||||
|
||||
def emit_suite(name, suite, prefix):
|
||||
executables = ' '.join(suite.executables)
|
||||
slow_test_numbers = ' '.join((str(x) for x in suite.slow_tests))
|
||||
test_numbers = ' '.join((str(x) for x in suite.tests))
|
||||
print('.test.suite-quick.%s := %s' % (name, test_numbers))
|
||||
print('.test.suite-slow.%s := $(.test.suite-quick.%s) %s' % (name, name, slow_test_numbers))
|
||||
print('check-build: %s' % executables)
|
||||
print('.PHONY: check-%s' % name)
|
||||
print('.PHONY: check-report-%s.tap' % name)
|
||||
print('check: check-%s' % name)
|
||||
print('check-%s: all %s' % (name, executables))
|
||||
print('\t$(call .test.human, $(.test.suite-$(SPEED).%s))' % (name, ))
|
||||
print('check-report.tap: check-report-%s.tap' % name)
|
||||
print('check-report-%s.tap: %s' % (name, executables))
|
||||
print('\t$(call .test.tap, $(.test.suite-$(SPEED).%s))' % (name, ))
|
||||
target = '%s-%s' % (prefix, name)
|
||||
print('.test.quick.%s := %s' % (target, test_numbers))
|
||||
print('.test.slow.%s := $(.test.quick.%s) %s' % (target, target, slow_test_numbers))
|
||||
print('%s-build: %s' % (prefix, executables))
|
||||
print('.PHONY: %s' % (target, ))
|
||||
print('.PHONY: %s-report-%s.tap' % (prefix, name))
|
||||
print('%s: run-tests' % (target, ))
|
||||
print('ifneq ($(filter %s %s, $(MAKECMDGOALS)),)' % (target, prefix))
|
||||
print('.tests += $(.test.$(SPEED).%s)' % (target, ))
|
||||
print('endif')
|
||||
|
||||
testsuites = defaultdict(Suite)
|
||||
for test in introspect['tests']:
|
||||
process_tests(test, testsuites)
|
||||
emit_prolog(testsuites, 'check')
|
||||
for name, suite in testsuites.items():
|
||||
emit_suite(name, suite, 'check')
|
||||
|
||||
benchsuites = defaultdict(Suite)
|
||||
for test in introspect['benchmarks']:
|
||||
process_tests(test, benchsuites)
|
||||
emit_prolog(benchsuites, 'bench')
|
||||
for name, suite in benchsuites.items():
|
||||
emit_suite(name, suite, 'bench')
|
||||
|
||||
print('run-tests: $(patsubst %, run-test-%, $(.tests))')
|
||||
|
||||
@@ -34,6 +34,7 @@ import os
|
||||
import re
|
||||
import json
|
||||
import argparse
|
||||
import hashlib
|
||||
import shutil
|
||||
|
||||
|
||||
@@ -51,6 +52,9 @@ else:
|
||||
normpath = os.path.normpath
|
||||
|
||||
|
||||
def sha1_text(text):
|
||||
return hashlib.sha1(text.encode()).hexdigest()
|
||||
|
||||
# ---- lexer and parser ----
|
||||
|
||||
PATH_RE = r"[^$\s:|]+|\$[$ :]|\$[a-zA-Z0-9_-]+|\$\{[a-zA-Z0-9_.-]+\}"
|
||||
@@ -767,7 +771,6 @@ class Ninja2Make(NinjaParserEventsWithVars):
|
||||
self.build_vars = defaultdict(lambda: dict())
|
||||
self.rule_targets = defaultdict(lambda: list())
|
||||
self.stamp_targets = defaultdict(lambda: list())
|
||||
self.num_stamp = defaultdict(lambda: 0)
|
||||
self.all_outs = set()
|
||||
self.all_ins = set()
|
||||
self.all_phony = set()
|
||||
@@ -903,8 +906,7 @@ class Ninja2Make(NinjaParserEventsWithVars):
|
||||
if len(out) == 1:
|
||||
stamp = out[0] + '.stamp'
|
||||
else:
|
||||
stamp = '%s%d.stamp' %(rule, self.num_stamp[rule])
|
||||
self.num_stamp[rule] += 1
|
||||
stamp = '%s@%s.stamp' % (rule, sha1_text(targets)[0:11])
|
||||
self.print('%s: %s; @:' % (targets, stamp))
|
||||
self.print('%s: %s | %s; ${ninja-command-restat}' % (stamp, inputs, orderonly))
|
||||
self.rule_targets[rule].append(stamp)
|
||||
|
||||
@@ -81,7 +81,7 @@ rm qemu-fuzz-i386
|
||||
# Build a second time to build the final binary with correct rpath
|
||||
../configure --disable-werror --cc="$CC" --cxx="$CXX" --enable-fuzzing \
|
||||
--prefix="$DEST_DIR" --bindir="$DEST_DIR" --datadir="$DEST_DIR/data/" \
|
||||
--extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="-Wl,-rpath,'\$\$ORIGIN/lib'" \
|
||||
--extra-cflags="$EXTRA_CFLAGS" --extra-ldflags="-Wl,-rpath,\$ORIGIN/lib" \
|
||||
--target-list="i386-softmmu"
|
||||
make "-j$(nproc)" qemu-fuzz-i386 V=1
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#! /usr/bin/env python3
|
||||
|
||||
# Wrapper for tests that hides the output if they succeed.
|
||||
# Used by "make check"
|
||||
#
|
||||
# Copyright (C) 2020 Red Hat, Inc.
|
||||
#
|
||||
# Author: Paolo Bonzini <pbonzini@redhat.com>
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import os
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Test driver for QEMU')
|
||||
parser.add_argument('-C', metavar='DIR', dest='dir', default='.',
|
||||
help='change to DIR before doing anything else')
|
||||
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
|
||||
help='be more verbose')
|
||||
parser.add_argument('test_args', nargs=argparse.REMAINDER)
|
||||
|
||||
args = parser.parse_args()
|
||||
os.chdir(args.dir)
|
||||
|
||||
test_args = args.test_args
|
||||
if test_args[0] == '--':
|
||||
test_args = test_args[1:]
|
||||
|
||||
if args.verbose:
|
||||
result = subprocess.run(test_args, stdout=None, stderr=None)
|
||||
else:
|
||||
result = subprocess.run(test_args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
if result.returncode:
|
||||
sys.stdout.buffer.write(result.stdout)
|
||||
sys.exit(result.returncode)
|
||||
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Before a shared module's DSO is produced, a static library is built for it
|
||||
# and passed to this script. The script generates -Wl,-u options to force
|
||||
# the inclusion of symbol from libqemuutil.a if the shared modules need them,
|
||||
# This is necessary because the modules may use functions not needed by the
|
||||
# executable itself, which would cause the function to not be linked in.
|
||||
# Then the DSO loading would fail because of the missing symbol.
|
||||
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
def filter_lines_set(stdout, from_staticlib):
|
||||
linesSet = set()
|
||||
for line in stdout.splitlines():
|
||||
tokens = line.split(b' ')
|
||||
if len(tokens) >= 1:
|
||||
if len(tokens) > 1:
|
||||
if from_staticlib and tokens[1] == b'U':
|
||||
continue
|
||||
if not from_staticlib and tokens[1] != b'U':
|
||||
continue
|
||||
new_line = b'-Wl,-u,' + tokens[0]
|
||||
if not new_line in linesSet:
|
||||
linesSet.add(new_line)
|
||||
return linesSet
|
||||
|
||||
def main(args):
|
||||
if len(args) <= 3:
|
||||
sys.exit(0)
|
||||
|
||||
nm = args[1]
|
||||
staticlib = args[2]
|
||||
pc = subprocess.run([nm, "-P", "-g", staticlib], stdout=subprocess.PIPE)
|
||||
if pc.returncode != 0:
|
||||
sys.exit(1)
|
||||
staticlib_syms = filter_lines_set(pc.stdout, True)
|
||||
|
||||
shared_modules = args[3:]
|
||||
pc = subprocess.run([nm, "-P", "-g"] + shared_modules, stdout=subprocess.PIPE)
|
||||
if pc.returncode != 0:
|
||||
sys.exit(1)
|
||||
modules_undef_syms = filter_lines_set(pc.stdout, False)
|
||||
lines = sorted(staticlib_syms.intersection(modules_undef_syms))
|
||||
sys.stdout.buffer.write(b'\n'.join(lines))
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user