Browse Source

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 <christoph.muellner@vrull.eu>
pull/1263/head
Christoph Müllner 4 years ago
committed by Kito Cheng
parent
commit
ea26fd6cb8
  1. 54
      Makefile.in
  2. 42
      README.md
  3. 53
      configure
  4. 12
      configure.ac

54
Makefile.in

@ -12,6 +12,7 @@ GDB_SRCDIR := @with_gdb_src@
QEMU_SRCDIR := @with_qemu_src@
SPIKE_SRCDIR := @with_spike_src@
PK_SRCDIR := @with_pk_src@
LLVM_SRCDIR := @with_llvm_src@
SIM ?= @WITH_SIM@
@ -115,8 +116,16 @@ newlib: stamps/build-gdb-newlib
linux: stamps/build-gdb-linux
endif
linux-native: stamps/build-gcc-linux-native
ifeq (@enable_llvm@,--enable-llvm)
all: stamps/build-llvm-@default_target@
newlib: stamps/build-llvm-newlib
linux: stamps/build-llvm-linux
ifeq (@multilib_flags@,--enable-multilib)
$(error "Setting multilib flags for LLVM builds is not supported.")
endif
endif
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu
.PHONY: build-binutils build-gdb build-gcc1 build-libc build-gcc2 build-qemu build-llvm
build-binutils: stamps/build-binutils-@default_target@
build-gdb: stamps/build-gdb-@default_target@
build-gcc%: stamps/build-gcc-@default_target@-stage%
@ -127,6 +136,7 @@ build-libc: stamps/build-newlib stamps/build-newlib-nano \
stamps/merge-newlib-nano
endif
build-qemu: stamps/build-qemu
build-llvm: stamps/build-llvm-@default_target@
REGRESSION_TEST_LIST = gcc
@ -272,6 +282,12 @@ else
SPIKE_SRC_GIT :=
endif
ifeq ($(findstring $(srcdir),$(LLVM_SRCDIR)),$(srcdir))
LLVM_SRC_GIT := $(LLVM_SRCDIR)/.git
else
LLVM_SRC_GIT :=
endif
ifneq ("$(wildcard $(GCC_SRCDIR)/.git)","")
GCCPKGVER := g$(shell git -C $(GCC_SRCDIR) describe --always --dirty --exclude '*')
else
@ -865,6 +881,42 @@ stamps/build-qemu: $(QEMU_SRCDIR) $(QEMU_SRC_GIT)
mkdir -p $(dir $@)
date > $@
stamps/build-llvm-linux: $(LLVM_SRCDIR) $(LLVM_SRC_GIT) \
stamps/build-gcc-linux-stage2
# We have the following situation:
# - sysroot directory: $(INSTALL_DIR)/sysroot
# - GCC install directory: $(INSTALL_DIR)
# However, LLVM does not allow to set a GCC install prefix
# (-DGCC_INSTALL_PREFIX) if a sysroot (-DDEFAULT_SYSROOT) is set
# (the GCC install prefix will be ignored silently).
# Without a proper sysroot path feature.h won't be found by clang.
# Without a proper GCC install directory libgcc won't be found.
# As a workaround we have to merge both paths:
mkdir -p $(SYSROOT)/lib/
ln -s $(INSTALL_DIR)/lib/gcc $(SYSROOT)/lib/gcc
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)
cd $(notdir $@) && \
cmake $(LLVM_SRCDIR)/llvm \
-DCMAKE_INSTALL_PREFIX=$(INSTALL_DIR) \
-DCMAKE_BUILD_TYPE=Release \
-DLLVM_TARGETS_TO_BUILD="RISCV" \
-DLLVM_ENABLE_PROJECTS="clang;lld" \
-DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \
-DLLVM_DEFAULT_TARGET_TRIPLE="$(LINUX_TUPLE)" \
-DDEFAULT_SYSROOT="$(INSTALL_DIR)/sysroot" \
-DLLVM_RUNTIME_TARGETS=$(call make_tuple,$(XLEN),linux-gnu) \
-DLLVM_INSTALL_TOOLCHAIN_ONLY=On \
-DLLVM_PARALLEL_LINK_JOBS=4
$(MAKE) -C $(notdir $@)
$(MAKE) -C $(notdir $@) install
cd $(INSTALL_DIR)/bin && ln -s clang $(LINUX_TUPLE)-clang
mkdir -p $(dir $@) && touch $@
stamps/build-llvm-newlib:
echo "Building LLVM is only supported in combination with a Linux toolchain."
exit 1
stamps/build-dejagnu: $(srcdir)/dejagnu $(srcdir)/dejagnu/.git
rm -rf $@ $(notdir $@)
mkdir $(notdir $@)

42
README.md

@ -245,6 +245,37 @@ The command below can be used to run the glibc tests:
make check-glibc-linux
### LLVM / clang
LLVM can be used in combination with the RISC-V GNU Compiler Toolchain
to build RISC-V applications. To build LLVM with C and C++ support the
configure flag `--enable-llvm` can be used.
E.g. to build LLVM on top of a RV64 Linux toolchain the following commands
can be used:
./configure --prefix=$RISCV --enable-llvm --enable-linux
make
Note, that a combination of `--enable-llvm` and multilib configuration flags
is not supported.
Also note, that building LLVM is only supported in combination with building
a Linux toolchain.
Below is an example how to build a rv64gc Linux toolchain with LLVM support,
how to use it to build a C and a C++ application using clang, and how to
execute the generated binaries using QEMU:
# Build rv64gc toolchain with LLVM
./configure --prefix=$RISCV --enable-llvm --enable-linux --with-arch=rv64gc --with-abi=lp64d
make -j$(nproc) all build-sim SIM=qemu
# Build C application with clang
$RISCV/bin/clang -march=rv64imafdc -o hello_world hello_world.c
$RISCV/bin/qemu-riscv64 ./hello-world
# Build C++ application with clang
$RISCV/bin/clang++ -march=rv64imafdc -stdlib=libc++ -o hello_world_cpp hello_world_cpp.cxx
$RISCV/bin/qemu-riscv64 ./hello-world_cpp
### Development
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
Here is the list of configure option for specify source tree:
--with-gcc-src
--with-binutils-src
--with-newlib-src
--with-glibc-src
--with-musl-src
--with-gcc-src
--with-gdb-src
--with-glibc-src
--with-linux-headers-src
--with-llvm-src
--with-musl-src
--with-newlib-src
--with-pk-src
--with-qemu-src
--with-spike-src
--with-pk-src

