Skip to content

Development documentation for scripts for ARC‐V GNU toolchain

Yuriy Kolerov edited this page Dec 12, 2025 · 6 revisions

Buildlib for ARC-V GNU toolchain

riscv64-snps-elf-buildlib is a Python script which helps a user to build Picolibc, libgcc and libstdc++ for a custom target configuration. The development is done in ykolerov/buildlib-slow branch.

How buildlib tool works

These steps are performed to build a custom configuration:

  1. First, buildlib tries to find riscv64-snps-elf-gcc in PATH or in a local directory. It fails if GCC could not be found.
  2. Create the main buildlib directory and build directories for Picolibc and GCC. Create symbolic links for Picolibc and GCC sources.
  3. Configure, build and install Picolibc and then GCC. All libraries are installed to the buildlib directory.
  4. Delete symbolic links to sources and build directories for Picolibc and GCC (if --no-clean is not passed).

Build a sample configuration:

$ ./riscv64-snps-elf-buildlib build \
    --buildlib-dir-path buildlib \
    --gcc-sources-dir-path <path-to-gcc> \
    --picolibc-sources-dir-path <path-to-picolibc> \
    --march rv32imac \
    --mabi ilp32 \
    --mtune arc-v-rmx-500-series \
    --mcmodel medlow \
    --nproc 4 \
    --cflags "-O3 -g0"
INFO: Found GCC in PATH: /SCRATCH/ykolerov/tools/gcc-arcv-elf-picolibc-latest/bin/riscv64-snps-elf-gcc
INFO: Creating a symbolic link to Picolibc sources: /home/ykolerov/workspace/arc-v/gcc-buildlib/custom-build/picolibc
INFO: Creating a build directory: /home/ykolerov/workspace/arc-v/gcc-buildlib/custom-build/arcv-tcf-wrapper/buildlib/build-picolibc
INFO: Configuring Picolibc library.
INFO: Building Picolibc library.
INFO: Installing Picolibc library.
INFO: Creating a symbolic link to GCC sources: /home/ykolerov/workspace/arc-v/gcc-buildlib/custom-build/gcc
INFO: Creating a build directory: /home/ykolerov/workspace/arc-v/gcc-buildlib/custom-build/arcv-tcf-wrapper/buildlib/build-gcc
INFO: Configuring GCC.
INFO: Building libgcc and libstdc++.
INFO: Installing libgcc and libstdc++.
INFO: Saving buildlib.specs.
INFO: Finished building and installing libgcc and libstdc++.

Here is a buildlib directory structure:

$ tree -d -L 3 buildlib
buildlib
├── lib
│   └── gcc
│       └── riscv64-snps-elf
├── riscv64-snps-elf
│   ├── include
│   │   ├── arpa
│   │   ├── bits
│   │   ├── c++
│   │   ├── machine
│   │   ├── rpc
│   │   ├── ssp
│   │   └── sys
│   ├── lib
│   └── sys-include
│       ├── arpa
│       ├── bits
│       ├── machine
│       ├── rpc
│       ├── ssp
│       └── sys
└── share
    └── gcc-15.2.0
        └── python

So, basically buildlib directory is a subset of toolchain's directory.

Building an application with custom libraries

To build and link an application with a custom library, you need to pass extra arguments:

  1. -specs=./buildlib/buildlib.specs - include a .specs file which turns off default multilib rules.
  2. -isystem ./buildlib/riscv64-snps-elf/sys-include -isystem ./buildlib/riscv64-snps-elf/include - use included from a custom Picolibc.
  3. -B./buildlib/lib/gcc -B./buildlib/riscv64-snps-elf/lib - use custom libraries by default instead of original.

Consider this example:

int main()
{
    printf("Hello, World!\n");
    return 0;
}

How to link an application with custom libraries (also, we pass -Wl,-t to ensure that custom libraries are linked with our application):

$ riscv64-snps-elf-gcc \
     -march=rv32imac \
     -mabi=ilp32 \
     -mtune=arc-v-rmx-100-series \
     -mcmodel=medlow \
     -isystem ./buildlib/riscv64-snps-elf/sys-include \
     -isystem ./buildlib/riscv64-snps-elf/include \
     -B./buildlib/lib/gcc \
     -B./buildlib/riscv64-snps-elf/lib \
     -specs=picolibc.specs \
     -specs=buildlib.specs \
     --oslib=semihost \
     --crt0=semihost \
     hello.c -o hello.elf \
    -Wl,-t
./buildlib/riscv64-snps-elf/lib/crt0-semihost.o
/tmp/ccUptbxg.o
./buildlib/lib/gcc/riscv64-snps-elf/15.2.0/libgcc.a
./buildlib/lib/gcc/riscv64-snps-elf/15.2.0/libgcc.a
./buildlib/riscv64-snps-elf/lib/libc.a
./buildlib/riscv64-snps-elf/lib/libsemihost.a
./buildlib/lib/gcc/riscv64-snps-elf/15.2.0/libgcc.a
./buildlib/riscv64-snps-elf/lib/libc.a
./buildlib/riscv64-snps-elf/lib/libsemihost.a
./buildlib/lib/gcc/riscv64-snps-elf/15.2.0/libgcc.a

Now we can run the example:

$ nsimdrv -p nsim_isa_family=rv32 -p nsim_isa_ext=-all.i.m.a.c.zicsr -p nsim_semihosting=1 -p enable_exceptions=0 hello.elf
Hello, World!