Skip to content

Commit ce6d6cc

Browse files
authored
Merge pull request riscv-collab#1263 from alexsifivetw/alexc/riscv-llvm-qemu
Enable RISC-V LLVM & QEMU Build Flow
2 parents d1dfc7c + 02a9678 commit ce6d6cc

File tree

8 files changed

+197
-25
lines changed

8 files changed

+197
-25
lines changed

.github/setup-apt.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# install OS prerequisites
44
dpkg --add-architecture i386
55
apt update
6-
apt install -y autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev \
6+
apt install -y autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev \
77
libgmp-dev gawk build-essential bison flex texinfo gperf libtool \
8-
patchutils bc zlib1g-dev libexpat-dev git ninja-build expect \
8+
patchutils bc zlib1g-dev libexpat-dev git ninja-build cmake libglib2.0-dev expect \
99
device-tree-compiler

.github/workflows/nightly-release.yaml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,19 @@ jobs:
6868
- name: build toolchain
6969
run: |
7070
TARGET_TUPLE=($(echo ${{ matrix.target }} | tr "-" "\n"))
71-
./configure --prefix=/opt/riscv --with-arch=${TARGET_TUPLE[0]} --with-abi=${TARGET_TUPLE[1]}
72-
sudo make -j $(nproc) ${{ matrix.mode }}
71+
BUILD_TOOLCHAIN="./configure --prefix=/opt/riscv --with-arch=${TARGET_TUPLE[0]} --with-abi=${TARGET_TUPLE[1]}"
72+
if [ "${{ matrix.mode }}" == "linux" ]; then # build toolchain with llvm
73+
$BUILD_TOOLCHAIN --enable-llvm --enable-linux
74+
sudo make -j $(nproc) all
75+
else
76+
$BUILD_TOOLCHAIN
77+
sudo make -j $(nproc) ${{ matrix.mode }}
78+
fi
79+
80+
- name: build qemu
81+
if: "${{ matrix.mode }}" == "linux"
82+
run: |
83+
make -j$(nproc) build-sim SIM=qemu
7384
7485
- name: tarball build
7586
run: tar czvf riscv.tar.gz -C /opt/ riscv/

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,7 @@
3636
path = pk
3737
url = https://github.com/riscv-software-src/riscv-pk.git
3838
branch = master
39+
[submodule "llvm"]
40+
path = llvm
41+
url = https://github.com/llvm/llvm-project.git
42+
branch = release/15.x

Makefile.in

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ GDB_SRCDIR := @with_gdb_src@
1212
QEMU_SRCDIR := @with_qemu_src@
1313
SPIKE_SRCDIR := @with_spike_src@
1414
PK_SRCDIR := @with_pk_src@
15+
LLVM_SRCDIR := @with_llvm_src@
1516
DEJAGNU_SRCDIR := @with_dejagnu_src@
1617
DEBUG_INFO := @debug_info@
18+
DEJAGNU_SRCDIR := @with_dejagnu_src@
1719

1820
SIM ?= @WITH_SIM@
1921

@@ -118,8 +120,16 @@ newlib: stamps/build-gdb-newlib
118120
linux: stamps/build-gdb-linux
119121
endif
120122
linux-native: stamps/build-gcc-linux-native
123+
ifeq (@enable_llvm@,--enable-llvm)
124+
all: stamps/build-llvm-@default_target@
125+
newlib: stamps/build-llvm-newlib
126+
linux: stamps/build-llvm-linux
127+
ifeq (@multilib_flags@,--enable-multilib)
128+
$(error "Setting multilib flags for LLVM builds is not supported.")
129+
endif
130+
endif
121131

122-
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu
132+
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu build-llvm
123133
build-binutils: stamps/build-binutils-@default_target@
124134
build-gdb: stamps/build-gdb-@default_target@
125135
build-gcc%: stamps/build-gcc-@default_target@-stage%
@@ -130,6 +140,7 @@ build-libc: stamps/build-newlib stamps/build-newlib-nano \
130140
stamps/merge-newlib-nano
131141
endif
132142
build-qemu: stamps/build-qemu
143+
build-llvm: stamps/build-llvm-@default_target@
133144

134145
REGRESSION_TEST_LIST = gcc
135146

