diff mbox series

[v2] docs/devel: Add cross-compiling doc

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

Commit Message

Andrew Jones Sept. 7, 2023, 8:46 a.m. UTC
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

Comments

Alex Bennée Sept. 7, 2023, 10:20 a.m. UTC | #1
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
Andrew Jones Sept. 7, 2023, 12:31 p.m. UTC | #2
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
Andrew Jones Sept. 7, 2023, 12:36 p.m. UTC | #3
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
Daniel Henrique Barboza Sept. 10, 2023, 10:33 a.m. UTC | #4
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 mbox series

Patch

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