| #!/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 |