Skip to content

Commit ea26fd6

Browse files
cmuellnerkito-cheng
authored andcommitted
Add support to build LLVM/clang with C and C++ support
We currently have a stale "llvm" branch, that does not build. However, there is clear demand in the RISC-V toolchain community for a working LLVM on top of a recent GNU toolchain. In order to build such a toolchain, quite some LLVM and clang know-how is required to avoid path issues at LLVM build time or later when using clang. The main purpose of this commit is to demonstrate a way to combine the RISC-V GNU toolchain repo with LLVM, with the intent to save others hours of frustration, debugging time or support time. Signed-off-by: Christoph Müllner <[email protected]>
1 parent ee1bb92 commit ea26fd6

File tree

4 files changed

+142
-19
lines changed

4 files changed

+142
-19
lines changed

Makefile.in

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ 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

1617
SIM ?= @WITH_SIM@
1718

@@ -115,8 +116,16 @@ newlib: stamps/build-gdb-newlib
115116
linux: stamps/build-gdb-linux
116117
endif
117118
linux-native: stamps/build-gcc-linux-native
119+
ifeq (@enable_llvm@,--enable-llvm)
120+
all: stamps/build-llvm-@default_target@
121+
newlib: stamps/build-llvm-newlib
122+
linux: stamps/build-llvm-linux
123+
ifeq (@multilib_flags@,--enable-multilib)
124+
$(error "Setting multilib flags for LLVM builds is not supported.")
125+
endif
126+
endif
118127

119-
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu
128+
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu build-llvm
120129
build-binutils: stamps/build-binutils-@default_target@
121130
build-gdb: stamps/build-gdb-@default_target@
122131
build-gcc%: stamps/build-gcc-@default_target@-stage%
@@ -127,6 +136,7 @@ build-libc: stamps/build-newlib stamps/build-newlib-nano \
127136
stamps/merge-newlib-nano
128137
endif
129138
build-qemu: stamps/build-qemu
139+
build-llvm: stamps/build-llvm-@default_target@
130140

131141
REGRESSION_TEST_LIST = gcc
132142

@@ -272,6 +282,12 @@ else
272282
SPIKE_SRC_GIT :=
273283
endif
274284

285+
ifeq ($(findstring $(srcdir),$(LLVM_SRCDIR)),$(srcdir))
286+
LLVM_SRC_GIT := $(LLVM_SRCDIR)/.git
287+
else
288+
LLVM_SRC_GIT :=
289+
endif
290+
275291
ifneq ("$(wildcard $(GCC_SRCDIR)/.git)","")
276292
GCCPKGVER := g$(shell git -C $(GCC_SRCDIR) describe --always --dirty --exclude '*')
277293
else
@@ -865,6 +881,42 @@ stamps/build-qemu: $(QEMU_SRCDIR) $(QEMU_SRC_GIT)
865881
mkdir -p $(dir $@)
866882
date > $@
867883

