Skip to content

Commit 42267ab

Browse files
committed
Build RISC-V binaries by default
Let's update the Makefile and README to build RISC-V binaries by default. Most distros now have enough RISC-V support to allow this by just using the package manager. Signed-off-by: Alistair Francis <[email protected]>
1 parent 12b066f commit 42267ab

File tree

2 files changed

+172
-153
lines changed

2 files changed

+172
-153
lines changed

Configuration.mk

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -55,16 +55,7 @@ PACKAGE_NAME ?= $(shell basename "$(shell pwd)")
5555
# 2. (Optional) The name to use when creating the output file.
5656
# 3. (Optional) The address to use as the fixed start of flash.
5757
# 4. (Optional) The address to use as the fixed start of RAM.
58-
#
59-
# By default we currently only build the Cortex-M targets. To enable the RISC-V
60-
# targets, set the RISCV variable like so:
61-
#
62-
# $ make RISCV=1
63-
#
64-
# Once the RV32 toolchain distribution stabilizes (as of June 2020 the toolchain
65-
# isn't as easily obtained as we would like), we intend to make the RISC-V
66-
# targets build by default as well.
67-
ifeq ($(RISCV),)
58+
ifneq ($(NORISCV),)
6859
TOCK_TARGETS ?= cortex-m0 cortex-m3 cortex-m4 cortex-m7
6960
else
7061
# Specific addresses useful for the OpenTitan hardware memory map.
@@ -286,28 +277,57 @@ override WLFLAGS_rv32imac += $(WLFLAGS_rv32)
286277

287278
# Set the system libraries we link against for RISC-V. We support C++ apps by
288279
# default.
289-
override LINK_LIBS_rv32 += \
290-
-lgcc -lstdc++ -lsupc++
280+
ifeq ($(PICOLIBC),)
281+
override LINK_LIBS_rv32 += \
282+
-lgcc -lstdc++ -lsupc++
291283

292-
override LINK_LIBS_rv32i += $(LINK_LIBS_rv32)
293-
override LINK_LIBS_rv32imc += $(LINK_LIBS_rv32)
294-
override LINK_LIBS_rv32imac += $(LINK_LIBS_rv32)
284+
# Use precompiled libaries we provide to link against.
285+
override LEGACY_LIBS_rv32i += \
286+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libc.a\
287+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libm.a
288+
289+
override LEGACY_LIBS_rv32im += \
290+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32im/libc.a\
291+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32im/libm.a
292+
293+
override LEGACY_LIBS_rv32imc += $(LEGACY_LIBS_rv32im)
294+
295+
override LEGACY_LIBS_rv32imac += \
296+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libc.a\
297+
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libm.a
298+
else
299+
override LEGACY_LIBS_rv32i += \
300+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32i/ilp32/libc.a\
301+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32i/ilp32/libm.a
302+
override LEGACY_LIBS_rv32im += \
303+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32im/ilp32/libc.a\
304+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32im/ilp32/libm.a
305+
306+
override LEGACY_LIBS_rv32imc += $(LEGACY_LIBS_rv32im)
295307

296-
# Use precompiled libaries we provide to link against.
297-
override LEGACY_LIBS_rv32i += \
298-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libc.a\
299-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32i/libm.a
308+
override LEGACY_LIBS_rv32imac += \
309+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32imac/ilp32/libc.a\
310+
/usr/lib/picolibc/riscv64-unknown-elf/lib/rv32imac/ilp32/libm.a
300311

301-
override LEGACY_LIBS_rv32im += \
302-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32im/libc.a\
303-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32im/libm.a
312+
override CFLAGS_rv32i += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
313+
override CPPFLAGS_rv32i += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
304314

305-
override LEGACY_LIBS_rv32imc += $(LEGACY_LIBS_rv32im)
315+
override CFLAGS_rv32im += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
316+
override CPPFLAGS_rv32im += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
306317

307-
override LEGACY_LIBS_rv32imac += \
308-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libc.a\
309-
$(TOCK_USERLAND_BASE_DIR)/newlib/rv32/rv32imac/libm.a
318+
override CFLAGS_rv32imc += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
319+
override CPPFLAGS_rv32imc += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
310320