@@ -275,6 +286,12 @@ else
275286
SPIKE_SRC_GIT :=
276287
endif
277288

289+
ifeq ($(findstring $(srcdir),$(LLVM_SRCDIR)),$(srcdir))
290+
LLVM_SRC_GIT := $(LLVM_SRCDIR)/.git
291+
else
292+
LLVM_SRC_GIT :=
293+
endif
294+
278295
ifeq ($(findstring $(srcdir),$(DEJAGNU_SRCDIR)),$(srcdir))
279296
DEJAGNU_SRC_GIT := $(DEJAGNU_SRCDIR)/.git
280297
else
@@ -890,6 +907,44 @@ stamps/build-qemu: $(QEMU_SRCDIR) $(QEMU_SRC_GIT)
890907
mkdir -p $(dir $@)
891908
date > $@
892909

910+
stamps/build-llvm-linux: $(LLVM_SRCDIR) $(LLVM_SRC_GIT) \
911+
stamps/build-gcc-linux-stage2
912+
# We have the following situation:
913+
# - sysroot directory: $(INSTALL_DIR)/sysroot
914+
# - GCC install directory: $(INSTALL_DIR)
915+
# However, LLVM does not allow to set a GCC install prefix
916+
# (-DGCC_INSTALL_PREFIX) if a sysroot (-DDEFAULT_SYSROOT) is set
917+
# (the GCC install prefix will be ignored silently).
918+
# Without a proper sysroot path feature.h won't be found by clang.
919+
# Without a proper GCC install directory libgcc won't be found.
920+
# As a workaround we have to merge both paths:
921+
mkdir -p $(SYSROOT)/lib/
922+
ln -s -f $(INSTALL_DIR)/lib/gcc $(SYSROOT)/lib/gcc
923+
rm -rf $@ $(notdir $@)
924+
mkdir $(notdir $@)
925+
cd $(notdir $@) && ln -f -s $(SYSROOT) sysroot
926+
cd $(notdir $@) && \
927+
cmake $(LLVM_SRCDIR)/llvm \
928+
-DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) \
929+
-DCMAKE_BUILD_TYPE=Release \
930+
-DLLVM_TARGETS_TO_BUILD="RISCV" \
931+
-DLLVM_ENABLE_PROJECTS="clang;lld" \
932+
-DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \
933+
-DLLVM_DEFAULT_TARGET_TRIPLE="$(LINUX_TUPLE)" \
934+
-DDEFAULT_SYSROOT="../sysroot" \
935+
-DLLVM_RUNTIME_TARGETS=$(call make_tuple,$(XLEN),linux-gnu) \
936+
-DLLVM_INSTALL_TOOLCHAIN_ONLY=On \
937+
-DLLVM_PARALLEL_LINK_JOBS=4
938+
$(MAKE) -C $(notdir $@)
939+
$(MAKE) -C $(notdir $@) install
940+
cp $(notdir $@)/lib/riscv$(XLEN)-unknown-linux-gnu/libc++* $(SYSROOT)/lib
941+
cd $(INSTALL_DIR)/bin && ln -s clang $(LINUX_TUPLE)-clang
942+
mkdir -p $(dir $@) && touch $@
943+
944+
stamps/build-llvm-newlib:
945+
echo "Building LLVM is only supported in combination with a Linux toolchain."
946+
exit 1
947+
893948
stamps/build-dejagnu: $(DEJAGNU_SRCDIR) $(DEJAGNU_SRC_GIT)
894949
rm -rf $@ $(notdir $@)
895950
mkdir $(notdir $@)

README.md

Lines changed: 38 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Several standard packages are needed to build the toolchain.
2020

2121
On Ubuntu, executing the following command should suffice:
2222

23-
$ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build
23+
$ sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev
2424

2525
On Fedora/CentOS/RHEL OS, executing the following command should suffice:
2626

@@ -246,6 +246,37 @@ The command below can be used to run the glibc tests:
246246

247247
make check-glibc-linux
248248