884+
stamps/build-llvm-linux: $(LLVM_SRCDIR) $(LLVM_SRC_GIT) \
885+
stamps/build-gcc-linux-stage2
886+
# We have the following situation:
887+
# - sysroot directory: $(INSTALL_DIR)/sysroot
888+
# - GCC install directory: $(INSTALL_DIR)
889+
# However, LLVM does not allow to set a GCC install prefix
890+
# (-DGCC_INSTALL_PREFIX) if a sysroot (-DDEFAULT_SYSROOT) is set
891+
# (the GCC install prefix will be ignored silently).
892+
# Without a proper sysroot path feature.h won't be found by clang.
893+
# Without a proper GCC install directory libgcc won't be found.
894+
# As a workaround we have to merge both paths:
895+
mkdir -p $(SYSROOT)/lib/
896+
ln -s $(INSTALL_DIR)/lib/gcc $(SYSROOT)/lib/gcc
897+
rm -rf $@ $(notdir $@)
898+
mkdir $(notdir $@)
899+
cd $(notdir $@) && \
900+
cmake $(LLVM_SRCDIR)/llvm \
901+
-DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) \
902+
-DCMAKE_BUILD_TYPE=Release \
903+
-DLLVM_TARGETS_TO_BUILD="RISCV" \
904+
-DLLVM_ENABLE_PROJECTS="clang;lld" \
905+
-DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \
906+
-DLLVM_DEFAULT_TARGET_TRIPLE="$(LINUX_TUPLE)" \
907+
-DDEFAULT_SYSROOT="$(INSTALL_DIR)/sysroot" \
908+
-DLLVM_RUNTIME_TARGETS=$(call make_tuple,$(XLEN),linux-gnu) \
909+
-DLLVM_INSTALL_TOOLCHAIN_ONLY=On \
910+
-DLLVM_PARALLEL_LINK_JOBS=4
911+
$(MAKE) -C $(notdir $@)
912+
$(MAKE) -C $(notdir $@) install
913+
cd $(INSTALL_DIR)/bin && ln -s clang $(LINUX_TUPLE)-clang
914+
mkdir -p $(dir $@) && touch $@
915+
916+
stamps/build-llvm-newlib:
917+
echo "Building LLVM is only supported in combination with a Linux toolchain."
918+
exit 1
919+
868920
stamps/build-dejagnu: $(srcdir)/dejagnu $(srcdir)/dejagnu/.git
869921
rm -rf $@ $(notdir $@)
870922
mkdir $(notdir $@)

README.md

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,37 @@ The command below can be used to run the glibc tests:
245245

246246
make check-glibc-linux
247247

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

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

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

298-
--with-gcc-src
299329
--with-binutils-src
300-
--with-newlib-src
301-
--with-glibc-src
302-
--with-musl-src
330+
--with-gcc-src
303331
--with-gdb-src
332+
--with-glibc-src
304333
--with-linux-headers-src
334+
--with-llvm-src
335+
--with-musl-src
336+
--with-newlib-src
337+
--with-pk-src
305338
--with-qemu-src
306339
--with-spike-src
307-
--with-pk-src

configure

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ LIBOBJS
587587
qemu_targets
588588
enable_libsanitizer
589589
with_linux_headers_src
590+
with_llvm_src
590591
with_pk_src
591592
with_spike_src
592593
with_qemu_src
@@ -596,6 +597,7 @@ with_glibc_src
596597
with_newlib_src
597598
with_binutils_src
598599
with_gcc_src
600+
enable_llvm
599601
enable_gdb
600602
with_guile
601603
with_system_zlib
@@ -651,7 +653,6 @@ infodir
651653
docdir
652654
oldincludedir
653655
includedir
654-
runstatedir
655656
localstatedir
656657
sharedstatedir
657658
sysconfdir
@@ -690,6 +691,7 @@ with_host
690691
with_system_zlib
691692
with_guile
692693
enable_gdb
694+
enable_llvm
693695
with_gcc_src
694696
with_binutils_src
695697
with_newlib_src
@@ -699,6 +701,7 @@ with_gdb_src
699701
with_qemu_src
700702
with_spike_src
701703
with_pk_src
704+
with_llvm_src
702705
with_linux_headers_src
703706
enable_libsanitizer
704707
enable_qemu_system
@@ -749,7 +752,6 @@ datadir='${datarootdir}'
749752
sysconfdir='${prefix}/etc'
750753
sharedstatedir='${prefix}/com'
751754
localstatedir='${prefix}/var'
752-
runstatedir='${localstatedir}/run'
753755
includedir='${prefix}/include'
754756
oldincludedir='/usr/include'
755757
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@@ -1002,15 +1004,6 @@ do
10021004
| -silent | --silent | --silen | --sile | --sil)
10031005
silent=yes ;;
10041006

