lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 1 | # Build Software |
| 2 | |
| 3 | ## Prerequisites |
| 4 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 5 | _Make sure you followed the install instructions to [prepare the system]({{< relref "install_instructions#system-preparation" >}}) and install the [compiler toolchain]({{< relref "install_instructions#compiler-toolchain" >}})._ |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 6 | |
| 7 | ## Building software |
| 8 | |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 9 | OpenTitan software is built using [Meson](https://mesonbuild.com). |
| 10 | However, Meson is not an exact fit for a lot of things OpenTitan does (such as distinguishing between FPGA, ASIC, and simulations), so the setup is a little bit different. |
| 11 | |
| 12 | For example, the following commands build the `boot_rom` and `hello_world` binaries for FPGA: |
Miguel Osorio | 39fc9a4 | 2019-10-31 15:05:40 -0700 | [diff] [blame] | 13 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 14 | ```console |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 15 | # Configure the Meson environment. |
Miguel Osorio | 39fc9a4 | 2019-10-31 15:05:40 -0700 | [diff] [blame] | 16 | $ cd $REPO_TOP |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 17 | $ ./meson_init.sh |
| 18 | |
| 19 | # Build the two targets we care about, specifically. |
Miguel Young de la Sota | 76526c3 | 2020-01-28 10:24:41 -0500 | [diff] [blame] | 20 | $ ninja -C build-out sw/device/boot_rom/boot_rom_export_fpga_nexysvideo |
| 21 | $ ninja -C build-out sw/device/examples/hello_world/hello_world_export_fpga_nexysvideo |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 22 | |
Miguel Young de la Sota | 76526c3 | 2020-01-28 10:24:41 -0500 | [diff] [blame] | 23 | # Build *everything*, including targets for other devices. |
| 24 | $ ninja -C build-out all |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 25 | ``` |
| 26 | |
Miguel Young de la Sota | 76526c3 | 2020-01-28 10:24:41 -0500 | [diff] [blame] | 27 | Note that specific targets are followed by the device they are built for. |
| 28 | OpenTitan needs to link the same device executable for multiple devices, so each executable target is duplicated one for each device we support. |
| 29 | |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 30 | In general, `clean` rules are unnecessary, and Meson will set up `ninja` such that it reruns `meson.build` files which have changed. |
Greg Chadwick | 567cfd6 | 2019-10-31 16:15:33 +0000 | [diff] [blame] | 31 | |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 32 | Build intermediates will show up in `$REPO_TOP/build-out`, including unlinked object files and libraries, while completed executables are exported to `$REPO_TOP/build-bin`. |
| 33 | As a rule, you should only ever need to refer to artifacts inside of `build-bin`; the exact structure of `build-out` is subject to change. |
| 34 | Complete details of these semantics are documented in `util/build_consts.sh`. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 35 | |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 36 | The locations of `build-{out,bin}` can be controled by setting the `$BUILD_ROOT` enviromnent variable, which defaults to `$REPO_TOP`. |
Srikrishna Iyer | 4523cb2 | 2019-10-02 16:41:05 -0700 | [diff] [blame] | 37 | |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 38 | `./meson_init.sh` itself is idempotent, but this behavior can be changed with additional flags; see `./meson_init.sh` for more information. |
| 39 | For this reason, most examples involving Meson will include a call to `./meson_init.sh`, but you will rarely need to run it more than once per checkout. |
| 40 | |
Miguel Young de la Sota | 76526c3 | 2020-01-28 10:24:41 -0500 | [diff] [blame] | 41 | Building an executable `foo` destined to run on the OpenTitan device `$DEVICE` will output the following files under `build-bin/sw/device`: |
| 42 | * `foo_$DEVICE.elf`: the linked program, in ELF format. |
| 43 | * `foo_$DEVICE.bin`: the linked program, as a plain binary with ELF debug information removed. |
| 44 | * `foo_$DEVICE.dis`: the disassembled program with inline source code. |
| 45 | * `foo_$DEVICE.vmem`: a Verilog memory file which can be read by `$readmemh()` in Verilog code. |
| 46 | |
| 47 | In general, this executable is built by building the `foo_export_$DEVICE` target. |
Miguel Young de la Sota | 8ff30b8 | 2019-11-25 12:58:34 -0600 | [diff] [blame] | 48 | |
| 49 | Building an executable destined to run on a host machine (i.e., under `sw/host`) will output a host excecutable under `build-bin/sw/host`, which can be run directly. |
Satnam Singh | 0caa6e0 | 2020-04-01 15:24:27 -0700 | [diff] [blame] | 50 | |
| 51 | ## Troubleshooting |
| 52 | If you encounter an error running `./meson_init.sh` you could re-run using the `-f` flag which will erase any existing building directories to yield a clean build. This sledgehammer is only intended to be used as a last resort when the existing configuration is seriously broken. |
| 53 | ```console |
| 54 | $ ./meson_init.sh -f |
| 55 | ``` |
| 56 | If any `meson.build` files are changed the configuration can be regenerated by passing the `-r` flag to `./meson_init.sh` |
| 57 | ```console |
| 58 | $ ./meson_init.sh -r |
Sam Elliott | 4cac9ec | 2020-06-03 11:53:04 +0100 | [diff] [blame] | 59 | ``` |
| 60 | |
| 61 | ## Bringing Your Own Toolchain |
| 62 | |
| 63 | `./meson_init.sh` needs to know where the toolchain you are using is, and which tools from it should be used. |
| 64 | |
| 65 | If you are using the lowrisc-provided toolchain (obtained with `get-toolchain.py`), and it is installed in the default location (`/tools/riscv`), then `./meson_init.sh` does not need additional configuration. |
| 66 | |
| 67 | If you are using the lowrisc-provided toolchain, but have located it in a non-default location (using `get-toolchain.py -t /path/to/lowrisc/toolchain`), you can use the environment variable `TOOLCHAIN_PATH` to point to your toolchain location, like so: |
| 68 | ```console |
| 69 | $ export TOOLCHAIN_PATH=/path/to/lowrisc/toolchain |
| 70 | $ ./meson_init.sh |
| 71 | ``` |
| 72 | |
| 73 | If you have moved a lowrisc-provided toolchain (obtained with `get-toolchain.py`), you will need to update paths within the meson toolchain configuration files within the toolchain installation. |
| 74 | These are called `meson-<triple>-<compiler>.txt`, and are present in toolchains since version 20200602-1. |
| 75 | You can still use `TOOLCHAIN_PATH` to point to the toolchain location if you have updated the paths within these files. |
| 76 | |
| 77 | If you have built your own toolchain by following option 2 under [Installing Software Build Requirements]({{< relref "doc/ug/install_instructions/index#device-compiler-toolchain-rv32imc" >}}), then you need to point `./meson_init.sh` to your custom toolchain file using `-t FILE`: |
| 78 | ```console |
| 79 | $ ./meson_init -t /path/to/toolchain/file |
| 80 | ``` |
| 81 | |
| 82 | If you do not specify your own toolchain configuration file (using `./meson_init.sh -t`), and `meson_init.sh` cannot find the default configuration in your toolchain, the legacy `toolchain.txt` from the main OpenTitan repository will be used. |
| 83 | If `TOOLCHAIN_PATH` is set, this will be used to update any paths within the legacy configuration. |