Files
ada_language_server/scripts/build_als.sh
Elie Richa 780c85cd40 Move alire.toml out of the root directory as it's not yet readily usable
Some dependencies are not yet available in the community index which
makes it impractical to work with the repository as an Alire crate.

For eng/ide/ada_language_server#1430
2024-09-27 12:10:00 +00:00

271 lines
7.3 KiB
Bash
Executable File

#!/bin/bash
set -e -x
STEP=${1:-all}
TAG=$2 # For master it's 24.0.999, while for tag it's the tag itself
NODE_ARCH_PLATFORM=$3 # Empty - autodetect with `node`, otherwise one of:
# arm64/darwin
# arm64/linux
# x64/darwin
# x64/linux
# x64/win32
# Crates to pin from GitHub repo
PINS="
adasat
gnatcoll
gnatdoc
gnatformat
lal_refactor
langkit_support
libadalang
libadalang_tools
libgpr
libgpr2
markdown
prettier_ada
spawn
vss
"
# Pins repo names (crate name by default)
repo_gnatcoll=gnatcoll-core
repo_lal_refactor=lal-refactor
repo_langkit_support=langkit
repo_libadalang_tools=libadalang-tools
repo_libgpr=gprbuild
repo_libgpr2=gpr
repo_prettier_ada=prettier-ada
repo_vss=VSS
# Pins branches (master by default)
branch_gnatdoc=edge
branch_lal_refactor=edge
branch_gnatformat=edge
branch_libgpr2=next
branch_prettier_ada=main
# A temporary file for langkit setevn
SETENV=$PWD/subprojects/libadalang/setenv.sh
# Set `prod` build mode
########################
# for adasat,gnatformat,lal,langkit,lal_refactor,laltools,markdown,spawn
export BUILD_MODE=prod
# for others
export GNATCOLL_BUILD_MODE=PROD
export GPR_BUILD=production
export GPR2_BUILD=release
export VSS_BUILD_PROFILE=release
export PRETTIER_ADA_BUILD_MODE=prod
# Install custom Alire index with missing crates
function install_index() {
alr index --del=als || true
alr index --add="$PWD" --name=als
}
# Clone dependencies
function pin_crates() {
# Many dependencies are not yet available as Alire crates in the community
# index. To work around that we have defined crates for those projects at
# subprojects/*.toml. For each project, we check out its repository and
# place the corresponding .toml file at the root. This includes the crate
# file for the ALS itself.
# Place the ALS toml at the root
cp -v "subprojects/als.toml" "$PWD/alire.toml"
for crate in $PINS; do
repo_var=repo_$crate
branch_var=branch_$crate
repo=${!repo_var}
branch=${!branch_var}
commit=""
if [ -f deps.txt ]; then
commit=$(grep "^${repo:-$crate}=" deps.txt | sed -e 's/.*=//')
fi
URL="https://github.com/AdaCore/${repo:-$crate}.git"
if [ ! -d "subprojects/$crate" ]; then
git clone "$URL" "subprojects/$crate"
git -C "subprojects/$crate" checkout "${commit:-${branch:-master}}"
fi
cp -v "subprojects/$crate".toml "subprojects/$crate/alire.toml"
alr --force --non-interactive pin "$crate" "--use=$PWD/subprojects/$crate"
done
alr exec alr -- action -r post-fetch # Configure XmlAda, etc
}
# Build langkit shared libraries required to generate libadalang.
# Export setenv to $SETENV
# Clean `.ali` and `.o` to avoid static vis relocatable mess
function build_so_raw() {
cd subprojects/langkit_support
echo "GPR_PROJECT_PATH=$GPR_PROJECT_PATH"
sed -i.bak -e 's/GPR_BUILD/GPR_LIBRARY_TYPE/' ./langkit/libmanage.py
pip install .
python manage.py make --no-mypy --generate-auto-dll-dirs \
--library-types=relocatable --gargs "-cargs -fPIC"
python manage.py setenv >"$SETENV"
cd -
find . -name '*.o' -delete
find . -name '*.ali' -delete
}
# Run build_so_raw in Alire environment
function build_so() {
LIBRARY_PATH=relocatable alr exec bash -- "$0" build_so_raw
}
# Build ALS with alire
function build_als() {
ADALIB=$(alr exec gcc -- -print-libgcc-file-name)
if [[ $NODE_ARCH_PLATFORM == "x64/win32" ]]; then
ADALIB=$(cygpath -u "$ADALIB")
# Fix setenv.sh to be bash script for MSYS2 by replacing
# 1) C:\ -> /C/ 2) '\' -> '/' and ';' -> ':' 3) ": export" -> "; export"
sed -i -e 's#\([A-Z]\):\\#/\1/#g' -e 'y#\\;#/:#' -e 's/: export /; export /' "$SETENV"
cat "$SETENV"
# libgcc_s_seh-1.dll is already in PATH
elif [[ $NODE_ARCH_PLATFORM == "x64/linux" ]]; then
NEW_PATH=$(dirname "$(alr exec gcc -- -print-file-name=libgcc_s.so.1)")
else
NEW_PATH=$(dirname "$(alr exec gcc -- -print-file-name=libgcc_s.dylib.1)")
fi
ADALIB=$(dirname "$ADALIB")/adalib
DEPS=$PWD/alire/cache/dependencies
NEW_PATH=$ADALIB:$NEW_PATH
for ITEM in $DEPS/*/{iconv,gmp,schema,dom,sax,input_sources,unicode}; do
[ -d "$ITEM" ] && NEW_PATH=$ITEM/lib/relocatable:$NEW_PATH
done
echo "NEW_PATH=$NEW_PATH"
export DYLD_LIBRARY_PATH=$NEW_PATH:$DYLD_LIBRARY_PATH
export PATH=$NEW_PATH":$PATH"
# Let's ignore make check exit code until it is stable
LIBRARY_TYPE=static STANDALONE=no alr exec make -- "VERSION=$TAG" check || true
}
# Find the path to libgmp as linked in the given executable
function get_gmp_full_path() {
otool -l "$1" | grep '^\s*name.*libgmp.10.dylib' | awk '/ name /{print $2 }'
}
function do_fix_rpath() {
# Remove all rpath entries
for R in $(otool -l "$1" | grep -A2 LC_RPATH | awk '/ path /{ print $2 }'); do
install_name_tool -delete_rpath "$R" "$1"
done
# Change reference to full path of libgmp into a reference to the rpath.
gmp_full_path=$(get_gmp_full_path "$1")
if [ -n "$gmp_full_path" ]; then
install_name_tool -change "$gmp_full_path" @rpath/libgmp.10.dylib "$1"
fi
# Add the executable directory to rpath so it can find shared libraries
# packaged alongside the executable.
install_name_tool -add_rpath @executable_path "$1"
}
if [[ -z "$NODE_ARCH_PLATFORM" ]]; then
# Get architecture and platform information from node.
NODE_PLATFORM=$(node -e "console.log(process.platform)")
NODE_ARCH=$(node -e "console.log(process.arch)")
NODE_ARCH_PLATFORM=$NODE_ARCH/$NODE_PLATFORM
fi
ALS_EXEC_DIR=integration/vscode/ada/$NODE_ARCH_PLATFORM
function fix_rpath() {
if [ "$RUNNER_OS" = macOS ]; then
# Get full path of libgmp as linked in the ALS exec
gmp_full_path=$(get_gmp_full_path "$ALS_EXEC_DIR/ada_language_server")
if [ -f "$gmp_full_path" ]; then
# Copy libgmp alongside the ALS exec
cp -v -f "$gmp_full_path" "$ALS_EXEC_DIR"
fi
# Fix rpath entries of the ALS exec so it can find libgmp alongside it
do_fix_rpath "$ALS_EXEC_DIR/ada_language_server"
fi
}
function strip_debug() {
cd "$ALS_EXEC_DIR"
if [ "$RUNNER_OS" = Windows ]; then
ALS=ada_language_server.exe
else
ALS=ada_language_server
fi
if [ "$RUNNER_OS" = macOS ]; then
# On macOS using objcopy from binutils to strip debug symbols to a
# separate file doesn't work. Namely, the last step `objcopy
# --add-gnu-debuglink` yields an executable that crashes at startup.
#
# Instead we use dsymutil and strip which are commands provided by the
# system (or by XCode).
dsymutil "$ALS"
strip "$ALS"
elif [[ $NODE_ARCH_PLATFORM == "arm64/linux" ]]; then
aarch64-linux-gnu-objcopy --only-keep-debug ${ALS} ${ALS}.debug
aarch64-linux-gnu-objcopy --strip-all ${ALS}
aarch64-linux-gnu-objcopy --add-gnu-debuglink=${ALS}.debug ${ALS}
else
objcopy --only-keep-debug ${ALS} ${ALS}.debug
objcopy --strip-all ${ALS}
objcopy --add-gnu-debuglink=${ALS}.debug ${ALS}
fi
cd -
}
case $STEP in
all)
install_index
pin_crates
build_so
build_als
fix_rpath
strip_debug
;;
install_index)
install_index
;;
pin_crates)
pin_crates
;;
build_so)
build_so
;;
build_so_raw)
build_so_raw
;;
build_als)
build_als
;;
fix_rpath)
fix_rpath
;;
strip_debug)
strip_debug
;;
esac