.. _build-from-scratch: Build SOF from scratch ###################### .. contents:: :local: :depth: 3 You may boot and test |SOF| on a target machine or VM. Current target Intel platforms include: |BYT|, |CHT|, |HSW|, |BDW|, |APL|, |CNL|, |ICL| and |JSL|. Support also exists for NXP i.MX8/i.MX8X/i.MX8M platforms. Build SOF ********* The following steps describe how to install the SOF development environment on Ubuntu 16.04, 18.04, and 18.10. They should work on 19.04, 19.10 and other Linux distributions with minor or no modifications. .. note:: ``$SOF_WORKSPACE`` environment variable should point to the directory you wish to store all sof work in. The code examples assume ``$SOF_WORKSPACE`` as the top-level working directory. Clone all git repositories at the same directory level because some default configuration files refer to other clones using relative locations like ``../sof/``. Step 0 Set up the workspace directory ===================================== .. code-block:: bash SOF_WORKSPACE=~/work/sof mkdir "$SOF_WORKSPACE" Step 1 Set up build environment =============================== Install packaged dependencies ----------------------------- * For Ubuntu 18.10: .. code-block:: bash sudo apt-get install libgtk-3-dev libsdl1.2-dev libspice-protocol-dev \ libspice-server-dev libusb-1.0-0-dev libusbredirhost-dev libtool-bin \ acpica-tools valgrind texinfo virt-manager qemu-kvm \ libvirt-daemon-system libvirt-clients virtinst libfdt-dev libssl-dev \ pkg-config help2man gawk libncurses5 libncurses5-dev * For Ubuntu 16.04 and 18.04: .. code-block:: bash sudo apt-get install libgtk-3-dev libsdl1.2-dev libspice-protocol-dev \ libspice-server-dev libusb-1.0-0-dev libusbredirhost-dev libtool-bin \ iasl valgrind texinfo virt-manager qemu-kvm libvirt-bin virtinst \ libfdt-dev libssl-dev pkg-config help2man gawk libncurses5 \ libncurses5-dev If you are using Ubuntu 16.04, the gcc version must be updated to gcc 7.3+ in order for the Advanced Linux Sound Architecture (ALSA) to build. .. code-block:: bash sudo add-apt-repository ppa:ubuntu-toolchain-r/test sudo apt-get update sudo apt-get install gcc-7 g++-7 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-7 70 --slave /usr/bin/g++ g++ /usr/bin/g++-7 Install CMake ------------- If you use Ubuntu 18.04+ you can install CMake with apt: .. code-block:: bash sudo apt-get install cmake For Ubuntu 16.04, CMake from apt is outdated and you must install CMake from sources. Refer to this short guide: https://cmake.org/install/ Build alsa-lib and alsa-utils ----------------------------- This project requires some new features in :git-alsa:`alsa-lib` and :git-alsa:`alsa-utils`, so build the newest ALSA from source code. .. warning:: Installing alsa-lib systemwide may break some audio applications. Only perform this if you know what you are doing. We recommend that you install it locally (under $HOME) or use Docker (see :ref:`build-with-docker`.) .. code-block:: bash cd "$SOF_WORKSPACE" git clone git://git.alsa-project.org/alsa-lib cd alsa-lib ./gitcompile sudo make install (Optional) To enable alsabat's frequency analysis, install the FFT library before you configure alsa-utils. .. code-block:: bash sudo apt-get install libfftw3-dev libfftw3-doc Clone, build, and install alsa-utils. .. code-block:: bash cd "$SOF_WORKSPACE" git clone git://git.alsa-project.org/alsa-utils cd alsa-utils ./gitcompile sudo make install If you run into alsa-lib linking errors, try to re-build it with the libdir parameter. .. code-block:: bash cd ../alsa-lib ./gitcompile --prefix=/usr --libdir=/usr/lib/x86_64-linux-gnu/ sudo make install cd ../alsa-utils ./gitcompile --prefix=/usr --with-curses=ncurses --disable-xmlto --disable-bat sudo make install .. note:: If the gitcompile script does not work, refer to the INSTALL file for manual build instructions. Create or append to the ``LD_LIBRARY_PATH`` environment variable. .. code-block:: bash export LD_LIBRARY_PATH="${SOF_WORKSPACE}"/alsa-lib/src/.libs:$LD_LIBRARY_PATH .. _build-toolchains-from-source: Step 2 Build toolchains from source =================================== Build the xtensa cross-compilation toolchains with crosstool-ng for Intel |BYT|, |CHT|, |HSW|, |BDW|, |APL|, |CNL|, |ICL|, |JSL| platforms and NXP i.MX8/i.MX8X/i.MX8M platforms. crosstool-ng ------------ Clone both repos and check out the ``sof-gcc8.1`` branch. .. code-block:: bash cd "$SOF_WORKSPACE" git clone https://github.com/thesofproject/xtensa-overlay git clone https://github.com/thesofproject/crosstool-ng cd xtensa-overlay git checkout sof-gcc8.1 cd ../crosstool-ng git checkout sof-gcc8.1 Build crosstool-ng and install it in its own source directory. .. code-block:: bash ./bootstrap ./configure --prefix=$(pwd) make make install Toolchains ---------- The config files provided refer to ``../xtensa-overlay/`` and point at different ``./build/xtensa-*-elf`` subdirectories. Copy the ones you want to ``.config`` and build the cross-compiler(s) for your target platform(s). ``./ct-ng build`` requires an network connection to download gcc components. .. code-block:: bash # Baytrail/Cherrytrail cp config-byt-gcc8.1-gdb8.1 .config ./ct-ng build # Haswell/Broadwell cp config-hsw-gcc8.1-gdb8.1 .config ./ct-ng build # Apollo Lake cp config-apl-gcc8.1-gdb8.1 .config ./ct-ng build # Cannon Lake, Ice Lake and Jasper Lake cp config-cnl-gcc8.1-gdb8.1 .config ./ct-ng build # i.MX8/i.MX8X cp config-imx-gcc8.1-gdb8.1 .config ./ct-ng build # i.MX8M cp config-imx8m-gcc8.1-gdb8.1 .config ./ct-ng build ``./ct-ng`` is a Linux kernel style Makefile; so the sample commands below can be used to fix some out of date ``config-*-gcc8.1-gdb8.1`` file or find default values missing from it: .. code-block:: bash ./ct-ng help cp config-apl-gcc8.1-gdb8.1 .config ./ct-ng oldconfig V=1 diff -u config-apl-gcc8.1-gdb8.1 .config "Install" toolchains by copying them to ``$SOF_WORKSPACE``. .. code-block:: bash ls builds/ # xtensa-apl-elf xtensa-byt-elf xtensa-cnl-elf xtensa-hsw-elf xtensa-imx-elf xtensa-imx8m-elf cp -r builds/* "$SOF_WORKSPACE" .. note:: |HSW| and |BDW| share the same toolchain: xtensa-hsw-elf |BYT| and |CHT| share the same toolchain: xtensa-byt-elf |CNL|, |ICL| and |JSL| share the same toolchain: xtensa-cnl-elf i.MX8 and i.MX8X share the same toolchain: xtensa-imx-elf Add your toolchains to your PATH variable. .. code-block:: bash PATH="${SOF_WORKSPACE}"/xtensa-byt-elf/bin/:$PATH PATH="${SOF_WORKSPACE}"/xtensa-hsw-elf/bin/:$PATH PATH="${SOF_WORKSPACE}"/xtensa-apl-elf/bin/:$PATH PATH="${SOF_WORKSPACE}"/xtensa-cnl-elf/bin/:$PATH PATH="${SOF_WORKSPACE}"/xtensa-imx-elf/bin/:$PATH PATH="${SOF_WORKSPACE}"/xtensa-imx8m-elf/bin/:$PATH Additional headers ------------------ To get some required headers, clone the following newlib repository and switch to the `xtensa` branch. .. code-block:: bash cd "$SOF_WORKSPACE" git clone https://github.com/jcmvbkbc/newlib-xtensa cd newlib-xtensa git checkout -b xtensa origin/xtensa Build and install for each platform. .. code-block:: bash XTENSA_ROOT="${SOF_WORKSPACE}"/xtensa-root # Baytrail/Cherrytrail ./configure --target=xtensa-byt-elf --prefix="${XTENSA_ROOT}" make make install rm -fr rm etc/config.cache # Haswell/Broadwell ./configure --target=xtensa-hsw-elf --prefix="${XTENSA_ROOT}" make make install rm -fr rm etc/config.cache # Apollo Lake ./configure --target=xtensa-apl-elf --prefix="${XTENSA_ROOT}" make make install rm -fr rm etc/config.cache # Cannon Lake, Ice Lake and Jasper Lake ./configure --target=xtensa-cnl-elf --prefix="${XTENSA_ROOT}" make make install rm -fr rm etc/config.cache # i.MX8/i.MX8X ./configure --target=xtensa-imx-elf --prefix="${XTENSA_ROOT}" make make install rm -fr rm etc/config.cache # i.MX8M ./configure --target=xtensa-imx8m-elf --prefix="${XTENSA_ROOT}" make make install .. note:: ``--prefix=`` expects an absolute path. Define XTENSA_ROOT according to your environment. The required headers are now in ``"$SOF_WORKSPACE"/xtensa-root``, and cross-compilation toolchains for xtensa DSPs are set up. Step 3 Build firmware binaries ============================== After the SOF environment is set up, clone the *sof* repo. .. code-block:: bash cd "$SOF_WORKSPACE" git clone https://github.com/thesofproject/sof One-step rebuild from scratch ----------------------------- To rebuild |SOF| in just one step, use :git-sof-mainline:`scripts/xtensa-build-all.sh` after setting up the environment. Build the firmware for all platforms. .. code-block:: bash cd "$SOF_WORKSPACE"/sof/ ./scripts/xtensa-build-all.sh -a .. note:: This script will only work if the PATH includes both the cross-compiler and ``xtensa-root`` and if they are siblings in the same ``sof`` directory. As of April 2020, you may specify one or more of the following platform arguments: ``byt``, ``cht``, ``hsw``, ``bdw``, ``apl``, ``cnl``, ``sue``, ``icl``, ``jsl``, ``imx8``, ``imx8x``, ``imx8m``. Example: .. code-block:: bash ./scripts/xtensa-build-all.sh byt ./scripts/xtensa-build-all.sh byt apl For the latest platforms list and help message, run the script without any argument. You can also enable debug builds with -d, enable rom builds with -r and speed up the build with -j [n] .. code-block:: bash ./scripts/xtensa-build-all.sh -d byt ./scripts/xtensa-build-all.sh -d -r apl ./scripts/xtensa-build-all.sh -d -r -j 4 apl .. note:: xtensa-build-all.sh script uses ``rimage`` to build the final firmware image. ``rimage`` uses by default a public key included in sof repo for signing. However, if you need to use some other external key for signing you can specify the path to your key as environment variable before invoking the build: .. code-block:: bash export PRIVATE_KEY_OPTION=-DRIMAGE_PRIVATE_KEY=/path_to_key/private.pem The same export mechanism should work also when building with Docker. Incremental builds ------------------ This is a more detailed build guide for the *sof* repo. Unlike ``xtensa-build-all.sh``, this doesn't rebuild everything every time. Snippets below assume that your current directory is the root of the ``sof`` clone (``"$SOF_WORKSPACE"/sof/``). CMake recommends out-of-tree builds. Among others, this lets you build different configurations/platforms in different build directories from the same source without starting from scratch. .. note:: The ``-j`` argument tells make how many processes to use concurrently. Select a value that matches your build system. for |BYT|: .. code-block:: bash mkdir build_byt && cd build_byt cmake -DTOOLCHAIN=xtensa-byt-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-byt-elf .. make help # lists all available targets make baytrail_defconfig make bin -j4 VERBOSE=1 for |CHT|: .. code-block:: bash mkdir build_cht && cd build_cht cmake -DTOOLCHAIN=xtensa-byt-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-byt-elf .. make cherrytrail_defconfig make bin -j4 for |HSW|: .. code-block:: bash mkdir build_hsw && cd build_hsw cmake -DTOOLCHAIN=xtensa-hsw-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-hsw-elf .. make haswell_defconfig make bin -j4 for |BDW|: .. code-block:: bash mkdir build_bdw && cd build_bdw cmake -DTOOLCHAIN=xtensa-hsw-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-hsw-elf .. make broadwell_defconfig make bin -j4 for |APL|: .. code-block:: bash mkdir build_apl && cd build_apl cmake -DTOOLCHAIN=xtensa-apl-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-apl-elf .. make apollolake_defconfig make bin -j4 for |CNL|: .. code-block:: bash mkdir build_cnl && cd build_cnl cmake -DTOOLCHAIN=xtensa-cnl-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-cnl-elf .. make cannonlake_defconfig make bin -j4 for |ICL|: .. code-block:: bash mkdir build_icl && cd build_icl cmake -DTOOLCHAIN=xtensa-cnl-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-cnl-elf .. make icelake_defconfig make bin -j4 for |JSL|: .. code-block:: bash mkdir build_jsl && cd build_jsl cmake -DTOOLCHAIN=xtensa-cnl-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-cnl-elf .. make jasperlake_defconfig make bin -j4 for i.MX8: .. code-block:: bash mkdir build_imx8 && cd build_imx8 cmake -DTOOLCHAIN=xtensa-imx-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-imx-elf .. make imx8_defconfig make bin -j4 for i.MX8X: .. code-block:: bash mkdir build_imx8x && cd build_imx8x cmake -DTOOLCHAIN=xtensa-imx-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-imx-elf .. make imx8x_defconfig make bin -j4 for i.MX8M: .. code-block:: bash mkdir build_imx8m && cd build_imx8m cmake -DTOOLCHAIN=xtensa-imx8m-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-imx8m-elf .. make imx8m_defconfig make bin -j4 .. note:: After the 'make \*_defconfig' step, you can customize your build with 'make menuconfig'. DEBUG and ROM options are available for the FW binary build. Enable them with 'make menuconfig'. .. code-block:: bash mkdir build_cnl_custom && cd build_cnl_custom cmake -DTOOLCHAIN=xtensa-cnl-elf -DROOT_DIR="$XTENSA_ROOT"/xtensa-cnl-elf .. make cannonlake_defconfig make menuconfig # select/deselect options and save make bin -j4 .. note:: If you have `Ninja `_ installed, you can use it instead of Make. Just type *cmake -GNinja ...* during the configuration step. Firmware build results ---------------------- The firmware binary files are located in build_/src/arch/xtensa/. Copy them to your target machine's /lib/firmware/intel/sof folder. .. code-block:: bash sof-apl.ri sof-bdw.ri sof-byt.ri sof-cht.ri sof-cnl.ri sof-hsw.ri Step 4 Build topology and tools =============================== One-step rebuild from scratch ----------------------------- Without any argument :git-sof-mainline:`scripts/build-tools.sh` rebuilds only the minimum subset of :git-sof-mainline:`tools/`. .. code-block:: bash cd "$SOF_WORKSPACE"/sof/ ./scripts/build-tools.sh ./scripts/build-tools.sh -h usage: ./scripts/build-tools.sh [-t|-f] [-t] Build test topologies [-f] Build fuzzer" Incremental build ----------------- .. code-block:: bash cd "$SOF_WORKSPACE"/sof/tools/ mkdir build_tools && cd build_tools cmake .. make -j4 If your ``cmake --version`` is 3.13 or higher, you may prefer the new -B option: .. code-block:: bash cmake -B build_tools/ make -C build_tools/ -j4 VERBOSE=1 rm -rf build_tools/ # no need to change directory ever Topology and tools build results -------------------------------- The topology files are located in the *tools/build_tools/topology* folder. Copy them to the target machine's /lib/firmware/intel/sof-tplg folder. The *sof-logger* tool is in the *tools/build_tools/logger* folder. Copy it to the target machine's /usr/bin directory. .. _Build Linux kernel: Build Linux kernel ****************** |SOF| uses the Linux kernel dev branch, and it must work with other dev branch firmware and topology. This short section shows how to build Debian kernel packages tested on Ubuntu in a small number of commands. Note that these commands rebuild everything from scratch every time which makes then unsuitably slow for development. If you need to make kernel code changes, ignore this and look at :ref:`setup-ktest-environment`, the `README `_ file of the kconfig repo, and the :ref:`sof_driver_arch`. #. Build the kernel with this branch. .. code-block:: bash sudo apt-get install bison flex libelf-dev cd "$SOF_WORKSPACE" git clone https://github.com/thesofproject/linux cd linux git checkout topic/sof-dev make defconfig git clone https://github.com/thesofproject/kconfig scripts/kconfig/merge_config.sh .config ./kconfig/base-defconfig ./kconfig/sof-defconfig ./kconfig/mach-driver-defconfig ./kconfig/hdaudio-codecs-defconfig (optional) make menuconfig Select the SOF driver support and disable SST drivers. #. Make the kernel deb package to install on the target machine. .. code-block:: bash make deb-pkg -j 4 #. Copy the three resulting *.deb* files to the target machine and install them. .. code-block:: bash sudo dpkg -i /absolute/path/to/deb/file sudo apt-get install -f