53
configure

@ -587,6 +587,7 @@ LIBOBJS
qemu_targets
enable_libsanitizer
with_linux_headers_src
with_llvm_src
with_pk_src
with_spike_src
with_qemu_src
@ -596,6 +597,7 @@ with_glibc_src
with_newlib_src
with_binutils_src
with_gcc_src
enable_llvm
enable_gdb
with_guile
with_system_zlib
@ -651,7 +653,6 @@ infodir
docdir
oldincludedir
includedir
runstatedir
localstatedir
sharedstatedir
sysconfdir
@ -690,6 +691,7 @@ with_host
with_system_zlib
with_guile
enable_gdb
enable_llvm
with_gcc_src
with_binutils_src
with_newlib_src
@ -699,6 +701,7 @@ with_gdb_src
with_qemu_src
with_spike_src
with_pk_src
with_llvm_src
with_linux_headers_src
enable_libsanitizer
enable_qemu_system
@ -749,7 +752,6 @@ datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
runstatedir='${localstatedir}/run'
includedir='${prefix}/include'
oldincludedir='/usr/include'
docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
@ -1002,15 +1004,6 @@ do
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
-runstatedir | --runstatedir | --runstatedi | --runstated \
| --runstate | --runstat | --runsta | --runst | --runs \
| --run | --ru | --r)
ac_prev=runstatedir ;;
-runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \
| --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \
| --run=* | --ru=* | --r=*)
runstatedir=$ac_optarg ;;
-sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
ac_prev=sbindir ;;
-sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
@ -1148,7 +1141,7 @@ fi
for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
datadir sysconfdir sharedstatedir localstatedir includedir \
oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
libdir localedir mandir runstatedir
libdir localedir mandir
do
eval ac_val=\$$ac_var
# Remove trailing slashes.
@ -1301,7 +1294,6 @@ Fine tuning of the installation directories:
--sysconfdir=DIR read-only single-machine data [PREFIX/etc]
--sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
--localstatedir=DIR modifiable single-machine data [PREFIX/var]
--runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
--libdir=DIR object code libraries [EPREFIX/lib]
--includedir=DIR C header files [PREFIX/include]
--oldincludedir=DIR C header files for non-gcc [/usr/include]
@ -1339,6 +1331,7 @@ Optional Features:
slow, only enable it when developing gcc
[--disable-gcc-checking]
--disable-gdb Don't build GDB, as it's not upstream
--enable-llvm Build LLVM (clang)
--enable-libsanitizer Build libsanitizer, which only supports rv64
--enable-qemu-system Build qemu with system-mode emulation
@ -1375,6 +1368,7 @@ Optional Packages:
--with-qemu-src Set qemu source path, use builtin source by default
--with-spike-src Set spike source path, use builtin source by default
--with-pk-src Set pk source path, use builtin source by default
--with-llvm-src Set llvm source path, use builtin source by default
--with-linux-headers-src
Set linux-headers source path, use builtin source by
default
@ -3556,6 +3550,20 @@ else
fi
# Check whether --enable-llvm was given.
if test "${enable_llvm+set}" = set; then :
enableval=$enable_llvm; enable_llvm=yes
fi
if test "x$enable_llvm" != xyes; then :
enable_llvm=--disable-llvm
else
enable_llvm=--enable-llvm
fi
{
@ -3726,6 +3734,25 @@ fi
else
with_pk_src="\$(srcdir)/pk"
fi
}
{
# Check whether --with-llvm-src was given.
if test "${with_llvm_src+set}" = set; then :
withval=$with_llvm_src;
else
with_llvm_src=default
fi
if test "x$with_llvm_src" != xdefault; then :
with_llvm_src=$with_llvm_src
else
with_llvm_src="\$(srcdir)/llvm"
fi
}

12
configure.ac

@ -221,6 +221,17 @@ AS_IF([test "x$enable_gdb" != xno],
[AC_SUBST(enable_gdb, --enable-gdb)],
[AC_SUBST(enable_gdb, --disable-gdb)])
AC_ARG_ENABLE(llvm,
[AS_HELP_STRING([--enable-llvm],
[Build LLVM (clang)])],
[enable_llvm=yes],
[]
)
AS_IF([test "x$enable_llvm" != xyes],
[AC_SUBST(enable_llvm, --disable-llvm)],
[AC_SUBST(enable_llvm, --enable-llvm)])
AC_DEFUN([AX_ARG_WITH_SRC],
[{m4_pushdef([opt_name], with_$1_src)
AC_ARG_WITH($1-src,
@ -244,6 +255,7 @@ AX_ARG_WITH_SRC(gdb, gdb)
AX_ARG_WITH_SRC(qemu, qemu)
AX_ARG_WITH_SRC(spike, spike)
AX_ARG_WITH_SRC(pk, pk)
AX_ARG_WITH_SRC(llvm, llvm)
AC_ARG_WITH(linux-headers-src,
[AC_HELP_STRING([--with-linux-headers-src],

Loading…
Cancel
Save