249+
### LLVM / clang
250+
251+
LLVM can be used in combination with the RISC-V GNU Compiler Toolchain
252+
to build RISC-V applications. To build LLVM with C and C++ support the
253+
configure flag `--enable-llvm` can be used.
254+
255+
E.g. to build LLVM on top of a RV64 Linux toolchain the following commands
256+
can be used:
257+
258+
./configure --prefix=$RISCV --enable-llvm --enable-linux
259+
make
260+
261+
Note, that a combination of `--enable-llvm` and multilib configuration flags
262+
is not supported.
263+
Also note, that building LLVM is only supported in combination with building
264+
a Linux toolchain.
265+
266+
Below is an example how to build a rv64gc Linux toolchain with LLVM support,
267+
how to use it to build a C and a C++ application using clang, and how to
268+
execute the generated binaries using QEMU:
269+
270+
# Build rv64gc toolchain with LLVM
271+
./configure --prefix=$RISCV --enable-llvm --enable-linux --with-arch=rv64gc --with-abi=lp64d
272+
make -j$(nproc) all build-sim SIM=qemu
273+
# Build C application with clang
274+
$RISCV/bin/clang -march=rv64imafdc -o hello_world hello_world.c
275+
$RISCV/bin/qemu-riscv64 -L $RISCV/sysroot ./hello_world
276+
# Build C++ application with clang
277+
$RISCV/bin/clang++ -march=rv64imafdc -stdlib=libc++ -o hello_world_cpp hello_world_cpp.cxx
278+
$RISCV/bin/qemu-riscv64 -L $RISCV/sysroot ./hello_world_cpp
279+
249280
### Development
250281

251282
This section is only for developer or advanced user, or you want to build
@@ -296,13 +327,14 @@ For example you have a gcc in `$HOME/gcc`, use `--with-gcc-src` can specify that
296327

297328
Here is the list of configure option for specify source tree:
298329

299-
--with-gcc-src
300330
--with-binutils-src
301-
--with-newlib-src
302-
--with-glibc-src
303-
--with-musl-src
331+
--with-gcc-src
304332
--with-gdb-src
333+
--with-glibc-src
305334
--with-linux-headers-src
335+
--with-llvm-src
336+
--with-musl-src
337+
--with-newlib-src
338+
--with-pk-src
306339
--with-qemu-src
307340
--with-spike-src
308-
--with-pk-src

configure

Lines changed: 64 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,10 @@ LIBOBJS
587587
qemu_targets
588588
enable_libsanitizer
589589
with_linux_headers_src
590+
with_llvm_src
591+
with_pk_src
592+
with_dejagnu_src
593+
with_pk_src
590594
with_dejagnu_src
591595
with_pk_src
592596
with_spike_src
@@ -597,6 +601,7 @@ with_glibc_src
597601
with_newlib_src
598602
with_binutils_src
599603
with_gcc_src
604+
enable_llvm
600605
enable_gdb
601606
with_guile
602607
with_system_zlib
@@ -653,7 +658,6 @@ infodir
653658
docdir
654659
oldincludedir
655660
includedir
656-
runstatedir
657661
localstatedir
658662
sharedstatedir
659663
sysconfdir
@@ -693,6 +697,7 @@ with_host
693697
with_system_zlib
694698
with_guile
695699
enable_gdb
700+
enable_llvm
696701
with_gcc_src
697702
with_binutils_src
698703
with_newlib_src
@@ -702,6 +707,7 @@ with_gdb_src
702707
with_qemu_src
703708
with_spike_src
704709
with_pk_src
710+
with_llvm_src
705711
with_dejagnu_src
706712
with_linux_headers_src
707713
enable_libsanitizer
@@ -753,7 +759,6 @@ datadir='${datarootdir}'
753759
sysconfdir='${prefix}/etc'
754760
sharedstatedir='${prefix}/com'
755761
localstatedir='${prefix}/var'
756-
runstatedir='${localstatedir}/run'
757762
includedir='${prefix}/include'
758763
oldincludedir='/usr/include'
759764
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1006,15 +1011,6 @@ do
10061011
| -silent | --silent | --silen | --sile | --sil)
10071012
silent=yes ;;
10081013

