#!/usr/bin/env bash # Copyright 2023 The IREE Authors # # Licensed under the Apache License v2.0 with LLVM Exceptions. # See https://llvm.org/LICENSE.txt for license information. # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception # This script illustrates how IREE can be built with various forms of LLVM # installations with the option -DIREE_BUILD_BUNDLED_LLVM=OFF set, disabling # a source dependency on the bundled LLVM submodule. # # Usage: # byo_llvm.sh build_llvm && \ # byo_llvm.sh build_mlir && \ # byo_llvm.sh build_iree # # Additionally, to run tests: # byo_llvm.sh test_iree # # This script has minimal configurability, which can be extended as needed. The # defaults should suffice for testing on CI. Different configurations are # possible (i.e. building MLIR bundled with LLVM vs standalone), and this # is just normal CMake package management options. # # Fully separating LLVM+LLD+CLANG from MLIR and from IREE enables maximum # flexibility for the cases where multiple teams are responsible for # different parts. Note that IREE often has a tight dependency on specific # MLIR commits, and the bundled submodule often carries patches and fixes # required for full functionality of all backends. TD="$(cd $(dirname $0) && pwd)" REPO_ROOT="$(cd $TD/../.. && pwd)" LLVM_SOURCE_DIR="${LLVM_SOURCE_DIR:-${REPO_ROOT}/third_party/llvm-project}" IREE_BYOLLVM_BUILD_DIR="${IREE_BYOLLVM_BUILD_DIR:-${REPO_ROOT}/../iree-byollvm-build}" IREE_BYOLLVM_INSTALL_DIR="${IREE_BYOLLVM_INSTALL_DIR:-${REPO_ROOT}/../iree-byollvm-install}" # Canonicalize as absolute paths. These end up in CMake variables such as # CMAKE_MODULE_PATH, where relative paths are a footgun as CMake gets invoked # from different directories. LLVM_SOURCE_DIR="$(realpath -m "${LLVM_SOURCE_DIR}")" IREE_BYOLLVM_BUILD_DIR="$(realpath -m "${IREE_BYOLLVM_BUILD_DIR}")" IREE_BYOLLVM_INSTALL_DIR="$(realpath -m "${IREE_BYOLLVM_INSTALL_DIR}")" echo "Paths canonicalized as:" echo "LLVM_SOURCE_DIR=${LLVM_SOURCE_DIR}" echo "IREE_BYOLLVM_BUILD_DIR=${IREE_BYOLLVM_BUILD_DIR}" echo "IREE_BYOLLVM_INSTALL_DIR=${IREE_BYOLLVM_INSTALL_DIR}" command="$1" shift # Detect commands. has_ccache=false if (command -v ccache &> /dev/null); then has_ccache=true fi has_clang=false if (command -v clang &> /dev/null) && (command -v clang++ &> /dev/null); then has_clang=true fi has_lld=false if (command -v lld &> /dev/null); then has_lld=true fi python3_command="" if (command -v python3 &> /dev/null); then python3_command="python3" elif (command -v python &> /dev/null); then python3_command="python" fi set -euo pipefail print_toolchain_config() { if $has_ccache; then echo -n "-DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache " fi if $has_clang; then echo "-DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++" fi } do_build_llvm() { echo "*********************** BUILDING LLVM *********************************" main_build_dir="${IREE_BYOLLVM_BUILD_DIR}/llvm" main_install_dir="${IREE_BYOLLVM_INSTALL_DIR}/llvm" targets_to_build="${LLVM_TARGETS_TO_BUILD:-X86}" cmake_options="-DLLVM_TARGETS_TO_BUILD='${targets_to_build}'" cmake_options="${cmake_options} -DCMAKE_BUILD_TYPE=Release" cmake_options="${cmake_options} -C $TD/llvm_config.cmake" cmake_options="${cmake_options} -DCMAKE_INSTALL_PREFIX=${main_install_dir}" cmake_options="${cmake_options} $(print_toolchain_config)" if $has_lld; then cmake_options="${cmake_options} -DLLVM_ENABLE_LLD=ON" fi echo "Source Directory: ${LLVM_SOURCE_DIR}" echo "Build Directory: ${main_build_dir}" echo "CMake Options: ${cmake_options}" cmake -GNinja -S "${LLVM_SOURCE_DIR}/llvm" -B "${main_build_dir}" \ $cmake_options cmake --build "${main_build_dir}" \ --target install-toolchain-distribution \ --target install-development-distribution } do_build_mlir() { echo "*********************** BUILDING MLIR *********************************" main_install_dir="${IREE_BYOLLVM_INSTALL_DIR}/llvm" mlir_build_dir="${IREE_BYOLLVM_BUILD_DIR}/mlir" mlir_install_dir="${IREE_BYOLLVM_INSTALL_DIR}/mlir" cmake_options="-DLLVM_DIR='${main_install_dir}/lib/cmake/llvm'" cmake_options="${cmake_options} -DPython3_EXECUTABLE='$(which $python3_command)'" cmake_options="${cmake_options} -DMLIR_ENABLE_BINDINGS_PYTHON=ON" cmake_options="${cmake_options} -DCMAKE_INSTALL_PREFIX=${mlir_install_dir}" cmake_options="${cmake_options} -C $TD/mlir_config.cmake" cmake_options="${cmake_options} $(print_toolchain_config)" if $has_lld; then cmake_options="${cmake_options} -DLLVM_ENABLE_LLD=ON" fi echo "Source Directory: ${LLVM_SOURCE_DIR}" echo "Build Directory: ${mlir_build_dir}" echo "CMake Options: ${cmake_options}" cmake -GNinja -S "${LLVM_SOURCE_DIR}/mlir" -B "${mlir_build_dir}" \ $cmake_options cmake --build "${mlir_build_dir}" \ --target install-mlirdevelopment-distribution } print_iree_config() { llvm_cmake_dir="${IREE_BYOLLVM_INSTALL_DIR}/llvm/lib/cmake/llvm" lld_cmake_dir="${IREE_BYOLLVM_INSTALL_DIR}/llvm/lib/cmake/lld" clang_cmake_dir="${IREE_BYOLLVM_INSTALL_DIR}/llvm/lib/cmake/clang" mlir_cmake_dir="${IREE_BYOLLVM_BUILD_DIR}/mlir/lib/cmake/mlir" if ! [ -d "$llvm_cmake_dir" ]; then echo "WARNING: CMake dir does not exist ($llvm_cmake_dir)" >&2 return 1 fi if ! [ -d "$lld_cmake_dir" ]; then echo "WARNING: CMake dir does not exist ($lld_cmake_dir)" >&2 return 1 fi if ! [ -d "$clang_cmake_dir" ]; then echo "WARNING: CMake dir does not exist ($clang_cmake_dir)" >&2 return 1 fi if ! [ -d "$mlir_cmake_dir" ]; then echo "WARNING: CMake dir does not exist ($mlir_cmake_dir)" >&2 return 1 fi echo "-DLLVM_DIR='$llvm_cmake_dir' -DLLD_DIR='$lld_cmake_dir' -DMLIR_DIR='$mlir_cmake_dir' -DClang_DIR='$clang_cmake_dir' -DIREE_BUILD_BUNDLED_LLVM=OFF" } do_build_iree() { echo "*********************** BUILDING IREE *********************************" iree_build_dir="${IREE_BYOLLVM_BUILD_DIR}/iree" iree_install_dir="${IREE_BYOLLVM_INSTALL_DIR}/iree" cmake_options="$(print_iree_config)" cmake_options="${cmake_options} -DPython3_EXECUTABLE='$(which $python3_command)'" cmake_options="${cmake_options} -DIREE_BUILD_PYTHON_BINDINGS=ON" # Feel free to manually enable or disable any backend, for example # -DIREE_TARGET_BACKEND_LLVM_CPU=OFF # Be aware though that several tests in IREE's own suite are currently # assuming that certain backends are enabled (#14034), so that may cause test # failures, but that's a test-only issue. cmake_options="${cmake_options} -DIREE_TARGET_BACKEND_DEFAULTS=OFF" cmake_options="${cmake_options} -DIREE_TARGET_BACKEND_LLVM_CPU=ON" cmake_options="${cmake_options} -DIREE_HAL_DRIVER_DEFAULTS=OFF" cmake_options="${cmake_options} -DIREE_HAL_DRIVER_LOCAL_SYNC=ON" cmake_options="${cmake_options} -DIREE_HAL_DRIVER_LOCAL_TASK=ON" cmake_options="${cmake_options} -DCMAKE_BUILD_TYPE=Release" cmake_options="${cmake_options} $(print_toolchain_config)" if $has_lld; then cmake_options="${cmake_options} -DIREE_ENABLE_LLD=ON" fi echo "Source Directory: ${REPO_ROOT}" echo "Build Directory: ${iree_build_dir}" echo "CMake Options: ${cmake_options}" cmake -GNinja -S "${REPO_ROOT}" -B "${iree_build_dir}" \ $cmake_options cmake --build "${iree_build_dir}" cmake -DCMAKE_INSTALL_PREFIX="${iree_install_dir}" -P "${iree_build_dir}/cmake_install.cmake" } do_test_iree() { echo "*********************** TESTING IREE **********************************" iree_build_dir="${IREE_BYOLLVM_BUILD_DIR}/iree" iree_install_dir="${IREE_BYOLLVM_INSTALL_DIR}/iree" echo "Source Directory: ${REPO_ROOT}" echo "Build Directory: ${iree_build_dir}" cmake --build "${iree_build_dir}" --target iree-test-deps "${REPO_ROOT}/build_tools/cmake/ctest_all.sh" "${iree_build_dir}" } case "${command}" in build_llvm) do_build_llvm ;; build_mlir) do_build_mlir ;; build_iree) do_build_iree ;; test_iree) do_test_iree ;; *) echo "ERROR: Expected command of 'build_llvm', 'clean_install' (got '${command}')" exit 1 ;; esac