1005-
-runstatedir | --runstatedir | --runstatedi | --runstated \
1006-
| --runstate | --runstat | --runsta | --runst | --runs \
1007-
| --run | --ru | --r)
1008-
ac_prev=runstatedir ;;
1009-
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
1010-
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
1011-
| --run=* | --ru=* | --r=*)
1012-
runstatedir=$ac_optarg ;;
1013-
10141007
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
10151008
ac_prev=sbindir ;;
10161009
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@@ -1148,7 +1141,7 @@ fi
11481141
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
11491142
datadir sysconfdir sharedstatedir localstatedir includedir \
11501143
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
1151-
libdir localedir mandir runstatedir
1144+
libdir localedir mandir
11521145
do
11531146
eval ac_val=\$$ac_var
11541147
# Remove trailing slashes.
@@ -1301,7 +1294,6 @@ Fine tuning of the installation directories:
13011294
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
13021295
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
13031296
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
1304-
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
13051297
--libdir=DIR object code libraries [EPREFIX/lib]
13061298
--includedir=DIR C header files [PREFIX/include]
13071299
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@@ -1339,6 +1331,7 @@ Optional Features:
13391331
slow, only enable it when developing gcc
13401332
[--disable-gcc-checking]
13411333
--disable-gdb Don't build GDB, as it's not upstream
1334+
--enable-llvm Build LLVM (clang)
13421335
--enable-libsanitizer Build libsanitizer, which only supports rv64
13431336
--enable-qemu-system Build qemu with system-mode emulation
13441337
@@ -1375,6 +1368,7 @@ Optional Packages:
13751368
--with-qemu-src Set qemu source path, use builtin source by default
13761369
--with-spike-src Set spike source path, use builtin source by default
13771370
--with-pk-src Set pk source path, use builtin source by default
1371+
--with-llvm-src Set llvm source path, use builtin source by default
13781372
--with-linux-headers-src
13791373
Set linux-headers source path, use builtin source by
13801374
default
@@ -3556,6 +3550,20 @@ else
35563550
35573551
fi
35583552
3553+
# Check whether --enable-llvm was given.
3554+
if test "${enable_llvm+set}" = set; then :
3555+
enableval=$enable_llvm; enable_llvm=yes
3556+
fi
3557+
3558+
3559+
if test "x$enable_llvm" != xyes; then :
3560+
enable_llvm=--disable-llvm
3561+
3562+
else
3563+
enable_llvm=--enable-llvm
3564+
3565+
fi
3566+
35593567
35603568
35613569
{
@@ -3726,6 +3734,25 @@ fi
37263734
else
37273735
with_pk_src="\$(srcdir)/pk"
37283736
3737+
fi
3738+
3739+
}
3740+
{
3741+
3742+
# Check whether --with-llvm-src was given.
3743+
if test "${with_llvm_src+set}" = set; then :
3744+
withval=$with_llvm_src;
3745+
else
3746+
with_llvm_src=default
3747+
3748+
fi
3749+
3750+
if test "x$with_llvm_src" != xdefault; then :
3751+
with_llvm_src=$with_llvm_src
3752+
3753+
else
3754+
with_llvm_src="\$(srcdir)/llvm"
3755+
37293756
fi
37303757
37313758
}

configure.ac

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,17 @@ AS_IF([test "x$enable_gdb" != xno],
221221
[AC_SUBST(enable_gdb, --enable-gdb)],
222222
[AC_SUBST(enable_gdb, --disable-gdb)])
223223

224+
AC_ARG_ENABLE(llvm,
225+
[AS_HELP_STRING([--enable-llvm],
226+
[Build LLVM (clang)])],
227+
[enable_llvm=yes],
228+
[]
229+
)
230+
231+
AS_IF([test "x$enable_llvm" != xyes],
232+
[AC_SUBST(enable_llvm, --disable-llvm)],
233+
[AC_SUBST(enable_llvm, --enable-llvm)])
234+
224235
AC_DEFUN([AX_ARG_WITH_SRC],
225236
[{m4_pushdef([opt_name], with_$1_src)
226237
AC_ARG_WITH($1-src,
@@ -244,6 +255,7 @@ AX_ARG_WITH_SRC(gdb, gdb)
244255
AX_ARG_WITH_SRC(qemu, qemu)
245256
AX_ARG_WITH_SRC(spike, spike)
246257
AX_ARG_WITH_SRC(pk, pk)
258+
AX_ARG_WITH_SRC(llvm, llvm)
247259

248260
AC_ARG_WITH(linux-headers-src,
249261
[AC_HELP_STRING([--with-linux-headers-src],

0 commit comments

Comments
 (0)