#!/usr/bin/env bash # Copyright (c) the JPEG XL Project Authors. All rights reserved. # # Use of this source code is governed by a BSD-style # license that can be found in the LICENSE file. set -eu MYDIR=$(dirname $(realpath "$0")) # Convenience flag to pass both CMAKE_C_FLAGS and CMAKE_CXX_FLAGS CMAKE_FLAGS=${CMAKE_FLAGS:-} CMAKE_C_FLAGS=${CMAKE_C_FLAGS:-${CMAKE_FLAGS}} CMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS:-${CMAKE_FLAGS}} CMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS:-} CLANG_VERSION="${CLANG_VERSION:-}" # Detect the clang version suffix and store it in CLANG_VERSION. For example, # "6.0" for clang 6 or "7" for clang 7. detect_clang_version() { if [[ -n "${CLANG_VERSION}" ]]; then return 0 fi local clang_version=$("${CC:-clang}" --version | head -n1) local llvm_tag case "${clang_version}" in "clang version 6."*) CLANG_VERSION="6.0" ;; "clang version 7."*) CLANG_VERSION="7" ;; "clang version 8."*) CLANG_VERSION="8" ;; "clang version 9."*) CLANG_VERSION="9" ;; *) echo "Unknown clang version: ${clang_version}" >&2 return 1 esac } # Temporary files cleanup hooks. CLEANUP_FILES=() cleanup() { if [[ ${#CLEANUP_FILES[@]} -ne 0 ]]; then rm -fr "${CLEANUP_FILES[@]}" fi } trap "{ set +x; } 2>/dev/null; cleanup" INT TERM EXIT # Install libc++ libraries compiled with msan in the msan_prefix for the current # compiler version. cmd_msan_install() { local tmpdir=$(mktemp -d) CLEANUP_FILES+=("${tmpdir}") # Detect the llvm to install: export CC="${CC:-clang}" export CXX="${CXX:-clang++}" detect_clang_version local llvm_tag case "${CLANG_VERSION}" in "6.0") llvm_tag="llvmorg-6.0.1" ;; "7") llvm_tag="llvmorg-7.0.1" ;; "8") llvm_tag="llvmorg-8.0.0" ;; *) echo "Unknown clang version: ${clang_version}" >&2 return 1 esac local llvm_targz="${tmpdir}/${llvm_tag}.tar.gz" curl -L --show-error -o "${llvm_targz}" \ "https://github.com/llvm/llvm-project/archive/${llvm_tag}.tar.gz" tar -C "${tmpdir}" -zxf "${llvm_targz}" local llvm_root="${tmpdir}/llvm-project-${llvm_tag}" local msan_prefix="${HOME}/.msan/${CLANG_VERSION}" rm -rf "${msan_prefix}" declare -A CMAKE_EXTRAS CMAKE_EXTRAS[libcxx]="\ -DLIBCXX_CXX_ABI=libstdc++ \ -DLIBCXX_INSTALL_EXPERIMENTAL_LIBRARY=ON" for project in libcxx; do local proj_build="${tmpdir}/build-${project}" local proj_dir="${llvm_root}/${project}" mkdir -p "${proj_build}" cmake -B"${proj_build}" -H"${proj_dir}" \ -G Ninja \ -DCMAKE_BUILD_TYPE=Release \ -DLLVM_USE_SANITIZER=Memory \ -DLLVM_PATH="${llvm_root}/llvm" \ -DLLVM_CONFIG_PATH="$(which llvm-config llvm-config-7 llvm-config-6.0 | \ head -n1)" \ -DCMAKE_CXX_FLAGS="${CMAKE_CXX_FLAGS}" \ -DCMAKE_C_FLAGS="${CMAKE_C_FLAGS}" \ -DCMAKE_EXE_LINKER_FLAGS="${CMAKE_EXE_LINKER_FLAGS}" \ -DCMAKE_INSTALL_PREFIX="${msan_prefix}" \ ${CMAKE_EXTRAS[${project}]} cmake --build "${proj_build}" ninja -C "${proj_build}" install done } main() { set -x for version in 6.0 7 8; do if ! which "clang-${version}" >/dev/null; then echo "Skipping msan install for clang version ${version}" continue fi ( trap "{ set +x; } 2>/dev/null; cleanup" INT TERM EXIT export CLANG_VERSION=${version} export CC=clang-${version} export CXX=clang++-${version} cmd_msan_install ) & done wait } main "$@"