321+
override CFLAGS_rv32imac += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
322+
override CPPFLAGS_rv32imac += -I/usr/lib/picolibc/riscv64-unknown-elf/include/
323+
324+
override LINK_LIBS_rv32 += \
325+
-lgcc
326+
endif
327+
328+
override LINK_LIBS_rv32i += $(LINK_LIBS_rv32)
329+
override LINK_LIBS_rv32imc += $(LINK_LIBS_rv32)
330+
override LINK_LIBS_rv32imac += $(LINK_LIBS_rv32)
311331

312332
################################################################################
313333
##
@@ -442,6 +462,8 @@ override CPPFLAGS += -Wwrite-strings # # { char* c = "foo"; c[0] = 'b
442462
override CPPFLAGS_gcc += -Wlogical-op # # "suspicious use of logical operators in expressions" (a lint)
443463
override CPPFLAGS_gcc += -Wtrampolines # # attempt to generate a trampoline on the NX stack
444464

465+
override CPPFLAGS_gcc += -Wno-error=sign-compare # Triggers an error inside picolibc
466+
445467
#CPPFLAGS += -Wabi -Wabi-tag # inter-compiler abi issues
446468
#CPPFLAGS += -Waggregate-return # warn if things return struct's
447469
#CPPFLAGS += -Wcast-align # { char *c; int *i = (int*) c}, 1 byte -> 4 byte align

README.md