1009-
-runstatedir | --runstatedir | --runstatedi | --runstated \
1010-
| --runstate | --runstat | --runsta | --runst | --runs \
1011-
| --run | --ru | --r)
1012-
ac_prev=runstatedir ;;
1013-
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
1014-
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
1015-
| --run=* | --ru=* | --r=*)
1016-
runstatedir=$ac_optarg ;;
1017-
10181014
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
10191015
ac_prev=sbindir ;;
10201016
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1152,7 +1148,7 @@ fi
11521148
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
11531149
datadir sysconfdir sharedstatedir localstatedir includedir \
11541150
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
1155-
libdir localedir mandir runstatedir
1151+
libdir localedir mandir
11561152
do
11571153
eval ac_val=\$$ac_var
11581154
# Remove trailing slashes.
@@ -1305,7 +1301,6 @@ Fine tuning of the installation directories:
13051301
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
13061302
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
13071303
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
1308-
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
13091304
--libdir=DIR object code libraries [EPREFIX/lib]
13101305
--includedir=DIR C header files [PREFIX/include]
13111306
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1339,12 +1334,14 @@ Optional Features:
13391334
[--disable-linux]
13401335
--enable-debug-info build glibc/musl/newlibc/libgcc with debug
13411336
information
1337+
--disable-debug-info build glibc and musl without debug infromation
13421338
--enable-multilib build both RV32 and RV64 runtime libraries (only
13431339
RV64 for musl libc) [--disable-multilib]
13441340
--enable-gcc-checking Enable gcc internal checking, it will make gcc very
13451341
slow, only enable it when developing gcc
13461342
[--disable-gcc-checking]
13471343
--disable-gdb Don't build GDB, as it's not upstream
1344+
--enable-llvm Build LLVM (clang)
13481345
--enable-libsanitizer Build libsanitizer, which only supports rv64
13491346
--enable-qemu-system Build qemu with system-mode emulation
13501347
@@ -1382,6 +1379,7 @@ Optional Packages:
13821379
--with-qemu-src Set qemu source path, use builtin source by default
13831380
--with-spike-src Set spike source path, use builtin source by default
13841381
--with-pk-src Set pk source path, use builtin source by default
1382+
--with-llvm-src Set llvm source path, use builtin source by default
13851383
--with-dejagnu-src Set dejagnu source path, use builtin source by
13861384
default
13871385
--with-linux-headers-src
@@ -3305,7 +3303,7 @@ if test "${enable_debug_info+set}" = set; then :
33053303
enableval=$enable_debug_info; enable_debug_info=yes
33063304
else
33073305
enable_debug_info=no
3308-
3306+
enableval=$enable_debug_info; disable_debug_info=yes
33093307
fi
33103308
33113309
@@ -3582,6 +3580,20 @@ else
35823580
35833581
fi
35843582
3583+
# Check whether --enable-llvm was given.
3584+
if test "${enable_llvm+set}" = set; then :
3585+
enableval=$enable_llvm; enable_llvm=yes
3586+
fi
3587+
3588+
3589+
if test "x$enable_llvm" != xyes; then :
3590+
enable_llvm=--disable-llvm
3591+
3592+
else
3593+
enable_llvm=--enable-llvm
3594+
3595+
fi
3596+
35853597
35863598
35873599
{
@@ -3757,6 +3769,44 @@ fi
37573769
}
37583770
{
37593771
3772+
# Check whether --with-llvm-src was given.
3773+
if test "${with_llvm_src+set}" = set; then :
3774+
withval=$with_llvm_src;
3775+
else
3776+
with_llvm_src=default
3777+
3778+
fi
3779+
3780+
if test "x$with_llvm_src" != xdefault; then :
3781+
with_llvm_src=$with_llvm_src
3782+
3783+
else
3784+
with_llvm_src="\$(srcdir)/llvm"
3785+
3786+
fi
3787+
3788+
}
3789+
{
3790+
3791+
# Check whether --with-dejagnu-src was given.
3792+
if test "${with_dejagnu_src+set}" = set; then :
3793+
withval=$with_dejagnu_src;
3794+
else
3795+
with_dejagnu_src=default
3796+
3797+
fi
3798+
3799+
if test "x$with_dejagnu_src" != xdefault; then :
3800+
with_dejagnu_src=$with_dejagnu_src
3801+
3802+
else
3803+
with_dejagnu_src="\$(srcdir)/dejagnu"
3804+
3805+
fi
3806+
3807+
}
3808+
{
3809+
37603810
# Check whether --with-dejagnu-src was given.
37613811
if test "${with_dejagnu_src+set}" = set; then :
37623812
withval=$with_dejagnu_src;

0 commit comments

Comments
 (0)