Compiling C programs
This page describes how to compile a simple C program using the Build class from the Python SDK
Sabana allows you to conveniently compile C programs for RISC-V CPUs, saving you the effort of having to install or compile your own toolchain.
We provide a programmatic interface to a gcc based toolchain. Let's go through the steps of getting our first C binary compiled.
For this example we will be compiling this simple C program:
#include <stdio.h>
int main() {
printf("hello world from riscv\n");
return 0;

Creating a Build object

The first step is to create a Build object from the Python SDK. It will provide a handler to define the project and to submit the compilation request to the platform:
from import Build
build = Build(toolchain="riscv64-unknown-elf", version="10.2.0")
At this stage you can select the toolchain that will be used to compile the project and its version.
Currentlyriscv64-unknown-elf is the only toolchain supported

Adding files

The next step of the process is to use the Build object to create a list with all the files that will be sent for compilation. We do this using the file function. Also note how in our examples we use the pathlib module in order to conveniently generate paths that are safe and consistent across operating systems:
from pathlib import Path
cwd = Path(__file__).resolve().parent

Compiling the C program

After we have added all the project files we request the project to be compiled:
result = build.compile()
The output of the compile function is a dictionary with a few entries:
  • binarray: a numpy array object with the compiled binary
  • objdump: a string containing the dis-assembly file as produced by objdump

Compilation results

If the compilation is successful the results variable will contain a Python dictionary with the following elements:
  • elfarray: This is a numpy array of int8 elements containing the compiled executable in elf form
  • binarray: This is a numpy array of int8 elements containing the compile executable in binary form
  • objdump: This is a string containing the dis-assembly of the program compiled, as it would be output by objdump
Typically the binarray will be used as a direct input to a program buffer write request, in order to write this binary in the memory used by a CPU implemented in a Sabana image. However in this example we will write elfarray to a file so we can use it in a local RISC-V simulator.
x = result["elfarray"]
with open("main", "wb") as f:
You can use Sabana's C compilation program to compile programs for any supported CPU!

Next steps

Using spike

As an advanced exercise you could use the Spike Simulator to test the elf file we created in this example with the following command:
spike pk main
The output should be:
bbl loader
hello world from riscv

Other programs

C programs are not usually this simple. Even more, for embedded systems or other small processors (like those you can deploy packaged as images in Sabana) you will need to provide an extra set of flags or more files for the correct compilation or initialization of the system.
Head to the next page where we will be showing you how to compile more complex C programs with optional flags:
Copy link
On this page
Creating a Build object
Adding files
Compiling the C program
Compilation results
Next steps
Using spike
Other programs