Lines changed: 124 additions & 127 deletions
Original file line numberDiff line numberDiff line change
@@ -33,161 +33,158 @@ Prerequisites
3333
$ cd libtock-c
3434
```
3535
36-
1. The main requirement to build the C applications in this repository is having
37-
cross compilers for embedded targets. You will need an `arm-none-eabi`
38-
toolchain for Cortex-M targets.
36+
1. There are two requirements for building libtock-c applications.
3937
40-
**MacOS**:
41-
```
42-
$ brew tap ARMmbed/homebrew-formulae && brew update && brew install arm-none-eabi-gcc
43-
```
38+
1. Cross compiler for embedded targets
4439
45-
**Ubuntu (18.04LTS or later)**:
46-
```
47-
$ sudo apt install gcc-arm-none-eabi
48-
```
40+
*ARM*
4941
50-
**Arch**:
51-
```
52-
$ sudo pacman -Syu arm-none-eabi-gcc arm-none-eabi-newlib
53-
```
42+
You will need an `arm-none-eabi` toolchain for Cortex-M targets.
5443
55-
**Fedora**:
56-
```
57-
$ sudo dnf install arm-none-eabi-newlib arm-none-eabi-gcc-cs
58-
```
44+
**MacOS**:
45+
```
46+
$ brew tap ARMmbed/homebrew-formulae && brew update && brew install arm-none-eabi-gcc
47+
```
5948
60-
2. Optional: libtock-c also includes support for building for ***RISC-V
61-
targets***. These are not included by default since obtaining the toolchain
62-
can be difficult (as of July 2022). You will need a RISC-V toolchain that
63-
supports rv32 targets (64 bit toolchains support rv32 if compiled with
64-
multilib support). Some toolchains that can work:
49+
**Ubuntu (18.04LTS or later)**:
50+
```
51+
$ sudo apt install gcc-arm-none-eabi
52+
```
6553
66-
- riscv64-none-elf
67-
- riscv32-none-elf
68-
- riscv64-elf
69-
- riscv64-unknown-elf
70-
- riscv32-unknown-elf
54+
**Arch**:
55+
```
56+
$ sudo pacman -Syu arm-none-eabi-gcc
57+
```
7158
72-
To actually build for the RISC-V targets, add `RISCV=1` to the make command:
59+
**Fedora**:
60+
```
61+
$ sudo dnf install arm-none-eabi-gcc-cs
62+
```
7363
74-
$ make RISCV=1
64+
*RISC-V*
7565
76-
**MacOS**:
77-
```
78-
$ brew tap riscv/riscv && brew update && brew install riscv-gnu-toolchain
79-
```
66+
You will need a RISC-V toolchain that supports rv32 targets (64 bit
67+
toolchains support rv32 if compiled with multilib support).
68+
Some toolchains that can work:
69+
- riscv64-none-elf
70+
- riscv32-none-elf
71+
- riscv64-elf
72+
- riscv64-unknown-elf
73+
- riscv32-unknown-elf
8074
81-
**Ubuntu (21.10 or later)**:
82-
```
83-
$ sudo apt install gcc-riscv64-unknown-elf picolibc-riscv64-unknown-elf
84-
```
75+
**MacOS**:
8576
86-
**Ubuntu (21.04 or earlier)**:
77+
```shell
78+
$ brew tap riscv/riscv && brew update && brew install riscv-gnu-toolchain
79+
```
8780
88-
Unfortunately, older Ubuntu does not provide a package for RISC-V libc. We
89-
have created a .deb file you can use to install a suitable libc based on
90-
newlib:
91-
```
92-
$ wget http://cs.virginia.edu/~bjc8c/archive/newlib_3.3.0-1_amd64.deb
93-
$ sudo dpkg -i newlib_3.3.0-1_amd64.deb
94-
```
81+
**Ubuntu (21.10 or later) or Debian (11 or later)**:
9582
96-
If you would rather compile your own newlib-based libc, follow the steps
97-
below. Section [newlib-nano](newlib-nano) describes some extra config options
98-
to build a size optimised newlib.
99-
```
100-
# Download newlib 3.3 from https://sourceware.org/newlib/
101-
$ wget ftp://sourceware.org/pub/newlib/newlib-3.3.0.tar.gz
102-
$ tar -xvf newlib-3.3.0.tar.gz
103-
$ cd newlib-3.3.0
104-
# Disable stdlib for building
105-
$ export CFLAGS=-nostdlib
106-
# Run configure
107-
$ ./configure --disable-newlib-supplied-syscalls --with-gnu-ld --with-newlib --enable-languages=c --target=riscv64-unknown-elf --host=x86 --disable-multi-lib --prefix /usr
108-
# Build and then install
109-
$ make -j8
110-
$ sudo make install
111-
```
83+
```shell
84+
$ sudo apt install gcc-riscv64-unknown-elf
85+
```
11286
113-
Alternatively, you may use a pre-compiled toolchain that we created with
114-
Crosstool-NG.
115-
```
116-
$ wget http://cs.virginia.edu/~bjc8c/archive/gcc-riscv64-unknown-elf-8.3.0-ubuntu.zip
117-
$ unzip gcc-riscv64-unknown-elf-8.3.0-ubuntu.zip
118-
# add gcc-riscv64-unknown-elf-8.3.0-ubuntu/bin to your `$PATH` variable.
119-
```
87+
**Arch**:
88+
```shell
89+
$ sudo pacman -Syu riscv64-elf-gcc
90+
```
12091
121-
**Arch**:
122-
```
123-
$ sudo pacman -Syu riscv64-elf-gcc riscv32-elf-newlib arm-none-eabi-newlib riscv64-elf-newlib
124-
```
92+
**Other distros**:
12593
126-
**Fedora**:
94+
If your distro doesn't provide a RISC-V toolchain you can build one yourself
95+
or just disable RISC-V support by running
12796
128-
**dnf** does not contain the `riscv-gnu-toolchain`, an alternative is to
129-
compile from source. Start with some of the tools we need to compile the
130-
source.
131-
```
132-
$ sudo dnf install make automake gcc gcc-c++ kernel-devel texinfo expat expat-devel
133-
$ sudo dnf group install "Development Tools" "C Development Tools and Libraries"
134-
```
135-
Get `riscv-gnu-toolchain`, [summarised instructions as stated
136-
here](https://github.com/riscv-collab/riscv-gnu-toolchain/blob/master/README.md)
137-
```
138-
$ git clone https://github.com/riscv/riscv-gnu-toolchain
139-
$ cd riscv-gnu-toolchain/
140-
```
141-
**Note: add /opt/riscv/bin to your PATH**, then,
142-
```
143-
$ ./configure --prefix=/opt/riscv --enable-multilib
144-
```
145-
`--enable-multilib` ensures that "the multilib compiler will have the prefix
146-
riscv64-unknown-elf- or riscv64-unknown-linux-gnu- but will be able to target
147-
both 32-bit and 64-bit systems."
148-
```
149-
$ sudo make [might need elevated privileges writing to `/opt/`]
150-
```
151-
additionally, with
152-
```
153-
$ sudo make linux
154-
```
155-
you can also build `riscv64-unknown-linux-gnu`, which can be useful with tock
156-
where `riscv64-unknown-linux-gnu-objcopy` is used.
97+
```shell
98+
NORISCV=1 make
99+
```
157100
158-
After the the source has been compiled and copied to `/opt/riscv` and
159-
`/opt/riscv/bin`has appended to the PATH, the toolchain is ready to be used.
101+
1. libc for embedded targets
160102
103+
*ARM*
161104
162-
**newlib-nano**:
105+
**Ubuntu (21.10 or later) or Debian (11 or later)**:
163106
164-
newlib can require a large amount of memory, especially for printing.
165-
If this is a concern you can instead use a more size optimised version.
166-
As of August 2020 there are a few options for this.
107+
```shell
108+
$ sudo apt install picolibc-arm-unknown-elf libnewlib-arm-none-eabi
109+
```
167110
168-
- See if the version of newlib from your distro already has the flags below
169-
enabled. If it does it's already size optimsed.
170-
- See if your distro pacakges a newlib-nano (Debian does this) that will
171-
already include the flags below.
172-
- See if your distro packages picolibc, which is a optimised fork of newlib.
173-
- You can compile newlib with these extra flags:
111+
**Arch**:
174112
```
175-
--enable-newlib-reent-small \
176-
--disable-newlib-fvwrite-in-streamio \
177-
--disable-newlib-fseek-optimization \
178-
--disable-newlib-wide-orient \
179-
--enable-newlib-nano-malloc \
180-
--disable-newlib-unbuf-stream-opt \
181-
--enable-lite-exit \
182-
--enable-newlib-global-atexit \
183-
--enable-newlib-nano-formatted-io
113+
$ sudo pacman -Syu arm-none-eabi-newlib
184114
```
185115
186-
3. Optional: libtock-c also includes support for building RISC-V targets with
116+
**Fedora**:
117+
```
118+
$ sudo dnf install arm-none-eabi-newlib
119+
```
120+
121+
*RISC-V*
122+
123+
**Ubuntu (21.10 or later) or Debian (11 or later)**:
124+
125+
Use picolibc instead of newlib
126+
127+
```shell
128+
$ sudo apt install picolibc-riscv64-unknown-elf
129+
```
130+
**Arch**:
131+
```shell
132+
$ sudo pacman -Syu riscv32-elf-newlib
133+
```
134+
135+
*newlib-nano*
136+
137+
newlib can require a large amount of memory, especially for printing.
138+
If this is a concern you can instead use a more size optimised version.
139+
As of August 2020 there are a few options for this.
140+
141+
- See if the version of newlib from your distro already has the flags below
142+
enabled. If it does it's already size optimsed.
143+
- See if your distro packages picolibc, which is a optimised fork of newlib.
144+
- You can compile newlib with these extra flags:
145+
```shell
146+
--enable-newlib-reent-small \
147+
--disable-newlib-fvwrite-in-streamio \
148+
--disable-newlib-fseek-optimization \
149+
--disable-newlib-wide-orient \
150+
--enable-newlib-nano-malloc \
151+
--disable-newlib-unbuf-stream-opt \
152+
--enable-lite-exit \
153+
--enable-newlib-global-atexit \
154+
--enable-newlib-nano-formatted-io
155+
```
156+
157+
If you would rather compile your own newlib-based libc, follow the steps
158+
below.
159+
160+
```shell
161+
# Download newlib 4.1 from https://sourceware.org/newlib/
162+
$ wget ftp://sourceware.org/pub/newlib/newlib-4.1.0.tar.gz
163+
$ tar -xvf newlib-4.1.0.tar.gz
164+
$ cd newlib-4.1.0
165+
# Disable stdlib for building
166+
$ export CFLAGS=-nostdlib
167+
# Run configure
168+
$ ./configure --disable-newlib-supplied-syscalls --with-gnu-ld --with-newlib --enable-languages=c --target=riscv64-unknown-elf --host=x86 --disable-multi-lib --prefix /usr
169+
# Build and then install
170+
$ make -j8
171+
$ sudo make install
172+
```
173+
174+
1. Optional: If using picolibc (Debian can do this) then specify the `PICOLIBC`
175+
variable. picolibc is an optimised version of newlib
176+
177+
```shell
178+
$ make PICOLIBC=1
179+
```
180+
181+
1. Optional: libtock-c also includes support for building RISC-V targets with
187182
the LLVM clang compiler. If you have a compatible clang toolchain, you can
188183
add `CLANG=1` to the make command to use clang instead of the default GCC.
189184
190-
$ make RISCV=1 CLANG=1
185+
```shell
186+
$ make CLANG=1
187+
```
191188
192189
This support is only included for RISC-V targets as Cortex-M targets require
193190
the FDPIC support only present in GCC.

0 commit comments

Comments
 (0)