* [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design
@ 2015-09-24 13:41 Daniel P. Berrange
2015-09-24 18:33 ` Laszlo Ersek
2015-09-25 10:05 ` Paolo Bonzini
0 siblings, 2 replies; 3+ messages in thread
From: Daniel P. Berrange @ 2015-09-24 13:41 UTC (permalink / raw)
To: qemu-devel; +Cc: John Snow, Laszlo Ersek, Paolo Bonzini
Developers who are new to QEMU, or have a background familiarity
with GNU autotools, can have trouble getting their head around the
home-grown QEMU build system. This document attempts to explain
the structure / design of the configure script and the various
Makefile pieces that live across the source tree.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
Changed in v4:
- One speling eror fix
- Listed new file in MAINTAINERS
Changed in v3:
- More speling eror fixes
- Rephrased more paragraphs as suggested
Changed in v2:
- Misc speling eror fixes
- Rephrased some paragraphs as suggested
- Added note about config-host.h file generation & use
MAINTAINERS | 8 +
docs/build-system.txt | 507 ++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 515 insertions(+)
create mode 100644 docs/build-system.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index 71c652b..654fb3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1372,3 +1372,11 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
L: qemu-block@nongnu.org
S: Supported
F: tests/image-fuzzer/
+
+
+Documentation
+-------------
+Build system architecture
+M: Daniel P. Berrange <berrange@redhat.com>
+S: Odd Fixes
+F: docs/build-system.txt
diff --git a/docs/build-system.txt b/docs/build-system.txt
new file mode 100644
index 0000000..5ddddea
--- /dev/null
+++ b/docs/build-system.txt
@@ -0,0 +1,507 @@
+ The QEMU build system architecture
+ ==================================
+
+This document aims to help developers understand the architecture of the
+QEMU build system. As with projects using GNU autotools, the QEMU build
+system has two stages, first the developer runs the "configure" script
+to determine the local build environment characteristics, then they run
+"make" to build the project. There is about where the similarities with
+GNU autotools end, so try to forget what you know about them.
+
+
+Stage 1: configure
+==================
+
+The QEMU configure script is written directly in shell, and should be
+compatible with any POSIX shell, hence it uses #!/bin/sh. An important
+implication of this is that it is important to avoid using bash-isms on
+development platforms where bash is the primary host.
+
+In contrast to autoconf scripts, QEMU's configure is expected to be
+silent while it is checking for features. It will only display output
+when an error occurs, or to show the final feature enablement summary
+on completion.
+
+Adding new checks to the configure script usually comprises the
+following tasks:
+
+ - Initialize one or more variables with the default feature state.
+
+ Ideally features should auto-detect whether they are present,
+ so try to avoid hardcoding the initial state to either enabled
+ or disabled, as that forces the user to pass a --enable-XXX
+ / --disable-XXX flag on every invocation of configure.
+
+ - Add support to the command line arg parser to handle any new
+ --enable-XXX / --disable-XXX flags required by the feature XXX.
+
+ - Add information to the help output message to report on the new
+ feature flag.
+
+ - Add code to perform the actual feature check. As noted above, try to
+ be fully dynamic in checking enablement/disablement.
+
+ - Add code to print out the feature status in the configure summary
+ upon completion.
+
+ - Add any new makefile variables to $config_host_mak on completion.
+
+
+Taking (a simplified version of) the probe for gnutls from configure,
+we have the following pieces:
+
+ # Initial variable state
+ gnutls=""
+
+ ..snip..
+
+ # Configure flag processing
+ --disable-gnutls) gnutls="no"
+ ;;
+ --enable-gnutls) gnutls="yes"
+ ;;
+
+ ..snip..
+
+ # Help output feature message
+ gnutls GNUTLS cryptography support
+
+ ..snip..
+
+ # Test for gnutls
+ if test "$gnutls" != "no"; then
+ if ! $pkg_config --exists "gnutls"; then
+ gnutls_cflags=`$pkg_config --cflags gnutls`
+ gnutls_libs=`$pkg_config --libs gnutls`
+ libs_softmmu="$gnutls_libs $libs_softmmu"
+ libs_tools="$gnutls_libs $libs_tools"
+ QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
+ gnutls="yes"
+ elif test "$gnutls" = "yes"; then
+ feature_not_found "gnutls" "Install gnutls devel"
+ else
+ gnutls="no"
+ fi
+ fi
+
+ ..snip..
+
+ # Completion feature summary
+ echo "GNUTLS support $gnutls"
+
+ ..snip..
+
+ # Define make variables
+ if test "$gnutls" = "yes" ; then
+ echo "CONFIG_GNUTLS=y" >> $config_host_mak
+ fi
+
+
+Helper functions
+----------------
+
+The configure script provides a variety of helper functions to assist
+developers in checking for system features:
+
+ - do_cc $ARGS...
+
+ Attempt to run the system C compiler passing it $ARGS...
+
+ - do_cxx $ARGS...
+
+ Attempt to run the system C++ compiler passing it $ARGS...
+
+ - 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.
+
+ - 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.
+
+ - 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.
+
+ - 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
+
+ - write_c_skeleton
+
+ Write a minimal C program main() function to the temporary file
+ indicated by $TMPC
+
+ - feature_not_found $NAME $REMEDY
+
+ Print a message to stderr that the feature $NAME was not available
+ on the system, suggesting the user try $REMEDY to address the
+ problem.
+
+ - error_exit $MESSAGE $MORE...
+
+ Print $MESSAGE to stderr, followed by $MORE... and then exit from the
+ configure script with non-zero status
+
+ - query_pkg_config $ARGS...
+
+ Run pkg-config passing it $ARGS. If QEMU is doing a static build,
+ then --static will be automatically added to $ARGS
+
+
+Stage 2: makefiles
+==================
+
+The use of GNU make is required with the QEMU build system.
+
+Although the source code is spread across multiple subdirectories, the
+build system should be considered largely non-recursive in nature, in
+contrast to common practices seen with automake. There is some recursive
+invocation of make, but this is related to the things being built,
+rather than the source directory structure.
+
+QEMU currently supports both VPATH and non-VPATH builds, so there are
+three general ways to invoke configure & perform a build.
+
+ - VPATH, build artifacts outside of QEMU source tree entirely
+
+ cd ../
+ mkdir build
+ cd build
+ ../qemu/configure
+ make
+
+ - VPATH, build artifacts in a subdir of QEMU source tree
+
+ mkdir build
+ cd build
+ ../configure
+ make
+
+ - non-VPATH, build artifacts everywhere
+
+ ./configure
+ make
+
+The QEMU maintainers generally recommend that a VPATH build is used by
+developers. Patches to QEMU are expected to ensure VPATH build still
+works.
+
+
+Module structure
+----------------
+
+There are a number of key outputs of the QEMU build system:
+
+ - Tools - qemu-img, qemu-nbd, qga (guest agent), etc
+ - System emulators - qemu-system-$ARCH
+ - Userspace emulators - qemu-$ARCH
+ - Unit tests
+
+The source code is highly modularized, split across many files to
+facilitate building of all of these components with as little duplicated
+compilation as possible. There can be considered to be two distinct
+groups of files, those which are independent of the QEMU emulation
+target and those which are dependent on the QEMU emulation target.
+
+In the target-independent set lives various general purpose helper code,
+such as error handling infrastructure, standard data structures,
+platform portability wrapper functions, etc. This code can be compiled
+once only and the .o files linked into all output binaries.
+
+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.
+
+The utility code that is used by all binaries is built into a
+static archive called libqemuutil.a, which is then linked to all the
+binaries. In order to provide hooks that are only needed by some of the
+binaries, code in libqemuutil.a may depend on other functions that are
+not fully implemented by all QEMU binaries. To deal with this there is a
+second library called libqemustub.a which provides dummy stubs for all
+these functions. These will get lazy linked into the binary if the real
+implementation is not present. In this way, the libqemustub.a static
+library can be thought of as a portable implementation of the weak
+symbols concept. All binaries should link to both libqemuutil.a and
+libqemustub.a. e.g.
+
+ qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a libqemustub.a
+
+
+Windows platform portability
+----------------------------
+
+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 '' on other platforms.
+
+A further complication for the system emulator binaries is that
+two separate binaries need to be generated.
+
+The main binary (e.g. qemu-system-x86_64.exe) is linked against the
+Windows console runtime subsystem. These are expected to be run from a
+command prompt window, and so will print stderr to the console that
+launched them.
+
+The second binary generated has a 'w' on the end of its name (e.g.
+qemu-system-x86_64w.exe) and is linked against the Windows graphical
+runtime subsystem. These are expected to be run directly from the
+desktop and will open up a dedicated console window for stderr output.
+
+The Makefile.target will generate the binary for the graphical subsystem
+first, and then use objcopy to relink it against the console subsystem
+to generate the second binary.
+
+
+Object 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. For
+example the libqemuutil.a file will be linked with all objects listed
+in a variable 'util-obj-y'. So, for example, util/Makefile.obj will
+contain a set of definitions looking like
+
+ util-obj-y += bitmap.o bitops.o hbitmap.o
+ util-obj-y += fifo8.o
+ util-obj-y += acl.o
+ util-obj-y += error.o qemu-error.o
+
+When there is an 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,
+
+ util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
+ util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
+
+On Windows this expands to
+
+ util-obj-y += oslib-win32.o qemu-thread-win32.o
+ util-obj-n += oslib-posix.o qemu-thread-posix.o
+
+Since libqemutil.a links in $(util-obj-y), the POSIX specific files
+listed against $(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. $(libs_softmmu) is used for
+libraries that must be linked to system emulator targets, $(LIBS_TOOLS)
+is used for tools like qemu-img, qemu-nbd, etc and $(LIBS_QGA) is used
+for the QEMU guest agent. There is currently no specific variable for
+the userspace emulator targets as the global $(LIBS), or more targeted
+variables shown below, are sufficient.
+
+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 curl block
+driver needs to link to the libcurl library, so block/Makefile defines
+some variables:
+
+ curl.o-cflags := $(CURL_CFLAGS)
+ curl.o-libs := $(CURL_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.
+
+
+Statically defined files
+------------------------
+
+The following key files are statically defined in the source tree, with
+the rules needed to build QEMU. Their behaviour is influenced by a
+number of dynamically created files listed later.
+
+- Makefile
+
+The main entry point used when invoking make to build all the components
+of QEMU. The default 'all' target will naturally result in the build of
+every component. The various tools and helper binaries are built
+directly via a non-recursive set of rules.
+
+Each system/userspace emulation target needs to have a slightly
+different set of make rules / variables. Thus, make will be recursively
+invoked for each of the emulation targets.
+
+The recursive invocation will end up processing the toplevel
+Makefile.target file (more on that later).
+
+
+- */Makefile.objs
+
+Since the source code is spread across multiple directories, the rules
+for each file are similarly modularized. Thus each subdirectory
+containing .c files will usually also contain a Makefile.objs file.
+These files are not directly invoked by a recursive make, but instead
+they are imported by the top level Makefile and/or Makefile.target
+
+Each Makefile.objs usually just declares a set of variables listing the
+.o files that need building from the source files in the directory. They
+will also define any custom linker or compiler flags. For example in
+block/Makefile.objs
+
+ block-obj-$(CONFIG_LIBISCSI) += iscsi.o
+ block-obj-$(CONFIG_CURL) += curl.o
+
+ ..snip...
+
+ iscsi.o-cflags := $(LIBISCSI_CFLAGS)
+ iscsi.o-libs := $(LIBISCSI_LIBS)
+ curl.o-cflags := $(CURL_CFLAGS)
+ curl.o-libs := $(CURL_LIBS)
+
+If there are any rules defined in the Makefile.objs file, they should
+all use $(obj) as a prefix to the target, e.g.
+
+ $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
+
+
+- Makefile.target
+
+This file provides the entry point used to build each individual system
+or userspace emulator target. Each enabled target has its own
+subdirectory. For example if configure is run with the argument
+'--target-list=x86_64-softmmu', then a sub-directory 'x86_64-softmu'
+will be created, containing a 'Makefile' which symlinks back to
+Makefile.target
+
+So when the recursive '$(MAKE) -C x86_64-softmmu' is invoked, it ends up
+using Makefile.target for the build rules.
+
+
+- rules.mak
+
+This file provides the generic helper rules for invoking build tools, in
+particular the compiler and linker. This also contains the magic (hairy)
+'unnest-vars' function which is used to merge the variable definitions
+from all Makefile.objs in the source tree down into the main Makefile
+context.
+
+
+- default-configs/*.mak
+
+The files under default-configs/ control what emulated hardware is built
+into each QEMU system and userspace emulator targets. They merely
+contain a long list of config variable definitions. For example,
+default-configs/x86_64-softmmu.mak has:
+
+ include pci.mak
+ include sound.mak
+ include usb.mak
+ CONFIG_QXL=$(CONFIG_SPICE)
+ CONFIG_VGA_ISA=y
+ CONFIG_VGA_CIRRUS=y
+ CONFIG_VMWARE_VGA=y
+ CONFIG_VIRTIO_VGA=y
+ ...snip...
+
+These files rarely need changing unless new devices / hardware need to
+be enabled for a particular system/userspace emulation target
+
+
+- tests/Makefile
+
+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.
+
+
+- po/Makefile
+
+Rules for building and installing the binary message catalogs from the
+text .po file sources. This almost never needs changing for any reason.
+
+
+Dynamically created files
+-------------------------
+
+The following files are generated dynamically by configure in order to
+control the behaviour of the statically defined makefiles. This avoids
+the need for QEMU makefiles to go through any pre-processing as seen
+with autotools, where Makefile.am generates Makefile.in which generates
+Makefile.
+
+
+- config-host.mak
+
+When configure has determined the characteristics of the build host it
+will write a long list of variables to config-host.mak file. This
+provides the various install directories, compiler / linker flags and a
+variety of CONFIG_* variables related to optionally enabled features.
+This is imported by the top level Makefile in order to tailor the build
+output.
+
+The variables defined here are those which are applicable to all QEMU
+build outputs. Variables which are potentially different for each
+emulator target are defined by the next file...
+
+It is also used as a dependency checking mechanism. If make sees that
+the modification timestamp on configure is newer than that on
+config-host.mak, then configure will be re-run.
+
+
+- config-host.h
+
+The config-host.h file is used by source code to determine what features
+are enabled. It is generated from the contents of config-host.mak using
+the scripts/create_config program. This extracts all the CONFIG_* variables,
+most of the HOST_* variables and a few other misc variables from
+config-host.mak, formatting them as C preprocessor macros.
+
+
+- $TARGET-NAME/config-target.mak
+
+TARGET-NAME is the name of a system or userspace emulator, for example,
+x86_64-softmmu denotes the system emulator for the x86_64 architecture.
+This file contains the variables which need to vary on a per-target
+basis. For example, it will indicate whether KVM or Xen are enabled for
+the target and any other potential custom libraries needed for linking
+the target.
+
+
+- $TARGET-NAME/config-devices.mak
+
+TARGET-NAME is again the name of a system or userspace emulator. The
+config-devices.mak file is automatically generated by make using the
+scripts/make_device_config.sh program, feeding it the
+default-configs/$TARGET-NAME file as input.
+
+
+- $TARGET-NAME/Makefile
+
+This is the entrypoint used when make recurses to build a single system
+or userspace emulator target. It is merely a symlink back to the
+Makefile.target in the top level.
--
2.4.3
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design
2015-09-24 13:41 [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design Daniel P. Berrange
@ 2015-09-24 18:33 ` Laszlo Ersek
2015-09-25 10:05 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Laszlo Ersek @ 2015-09-24 18:33 UTC (permalink / raw)
To: Daniel P. Berrange, qemu-devel; +Cc: Paolo Bonzini, John Snow
On 09/24/15 15:41, Daniel P. Berrange wrote:
> Developers who are new to QEMU, or have a background familiarity
> with GNU autotools, can have trouble getting their head around the
> home-grown QEMU build system. This document attempts to explain
> the structure / design of the configure script and the various
> Makefile pieces that live across the source tree.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
> Changed in v4:
>
> - One speling eror fix
> - Listed new file in MAINTAINERS
Acked-by: Laszlo Ersek <lersek@redhat.com>
Thank you,
Laszlo
>
> Changed in v3:
>
> - More speling eror fixes
> - Rephrased more paragraphs as suggested
>
> Changed in v2:
>
> - Misc speling eror fixes
> - Rephrased some paragraphs as suggested
> - Added note about config-host.h file generation & use
>
> MAINTAINERS | 8 +
> docs/build-system.txt | 507 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 515 insertions(+)
> create mode 100644 docs/build-system.txt
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 71c652b..654fb3c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1372,3 +1372,11 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
> L: qemu-block@nongnu.org
> S: Supported
> F: tests/image-fuzzer/
> +
> +
> +Documentation
> +-------------
> +Build system architecture
> +M: Daniel P. Berrange <berrange@redhat.com>
> +S: Odd Fixes
> +F: docs/build-system.txt
> diff --git a/docs/build-system.txt b/docs/build-system.txt
> new file mode 100644
> index 0000000..5ddddea
> --- /dev/null
> +++ b/docs/build-system.txt
> @@ -0,0 +1,507 @@
> + The QEMU build system architecture
> + ==================================
> +
> +This document aims to help developers understand the architecture of the
> +QEMU build system. As with projects using GNU autotools, the QEMU build
> +system has two stages, first the developer runs the "configure" script
> +to determine the local build environment characteristics, then they run
> +"make" to build the project. There is about where the similarities with
> +GNU autotools end, so try to forget what you know about them.
> +
> +
> +Stage 1: configure
> +==================
> +
> +The QEMU configure script is written directly in shell, and should be
> +compatible with any POSIX shell, hence it uses #!/bin/sh. An important
> +implication of this is that it is important to avoid using bash-isms on
> +development platforms where bash is the primary host.
> +
> +In contrast to autoconf scripts, QEMU's configure is expected to be
> +silent while it is checking for features. It will only display output
> +when an error occurs, or to show the final feature enablement summary
> +on completion.
> +
> +Adding new checks to the configure script usually comprises the
> +following tasks:
> +
> + - Initialize one or more variables with the default feature state.
> +
> + Ideally features should auto-detect whether they are present,
> + so try to avoid hardcoding the initial state to either enabled
> + or disabled, as that forces the user to pass a --enable-XXX
> + / --disable-XXX flag on every invocation of configure.
> +
> + - Add support to the command line arg parser to handle any new
> + --enable-XXX / --disable-XXX flags required by the feature XXX.
> +
> + - Add information to the help output message to report on the new
> + feature flag.
> +
> + - Add code to perform the actual feature check. As noted above, try to
> + be fully dynamic in checking enablement/disablement.
> +
> + - Add code to print out the feature status in the configure summary
> + upon completion.
> +
> + - Add any new makefile variables to $config_host_mak on completion.
> +
> +
> +Taking (a simplified version of) the probe for gnutls from configure,
> +we have the following pieces:
> +
> + # Initial variable state
> + gnutls=""
> +
> + ..snip..
> +
> + # Configure flag processing
> + --disable-gnutls) gnutls="no"
> + ;;
> + --enable-gnutls) gnutls="yes"
> + ;;
> +
> + ..snip..
> +
> + # Help output feature message
> + gnutls GNUTLS cryptography support
> +
> + ..snip..
> +
> + # Test for gnutls
> + if test "$gnutls" != "no"; then
> + if ! $pkg_config --exists "gnutls"; then
> + gnutls_cflags=`$pkg_config --cflags gnutls`
> + gnutls_libs=`$pkg_config --libs gnutls`
> + libs_softmmu="$gnutls_libs $libs_softmmu"
> + libs_tools="$gnutls_libs $libs_tools"
> + QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
> + gnutls="yes"
> + elif test "$gnutls" = "yes"; then
> + feature_not_found "gnutls" "Install gnutls devel"
> + else
> + gnutls="no"
> + fi
> + fi
> +
> + ..snip..
> +
> + # Completion feature summary
> + echo "GNUTLS support $gnutls"
> +
> + ..snip..
> +
> + # Define make variables
> + if test "$gnutls" = "yes" ; then
> + echo "CONFIG_GNUTLS=y" >> $config_host_mak
> + fi
> +
> +
> +Helper functions
> +----------------
> +
> +The configure script provides a variety of helper functions to assist
> +developers in checking for system features:
> +
> + - do_cc $ARGS...
> +
> + Attempt to run the system C compiler passing it $ARGS...
> +
> + - do_cxx $ARGS...
> +
> + Attempt to run the system C++ compiler passing it $ARGS...
> +
> + - 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.
> +
> + - 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.
> +
> + - 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.
> +
> + - 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
> +
> + - write_c_skeleton
> +
> + Write a minimal C program main() function to the temporary file
> + indicated by $TMPC
> +
> + - feature_not_found $NAME $REMEDY
> +
> + Print a message to stderr that the feature $NAME was not available
> + on the system, suggesting the user try $REMEDY to address the
> + problem.
> +
> + - error_exit $MESSAGE $MORE...
> +
> + Print $MESSAGE to stderr, followed by $MORE... and then exit from the
> + configure script with non-zero status
> +
> + - query_pkg_config $ARGS...
> +
> + Run pkg-config passing it $ARGS. If QEMU is doing a static build,
> + then --static will be automatically added to $ARGS
> +
> +
> +Stage 2: makefiles
> +==================
> +
> +The use of GNU make is required with the QEMU build system.
> +
> +Although the source code is spread across multiple subdirectories, the
> +build system should be considered largely non-recursive in nature, in
> +contrast to common practices seen with automake. There is some recursive
> +invocation of make, but this is related to the things being built,
> +rather than the source directory structure.
> +
> +QEMU currently supports both VPATH and non-VPATH builds, so there are
> +three general ways to invoke configure & perform a build.
> +
> + - VPATH, build artifacts outside of QEMU source tree entirely
> +
> + cd ../
> + mkdir build
> + cd build
> + ../qemu/configure
> + make
> +
> + - VPATH, build artifacts in a subdir of QEMU source tree
> +
> + mkdir build
> + cd build
> + ../configure
> + make
> +
> + - non-VPATH, build artifacts everywhere
> +
> + ./configure
> + make
> +
> +The QEMU maintainers generally recommend that a VPATH build is used by
> +developers. Patches to QEMU are expected to ensure VPATH build still
> +works.
> +
> +
> +Module structure
> +----------------
> +
> +There are a number of key outputs of the QEMU build system:
> +
> + - Tools - qemu-img, qemu-nbd, qga (guest agent), etc
> + - System emulators - qemu-system-$ARCH
> + - Userspace emulators - qemu-$ARCH
> + - Unit tests
> +
> +The source code is highly modularized, split across many files to
> +facilitate building of all of these components with as little duplicated
> +compilation as possible. There can be considered to be two distinct
> +groups of files, those which are independent of the QEMU emulation
> +target and those which are dependent on the QEMU emulation target.
> +
> +In the target-independent set lives various general purpose helper code,
> +such as error handling infrastructure, standard data structures,
> +platform portability wrapper functions, etc. This code can be compiled
> +once only and the .o files linked into all output binaries.
> +
> +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.
> +
> +The utility code that is used by all binaries is built into a
> +static archive called libqemuutil.a, which is then linked to all the
> +binaries. In order to provide hooks that are only needed by some of the
> +binaries, code in libqemuutil.a may depend on other functions that are
> +not fully implemented by all QEMU binaries. To deal with this there is a
> +second library called libqemustub.a which provides dummy stubs for all
> +these functions. These will get lazy linked into the binary if the real
> +implementation is not present. In this way, the libqemustub.a static
> +library can be thought of as a portable implementation of the weak
> +symbols concept. All binaries should link to both libqemuutil.a and
> +libqemustub.a. e.g.
> +
> + qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a libqemustub.a
> +
> +
> +Windows platform portability
> +----------------------------
> +
> +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 '' on other platforms.
> +
> +A further complication for the system emulator binaries is that
> +two separate binaries need to be generated.
> +
> +The main binary (e.g. qemu-system-x86_64.exe) is linked against the
> +Windows console runtime subsystem. These are expected to be run from a
> +command prompt window, and so will print stderr to the console that
> +launched them.
> +
> +The second binary generated has a 'w' on the end of its name (e.g.
> +qemu-system-x86_64w.exe) and is linked against the Windows graphical
> +runtime subsystem. These are expected to be run directly from the
> +desktop and will open up a dedicated console window for stderr output.
> +
> +The Makefile.target will generate the binary for the graphical subsystem
> +first, and then use objcopy to relink it against the console subsystem
> +to generate the second binary.
> +
> +
> +Object 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. For
> +example the libqemuutil.a file will be linked with all objects listed
> +in a variable 'util-obj-y'. So, for example, util/Makefile.obj will
> +contain a set of definitions looking like
> +
> + util-obj-y += bitmap.o bitops.o hbitmap.o
> + util-obj-y += fifo8.o
> + util-obj-y += acl.o
> + util-obj-y += error.o qemu-error.o
> +
> +When there is an 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,
> +
> + util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
> + util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
> +
> +On Windows this expands to
> +
> + util-obj-y += oslib-win32.o qemu-thread-win32.o
> + util-obj-n += oslib-posix.o qemu-thread-posix.o
> +
> +Since libqemutil.a links in $(util-obj-y), the POSIX specific files
> +listed against $(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. $(libs_softmmu) is used for
> +libraries that must be linked to system emulator targets, $(LIBS_TOOLS)
> +is used for tools like qemu-img, qemu-nbd, etc and $(LIBS_QGA) is used
> +for the QEMU guest agent. There is currently no specific variable for
> +the userspace emulator targets as the global $(LIBS), or more targeted
> +variables shown below, are sufficient.
> +
> +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 curl block
> +driver needs to link to the libcurl library, so block/Makefile defines
> +some variables:
> +
> + curl.o-cflags := $(CURL_CFLAGS)
> + curl.o-libs := $(CURL_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.
> +
> +
> +Statically defined files
> +------------------------
> +
> +The following key files are statically defined in the source tree, with
> +the rules needed to build QEMU. Their behaviour is influenced by a
> +number of dynamically created files listed later.
> +
> +- Makefile
> +
> +The main entry point used when invoking make to build all the components
> +of QEMU. The default 'all' target will naturally result in the build of
> +every component. The various tools and helper binaries are built
> +directly via a non-recursive set of rules.
> +
> +Each system/userspace emulation target needs to have a slightly
> +different set of make rules / variables. Thus, make will be recursively
> +invoked for each of the emulation targets.
> +
> +The recursive invocation will end up processing the toplevel
> +Makefile.target file (more on that later).
> +
> +
> +- */Makefile.objs
> +
> +Since the source code is spread across multiple directories, the rules
> +for each file are similarly modularized. Thus each subdirectory
> +containing .c files will usually also contain a Makefile.objs file.
> +These files are not directly invoked by a recursive make, but instead
> +they are imported by the top level Makefile and/or Makefile.target
> +
> +Each Makefile.objs usually just declares a set of variables listing the
> +.o files that need building from the source files in the directory. They
> +will also define any custom linker or compiler flags. For example in
> +block/Makefile.objs
> +
> + block-obj-$(CONFIG_LIBISCSI) += iscsi.o
> + block-obj-$(CONFIG_CURL) += curl.o
> +
> + ..snip...
> +
> + iscsi.o-cflags := $(LIBISCSI_CFLAGS)
> + iscsi.o-libs := $(LIBISCSI_LIBS)
> + curl.o-cflags := $(CURL_CFLAGS)
> + curl.o-libs := $(CURL_LIBS)
> +
> +If there are any rules defined in the Makefile.objs file, they should
> +all use $(obj) as a prefix to the target, e.g.
> +
> + $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
> +
> +
> +- Makefile.target
> +
> +This file provides the entry point used to build each individual system
> +or userspace emulator target. Each enabled target has its own
> +subdirectory. For example if configure is run with the argument
> +'--target-list=x86_64-softmmu', then a sub-directory 'x86_64-softmu'
> +will be created, containing a 'Makefile' which symlinks back to
> +Makefile.target
> +
> +So when the recursive '$(MAKE) -C x86_64-softmmu' is invoked, it ends up
> +using Makefile.target for the build rules.
> +
> +
> +- rules.mak
> +
> +This file provides the generic helper rules for invoking build tools, in
> +particular the compiler and linker. This also contains the magic (hairy)
> +'unnest-vars' function which is used to merge the variable definitions
> +from all Makefile.objs in the source tree down into the main Makefile
> +context.
> +
> +
> +- default-configs/*.mak
> +
> +The files under default-configs/ control what emulated hardware is built
> +into each QEMU system and userspace emulator targets. They merely
> +contain a long list of config variable definitions. For example,
> +default-configs/x86_64-softmmu.mak has:
> +
> + include pci.mak
> + include sound.mak
> + include usb.mak
> + CONFIG_QXL=$(CONFIG_SPICE)
> + CONFIG_VGA_ISA=y
> + CONFIG_VGA_CIRRUS=y
> + CONFIG_VMWARE_VGA=y
> + CONFIG_VIRTIO_VGA=y
> + ...snip...
> +
> +These files rarely need changing unless new devices / hardware need to
> +be enabled for a particular system/userspace emulation target
> +
> +
> +- tests/Makefile
> +
> +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.
> +
> +
> +- po/Makefile
> +
> +Rules for building and installing the binary message catalogs from the
> +text .po file sources. This almost never needs changing for any reason.
> +
> +
> +Dynamically created files
> +-------------------------
> +
> +The following files are generated dynamically by configure in order to
> +control the behaviour of the statically defined makefiles. This avoids
> +the need for QEMU makefiles to go through any pre-processing as seen
> +with autotools, where Makefile.am generates Makefile.in which generates
> +Makefile.
> +
> +
> +- config-host.mak
> +
> +When configure has determined the characteristics of the build host it
> +will write a long list of variables to config-host.mak file. This
> +provides the various install directories, compiler / linker flags and a
> +variety of CONFIG_* variables related to optionally enabled features.
> +This is imported by the top level Makefile in order to tailor the build
> +output.
> +
> +The variables defined here are those which are applicable to all QEMU
> +build outputs. Variables which are potentially different for each
> +emulator target are defined by the next file...
> +
> +It is also used as a dependency checking mechanism. If make sees that
> +the modification timestamp on configure is newer than that on
> +config-host.mak, then configure will be re-run.
> +
> +
> +- config-host.h
> +
> +The config-host.h file is used by source code to determine what features
> +are enabled. It is generated from the contents of config-host.mak using
> +the scripts/create_config program. This extracts all the CONFIG_* variables,
> +most of the HOST_* variables and a few other misc variables from
> +config-host.mak, formatting them as C preprocessor macros.
> +
> +
> +- $TARGET-NAME/config-target.mak
> +
> +TARGET-NAME is the name of a system or userspace emulator, for example,
> +x86_64-softmmu denotes the system emulator for the x86_64 architecture.
> +This file contains the variables which need to vary on a per-target
> +basis. For example, it will indicate whether KVM or Xen are enabled for
> +the target and any other potential custom libraries needed for linking
> +the target.
> +
> +
> +- $TARGET-NAME/config-devices.mak
> +
> +TARGET-NAME is again the name of a system or userspace emulator. The
> +config-devices.mak file is automatically generated by make using the
> +scripts/make_device_config.sh program, feeding it the
> +default-configs/$TARGET-NAME file as input.
> +
> +
> +- $TARGET-NAME/Makefile
> +
> +This is the entrypoint used when make recurses to build a single system
> +or userspace emulator target. It is merely a symlink back to the
> +Makefile.target in the top level.
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design
2015-09-24 13:41 [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design Daniel P. Berrange
2015-09-24 18:33 ` Laszlo Ersek
@ 2015-09-25 10:05 ` Paolo Bonzini
1 sibling, 0 replies; 3+ messages in thread
From: Paolo Bonzini @ 2015-09-25 10:05 UTC (permalink / raw)
To: Daniel P. Berrange, qemu-devel; +Cc: Laszlo Ersek, John Snow
On 24/09/2015 15:41, Daniel P. Berrange wrote:
> Developers who are new to QEMU, or have a background familiarity
> with GNU autotools, can have trouble getting their head around the
> home-grown QEMU build system. This document attempts to explain
> the structure / design of the configure script and the various
> Makefile pieces that live across the source tree.
>
> Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
> ---
> Changed in v4:
>
> - One speling eror fix
> - Listed new file in MAINTAINERS
>
> Changed in v3:
>
> - More speling eror fixes
> - Rephrased more paragraphs as suggested
>
> Changed in v2:
>
> - Misc speling eror fixes
> - Rephrased some paragraphs as suggested
> - Added note about config-host.h file generation & use
Thanks, will send a pull request with this soon.
Paolo
> MAINTAINERS | 8 +
> docs/build-system.txt | 507 ++++++++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 515 insertions(+)
> create mode 100644 docs/build-system.txt
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 71c652b..654fb3c 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1372,3 +1372,11 @@ M: Stefan Hajnoczi <stefanha@redhat.com>
> L: qemu-block@nongnu.org
> S: Supported
> F: tests/image-fuzzer/
> +
> +
> +Documentation
> +-------------
> +Build system architecture
> +M: Daniel P. Berrange <berrange@redhat.com>
> +S: Odd Fixes
> +F: docs/build-system.txt
> diff --git a/docs/build-system.txt b/docs/build-system.txt
> new file mode 100644
> index 0000000..5ddddea
> --- /dev/null
> +++ b/docs/build-system.txt
> @@ -0,0 +1,507 @@
> + The QEMU build system architecture
> + ==================================
> +
> +This document aims to help developers understand the architecture of the
> +QEMU build system. As with projects using GNU autotools, the QEMU build
> +system has two stages, first the developer runs the "configure" script
> +to determine the local build environment characteristics, then they run
> +"make" to build the project. There is about where the similarities with
> +GNU autotools end, so try to forget what you know about them.
> +
> +
> +Stage 1: configure
> +==================
> +
> +The QEMU configure script is written directly in shell, and should be
> +compatible with any POSIX shell, hence it uses #!/bin/sh. An important
> +implication of this is that it is important to avoid using bash-isms on
> +development platforms where bash is the primary host.
> +
> +In contrast to autoconf scripts, QEMU's configure is expected to be
> +silent while it is checking for features. It will only display output
> +when an error occurs, or to show the final feature enablement summary
> +on completion.
> +
> +Adding new checks to the configure script usually comprises the
> +following tasks:
> +
> + - Initialize one or more variables with the default feature state.
> +
> + Ideally features should auto-detect whether they are present,
> + so try to avoid hardcoding the initial state to either enabled
> + or disabled, as that forces the user to pass a --enable-XXX
> + / --disable-XXX flag on every invocation of configure.
> +
> + - Add support to the command line arg parser to handle any new
> + --enable-XXX / --disable-XXX flags required by the feature XXX.
> +
> + - Add information to the help output message to report on the new
> + feature flag.
> +
> + - Add code to perform the actual feature check. As noted above, try to
> + be fully dynamic in checking enablement/disablement.
> +
> + - Add code to print out the feature status in the configure summary
> + upon completion.
> +
> + - Add any new makefile variables to $config_host_mak on completion.
> +
> +
> +Taking (a simplified version of) the probe for gnutls from configure,
> +we have the following pieces:
> +
> + # Initial variable state
> + gnutls=""
> +
> + ..snip..
> +
> + # Configure flag processing
> + --disable-gnutls) gnutls="no"
> + ;;
> + --enable-gnutls) gnutls="yes"
> + ;;
> +
> + ..snip..
> +
> + # Help output feature message
> + gnutls GNUTLS cryptography support
> +
> + ..snip..
> +
> + # Test for gnutls
> + if test "$gnutls" != "no"; then
> + if ! $pkg_config --exists "gnutls"; then
> + gnutls_cflags=`$pkg_config --cflags gnutls`
> + gnutls_libs=`$pkg_config --libs gnutls`
> + libs_softmmu="$gnutls_libs $libs_softmmu"
> + libs_tools="$gnutls_libs $libs_tools"
> + QEMU_CFLAGS="$QEMU_CFLAGS $gnutls_cflags"
> + gnutls="yes"
> + elif test "$gnutls" = "yes"; then
> + feature_not_found "gnutls" "Install gnutls devel"
> + else
> + gnutls="no"
> + fi
> + fi
> +
> + ..snip..
> +
> + # Completion feature summary
> + echo "GNUTLS support $gnutls"
> +
> + ..snip..
> +
> + # Define make variables
> + if test "$gnutls" = "yes" ; then
> + echo "CONFIG_GNUTLS=y" >> $config_host_mak
> + fi
> +
> +
> +Helper functions
> +----------------
> +
> +The configure script provides a variety of helper functions to assist
> +developers in checking for system features:
> +
> + - do_cc $ARGS...
> +
> + Attempt to run the system C compiler passing it $ARGS...
> +
> + - do_cxx $ARGS...
> +
> + Attempt to run the system C++ compiler passing it $ARGS...
> +
> + - 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.
> +
> + - 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.
> +
> + - 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.
> +
> + - 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
> +
> + - write_c_skeleton
> +
> + Write a minimal C program main() function to the temporary file
> + indicated by $TMPC
> +
> + - feature_not_found $NAME $REMEDY
> +
> + Print a message to stderr that the feature $NAME was not available
> + on the system, suggesting the user try $REMEDY to address the
> + problem.
> +
> + - error_exit $MESSAGE $MORE...
> +
> + Print $MESSAGE to stderr, followed by $MORE... and then exit from the
> + configure script with non-zero status
> +
> + - query_pkg_config $ARGS...
> +
> + Run pkg-config passing it $ARGS. If QEMU is doing a static build,
> + then --static will be automatically added to $ARGS
> +
> +
> +Stage 2: makefiles
> +==================
> +
> +The use of GNU make is required with the QEMU build system.
> +
> +Although the source code is spread across multiple subdirectories, the
> +build system should be considered largely non-recursive in nature, in
> +contrast to common practices seen with automake. There is some recursive
> +invocation of make, but this is related to the things being built,
> +rather than the source directory structure.
> +
> +QEMU currently supports both VPATH and non-VPATH builds, so there are
> +three general ways to invoke configure & perform a build.
> +
> + - VPATH, build artifacts outside of QEMU source tree entirely
> +
> + cd ../
> + mkdir build
> + cd build
> + ../qemu/configure
> + make
> +
> + - VPATH, build artifacts in a subdir of QEMU source tree
> +
> + mkdir build
> + cd build
> + ../configure
> + make
> +
> + - non-VPATH, build artifacts everywhere
> +
> + ./configure
> + make
> +
> +The QEMU maintainers generally recommend that a VPATH build is used by
> +developers. Patches to QEMU are expected to ensure VPATH build still
> +works.
> +
> +
> +Module structure
> +----------------
> +
> +There are a number of key outputs of the QEMU build system:
> +
> + - Tools - qemu-img, qemu-nbd, qga (guest agent), etc
> + - System emulators - qemu-system-$ARCH
> + - Userspace emulators - qemu-$ARCH
> + - Unit tests
> +
> +The source code is highly modularized, split across many files to
> +facilitate building of all of these components with as little duplicated
> +compilation as possible. There can be considered to be two distinct
> +groups of files, those which are independent of the QEMU emulation
> +target and those which are dependent on the QEMU emulation target.
> +
> +In the target-independent set lives various general purpose helper code,
> +such as error handling infrastructure, standard data structures,
> +platform portability wrapper functions, etc. This code can be compiled
> +once only and the .o files linked into all output binaries.
> +
> +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.
> +
> +The utility code that is used by all binaries is built into a
> +static archive called libqemuutil.a, which is then linked to all the
> +binaries. In order to provide hooks that are only needed by some of the
> +binaries, code in libqemuutil.a may depend on other functions that are
> +not fully implemented by all QEMU binaries. To deal with this there is a
> +second library called libqemustub.a which provides dummy stubs for all
> +these functions. These will get lazy linked into the binary if the real
> +implementation is not present. In this way, the libqemustub.a static
> +library can be thought of as a portable implementation of the weak
> +symbols concept. All binaries should link to both libqemuutil.a and
> +libqemustub.a. e.g.
> +
> + qemu-img$(EXESUF): qemu-img.o ..snip.. libqemuutil.a libqemustub.a
> +
> +
> +Windows platform portability
> +----------------------------
> +
> +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 '' on other platforms.
> +
> +A further complication for the system emulator binaries is that
> +two separate binaries need to be generated.
> +
> +The main binary (e.g. qemu-system-x86_64.exe) is linked against the
> +Windows console runtime subsystem. These are expected to be run from a
> +command prompt window, and so will print stderr to the console that
> +launched them.
> +
> +The second binary generated has a 'w' on the end of its name (e.g.
> +qemu-system-x86_64w.exe) and is linked against the Windows graphical
> +runtime subsystem. These are expected to be run directly from the
> +desktop and will open up a dedicated console window for stderr output.
> +
> +The Makefile.target will generate the binary for the graphical subsystem
> +first, and then use objcopy to relink it against the console subsystem
> +to generate the second binary.
> +
> +
> +Object 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. For
> +example the libqemuutil.a file will be linked with all objects listed
> +in a variable 'util-obj-y'. So, for example, util/Makefile.obj will
> +contain a set of definitions looking like
> +
> + util-obj-y += bitmap.o bitops.o hbitmap.o
> + util-obj-y += fifo8.o
> + util-obj-y += acl.o
> + util-obj-y += error.o qemu-error.o
> +
> +When there is an 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,
> +
> + util-obj-$(CONFIG_WIN32) += oslib-win32.o qemu-thread-win32.o
> + util-obj-$(CONFIG_POSIX) += oslib-posix.o qemu-thread-posix.o
> +
> +On Windows this expands to
> +
> + util-obj-y += oslib-win32.o qemu-thread-win32.o
> + util-obj-n += oslib-posix.o qemu-thread-posix.o
> +
> +Since libqemutil.a links in $(util-obj-y), the POSIX specific files
> +listed against $(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. $(libs_softmmu) is used for
> +libraries that must be linked to system emulator targets, $(LIBS_TOOLS)
> +is used for tools like qemu-img, qemu-nbd, etc and $(LIBS_QGA) is used
> +for the QEMU guest agent. There is currently no specific variable for
> +the userspace emulator targets as the global $(LIBS), or more targeted
> +variables shown below, are sufficient.
> +
> +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 curl block
> +driver needs to link to the libcurl library, so block/Makefile defines
> +some variables:
> +
> + curl.o-cflags := $(CURL_CFLAGS)
> + curl.o-libs := $(CURL_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.
> +
> +
> +Statically defined files
> +------------------------
> +
> +The following key files are statically defined in the source tree, with
> +the rules needed to build QEMU. Their behaviour is influenced by a
> +number of dynamically created files listed later.
> +
> +- Makefile
> +
> +The main entry point used when invoking make to build all the components
> +of QEMU. The default 'all' target will naturally result in the build of
> +every component. The various tools and helper binaries are built
> +directly via a non-recursive set of rules.
> +
> +Each system/userspace emulation target needs to have a slightly
> +different set of make rules / variables. Thus, make will be recursively
> +invoked for each of the emulation targets.
> +
> +The recursive invocation will end up processing the toplevel
> +Makefile.target file (more on that later).
> +
> +
> +- */Makefile.objs
> +
> +Since the source code is spread across multiple directories, the rules
> +for each file are similarly modularized. Thus each subdirectory
> +containing .c files will usually also contain a Makefile.objs file.
> +These files are not directly invoked by a recursive make, but instead
> +they are imported by the top level Makefile and/or Makefile.target
> +
> +Each Makefile.objs usually just declares a set of variables listing the
> +.o files that need building from the source files in the directory. They
> +will also define any custom linker or compiler flags. For example in
> +block/Makefile.objs
> +
> + block-obj-$(CONFIG_LIBISCSI) += iscsi.o
> + block-obj-$(CONFIG_CURL) += curl.o
> +
> + ..snip...
> +
> + iscsi.o-cflags := $(LIBISCSI_CFLAGS)
> + iscsi.o-libs := $(LIBISCSI_LIBS)
> + curl.o-cflags := $(CURL_CFLAGS)
> + curl.o-libs := $(CURL_LIBS)
> +
> +If there are any rules defined in the Makefile.objs file, they should
> +all use $(obj) as a prefix to the target, e.g.
> +
> + $(obj)/generated-tcg-tracers.h: $(obj)/generated-tcg-tracers.h-timestamp
> +
> +
> +- Makefile.target
> +
> +This file provides the entry point used to build each individual system
> +or userspace emulator target. Each enabled target has its own
> +subdirectory. For example if configure is run with the argument
> +'--target-list=x86_64-softmmu', then a sub-directory 'x86_64-softmu'
> +will be created, containing a 'Makefile' which symlinks back to
> +Makefile.target
> +
> +So when the recursive '$(MAKE) -C x86_64-softmmu' is invoked, it ends up
> +using Makefile.target for the build rules.
> +
> +
> +- rules.mak
> +
> +This file provides the generic helper rules for invoking build tools, in
> +particular the compiler and linker. This also contains the magic (hairy)
> +'unnest-vars' function which is used to merge the variable definitions
> +from all Makefile.objs in the source tree down into the main Makefile
> +context.
> +
> +
> +- default-configs/*.mak
> +
> +The files under default-configs/ control what emulated hardware is built
> +into each QEMU system and userspace emulator targets. They merely
> +contain a long list of config variable definitions. For example,
> +default-configs/x86_64-softmmu.mak has:
> +
> + include pci.mak
> + include sound.mak
> + include usb.mak
> + CONFIG_QXL=$(CONFIG_SPICE)
> + CONFIG_VGA_ISA=y
> + CONFIG_VGA_CIRRUS=y
> + CONFIG_VMWARE_VGA=y
> + CONFIG_VIRTIO_VGA=y
> + ...snip...
> +
> +These files rarely need changing unless new devices / hardware need to
> +be enabled for a particular system/userspace emulation target
> +
> +
> +- tests/Makefile
> +
> +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.
> +
> +
> +- po/Makefile
> +
> +Rules for building and installing the binary message catalogs from the
> +text .po file sources. This almost never needs changing for any reason.
> +
> +
> +Dynamically created files
> +-------------------------
> +
> +The following files are generated dynamically by configure in order to
> +control the behaviour of the statically defined makefiles. This avoids
> +the need for QEMU makefiles to go through any pre-processing as seen
> +with autotools, where Makefile.am generates Makefile.in which generates
> +Makefile.
> +
> +
> +- config-host.mak
> +
> +When configure has determined the characteristics of the build host it
> +will write a long list of variables to config-host.mak file. This
> +provides the various install directories, compiler / linker flags and a
> +variety of CONFIG_* variables related to optionally enabled features.
> +This is imported by the top level Makefile in order to tailor the build
> +output.
> +
> +The variables defined here are those which are applicable to all QEMU
> +build outputs. Variables which are potentially different for each
> +emulator target are defined by the next file...
> +
> +It is also used as a dependency checking mechanism. If make sees that
> +the modification timestamp on configure is newer than that on
> +config-host.mak, then configure will be re-run.
> +
> +
> +- config-host.h
> +
> +The config-host.h file is used by source code to determine what features
> +are enabled. It is generated from the contents of config-host.mak using
> +the scripts/create_config program. This extracts all the CONFIG_* variables,
> +most of the HOST_* variables and a few other misc variables from
> +config-host.mak, formatting them as C preprocessor macros.
> +
> +
> +- $TARGET-NAME/config-target.mak
> +
> +TARGET-NAME is the name of a system or userspace emulator, for example,
> +x86_64-softmmu denotes the system emulator for the x86_64 architecture.
> +This file contains the variables which need to vary on a per-target
> +basis. For example, it will indicate whether KVM or Xen are enabled for
> +the target and any other potential custom libraries needed for linking
> +the target.
> +
> +
> +- $TARGET-NAME/config-devices.mak
> +
> +TARGET-NAME is again the name of a system or userspace emulator. The
> +config-devices.mak file is automatically generated by make using the
> +scripts/make_device_config.sh program, feeding it the
> +default-configs/$TARGET-NAME file as input.
> +
> +
> +- $TARGET-NAME/Makefile
> +
> +This is the entrypoint used when make recurses to build a single system
> +or userspace emulator target. It is merely a symlink back to the
> +Makefile.target in the top level.
>
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2015-09-25 10:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-09-24 13:41 [Qemu-devel] [PATCH v4] docs: describe the QEMU build system structure / design Daniel P. Berrange
2015-09-24 18:33 ` Laszlo Ersek
2015-09-25 10:05 ` Paolo Bonzini
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).