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:
Peter Maydell
2020-09-08 13:23:58 +01:00
38 changed files with 666 additions and 1153 deletions
-2
View File
@@ -2,8 +2,6 @@
/build/
/.doctrees
/config-devices.*
/config-all-devices.*
/config-all-disas.*
/config-host.*
/config-target.*
/config.status
+25 -38
View File
@@ -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 '$*=$($*)'
-34
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
Vendored
+38 -266
View File
File diff suppressed because it is too large Load Diff
+1 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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])
-158
View File
@@ -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 '$*=$($*)'
-3
View File
@@ -1,3 +0,0 @@
#!/bin/sh
grep -h '=y$' "$@" | sort -u
+54 -44
View File
@@ -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))')
+5 -3
View File
@@ -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)
+1 -1
View File
@@ -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
+35
View File
@@ -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)
+49
View File
@@ -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