about summary refs log tree commit diff homepage
path: root/scripts/build/p-llvm.inc
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/build/p-llvm.inc')
-rw-r--r--scripts/build/p-llvm.inc366
1 files changed, 366 insertions, 0 deletions
diff --git a/scripts/build/p-llvm.inc b/scripts/build/p-llvm.inc
new file mode 100644
index 00000000..4e0740a2
--- /dev/null
+++ b/scripts/build/p-llvm.inc
@@ -0,0 +1,366 @@
+validate_build_config_llvm() {
+    # Check variables that are needed for building 
+    [[ -n "${LLVM_SRC_BASE}" ]] || { echo "LLVM_SRC_BASE not set"; exit 1; }
+    [[ -n "${LLVM_VERSION_SHORT}" ]] || { echo "LLVM_VERSION_SHORT not set"; exit 1; }
+}
+
+setup_build_variables_llvm() {
+    LLVM_SUFFIX=""
+
+    local BuildMode=""
+    local enable_optimized=$(to_bool "${ENABLE_OPTIMIZED}")
+    local enable_debug=$(to_bool "${ENABLE_DEBUG}")
+    local disable_assertions=$(to_bool "${DISABLE_ASSERTIONS}")
+    local requires_rtti=$(to_bool "${REQUIRES_RTTI}")
+
+    if [[ "${enable_optimized}" == "1" ]]; then
+      LLVM_SUFFIX+="_O"
+      BuildMode="Release"
+    else
+      LLVM_SUFFIX+="_NO"
+    fi
+
+    if [[ ("${enable_debug}" == "1") || ("${enable_optimized}" != "1") ]]; then
+      LLVM_SUFFIX+="_D"
+      [ -z "$BuildMode" ] && BuildMode="Debug" || BuildMode="$BuildMode+Debug"
+    else
+      LLVM_SUFFIX+="_ND"
+    fi
+
+    if [[ "${disable_assertions}" == "1" || -z "${disable_assertions}" ]]; then
+      LLVM_SUFFIX+="_NA"
+    else
+      LLVM_SUFFIX+="_A"
+      [ -z "$BuildMode" ] && BuildMode="Asserts" || BuildMode="$BuildMode+Asserts"
+    fi
+
+    if [[ "${requires_rtti}" == "1" ]]; then
+      LLVM_SUFFIX+="_RTTI"
+    fi
+
+    if [[ "${SANITIZER_SUFFIX}x" != "x" ]]; then
+      LLVM_SUFFIX+="${SANITIZER_SUFFIX}"
+    fi
+
+    LLVM_SRC_BASE="${BASE}/llvm-${LLVM_VERSION_SHORT}"
+    LLVM_BUILD="${LLVM_SRC_BASE}-build${LLVM_SUFFIX}"
+    LLVM_INSTALL="${LLVM_SRC_BASE}-install${LLVM_SUFFIX}"
+    LLVM_BIN="${LLVM_INSTALL}/bin"
+    if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+      LLVM_BUILDMODE="$BuildMode"
+      LLVM_BUILD_BIN="${LLVM_BUILD}/${LLVM_BUILDMODE}/bin"
+    else
+      LLVM_BUILD_BIN="${LLVM_BUILD}/bin"
+    fi
+
+    LLVM_CONFIG="${LLVM_BIN}/llvm-config"
+    BITCODE_CC="${LLVM_BIN}/clang"
+    BITCODE_CXX="${LLVM_BIN}/clang++"
+
+
+    for sanitizer in "${SANITIZERS[@]}"; do
+      [[ -z "${sanitizer}" ]] && continue
+      # Undefined Behaviour Sanitizer
+      if [ "${sanitizer}" == "memory" ]; then
+        SANITIZER_LLVM_UNINSTRUMENTED="${LLVM_BUILD}_uninstrumented"
+        SANITIZER_LLVM_LIBCXX="${LLVM_BUILD}_libcxx"
+
+        SANITIZER_C_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang"
+        SANITIZER_CXX_COMPILER="${SANITIZER_LLVM_UNINSTRUMENTED}/bin/clang++"
+        SANITIZER_CMAKE_C_COMPILER=("-DCMAKE_C_COMPILER=${SANITIZER_C_COMPILER}")
+        SANITIZER_CMAKE_CXX_COMPILER=("-DCMAKE_CXX_COMPILER=${SANITIZER_CXX_COMPILER}")
+
+        MSAN_LINK_FLAGS=("-lc++abi" "-Wl,--rpath=${SANITIZER_LLVM_LIBCXX}/lib" "-L${SANITIZER_LLVM_LIBCXX}/lib")
+        MSAN_FLAGS=("${MSAN_LINK_FLAGS[@]}" -nostdinc++
+           -isystem "${SANITIZER_LLVM_LIBCXX}/include"
+           -isystem "${SANITIZER_LLVM_LIBCXX}/include/c++/v1"
+           "-fsanitize=memory"
+           "-fsanitize-memory-track-origins"
+           -w -fno-omit-frame-pointer -g)
+        SANITIZER_CXX_FLAGS+=("${MSAN_FLAGS[@]}" "-stdlib=libc++")
+        SANITIZER_C_FLAGS+=("${MSAN_FLAGS[@]}")
+        SANITIZER_LD_FLAGS+=("${MSAN_LINK_FLAGS[@]}")
+
+        # Use the uninstrumented compiler
+        BITCODE_CC="${SANITIZER_C_COMPILER}"
+        BITCODE_CXX="${SANITIZER_CXX_COMPILER}"
+        # But point to the instrumented llvm-config
+        LLVM_CONFIG="${LLVM_BIN}/llvm-config"
+        continue
+      fi
+      # Setup default sanitizer arguments
+      SANITIZER_C_COMPILER="${LLVM_BIN}/clang"
+      SANITIZER_CXX_COMPILER="${LLVM_BIN}/clang++"
+    done
+}
+
+download_llvm() {
+  # Skip step if we already checked out code
+  [[ -f "${LLVM_SRC_BASE}/.src_checked_out" ]] && return 0
+
+  # Checkout LLVM code
+  svn co "http://llvm.org/svn/llvm-project/llvm/branches/release_${LLVM_VERSION_SHORT}" "${LLVM_SRC_BASE}"
+  cd "${LLVM_SRC_BASE}/tools" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/cfe/branches/release_${LLVM_VERSION_SHORT}" clang
+  cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+  svn co "http://llvm.org/svn/llvm-project/compiler-rt/branches/release_${LLVM_VERSION_SHORT}" compiler-rt
+
+  if [[ ${LLVM_VERSION_SHORT} -gt 37 ]]; then
+    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+    svn co "http://llvm.org/svn/llvm-project/libcxx/branches/release_${LLVM_VERSION_SHORT}" libcxx
+    cd "${LLVM_SRC_BASE}/projects" || (echo "Directory does not exist"; exit 1)
+    svn co "http://llvm.org/svn/llvm-project/libcxxabi/branches/release_${LLVM_VERSION_SHORT}" libcxxabi
+  fi
+
+  # Apply existing patches if needed
+  if [ -f "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch" ]; then
+     cd "${LLVM_SRC_BASE}" || (echo "Directory does not exist"; exit 1)
+     patch -p0 -i "${DIR}/patches/llvm${LLVM_VERSION_SHORT}.patch"
+  fi
+
+  touch "${LLVM_SRC_BASE}/.src_checked_out" 
+}
+
+build_llvm() {
+    local enable_optimized=$(to_bool "${ENABLE_OPTIMIZED}")
+    local enable_debug=$(to_bool "${ENABLE_DEBUG}")
+    local disable_assertions=$(to_bool "${DISABLE_ASSERTIONS}")
+    local requires_rtti=$(to_bool "${REQUIRES_RTTI}")
+
+    # For memory sanitizer, we have a multi-stage build process
+    if [[ "${SANITIZER_BUILD}" == "memory" ]]; then
+       if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+         echo "Memory sanitizer builds for <= LLVM 3.7 are not supported"
+         exit 1
+       fi
+       # Build uninstrumented compiler
+       mkdir -p "${SANITIZER_LLVM_UNINSTRUMENTED}"
+       cd "${SANITIZER_LLVM_UNINSTRUMENTED}"
+       cmake -GNinja -DCMAKE_BUILD_TYPE=Release "${LLVM_SRC_BASE}"
+       ninja
+
+       # Build instrumented libc/libc++
+       mkdir -p "${SANITIZER_LLVM_LIBCXX}"
+       cd "${SANITIZER_LLVM_LIBCXX}"
+       cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+        -DLLVM_USE_SANITIZER=MemoryWithOrigins \
+        "${SANITIZER_CMAKE_C_COMPILER}" \
+        "${SANITIZER_CMAKE_CXX_COMPILER}" \
+        "${LLVM_SRC_BASE}"
+       ninja cxx cxxabi
+
+       # Build instrumented clang
+       mkdir -p "${LLVM_BUILD}"
+       cd "${LLVM_BUILD}"
+       C_F="${SANITIZER_C_FLAGS[*]}"
+       CXX_F="${SANITIZER_CXX_FLAGS[*]}"
+       LD_F="${SANITIZER_LD_FLAGS[*]}"
+       cmake -GNinja \
+          "${SANITIZER_CMAKE_C_COMPILER[*]}" \
+          "${SANITIZER_CMAKE_CXX_COMPILER[*]}" \
+          -DCMAKE_C_FLAGS="$C_F" \
+          -DCMAKE_CXX_FLAGS="${CXX_F}" \
+          -DCMAKE_BUILD_TYPE=RelWithDebInfo \
+          -DLLVM_ENABLE_ASSERTIONS=On \
+          -DLLVM_USE_SANITIZER=MemoryWithOrigins \
+          -DLLVM_ENABLE_LIBCXX=ON \
+          -DCMAKE_EXE_LINKER_FLAGS="${LD_F}" \
+          -DCMAKE_INSTALL_PREFIX="${LLVM_INSTALL}" \
+          "${LLVM_SRC_BASE}"
+      # Build clang as a dependency and install all needed packages
+      ninja clang
+      return 0
+    fi
+
+  # Configure; build; and install
+  mkdir -p "${LLVM_BUILD}"
+  cd "${LLVM_BUILD}"
+
+  # Skip building if already finished
+  [[ -e "${LLVM_BUILD}/.build_finished" ]] && return 0
+
+
+  # Configure LLVM
+  if [[ ${LLVM_VERSION_SHORT} -le 37 ]]; then
+    local CONFIG=("--enable-jit" "--prefix=${LLVM_INSTALL}")
+    if [[ "${enable_optimized}" == "1" ]]; then
+      CONFIG+=(--enable-optimized)
+    else
+      CONFIG+=(--disable-optimized)
+    fi
+
+    if [[ "${disable_assertions}" == "1" ]]; then
+      CONFIG+=(--disable-assertions)
+    else
+      CONFIG+=(--enable-assertions)
+    fi
+
+    if [[ "${enable_debug}" == "1" ]]; then
+      CONFIG+=(--enable-debug-runtime --enable-debug-symbols)
+    else
+      CONFIG+=(--disable-debug-symbols)
+    fi
+
+    local variables=()
+    if [[ -n "${CC:-}" ]]; then
+        variables+=("CC=${CC}")
+    fi
+
+    if [[ -n "${CXX:-}" ]]; then
+        variables+=("CXX=${CXX}")
+    fi
+
+    if [[ -n "${LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
+        variables+=("CFLAGS=${LLVM_CFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
+        variables+=("CXXFLAGS=${LLVM_CXXFLAGS}")
+    fi
+
+    if [[ -n "${LLVM_LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+    ${variables[@]+"${variables[@]}"} "${LLVM_SRC_BASE}/configure" "${CONFIG[@]}"
+
+  else
+    CONFIG=(
+        "-DCMAKE_INSTALL_PREFIX=${LLVM_INSTALL}"
+        "-LLVM_BUILD_LLVM_DYLIB=TRUE"
+    )
+    # cmake build
+    if [[ "${enable_optimized}" == "1" && "${enable_debug}" != "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=Release")
+    fi
+    if [[ "${enable_optimized}" == "1" && "${enable_debug}" == "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=RelWithDebInfo")
+    fi
+    if [[ "${enable_optimized}" != "1" && "${enable_debug}" == "1" ]]; then
+      CONFIG+=("-DCMAKE_BUILD_TYPE=Debug")
+    fi
+
+    if [[ "${disable_assertions}" == "1" ]]; then
+      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=Off")
+    else
+      CONFIG+=("-DLLVM_ENABLE_ASSERTIONS=On")
+    fi
+
+    if [[ -n "${LLVM_CFLAGS:-}" ]]; then
+      CONFIG+=("-DCMAKE_C_FLAGS=\"$LLVM_CFLAGS\"")
+    fi
+
+    if [[ -n "${LLVM_CXXFLAGS:-}" ]]; then
+      CONFIG+=("-DCMAKE_CXX_FLAGS=\"$LLVM_CXXFLAGS\"")
+    fi
+
+    if [[ "${requires_rtti}" -eq 1 ]]; then
+      CONFIG+=("-DLLVM_ENABLE_RTTI=TRUE")
+    fi
+
+    # Remove unneeded targets
+    CONFIG+=(
+       -DLLVM_INCLUDE_EXAMPLES=OFF
+#       -DLLVM_INCLUDE_TESTS=OFF
+#       -DCLANG_INCLUDE_TESTS=OFF
+       -DLLVM_INCLUDE_BENCHMARKS=OFF
+       -DBUILD_SHARED_LIBS=ON
+    )
+
+    local variables=("")
+
+    if [[ -n "${CC:-}" ]]; then
+        variables+=("CC=${CC}")
+    fi
+
+    if [[ -n "${CXX:-}" ]]; then
+        variables+=("CXX=${CXX}")
+    fi
+
+    if [[ -n "${LDFLAGS:-}" ]]; then
+        variables+=("LDFLAGS=${LLVM_LDFLAGS}")
+    fi
+
+    if [[ -n "${variables[*]}" ]]; then
+      "${variables[*]}" cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
+    else
+      cmake "${CONFIG[@]}" "${LLVM_SRC_BASE}"
+    fi
+  fi
+
+  # Linking LLVM can require a lot of memory.
+  # First try multicore - if that doesn't work, try single core
+  (make "-j$(nproc)") || (make) || return 1
+  touch "${LLVM_BUILD}/.build_finished"
+}
+
+install_llvm() {
+  if [[ "${SANITIZER_BUILD}" != "memory" ]]; then
+    cd "${LLVM_BUILD}"
+    make "-j$(nproc)" install
+    cp "${LLVM_BUILD_BIN}/FileCheck" "${LLVM_INSTALL}/bin/"
+    cp "${LLVM_BUILD_BIN}/not" "${LLVM_INSTALL}/bin/"
+  
+    # Remove debug information from binaries
+    strip "${LLVM_INSTALL}/bin/"* || /bin/true
+    strip "${LLVM_INSTALL}/lib/libclang"* || /bin/true
+    strip "${LLVM_INSTALL}/lib/libLTO"* || /bin/true
+  else
+    # Handle memory sanitizer install
+    LLVM_PACKAGES=( \
+      install-clang install-llvm-config install-llvm-objdump
+      install-llvm-link install-llvm-ar install-llvm-nm install-llvm-dis
+      install-clang-headers install-llvm-as
+      install-llvm-symbolizer install-LLVMSupport install-lli not FileCheck )
+  
+    if [[ ${LLVM_VERSION_SHORT} -eq 38 ]]; then
+      LLVM_PACKAGES=("${LLVM_PACKAGES[@]}" installhdrs)
+    else
+      LLVM_PACKAGES=("${LLVM_PACKAGES[@]}" install-llvm-headers)
+    fi
+  
+    ninja "${LLVM_PACKAGES[@]}"
+
+    for i in $(ninja -t targets |grep install-LLVM | cut -d : -f 1); do ninja "$i"; done
+    
+    cp "${LLVM_BUILD}/bin/FileCheck" "${LLVM_INSTALL}/bin/"
+    cp "${LLVM_BUILD}/bin/not" "${LLVM_INSTALL}/bin/"
+  fi
+
+  touch "${LLVM_INSTALL}/.install_finished"
+}
+
+# Check if the binary artifact is installed
+is_installed_llvm() {
+  (
+    setup_build_variables_llvm
+    # Check if the specific llvm-config exists
+    [[ -f "${LLVM_BUILD_BIN}/llvm-config" ]]
+    [[ -f "${LLVM_INSTALL}/.install_finished" ]]
+  ) || return 1
+}
+
+# Returns a unique id for this configuration
+get_docker_config_id_llvm() {
+  (
+    setup_build_variables_llvm
+    echo "${LLVM_VERSION_SHORT}${LLVM_SUFFIX}"
+  )
+}
+
+setup_artifact_variables_llvm() {
+  setup_build_variables_llvm
+}
+
+get_build_artifacts_llvm() {
+  (
+    setup_build_variables_llvm
+    echo "${LLVM_INSTALL}"
+    echo "${LLVM_SRC_BASE}"
+    [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_UNINSTRUMENTED}"
+    [[ "${sanitizer}" == "memory" ]] && echo "${SANITIZER_LLVM_LIBCXX}"
+  )
+}
\ No newline at end of file