Message ID | 20230907084604.253347-2-ajones@ventanamicro.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2] docs/devel: Add cross-compiling doc | expand |
Andrew Jones <ajones@ventanamicro.com> writes: > Add instructions for how to cross-compile QEMU for RISC-V. The > file is named generically because there's no reason not to collect > other architectures steps into the same file, especially because > several subsections like those for cross-compiling QEMU dependencies > using meson and a cross-file could be shared. Additionally, other > approaches to creating sysroots, such as with debootstrap, may be > documented in this file in the future. > > Signed-off-by: Andrew Jones <ajones@ventanamicro.com> > --- > docs/devel/cross-compiling.rst | 221 +++++++++++++++++++++++++++++++++ > docs/devel/index-build.rst | 1 + > 2 files changed, 222 insertions(+) > create mode 100644 docs/devel/cross-compiling.rst > > diff --git a/docs/devel/cross-compiling.rst b/docs/devel/cross-compiling.rst > new file mode 100644 > index 000000000000..1b988ba54e4c > --- /dev/null > +++ b/docs/devel/cross-compiling.rst > @@ -0,0 +1,221 @@ > +.. SPDX-License-Identifier: GPL-2.0-or-later > + > +==================== > +Cross-compiling QEMU > +==================== > + > +Cross-compiling QEMU first requires the preparation of a cross-toolchain > +and the cross-compiling of QEMU's dependencies. While the steps will be > +similar across architectures, each architecture will have its own specific > +recommendations. "some architectures" - most of the cross compile stuff is hidden away by the build system on systems with appropriate development libraries installed. I think we would be remiss if we didn't just outline the common case: ../configure --cross-prefix=riscv64-linux-gnu- I think we could make it clearer that in most cases you don't need to prepare and cross-compile a bunch of dependencies lest we send developers down a rabbit hole. Maybe build-system.rst be updated and this reference it for the common case? > This document collects architecture-specific procedures > +and hints that may be used to cross-compile QEMU, where typically the host > +environment is x86. > + > +RISC-V > +====== > + > +Toolchain > +--------- > + > +Select a root directory for the cross environment > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Export an environment variable pointing to a root directory > +for the cross environment. For example, :: > + > + $ export PREFIX="$HOME/opt/riscv" > + > +Create a work directory > +^^^^^^^^^^^^^^^^^^^^^^^ > + > +Tools and several components will need to be downloaded and built. Create > +a directory for all the work, :: > + > + $ export WORK_DIR="$HOME/work/xqemu" > + $ mkdir -p "$WORK_DIR" > + > +Select and prepare the toolchain > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Select a toolchain such as [riscv-toolchain]_ and follow its instructions > +for building and installing it to ``$PREFIX``, e.g. :: > + > + $ cd "$WORK_DIR" > + $ git clone https://github.com/riscv/riscv-gnu-toolchain > + $ cd riscv-gnu-toolchain > + $ ./configure --prefix="$PREFIX" > + $ make -j$(nproc) linux > + > +Set the ``$CROSS_COMPILE`` environment variable to the prefix of the cross > +tools and add the tools to ``$PATH``, :: > + > +$ export CROSS_COMPILE=riscv64-unknown-linux-gnu- > +$ export PATH="$PREFIX/bin:$PATH" > + > +Also set ``$SYSROOT``, where all QEMU cross-compiled dependencies will be > +installed. The toolchain installation likely created a 'sysroot' directory > +at ``$PREFIX/sysroot``, which is the default location for most cross > +tools, making it a good location, :: > + > + $ mkdir -p "$PREFIX/sysroot" > + $ export SYSROOT="$PREFIX/sysroot" > + > +Create a pkg-config wrapper > +^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +The build processes of QEMU and some of its dependencies depend on > +pkg-config. Create a wrapper script for it which works for the cross > +environment: :: > + > + $ cat <<EOF >"$PREFIX/bin/${CROSS_COMPILE}pkg-config" > + #!/bin/sh > + > + [ "\$SYSROOT" ] || exit 1 > + > + export PKG_CONFIG_PATH= > + export PKG_CONFIG_LIBDIR="\${SYSROOT}/usr/lib/pkgconfig:\${SYSROOT}/usr/lib64/pkgconfig:\${SYSROOT}/usr/share/pkgconfig" > + > + exec pkg-config "\$@" > + EOF > + $ chmod +x "$PREFIX/bin/${CROSS_COMPILE}pkg-config" > + > +Create a cross-file for meson builds > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +meson setup, used by some of QEMU's dependencies, needs a "cross-file" to > +configure the cross environment. Create one, :: > + > + $ cd "$WORK_DIR" > + $ cat <<EOF >cross_file.txt > + [host_machine] > + system = 'linux' > + cpu_family = 'riscv64' > + cpu = 'riscv64' > + endian = 'little' > + > + [binaries] > + c = '${CROSS_COMPILE}gcc' > + cpp = '${CROSS_COMPILE}g++' > + ar = '${CROSS_COMPILE}ar' > + ld = '${CROSS_COMPILE}ld' > + objcopy = '${CROSS_COMPILE}objcopy' > + strip = '${CROSS_COMPILE}strip' > + pkgconfig = '${CROSS_COMPILE}pkg-config' > + EOF > + > +Cross-compile dependencies > +-------------------------- > + > +glibc > +^^^^^ > + > +If [riscv-toolchain]_ was selected for the toolchain then this step is > +already complete and glibc has already been installed into ``$SYSROOT``. > +Otherwise, cross-compile glibc and install it to ``$SYSROOT``. > + > +libffi > +^^^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git > + $ cd libffi > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +*Building libffi seperately avoids a compilation error generated when > +building it as a subproject of glib.* > + > +glib > +^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://github.com/GNOME/glib.git > + $ cd glib > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +libslirp [optional] > +^^^^^^^^^^^^^^^^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.com/qemu-project/libslirp.git > + $ cd libslirp > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +pixman > +^^^^^^ > + > +First ensure the 'libtool' package is installed, e.g. > +``sudo dnf install libtool`` or ``sudo apt install libtool`` > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.freedesktop.org/pixman/pixman > + $ cd pixman > + $ ./autogen.sh > + $ ./configure --prefix="$SYSROOT/usr" --host=riscv64-unknown-linux-gnu > + $ make -j$(nproc) > + $ make install > + > +Cross-compile QEMU > +------------------ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.com/qemu-project/qemu.git > + $ cd qemu > + $ mkdir -p build/install_dir > + $ cd build > + $ ../configure --target-list=riscv64-softmmu --cross-prefix=$CROSS_COMPILE --prefix="$PWD/install_dir" > + $ make -j$(nproc) > + $ make install > + > +*Cross-compiling QEMU with different configurations may require more > +dependencies to be built and installed in the sysroot.* > + > +Running QEMU > +------------ > + > +``build/install_dir`` may now be copied to the target and its bin > +directory may be added to the target user's PATH. Prior to running > +QEMU, ensure all the libraries it depends on are present, :: > + > + $ ldd /path/to/bin/qemu-system-riscv64 > + > +For example, it may necessary to install zlib libraries, e.g. > +``sudo dnf install zlib-devel`` or ``sudo apt install zlib1g-dev`` > + > +Subsequent QEMU Cross-compiling > +------------------------------- > + > +Unless it's necessary to update and recompile the toolchain or > +dependencies, then most steps do not need to be repeated for subsequent > +compiles. Simply ensure the toolchain is in ``$PATH``, ``$SYSROOT`` points > +at the sysroot, and then follow the QEMU cross-compile steps in > +"Cross-compile QEMU". For example, :: > + > + $ export PATH="$HOME/opt/riscv/bin:$PATH" > + $ export SYSROOT="$HOME/opt/riscv/sysroot" > + $ cd /path/to/qemu > + $ mkdir -p build/install_dir > + $ cd build > + $ ../configure --target-list=riscv64-softmmu --cross-prefix=riscv64-unknown-linux-gnu- --prefix="$PWD/install_dir" > + $ make -j > + $ make install > + > +References > +---------- > + > +.. [riscv-toolchain] https://github.com/riscv/riscv-gnu-toolchain > diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst > index 57e8d39d9856..d3c85927be24 100644 > --- a/docs/devel/index-build.rst > +++ b/docs/devel/index-build.rst > @@ -9,6 +9,7 @@ the basics if you are adding new files and targets to the build. > :maxdepth: 3 > > build-system > + cross-compiling > kconfig > testing > acpi-bits
On Thu, Sep 07, 2023 at 11:20:55AM +0100, Alex Bennée wrote: > > Andrew Jones <ajones@ventanamicro.com> writes: > > > Add instructions for how to cross-compile QEMU for RISC-V. The > > file is named generically because there's no reason not to collect > > other architectures steps into the same file, especially because > > several subsections like those for cross-compiling QEMU dependencies > > using meson and a cross-file could be shared. Additionally, other > > approaches to creating sysroots, such as with debootstrap, may be > > documented in this file in the future. > > > > Signed-off-by: Andrew Jones <ajones@ventanamicro.com> > > --- > > docs/devel/cross-compiling.rst | 221 +++++++++++++++++++++++++++++++++ > > docs/devel/index-build.rst | 1 + > > 2 files changed, 222 insertions(+) > > create mode 100644 docs/devel/cross-compiling.rst > > > > diff --git a/docs/devel/cross-compiling.rst b/docs/devel/cross-compiling.rst > > new file mode 100644 > > index 000000000000..1b988ba54e4c > > --- /dev/null > > +++ b/docs/devel/cross-compiling.rst > > @@ -0,0 +1,221 @@ > > +.. SPDX-License-Identifier: GPL-2.0-or-later > > + > > +==================== > > +Cross-compiling QEMU > > +==================== > > + > > +Cross-compiling QEMU first requires the preparation of a cross-toolchain > > +and the cross-compiling of QEMU's dependencies. While the steps will be > > +similar across architectures, each architecture will have its own specific > > +recommendations. > > "some architectures" - most of the cross compile stuff is hidden away by > the build system on systems with appropriate development libraries > installed. I think we would be remiss if we didn't just outline the > common case: > > ../configure --cross-prefix=riscv64-linux-gnu- > > I think we could make it clearer that in most cases you don't need to > prepare and cross-compile a bunch of dependencies lest we send > developers down a rabbit hole. > > Maybe build-system.rst be updated and this reference it for the common > case? > Hi Alex, tl;dr, I'd welcome instructions helping people get cross-arch development libraries installed without having to build them. I wouldn't make a good author for those instructions, though, since I don't know how. I'm guessing the dependencies can be installed with a distro's package management, assuming the package management supports cross-arch installation and installing to a specified root directory. I'm on Fedora, so I just tried $ sudo dnf install --forcearch=aarch64 --installroot=$SYSROOT --releasever=36 glib2-devel but it wanted to install a huge number of packages, which most people probably wouldn't want to do. Maybe that command isn't what you had in mind or other distros can manage this better. I'm all ears. Thanks, drew
On Thu, Sep 07, 2023 at 02:31:20PM +0200, Andrew Jones wrote: > On Thu, Sep 07, 2023 at 11:20:55AM +0100, Alex Bennée wrote: > > > > Andrew Jones <ajones@ventanamicro.com> writes: > > > > > Add instructions for how to cross-compile QEMU for RISC-V. The > > > file is named generically because there's no reason not to collect > > > other architectures steps into the same file, especially because > > > several subsections like those for cross-compiling QEMU dependencies > > > using meson and a cross-file could be shared. Additionally, other > > > approaches to creating sysroots, such as with debootstrap, may be > > > documented in this file in the future. > > > > > > Signed-off-by: Andrew Jones <ajones@ventanamicro.com> > > > --- > > > docs/devel/cross-compiling.rst | 221 +++++++++++++++++++++++++++++++++ > > > docs/devel/index-build.rst | 1 + > > > 2 files changed, 222 insertions(+) > > > create mode 100644 docs/devel/cross-compiling.rst > > > > > > diff --git a/docs/devel/cross-compiling.rst b/docs/devel/cross-compiling.rst > > > new file mode 100644 > > > index 000000000000..1b988ba54e4c > > > --- /dev/null > > > +++ b/docs/devel/cross-compiling.rst > > > @@ -0,0 +1,221 @@ > > > +.. SPDX-License-Identifier: GPL-2.0-or-later > > > + > > > +==================== > > > +Cross-compiling QEMU > > > +==================== > > > + > > > +Cross-compiling QEMU first requires the preparation of a cross-toolchain > > > +and the cross-compiling of QEMU's dependencies. While the steps will be > > > +similar across architectures, each architecture will have its own specific > > > +recommendations. > > > > "some architectures" - most of the cross compile stuff is hidden away by > > the build system on systems with appropriate development libraries > > installed. I think we would be remiss if we didn't just outline the > > common case: > > > > ../configure --cross-prefix=riscv64-linux-gnu- > > > > I think we could make it clearer that in most cases you don't need to > > prepare and cross-compile a bunch of dependencies lest we send > > developers down a rabbit hole. > > > > Maybe build-system.rst be updated and this reference it for the common > > case? > > > > Hi Alex, > > tl;dr, I'd welcome instructions helping people get cross-arch development > libraries installed without having to build them. I wouldn't make a good > author for those instructions, though, since I don't know how. > > I'm guessing the dependencies can be installed with a distro's package > management, assuming the package management supports cross-arch > installation and installing to a specified root directory. I'm on Fedora, > so I just tried > > $ sudo dnf install --forcearch=aarch64 --installroot=$SYSROOT --releasever=36 glib2-devel > > but it wanted to install a huge number of packages, which most people > probably wouldn't want to do. Maybe that command isn't what you had in > mind or other distros can manage this better. I'm all ears. > Ah, I just saw your other reply on the original posting. The magic is in docker stuff. I'll look into it, but I'd also make a poor author for anything regarding docker :-) Thanks, drew
On 9/7/23 05:46, Andrew Jones wrote: > Add instructions for how to cross-compile QEMU for RISC-V. The > file is named generically because there's no reason not to collect > other architectures steps into the same file, especially because > several subsections like those for cross-compiling QEMU dependencies > using meson and a cross-file could be shared. Additionally, other > approaches to creating sysroots, such as with debootstrap, may be > documented in this file in the future. > > Signed-off-by: Andrew Jones <ajones@ventanamicro.com> > --- Reviewed-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> > docs/devel/cross-compiling.rst | 221 +++++++++++++++++++++++++++++++++ > docs/devel/index-build.rst | 1 + > 2 files changed, 222 insertions(+) > create mode 100644 docs/devel/cross-compiling.rst > > diff --git a/docs/devel/cross-compiling.rst b/docs/devel/cross-compiling.rst > new file mode 100644 > index 000000000000..1b988ba54e4c > --- /dev/null > +++ b/docs/devel/cross-compiling.rst > @@ -0,0 +1,221 @@ > +.. SPDX-License-Identifier: GPL-2.0-or-later > + > +==================== > +Cross-compiling QEMU > +==================== > + > +Cross-compiling QEMU first requires the preparation of a cross-toolchain > +and the cross-compiling of QEMU's dependencies. While the steps will be > +similar across architectures, each architecture will have its own specific > +recommendations. This document collects architecture-specific procedures > +and hints that may be used to cross-compile QEMU, where typically the host > +environment is x86. > + > +RISC-V > +====== > + > +Toolchain > +--------- > + > +Select a root directory for the cross environment > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Export an environment variable pointing to a root directory > +for the cross environment. For example, :: > + > + $ export PREFIX="$HOME/opt/riscv" > + > +Create a work directory > +^^^^^^^^^^^^^^^^^^^^^^^ > + > +Tools and several components will need to be downloaded and built. Create > +a directory for all the work, :: > + > + $ export WORK_DIR="$HOME/work/xqemu" > + $ mkdir -p "$WORK_DIR" > + > +Select and prepare the toolchain > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +Select a toolchain such as [riscv-toolchain]_ and follow its instructions > +for building and installing it to ``$PREFIX``, e.g. :: > + > + $ cd "$WORK_DIR" > + $ git clone https://github.com/riscv/riscv-gnu-toolchain > + $ cd riscv-gnu-toolchain > + $ ./configure --prefix="$PREFIX" > + $ make -j$(nproc) linux > + > +Set the ``$CROSS_COMPILE`` environment variable to the prefix of the cross > +tools and add the tools to ``$PATH``, :: > + > +$ export CROSS_COMPILE=riscv64-unknown-linux-gnu- > +$ export PATH="$PREFIX/bin:$PATH" > + > +Also set ``$SYSROOT``, where all QEMU cross-compiled dependencies will be > +installed. The toolchain installation likely created a 'sysroot' directory > +at ``$PREFIX/sysroot``, which is the default location for most cross > +tools, making it a good location, :: > + > + $ mkdir -p "$PREFIX/sysroot" > + $ export SYSROOT="$PREFIX/sysroot" > + > +Create a pkg-config wrapper > +^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +The build processes of QEMU and some of its dependencies depend on > +pkg-config. Create a wrapper script for it which works for the cross > +environment: :: > + > + $ cat <<EOF >"$PREFIX/bin/${CROSS_COMPILE}pkg-config" > + #!/bin/sh > + > + [ "\$SYSROOT" ] || exit 1 > + > + export PKG_CONFIG_PATH= > + export PKG_CONFIG_LIBDIR="\${SYSROOT}/usr/lib/pkgconfig:\${SYSROOT}/usr/lib64/pkgconfig:\${SYSROOT}/usr/share/pkgconfig" > + > + exec pkg-config "\$@" > + EOF > + $ chmod +x "$PREFIX/bin/${CROSS_COMPILE}pkg-config" > + > +Create a cross-file for meson builds > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > + > +meson setup, used by some of QEMU's dependencies, needs a "cross-file" to > +configure the cross environment. Create one, :: > + > + $ cd "$WORK_DIR" > + $ cat <<EOF >cross_file.txt > + [host_machine] > + system = 'linux' > + cpu_family = 'riscv64' > + cpu = 'riscv64' > + endian = 'little' > + > + [binaries] > + c = '${CROSS_COMPILE}gcc' > + cpp = '${CROSS_COMPILE}g++' > + ar = '${CROSS_COMPILE}ar' > + ld = '${CROSS_COMPILE}ld' > + objcopy = '${CROSS_COMPILE}objcopy' > + strip = '${CROSS_COMPILE}strip' > + pkgconfig = '${CROSS_COMPILE}pkg-config' > + EOF > + > +Cross-compile dependencies > +-------------------------- > + > +glibc > +^^^^^ > + > +If [riscv-toolchain]_ was selected for the toolchain then this step is > +already complete and glibc has already been installed into ``$SYSROOT``. > +Otherwise, cross-compile glibc and install it to ``$SYSROOT``. > + > +libffi > +^^^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git > + $ cd libffi > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +*Building libffi seperately avoids a compilation error generated when > +building it as a subproject of glib.* > + > +glib > +^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://github.com/GNOME/glib.git > + $ cd glib > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +libslirp [optional] > +^^^^^^^^^^^^^^^^^^^ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.com/qemu-project/libslirp.git > + $ cd libslirp > + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build > + $ ninja -C _build > + $ ninja -C _build install > + > +pixman > +^^^^^^ > + > +First ensure the 'libtool' package is installed, e.g. > +``sudo dnf install libtool`` or ``sudo apt install libtool`` > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.freedesktop.org/pixman/pixman > + $ cd pixman > + $ ./autogen.sh > + $ ./configure --prefix="$SYSROOT/usr" --host=riscv64-unknown-linux-gnu > + $ make -j$(nproc) > + $ make install > + > +Cross-compile QEMU > +------------------ > + > +:: > + > + $ cd "$WORK_DIR" > + $ git clone https://gitlab.com/qemu-project/qemu.git > + $ cd qemu > + $ mkdir -p build/install_dir > + $ cd build > + $ ../configure --target-list=riscv64-softmmu --cross-prefix=$CROSS_COMPILE --prefix="$PWD/install_dir" > + $ make -j$(nproc) > + $ make install > + > +*Cross-compiling QEMU with different configurations may require more > +dependencies to be built and installed in the sysroot.* > + > +Running QEMU > +------------ > + > +``build/install_dir`` may now be copied to the target and its bin > +directory may be added to the target user's PATH. Prior to running > +QEMU, ensure all the libraries it depends on are present, :: > + > + $ ldd /path/to/bin/qemu-system-riscv64 > + > +For example, it may necessary to install zlib libraries, e.g. > +``sudo dnf install zlib-devel`` or ``sudo apt install zlib1g-dev`` > + > +Subsequent QEMU Cross-compiling > +------------------------------- > + > +Unless it's necessary to update and recompile the toolchain or > +dependencies, then most steps do not need to be repeated for subsequent > +compiles. Simply ensure the toolchain is in ``$PATH``, ``$SYSROOT`` points > +at the sysroot, and then follow the QEMU cross-compile steps in > +"Cross-compile QEMU". For example, :: > + > + $ export PATH="$HOME/opt/riscv/bin:$PATH" > + $ export SYSROOT="$HOME/opt/riscv/sysroot" > + $ cd /path/to/qemu > + $ mkdir -p build/install_dir > + $ cd build > + $ ../configure --target-list=riscv64-softmmu --cross-prefix=riscv64-unknown-linux-gnu- --prefix="$PWD/install_dir" > + $ make -j > + $ make install > + > +References > +---------- > + > +.. [riscv-toolchain] https://github.com/riscv/riscv-gnu-toolchain > diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst > index 57e8d39d9856..d3c85927be24 100644 > --- a/docs/devel/index-build.rst > +++ b/docs/devel/index-build.rst > @@ -9,6 +9,7 @@ the basics if you are adding new files and targets to the build. > :maxdepth: 3 > > build-system > + cross-compiling > kconfig > testing > acpi-bits
diff --git a/docs/devel/cross-compiling.rst b/docs/devel/cross-compiling.rst new file mode 100644 index 000000000000..1b988ba54e4c --- /dev/null +++ b/docs/devel/cross-compiling.rst @@ -0,0 +1,221 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +==================== +Cross-compiling QEMU +==================== + +Cross-compiling QEMU first requires the preparation of a cross-toolchain +and the cross-compiling of QEMU's dependencies. While the steps will be +similar across architectures, each architecture will have its own specific +recommendations. This document collects architecture-specific procedures +and hints that may be used to cross-compile QEMU, where typically the host +environment is x86. + +RISC-V +====== + +Toolchain +--------- + +Select a root directory for the cross environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Export an environment variable pointing to a root directory +for the cross environment. For example, :: + + $ export PREFIX="$HOME/opt/riscv" + +Create a work directory +^^^^^^^^^^^^^^^^^^^^^^^ + +Tools and several components will need to be downloaded and built. Create +a directory for all the work, :: + + $ export WORK_DIR="$HOME/work/xqemu" + $ mkdir -p "$WORK_DIR" + +Select and prepare the toolchain +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Select a toolchain such as [riscv-toolchain]_ and follow its instructions +for building and installing it to ``$PREFIX``, e.g. :: + + $ cd "$WORK_DIR" + $ git clone https://github.com/riscv/riscv-gnu-toolchain + $ cd riscv-gnu-toolchain + $ ./configure --prefix="$PREFIX" + $ make -j$(nproc) linux + +Set the ``$CROSS_COMPILE`` environment variable to the prefix of the cross +tools and add the tools to ``$PATH``, :: + +$ export CROSS_COMPILE=riscv64-unknown-linux-gnu- +$ export PATH="$PREFIX/bin:$PATH" + +Also set ``$SYSROOT``, where all QEMU cross-compiled dependencies will be +installed. The toolchain installation likely created a 'sysroot' directory +at ``$PREFIX/sysroot``, which is the default location for most cross +tools, making it a good location, :: + + $ mkdir -p "$PREFIX/sysroot" + $ export SYSROOT="$PREFIX/sysroot" + +Create a pkg-config wrapper +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The build processes of QEMU and some of its dependencies depend on +pkg-config. Create a wrapper script for it which works for the cross +environment: :: + + $ cat <<EOF >"$PREFIX/bin/${CROSS_COMPILE}pkg-config" + #!/bin/sh + + [ "\$SYSROOT" ] || exit 1 + + export PKG_CONFIG_PATH= + export PKG_CONFIG_LIBDIR="\${SYSROOT}/usr/lib/pkgconfig:\${SYSROOT}/usr/lib64/pkgconfig:\${SYSROOT}/usr/share/pkgconfig" + + exec pkg-config "\$@" + EOF + $ chmod +x "$PREFIX/bin/${CROSS_COMPILE}pkg-config" + +Create a cross-file for meson builds +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +meson setup, used by some of QEMU's dependencies, needs a "cross-file" to +configure the cross environment. Create one, :: + + $ cd "$WORK_DIR" + $ cat <<EOF >cross_file.txt + [host_machine] + system = 'linux' + cpu_family = 'riscv64' + cpu = 'riscv64' + endian = 'little' + + [binaries] + c = '${CROSS_COMPILE}gcc' + cpp = '${CROSS_COMPILE}g++' + ar = '${CROSS_COMPILE}ar' + ld = '${CROSS_COMPILE}ld' + objcopy = '${CROSS_COMPILE}objcopy' + strip = '${CROSS_COMPILE}strip' + pkgconfig = '${CROSS_COMPILE}pkg-config' + EOF + +Cross-compile dependencies +-------------------------- + +glibc +^^^^^ + +If [riscv-toolchain]_ was selected for the toolchain then this step is +already complete and glibc has already been installed into ``$SYSROOT``. +Otherwise, cross-compile glibc and install it to ``$SYSROOT``. + +libffi +^^^^^^ + +:: + + $ cd "$WORK_DIR" + $ git clone https://gitlab.freedesktop.org/gstreamer/meson-ports/libffi.git + $ cd libffi + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build + $ ninja -C _build + $ ninja -C _build install + +*Building libffi seperately avoids a compilation error generated when +building it as a subproject of glib.* + +glib +^^^^ + +:: + + $ cd "$WORK_DIR" + $ git clone https://github.com/GNOME/glib.git + $ cd glib + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build + $ ninja -C _build + $ ninja -C _build install + +libslirp [optional] +^^^^^^^^^^^^^^^^^^^ + +:: + + $ cd "$WORK_DIR" + $ git clone https://gitlab.com/qemu-project/libslirp.git + $ cd libslirp + $ meson setup --cross-file ../cross_file.txt --prefix="$SYSROOT/usr" _build + $ ninja -C _build + $ ninja -C _build install + +pixman +^^^^^^ + +First ensure the 'libtool' package is installed, e.g. +``sudo dnf install libtool`` or ``sudo apt install libtool`` + +:: + + $ cd "$WORK_DIR" + $ git clone https://gitlab.freedesktop.org/pixman/pixman + $ cd pixman + $ ./autogen.sh + $ ./configure --prefix="$SYSROOT/usr" --host=riscv64-unknown-linux-gnu + $ make -j$(nproc) + $ make install + +Cross-compile QEMU +------------------ + +:: + + $ cd "$WORK_DIR" + $ git clone https://gitlab.com/qemu-project/qemu.git + $ cd qemu + $ mkdir -p build/install_dir + $ cd build + $ ../configure --target-list=riscv64-softmmu --cross-prefix=$CROSS_COMPILE --prefix="$PWD/install_dir" + $ make -j$(nproc) + $ make install + +*Cross-compiling QEMU with different configurations may require more +dependencies to be built and installed in the sysroot.* + +Running QEMU +------------ + +``build/install_dir`` may now be copied to the target and its bin +directory may be added to the target user's PATH. Prior to running +QEMU, ensure all the libraries it depends on are present, :: + + $ ldd /path/to/bin/qemu-system-riscv64 + +For example, it may necessary to install zlib libraries, e.g. +``sudo dnf install zlib-devel`` or ``sudo apt install zlib1g-dev`` + +Subsequent QEMU Cross-compiling +------------------------------- + +Unless it's necessary to update and recompile the toolchain or +dependencies, then most steps do not need to be repeated for subsequent +compiles. Simply ensure the toolchain is in ``$PATH``, ``$SYSROOT`` points +at the sysroot, and then follow the QEMU cross-compile steps in +"Cross-compile QEMU". For example, :: + + $ export PATH="$HOME/opt/riscv/bin:$PATH" + $ export SYSROOT="$HOME/opt/riscv/sysroot" + $ cd /path/to/qemu + $ mkdir -p build/install_dir + $ cd build + $ ../configure --target-list=riscv64-softmmu --cross-prefix=riscv64-unknown-linux-gnu- --prefix="$PWD/install_dir" + $ make -j + $ make install + +References +---------- + +.. [riscv-toolchain] https://github.com/riscv/riscv-gnu-toolchain diff --git a/docs/devel/index-build.rst b/docs/devel/index-build.rst index 57e8d39d9856..d3c85927be24 100644 --- a/docs/devel/index-build.rst +++ b/docs/devel/index-build.rst @@ -9,6 +9,7 @@ the basics if you are adding new files and targets to the build. :maxdepth: 3 build-system + cross-compiling kconfig testing acpi-bits
Add instructions for how to cross-compile QEMU for RISC-V. The file is named generically because there's no reason not to collect other architectures steps into the same file, especially because several subsections like those for cross-compiling QEMU dependencies using meson and a cross-file could be shared. Additionally, other approaches to creating sysroots, such as with debootstrap, may be documented in this file in the future. Signed-off-by: Andrew Jones <ajones@ventanamicro.com> --- docs/devel/cross-compiling.rst | 221 +++++++++++++++++++++++++++++++++ docs/devel/index-build.rst | 1 + 2 files changed, 222 insertions(+) create mode 100644 docs/devel/cross-compiling.rst