146 lines
3.9 KiB
Bash
Executable file
146 lines
3.9 KiB
Bash
Executable file
#!/bin/sh
|
|
|
|
set -eu
|
|
|
|
script_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
|
|
cd "$script_dir"
|
|
|
|
usage() {
|
|
printf '%s\n' "usage: ./setup.sh [Debug|Release]" >&2
|
|
printf '%s\n' " GLOVE_INSTALL_PREFIX=/absolute/prefix ./setup.sh [Debug|Release]" >&2
|
|
}
|
|
|
|
build_type=${1:-Release}
|
|
if [ "$#" -gt 1 ]; then
|
|
usage
|
|
exit 2
|
|
fi
|
|
|
|
case "$build_type" in
|
|
Debug)
|
|
preset=dev
|
|
;;
|
|
Release)
|
|
preset=release
|
|
;;
|
|
-h|--help)
|
|
usage
|
|
exit 0
|
|
;;
|
|
*)
|
|
usage
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
case "$(uname -s)" in
|
|
Darwin|Linux)
|
|
;;
|
|
*)
|
|
printf '%s\n' "setup.sh supports macOS and Linux only" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
|
|
for command_name in cmake ninja; do
|
|
if ! command -v "$command_name" >/dev/null 2>&1; then
|
|
printf 'missing required command: %s\n' "$command_name" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
if [ -z "${CC:-}" ]; then
|
|
CC=clang
|
|
export CC
|
|
fi
|
|
if [ -z "${CXX:-}" ]; then
|
|
CXX=clang++
|
|
export CXX
|
|
fi
|
|
for compiler in "$CC" "$CXX"; do
|
|
if ! command -v "$compiler" >/dev/null 2>&1; then
|
|
printf 'missing required compiler: %s\n' "$compiler" >&2
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
probe_dir=$(mktemp -d "${TMPDIR:-/tmp}/glove-cxx-probe.XXXXXX")
|
|
trap 'rm -rf "$probe_dir"' 0 HUP INT TERM
|
|
probe_source=$probe_dir/required_features.cpp
|
|
probe_binary=$probe_dir/required_features
|
|
cat >"$probe_source" <<'EOF'
|
|
#include <expected>
|
|
|
|
int main() {
|
|
std::expected<int, int> value{1};
|
|
return *value - 1;
|
|
}
|
|
EOF
|
|
|
|
supports_required_cxx_features() {
|
|
# CXXFLAGS is an operator-owned compiler flag list and intentionally uses
|
|
# shell field splitting here, matching conventional build-tool behavior.
|
|
# shellcheck disable=SC2086
|
|
"$CXX" ${CXXFLAGS:-} "$@" -std=c++23 "$probe_source" -o "$probe_binary" \
|
|
>/dev/null 2>&1
|
|
}
|
|
|
|
if ! supports_required_cxx_features; then
|
|
case "$(uname -s):${CXXFLAGS:-}" in
|
|
Linux:*"-stdlib="*)
|
|
printf '%s\n' \
|
|
"selected C++ compiler/library lacks required C++23 features" >&2
|
|
exit 1
|
|
;;
|
|
Linux:*)
|
|
if supports_required_cxx_features -stdlib=libc++; then
|
|
CXXFLAGS="${CXXFLAGS:+${CXXFLAGS} }-stdlib=libc++"
|
|
export CXXFLAGS
|
|
printf '%s\n' \
|
|
"Default C++ library lacks required C++23 support; using libc++." \
|
|
"Set CXXFLAGS explicitly to select another compatible library."
|
|
else
|
|
printf '%s\n' \
|
|
"selected C++ compiler/library lacks required C++23 features" \
|
|
"Install a compatible standard library or set CC, CXX, and CXXFLAGS explicitly." \
|
|
>&2
|
|
exit 1
|
|
fi
|
|
;;
|
|
*)
|
|
printf '%s\n' \
|
|
"selected C++ compiler/library lacks required C++23 features" \
|
|
"Select a compatible compiler and standard library with CC, CXX, and CXXFLAGS." \
|
|
>&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
fi
|
|
|
|
if [ -z "${GLOVE_INSTALL_PREFIX:-}" ] && [ -z "${HOME:-}" ]; then
|
|
printf '%s\n' "HOME or GLOVE_INSTALL_PREFIX is required" >&2
|
|
exit 1
|
|
fi
|
|
install_prefix=${GLOVE_INSTALL_PREFIX:-${HOME}/.local}
|
|
case "$install_prefix" in
|
|
/*)
|
|
;;
|
|
*)
|
|
printf '%s\n' "GLOVE_INSTALL_PREFIX must be an absolute path" >&2
|
|
exit 2
|
|
;;
|
|
esac
|
|
|
|
printf 'Configuring Glove (%s)...\n' "$build_type"
|
|
cmake --preset "$preset"
|
|
cmake --build --preset "$preset"
|
|
ctest --preset "$preset"
|
|
cmake --install "build/$preset" --prefix "$install_prefix"
|
|
|
|
printf '\nInstalled Glove to %s\n' "$install_prefix"
|
|
printf '%s\n' "Next:"
|
|
printf ' %s/bin/glove setup guide\n' "$install_prefix"
|
|
printf ' %s/bin/glove setup --dry-run\n' "$install_prefix"
|
|
printf ' %s/bin/glove setup --yes\n' "$install_prefix"
|
|
printf ' %s/bin/glove daemon start\n' "$install_prefix"
|
|
printf ' %s/bin/glove doctor\n' "$install_prefix"
|