Skip to content

Instantly share code, notes, and snippets.

@aleph-ra
Last active March 16, 2025 14:05
Show Gist options
  • Save aleph-ra/cbed5ae5ce45b5155da884171452fb46 to your computer and use it in GitHub Desktop.
Save aleph-ra/cbed5ae5ce45b5155da884171452fb46 to your computer and use it in GitHub Desktop.
AdaptiveCpp installation script
#!/bin/bash
# Stop command echoing
set +x
# Propogate errors and fail on error
set -euo pipefail
# Default log level: INFO
QUIET_MODE=false
# Debug mode off
DEBUG_MODE=false
# Logging function
log() {
local level="$1"
local message="$2"
local timestamp
timestamp=$(date +"%Y-%m-%d %H:%M:%S")
case "$level" in
INFO)
[[ $QUIET_MODE == false ]] && echo -e "\033[1;34m[$timestamp] [INFO]\033[0m $message"
;;
WARN)
echo -e "\033[1;33m[$timestamp] [WARN]\033[0m $message" >&2
;;
ERROR)
echo -e "\033[1;31m[$timestamp] [ERROR]\033[0m $message" >&2
;;
*)
echo -e "\033[1;36m[$timestamp] [UNKNOWN]\033[0m $message" >&2
;;
esac
}
# Function to check if running inside Docker or Podman or other containerized envs
is_in_container() {
[[ -f /.dockerenv ]] && return 0
grep -qE '(docker|podman)' /proc/self/cgroup 2>/dev/null && return 0
grep -q 'containerd' /proc/self/cgroup 2>/dev/null && return 0
[[ -f /run/.containerenv ]] && return 0
return 1
}
# Function to check for sudo privileges
check_sudo() {
if ! is_in_container && ! sudo -n true 2>/dev/null; then
log WARN "This script requires sudo privileges. Please enter your password."
sudo -v || { log ERROR "Failed to acquire sudo privileges. Exiting."; exit 1; }
fi
}
# Function to check if a command exists
command_exists() {
command -v "$1" &>/dev/null
}
# Function to install missing dependencies
install_dependencies() {
local dependencies=("git" "software-properties-common" "cmake" "make" "wget")
local missing=()
for dep in "${dependencies[@]}"; do
if ! command_exists "$dep"; then
missing+=("$dep")
fi
done
if (( ${#missing[@]} > 0 )); then
log INFO "Installing missing dependencies: ${missing[*]}"
$SUDO apt update -y
export DEBIAN_FRONTEND=noninteractive # avoid fresh OS timezone setting
$SUDO apt install -y "${missing[@]}"
else
log INFO "All dependencies are already installed."
fi
}
# Function to check LLVM/Clang version
check_llvm_clang_version() {
local llvm_version=$(llvm-config-$1 --version 2>/dev/null | cut -d. -f1 || echo "0")
local clang_version=$(clang++-$1 --version 2>/dev/null | awk '/version/ {print $4}' | cut -d. -f1 || echo "0")
[[ "$llvm_version" -ne "0" && "$clang_version" -ne "0" ]]
}
# Function to return LLVM/Clang version found in a specified range
check_llvm_clang_versions_in_range() {
local min_version=$1
local max_version=$2
local found_version=0
for (( version=min_version; version<=max_version; version++ )); do
if check_llvm_clang_version $version; then
found_version=$version
fi
done
echo $found_version
}
#### AdaptiveCpp Install Script ####
ADAPTIVE_CPP_URL="https://github.com/AdaptiveCpp/AdaptiveCpp"
DEFAULT_INSTALL_PREFIX="/usr/local"
DEFAULT_KEEP_SOURCE_FILES=false
MINIMUM_LLVM_VERSION=14
INSTALL_PREFIX="$DEFAULT_INSTALL_PREFIX"
LLVM_VERSION=""
KEEP_SOURCE_FILES=$DEFAULT_KEEP_SOURCE_FILES
# Parse arguments
while [[ "$#" -gt 0 ]]; do
case $1 in
--acpp-install-prefix) INSTALL_PREFIX="$2"; shift ;;
--llvm-version) LLVM_VERSION="$2"; shift ;;
--keep-source-files) KEEP_SOURCE_FILES=true ;;
--quiet) QUIET_MODE=true ;;
--debug) DEBUG_MODE=true ;;
*) log ERROR "Unknown parameter: $1"; exit 1 ;;
esac
shift
done
# Enable debugging if requested
if [[ $DEBUG_MODE == true ]]; then
log INFO "Debug mode enabled."
set -x
fi
SUDO=$(is_in_container && echo "" || echo "sudo")
log INFO "Installing AdaptiveCPP to $INSTALL_PREFIX..."
# Ensure sudo privileges if not in Docker
check_sudo
# Install dependencies
install_dependencies
# Check for LLVM/Clang versions
if [[ $LLVM_VERSION ]]; then
if check_llvm_clang_version $LLVM_VERSION; then
FOUND_LLVM_VERSION=$LLVM_VERSION
else
FOUND_LLVM_VERSION=0
fi
else
# Get the latest stable version from apt.llvm.org
LLVM_VERSION=$(wget -q -O - https://apt.llvm.org/llvm.sh | grep -oP '(?<=CURRENT_LLVM_STABLE=)[0-9]+')
FOUND_LLVM_VERSION=$(check_llvm_clang_versions_in_range $MINIMUM_LLVM_VERSION $LLVM_VERSION)
fi
# Install LLVM/Clang if needed
if [ $FOUND_LLVM_VERSION -eq 0 ]; then
log INFO "Downloading and installing LLVM/Clang..."
wget -q https://apt.llvm.org/llvm.sh || { log ERROR "Failed to download LLVM setup script."; exit 1; }
chmod +x llvm.sh
log INFO "Installing LLVM/Clang version $LLVM_VERSION..."
$SUDO ./llvm.sh "$LLVM_VERSION"
# Revert command echoing if not in debug mode
if [[ $DEBUG_MODE == false ]]; then
set +x
fi
# Cleanup
rm -f llvm.sh
else
LLVM_VERSION=$FOUND_LLVM_VERSION
log INFO "Found LLVM/Clang version $FOUND_LLVM_VERSION. Skipping LLVM/Clang installation."
fi
# Ensure installation of required llvm-clang packages
$SUDO apt install -y \
"libclang-${LLVM_VERSION}-dev" "clang-tools-${LLVM_VERSION}" \
"libomp-${LLVM_VERSION}-dev" "llvm-${LLVM_VERSION}-dev" "lld-${LLVM_VERSION}"
# Get LLVM/Clang paths
LLVM_DIR=$(llvm-config-${LLVM_VERSION} --cmakedir)
log INFO "LLVM cmake path is $LLVM_DIR"
CLANG_EXECUTABLE_PATH=$(which clang++-${LLVM_VERSION})
log INFO "Clang++ executable path is $LLVM_DIR"
# Install libstdc++ for Clang
GCC_VERSION=$(clang++-${LLVM_VERSION} -v 2>&1 | awk -F/ '/Selected GCC/ {print $NF}')
log INFO "Installing libstdc++ version $GCC_VERSION..."
$SUDO apt install -y "libstdc++-${GCC_VERSION}-dev"
# Install Boost libraries for acpp
log INFO "Installing boost dependencies..."
$SUDO apt install -y libboost-fiber-dev libboost-context-dev libboost-test-dev
# Clone and build AdaptiveCpp
if [[ ! -d "AdaptiveCpp" ]]; then
log INFO "Cloning AdaptiveCpp repository..."
git clone "$ADAPTIVE_CPP_URL"
fi
cd AdaptiveCpp
rm -rf build && mkdir -p build && cd build
log INFO "Configuring build with CMake..."
CXX=$CLANG_EXECUTABLE_PATH cmake -DCMAKE_INSTALL_PREFIX="$INSTALL_PREFIX" -DLLVM_DIR="$LLVM_DIR" -DCLANG_EXECUTABLE_PATH="$CLANG_EXECUTABLE_PATH" ..
log INFO "Building and installing AdaptiveCpp..."
$SUDO make install
# Back to main pwd
cd ../..
# Clean up source files if not required
if [[ $KEEP_SOURCE_FILES == false ]]; then
log INFO "Removing source files as --keep-source-files is not set."
rm -rf AdaptiveCpp
fi
# Verify AdaptiveCpp installation
if ACPP_VERSION=$(acpp --acpp-version | grep 'AdaptiveCpp version:' | awk '{print $3}'); then
log INFO "\033[1;32mAdaptiveCpp version $ACPP_VERSION has been installed to $INSTALL_PREFIX.\033[0m"
else
log ERROR "Failed to verify AdaptiveCpp installation."
fi
@aleph-ra
Copy link
Author

aleph-ra commented Jan 28, 2025

The script can be used directly for installations as follows:
curl -L https://gist.githubusercontent.com/aleph-ra/cbed5ae5ce45b5155da884171452fb46/raw/772ed488a66f051400db59e2d760ab3e8abb95e2/install_acpp.sh | bash

Or by downloading it and running with available flags as follows:
chmod +x install_acpp.sh
./install_acpp.sh --install-prefix /opt/adaptivecpp --llvm-version 16

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment