diff --git a/README_OE.md b/README_OE.md index af956a923c04130b3e648c282c8f8719f20f36c7..ee97a9346a58af4de17ece0f0a540feb9d69a3fd 100644 --- a/README_OE.md +++ b/README_OE.md @@ -15,7 +15,14 @@ libstdc++-static \ libatomic + 交叉编译时需要额外安装autoconf、automake、libelf、libffi。 具体的编译选项可以在build.sh中查看,也可以通过“./build.sh -h”命令查看。 例如: - ./build.sh -r -b release -X X86 + ./build.sh -r -b release -X X86 -i + 交叉编译: + export BISHENG_LIBELF_PATH=/xxx/libelf/install + export BISHENG_LIBFFI_PATH=/xxx/libffi/install + export BISHENG_CROSS_TOOLCHAIN=/xxx/gcc-arm-aarch64-none-linux-gnu/ + export BISHENG_CROSS_SYSROOT=$BISHENG_CROSS_TOOLCHAIN/aarch64-none-linux-gnu/libc + ./build.sh -r -b release -X "AArch64;X86" -x aarch64 -i diff --git a/build.sh b/build.sh index 7b6b7908abbd185a34239ff96f5050a0c51b36d0..125109eb594bf66c9ab6e606ebacf3a874d282b1 100755 --- a/build.sh +++ b/build.sh @@ -4,10 +4,13 @@ C_COMPILER_PATH=gcc CXX_COMPILER_PATH=g++ +gcc_toolchain="$BISHENG_CROSS_TOOLCHAIN" +sysroot="$BISHENG_CROSS_SYSROOT" + # Initialize our own variables: buildtype=RelWithDebInfo backends="ARM;AArch64;X86" -enabled_projects="clang;lld;compiler-rt;openmp;clang-tools-extra" +enabled_projects="clang;lld;openmp;clang-tools-extra" embedded_toolchain="0" split_dwarf=on use_ccache="0" @@ -22,6 +25,8 @@ build_dir_name="build" install_dir_name="install" build_prefix="$dir/$build_dir_name" install_prefix="$dir/$install_dir_name" +cross_compile_arch="" +host_arch="$(uname -m)" # Use 8 threads for builds and tests by default. Use more threads if possible, # but avoid overloading the system by using up to 50% of available cores. @@ -58,12 +63,13 @@ Options: -t Enable unit tests for components that support them (make check-all). -v Enable verbose build output (default: quiet). -X archs Build only the specified semi-colon-delimited list of backends (default: "$backends"). + -x arch Build cross-compiling toolchain for the specified target. EOF } # Process command-line options. Remember the options for passing to the # containerized build script. -while getopts :b:cehiI:j:orstvX: optchr; do +while getopts :b:cehiI:j:orstvX:x: optchr; do case "$optchr" in b) buildtype="$OPTARG" @@ -117,7 +123,21 @@ while getopts :b:cehiI:j:orstvX: optchr; do X) backends="$OPTARG" ;; - :) + x) + cross_compile_arch=$OPTARG + case "${cross_compile_arch,,}" in + aarch64) + ;; + riscv64) + # RISCV backend is not built by default. + backends+=";RISCV" + ;; + *) + echo "$0: unsupported architecture for cross-compilation: $cross_compile_arch" + exit 1 + ;; + esac + ;; :) echo "$0: missing argument for option '-$OPTARG'" exit 1 ;; @@ -128,6 +148,23 @@ while getopts :b:cehiI:j:orstvX: optchr; do esac done +# Run a command as a background process, wait for its termination, and die +# if its exit code is non-zero. Running a command in the background and +# waiting allows the trap handler in this script to catch a signal and +# immediately stop all child processes. Note that sub-shells are not +# interruptible unless they also enable job control and wait for background +# commands. For this reason, sub-shells should be avoided. +run_or_die() { + set -x + "$@" & + set +x + wait $! || exit 1 +} + +COMMON_CFLAGS="-pthread" + +generator="Unix Makefiles" + CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$install_prefix \ -DCMAKE_BUILD_TYPE=$buildtype \ -DCMAKE_C_COMPILER=$C_COMPILER_PATH \ @@ -136,11 +173,11 @@ CMAKE_OPTIONS="-DCMAKE_INSTALL_PREFIX=$install_prefix \ # Warning: the -DLLVM_ENABLE_PROJECTS option is specified with cmake # to avoid issues with nested quotation marks +llvm_use_ccache="" if [ $use_ccache == "1" ]; then echo "Build using ccache" - CMAKE_OPTIONS="$CMAKE_OPTIONS \ - -DCMAKE_C_COMPILER_LAUNCHER=ccache \ - -DCMAKE_CXX_COMPILER_LAUNCHER=ccache " + llvm_use_ccache="-DCMAKE_C_COMPILER_LAUNCHER=ccache \ + -DCMAKE_CXX_COMPILER_LAUNCHER=ccache " fi if [ $embedded_toolchain == "1" ]; then @@ -167,15 +204,15 @@ fi mkdir -p "$build_prefix" && cd "$build_prefix" cmake $CMAKE_OPTIONS \ + $llvm_use_ccache \ -DCOMPILER_RT_BUILD_SANITIZERS=on \ -DLLVM_ENABLE_PROJECTS=$enabled_projects \ - -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ + -DLLVM_ENABLE_RUNTIMES="compiler-rt;libcxx;libcxxabi;libunwind" \ -DLLVM_USE_LINKER=gold \ -DLLVM_LIT_ARGS="-sv -j$threads" \ -DLLVM_USE_SPLIT_DWARF=$split_dwarf \ -DCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO="-Wl,--gdb-index -Wl,--compress-debug-sections=zlib"\ -DCMAKE_EXE_LINKER_FLAGS_DEBUG="-Wl,--gdb-index -Wl,--compress-debug-sections=zlib" \ - $verbose \ ../llvm make -j$threads @@ -187,6 +224,178 @@ if [ -n "$unit_test" ]; then make -j$threads $verbose check-all fi +build_openmp() { + local cross_suffix="-cross" + local stage_install_prefix="$cross_compile_install_prefix" + local cross_cmake_flags="$cross_cmake_flags \ + -DOPENMP_ENABLE_LIBOMPTARGET=off" + if [ -d "$libelf_path" ]; then + cross_cmake_flags="$cross_cmake_flags \ + -DLIBOMPTARGET_DEP_LIBELF_INCLUDE_DIR=$libelf_path/include \ + -DLIBOMPTARGET_DEP_LIBELF_LIBRARIES=$libelf_path/lib" + fi + if [ -d "$libffi_path" ]; then + cross_cmake_flags="$cross_cmake_flags \ + -DLIBOMPTARGET_DEP_LIBFFI_INCLUDE_DIR=$libffi_path/include \ + -DLIBOMPTARGET_DEP_LIBFFI_LIBRARIES=$libffi_path/lib64" + fi + + echo $1 + if [ "$1" = "static" ]; then + local static_suffix="-static" + local static_cmake_flags="-DLIBOMP_ENABLE_SHARED=off \ + -DLIBOMP_OMPT_SUPPORT=off \ + -DOPENMP_ENABLE_LIBOMPTARGET=off \ + -DOPENMP_ENABLE_OMPT_TOOLS=off" + else + local static_suffix="" + local static_cmake_flags="" + fi + + echo "$0: building openmp$static_suffix$cross_suffix" + + if [ $clean -eq 1 ]; then + rm -rf "$build_prefix"/projects/openmp"$static_suffix$cross_suffix" + fi + + mkdir -p "$build_prefix"/projects/openmp"$static_suffix$cross_suffix" && cd "$build_prefix"/projects/openmp"$static_suffix$cross_suffix" + # Disable OMPT and libomptarget, to prevent overwriting shared libraries + # that have already been built when building static archives. + run_or_die \ + cmake -Wno-dev -G "$generator" \ + -DCMAKE_BUILD_TYPE=$buildtype \ + -DCMAKE_INSTALL_PREFIX="$stage_install_prefix" \ + -DCMAKE_INSTALL_MESSAGE=LAZY \ + $llvm_use_ccache \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DLIBOMP_ENABLE_ASSERTIONS=off \ + $static_cmake_flags \ + -DOPENMP_LLVM_TOOLS_DIR="$(dirname $llvm_lit)" \ + -DOPENMP_LIT_ARGS="-sv -j$threads" \ + -DOPENMP_TEST_CXX_COMPILER="$stage_install_prefix/bin/clang++" \ + -DOPENMP_TEST_C_COMPILER="$stage_install_prefix/bin/clang" \ + $cross_cmake_flags \ + ../../../openmp + + run_or_die make -j$threads + run_or_die make -j$threads $verbose install +} + +build_libunwind() { + local stage_install_prefix="$cross_compile_install_prefix" + local cross_cmake_flags="$cross_cmake_flags" + + echo "$0: building libunwind-cross" + if [ $clean -eq 1 ]; then + rm -rf "$build_prefix"/projects/libunwind-cross + fi + mkdir -p "$build_prefix"/projects/libunwind-cross && cd "$build_prefix"/projects/libunwind-cross + run_or_die \ + cmake -Wno-dev -G "$generator" \ + -DCMAKE_BUILD_TYPE=$buildtype \ + -DCMAKE_INSTALL_PREFIX="$stage_install_prefix" \ + -DCMAKE_INSTALL_MESSAGE=LAZY \ + $llvm_use_ccache \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + $cross_cmake_flags \ + ../../../libunwind + + run_or_die make -j$threads + run_or_die make -j$threads $verbose install +} + +build_compiler_rt() { + local cross_cmake_flags="$cross_cmake_flags" + local stage_install_prefix="$($install_prefix/bin/clang --print-resource-dir)" + + echo "$0: building compiler-rt-cross" + if [ $clean -eq 1 ]; then + rm -rf "$build_prefix"/projects/compiler-rt-cross + fi + + mkdir -p "$build_prefix"/projects/compiler-rt-cross && cd "$build_prefix"/projects/compiler-rt-cross + run_or_die \ + cmake -Wno-dev -G "$generator" \ + -DCMAKE_BUILD_TYPE=$buildtype \ + -DCMAKE_INSTALL_PREFIX="$stage_install_prefix" \ + -DCMAKE_INSTALL_MESSAGE=LAZY \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DCOMPILER_RT_BUILD_BUILTINS=on \ + -DCOMPILER_RT_BUILD_LIBFUZZER=off \ + -DCOMPILER_RT_BUILD_PROFILE=on \ + -DCOMPILER_RT_BUILD_SANITIZERS=off \ + -DCOMPILER_RT_BUILD_XRAY=off \ + -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON \ + $cross_cmake_flags \ + ../../../compiler-rt + + run_or_die make -j$threads + run_or_die make -j$threads $verbose install +} + +build_libcxx() { + echo $install_libcxx + local stage_install_prefix="$cross_compile_install_prefix" + local cross_cmake_flags="$cross_cmake_flags" + + echo "$0: building libcxx-cross" + if [ $clean -eq 1 -a -e "$build_prefix/projects/libcxx-cross" ]; then + rm -rf "$build_prefix/projects/libcxx-cross" + fi + mkdir -p "$build_prefix/projects/libcxx-cross" && cd "$build_prefix/projects/libcxx-cross" + run_or_die \ + cmake -Wno-dev -G "$generator" \ + -DLLVM_ENABLE_PROJECTS="libcxx;libcxxabi" \ + -DCMAKE_BUILD_TYPE=$buildtype \ + -DCMAKE_C_COMPILER=clang \ + -DCMAKE_CXX_COMPILER=clang++ \ + -DLLVM_TABLEGEN=$install_prefix/bin/llvm-tblgen \ + -DCMAKE_INSTALL_PREFIX="$stage_install_prefix" \ + -DCMAKE_INSTALL_MESSAGE=LAZY \ + -DLLVM_ENABLE_ASSERTIONS=off \ + -DLLVM_ENABLE_ZSTD=off \ + -DLLVM_USE_SPLIT_DWARF=$split_dwarf \ + -DLLVM_LIT_ARGS="-sv -j$threads" \ + $cross_cmake_flags \ + ../../../llvm + + run_or_die make -j$threads $verbose + run_or_die make -j$threads $verbose install +} + +path_orig="$PATH" +ld_library_path_orig="$LD_LIBRARY_PATH" +export PATH="$install_prefix/bin:$path_orig" +export LD_LIBRARY_PATH="$install_prefix/lib:$ld_library_path_orig" + +if [ "$cross_compile_arch" != "" ]; then + if [ "$host_arch" = "$cross_compile_arch" ]; then + echo "$0: cannot cross-compile from $host_arch to $cross_compile_arch" + exit 1 + fi + + host_triple="$(llvm-config --host-target)" + cross_compile_triple="${host_triple/$host_arch/$cross_compile_arch}" + cross_compile_install_prefix="$install_prefix/$cross_compile_triple" + mkdir -p "$cross_compile_install_prefix" + + cross_cmake_flags="-DCMAKE_C_COMPILER_TARGET=$cross_compile_triple \ + -DCMAKE_CXX_COMPILER_TARGET=$cross_compile_triple \ + -DCMAKE_ASM_COMPILER_TARGET=$cross_compile_triple \ + -DCMAKE_SYSROOT=$sysroot \ + -DCMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN=$gcc_toolchain \ + -DCMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN=$gcc_toolchain" + + build_openmp shared + build_openmp static + build_libunwind + build_compiler_rt + build_libcxx +fi + cd .. # When building official deliverables, minimize file permissions under the