Files
OpenROAD/etc/Build.sh
Matt Liberty 2939447bf1 Merge pull request #9649 from alokkumardalei-wq/docs_depenency
docs: Add DependencyInstaller.sh functionalities(-local and -prefix) to Build.md
2026-04-15 15:17:19 +00:00

344 lines
11 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
DIR="$(dirname $(readlink -f $0))"
cd "$DIR/../"
# default values, can be overwritten by cmdline args
buildDir="build"
if [[ "$OSTYPE" == "linux-gnu"* ]]; then
numThreads=$(nproc --all)
elif [[ "$OSTYPE" == "darwin"* ]]; then
numThreads=$(sysctl -n hw.logicalcpu)
else
cat << EOF
WARNING: Unsupported OSTYPE: cannot determine number of host CPUs"
Defaulting to 2 threads. Use --threads N to use N threads"
EOF
numThreads=2
fi
cmakeOptions=()
isNinja=no
cleanBefore=no
depsPrefixesFile=""
compiler=gcc
_help() {
cat <<EOF
usage: $0 [OPTIONS]
OPTIONS:
-cmake='-<key>=<value> [-<key>=<value> ...]' User defined cmake options
Note: use single quote after
-cmake= and double quotes if
<key> has multiple <values>
e.g.: -cmake='-DFLAGS="-a -b"'
-compiler=COMPILER_NAME Compiler name: gcc or clang
Default: gcc
-no-warnings
Compiler warnings are
considered errors, i.e.,
use -Werror flag during build.
-dir=PATH Path to store build files.
Default: ./build
-coverage Enable cmake coverage options
-clean Remove build dir before compile
-no-gui Disable GUI support
-no-tests Disable GTest
-cpp20 Use C++20 standard
-build-man Build Man Pages (optional)
-threads=NUM_THREADS Number of threads to use during
compile. Default: \`nproc\` on linux
or \`sysctl -n hw.logicalcpu\` on macOS
-keep-log Keep a compile log in build dir
-help Shows this message
-gpu Enable GPU to accelerate the process
-deps-prefixes-file=FILE File with CMake packages roots,
its content extends -cmake argument.
By default, "openroad_deps_prefixes.txt"
file from OpenROAD's "etc" directory
or from system "/etc".
-local Install OpenROAD in \${HOME}/.local.
-prefix=DIR Install OpenROAD in a user-specified directory.
EOF
exit "${1:-1}"
}
__logging()
{
local log_file="${buildDir}/openroad_build.log"
echo "[INFO] Saving logs to ${log_file}"
echo "[INFO] $__CMD"
exec > >(tee -i "${log_file}")
exec 2>&1
}
__CMD="$0 $@"
while [ "$#" -gt 0 ]; do
case "${1}" in
-h|-help)
_help 0
;;
-local)
if [[ -n "${INSTALL_PREFIX_SET:-}" ]]; then
echo "[WARNING] Previous -prefix or -local argument will be overwritten." >&2
fi
cmakeOptions+=("-DCMAKE_INSTALL_PREFIX=${HOME}/.local")
INSTALL_PREFIX_SET=1
;;
-prefix=*)
if [[ -n "${INSTALL_PREFIX_SET:-}" ]]; then
echo "[WARNING] Previous -prefix or -local argument will be overwritten." >&2
fi
cmakeOptions+=("-DCMAKE_INSTALL_PREFIX=${1#*=}")
INSTALL_PREFIX_SET=1
;;
-no-gui)
cmakeOptions+=("-DBUILD_GUI=OFF")
;;
-no-tests)
cmakeOptions+=("-DENABLE_TESTS=OFF")
;;
-ninja)
cmakeOptions+=("-DCMAKE_C_COMPILER_LAUNCHER=ccache")
cmakeOptions+=("-DCMAKE_CXX_COMPILER_LAUNCHER=ccache")
cmakeOptions+=("-GNinja")
isNinja=yes
;;
-cpp20)
cmakeOptions+=("-DCMAKE_CXX_STANDARD=20")
;;
-build-man)
cmakeOptions+=("-DBUILD_MAN=ON")
;;
-compiler=*)
compiler="${1#*=}"
;;
-no-warnings )
cmakeOptions+=("-DALLOW_WARNINGS=OFF")
;;
-coverage )
cmakeOptions+=("-DCMAKE_BUILD_TYPE=Debug")
cmakeOptions+=("-DCMAKE_CXX_FLAGS=-fprofile-arcs -ftest-coverage")
cmakeOptions+=("-DCMAKE_EXE_LINKER_FLAGS=-lgcov")
;;
-cmake=*)
read -ra temp_arr <<< "${1#*=}"
cmakeOptions+=("${temp_arr[@]}")
;;
-clean )
cleanBefore=yes
;;
-dir=* )
buildDir="${1#*=}"
;;
-threads=* )
temp="${1#*=}"
if [[ "${temp}" != "NotSet" ]]; then
numThreads=${temp}
fi
;;
-deps-prefixes-file=*)
file="${1#-deps-prefixes-file=}"
if [[ ! -f "$file" ]]; then
echo "${file} does not exist" >&2
_help
fi
depsPrefixesFile="$file"
;;
-compiler | -cmake | -dir | -threads | -install | -deps-prefixes-file )
echo "${1} requires an argument" >&2
_help
;;
-gpu)
cmakeOptions+=("-DGPU=ON")
;;
*)
echo "unknown option: ${1}" >&2
_help
;;
esac
shift 1
done
if [[ -z "$depsPrefixesFile" ]]; then
if [[ -f "$DIR/openroad_deps_prefixes.txt" ]]; then
depsPrefixesFile="$DIR/openroad_deps_prefixes.txt"
elif [[ -f "/etc/openroad_deps_prefixes.txt" ]]; then
depsPrefixesFile="/etc/openroad_deps_prefixes.txt"
fi
fi
if [[ -f "$depsPrefixesFile" ]]; then
read -ra newOpts <<< "$(cat "$depsPrefixesFile")"
cmakeOptions+=("${newOpts[@]}")
echo "[INFO] Using additional CMake parameters from $depsPrefixesFile"
else
echo "[INFO] Auto-generated prefix file does not exist - CMake will choose the dependencies automatically"
fi
case "${compiler}" in
"gcc" )
if [[ -f "/opt/rh/devtoolset-8/enable" ]]; then
# the scl script has unbound variables
set +u
source /opt/rh/devtoolset-8/enable
set -u
fi
export CC="$(command -v gcc)"
export CXX="$(command -v g++)"
;;
"clang" )
if [[ -f "/opt/rh/llvm-toolset-7.0/enable" ]]; then
# the scl script has unbound variables
set +u
source /opt/rh/llvm-toolset-7.0/enable
set -u
fi
export CC="$(command -v clang)"
export CXX="$(command -v clang++)"
;;
"clang-16" )
export CC="$(command -v clang-16)"
export CXX="$(command -v clang++-16)"
;;
*)
export CC=""
export CXX=""
esac
if [[ -z "${CC}" || -z "${CXX}" ]]; then
echo "Compiler $compiler not installed or it is not supported." >&2
_help 1
fi
if [[ "${cleanBefore}" == "yes" ]]; then
rm -rf "${buildDir}"
fi
mkdir -p "${buildDir}"
__logging
if [[ "$OSTYPE" == "darwin"* ]]; then
_bison=$(brew --prefix bison 2>/dev/null || true)
_flex=$(brew --prefix flex 2>/dev/null || true)
_ortools=$(brew --prefix or-tools 2>/dev/null || true)
if [[ -z "$_bison" || ! -d "$_bison/bin" ]]; then
echo "[ERROR] bison not found or broken. Run: brew install bison" >&2
exit 1
fi
if [[ -z "$_flex" || ! -d "$_flex/bin" ]]; then
echo "[ERROR] flex not found or broken. Run: brew install flex" >&2
exit 1
fi
if [[ -z "$_ortools" || ! -d "$_ortools/lib" || ! -d "$_ortools/include" ]]; then
echo "[ERROR] or-tools not found or broken. Run: brew install or-tools" >&2
exit 1
fi
export PATH="$_bison/bin:$_flex/bin:$PATH"
export CMAKE_PREFIX_PATH="${_ortools}"
_qt5=$(brew --prefix qt@5 2>/dev/null || true)
if [[ -z "$_qt5" || ! -d "$_qt5/lib" ]]; then
echo "[ERROR] qt@5 not found or broken. Run: brew install qt@5" >&2
exit 1
fi
cmakeOptions+=" -DQt5_DIR=$_qt5/lib/cmake/Qt5"
_tcl8=$(brew --prefix tcl-tk@8 2>/dev/null || true)
if [[ -z "$_tcl8" || ! -d "$_tcl8/lib" || ! -d "$_tcl8/include" ]]; then
echo "[ERROR] tcl-tk@8 not found or broken. Run: brew install tcl-tk@8" >&2
exit 1
fi
cmakeOptions+=" -DTCL_LIBRARY=$_tcl8/lib/libtcl8.6.dylib"
cmakeOptions+=" -DTCL_INCLUDE_PATH=$_tcl8/include"
cmakeOptions+=" -DFLEX_INCLUDE_DIR=$_flex/include"
cmakeOptions+=" -DCMAKE_CXX_FLAGS=-DBOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED"
_icu="$(brew --prefix icu4c 2>/dev/null || true)"
if [[ -z "$_icu" || ! -d "$_icu/lib" ]]; then
echo "[ERROR] icu4c not found or broken. Run: brew install icu4c" >&2
exit 1
fi
export LDFLAGS="-L$_icu/lib"
export CPPFLAGS="-I$_icu/include"
export PKG_CONFIG_PATH="$_icu/lib/pkgconfig"
_extra_lib_paths=("$(brew --prefix)/lib")
_joined_paths="$(IFS=:; echo "${_extra_lib_paths[*]}")"
export LIBRARY_PATH="${_joined_paths}${LIBRARY_PATH:+:$LIBRARY_PATH}"
echo "[INFO] General LIBRARY_PATH=$LIBRARY_PATH"
fi
# ==============================================================================
# PRE-COMPILATION SYSTEM CHECKS
# ==============================================================================
if [[ -t 1 ]]; then
RED=$(tput setaf 1)
GREEN=$(tput setaf 2)
YELLOW=$(tput setaf 3)
NC=$(tput sgr0) # No Color
else
RED=''
GREEN=''
YELLOW=''
NC=''
fi
echo -e "${YELLOW}Running pre-compilation system checks...${NC}"
check_command() {
if ! command -v "$1" &> /dev/null; then
echo -e "${RED}[ERROR] Required dependency '$1' is missing!${NC}"
echo "Please install it using 'sudo ./etc/DependencyInstaller.sh' before building."
exit 1
else
echo -e "${GREEN}[OK] Found $1${NC}"
fi
}
# Essential build tools required for OpenROAD
check_command "cmake"
check_command "bison"
check_command "flex"
check_command "swig"
# Compiler check based on user selection
if [[ "${compiler:-gcc}" == "gcc" ]]; then
check_command "gcc"
check_command "g++"
elif [[ "${compiler}" == "clang" ]]; then
check_command "clang"
check_command "clang++"
elif [[ "${compiler}" == "clang-16" ]]; then
check_command "clang-16"
check_command "clang++-16"
else
# Handle unknown compilers gracefully - suggested by gemini-bot
echo -e "${YELLOW}[WARNING] Unsupported compiler '${compiler}' specified. Skipping compiler pre-compilation check.${NC}"
fi
echo -e "${GREEN}All pre-compilation checks passed! Proceeding...${NC}\n"
# ==============================================================================
echo "[INFO] Using ${numThreads} threads."
if [[ "$isNinja" == "yes" ]]; then
cmake "${cmakeOptions[@]}" -B "${buildDir}" .
cd "${buildDir}"
CLICOLOR_FORCE=1 ninja build_and_test
exit 0
fi
cmake "${cmakeOptions[@]}" -B "${buildDir}" .
time cmake --build "${buildDir}" -j "${numThreads}"