Skip to content

Instantly share code, notes, and snippets.

@melver
Last active July 17, 2020 07:58
Show Gist options
  • Save melver/fe8a5fd9e43e21fab569ee24fc9c6072 to your computer and use it in GitHub Desktop.
Save melver/fe8a5fd9e43e21fab569ee24fc9c6072 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# SPDX-License-Identifier: Apache-2.0
# Copyright 2020 Google LLC.
# Author: Marco Elver
#
# Helper script to checkout and build a recent Git version of Clang/LLVM.
set -ue
readonly LLVM_REPO="https://github.com/llvm/llvm-project.git"
readonly LLVM_SRC="llvm-project"
# May be overridden from environment.
: ${LLVM_COMMIT:="origin/release/11.x"}
pr_info() { printf '\e[1;32mINFO: \e[0m'"$@" 1>&2; }
die() { printf '\e[1;31mERROR: \e[0m'"$@" 1>&2; exit 1; }
check_have() { type -p "$1" &>/dev/null || die "'%s' not found!\n" "$1"; }
check_deps() {
check_have make
check_have cmake
}
prepare_and_cwd_build() {
pr_info "Preparing ...\n"
local dst_dir="${1%/}" # Strip trailing '/'
mkdir -p "$dst_dir" && cd "$dst_dir"
# Get the source and point it to the commit we want
if [[ ! -d "$LLVM_SRC" ]]; then
git clone "$LLVM_REPO" "$LLVM_SRC"
fi
if [[ -n "$LLVM_COMMIT" ]]; then
(cd "$LLVM_SRC" && git fetch && git checkout -B for-build "$LLVM_COMMIT")
fi
mkdir -p build && cd build
}
build() {
local prefix="$1"
# Let's build *with* assertions on, since we're pulling in a Git version.
local cmake_args=(
-DLLVM_ENABLE_PROJECTS="clang;compiler-rt"
-DCMAKE_BUILD_TYPE=Release
-DLLVM_ENABLE_ASSERTIONS=On
)
[[ -n "$prefix" ]] && cmake_args+=("-DCMAKE_INSTALL_PREFIX:PATH=$prefix") || :
if [[ -n "${LLVM_USE_COMPILER:-}" ]]; then
cmake_args+=(
-DCMAKE_C_COMPILER="${LLVM_USE_COMPILER% *}"
-DCMAKE_CXX_COMPILER="${LLVM_USE_COMPILER#* }"
)
fi
pr_info "Building ...\n"
echo cmake "${cmake_args[@]}" "../${LLVM_SRC}/llvm"
cmake "${cmake_args[@]}" "../${LLVM_SRC}/llvm"
make -j$(nproc)
}
check_install() {
local prefix="$1"
pr_info "Checking ...\n"
# At least run check-clang. All tests would probably be a little too much.
make -j$(nproc) check-clang
if [[ -z "$prefix" ]]; then
local expect_clang="$(pwd)/bin/clang"
else
make -j$(nproc) install
local expect_clang="${prefix}/bin/clang"
fi
[[ ! -x "$expect_clang" ]] && die "could not find: %s\n" "$expect_clang" || :
pr_info "Clang binary available at: %s\n" "$expect_clang"
}
main() {
if (( $# < 1 )); then
echo "Usage: $0 <build-dir> [<install-prefix>]"
echo "Optional: If <install-prefix> is provided, installs Clang/LLVM into <install-prefix>."
exit 42
fi
local build_dir="$1"
local prefix="${2:-}"
if [[ -n "$prefix" ]]; then
[[ ! -d "$prefix" ]] && die "Directory does not exist: %s\n" "$prefix" || :
# Get prefix before we cwd.
prefix="$(cd "$prefix" && pwd)"
fi
check_deps
prepare_and_cwd_build "$build_dir"
build "$prefix"
check_install "$prefix"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment