diff options
Diffstat (limited to '')
-rwxr-xr-x | packaging/macos/jhb/usr/bin/archive | 205 | ||||
-rwxr-xr-x | packaging/macos/jhb/usr/bin/bootstrap | 135 | ||||
-rwxr-xr-x | packaging/macos/jhb/usr/bin/jhb | 63 | ||||
-rwxr-xr-x | packaging/macos/jhb/usr/bin/run-parts | 73 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/README.md | 9 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/ansi.sh | 76 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/assert.sh | 42 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/bash_d.sh | 98 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/echo.sh | 52 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/error.sh | 45 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/lib.sh | 174 | ||||
-rw-r--r-- | packaging/macos/jhb/usr/src/bash_d/readlinkf.sh | 27 |
12 files changed, 999 insertions, 0 deletions
diff --git a/packaging/macos/jhb/usr/bin/archive b/packaging/macos/jhb/usr/bin/archive new file mode 100755 index 0000000..f84f0c8 --- /dev/null +++ b/packaging/macos/jhb/usr/bin/archive @@ -0,0 +1,205 @@ +#!/usr/bin/env bash +# +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This is a helper to create release archives and mount them. + +### shellcheck ################################################################# + +# Nothing here. + +### dependencies ############################################################### + +#------------------------------------------------------ source jhb configuration + +source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh + +#------------------------------------------- source common functions from bash_d + +# bash_d is already available (it's part of jhb configuration) + +bash_d_include error + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +function create_tar +{ + local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE + + echo_i "creating $file" + + tar -C "$WRK_DIR" -cp "$(basename "$VER_DIR")" | + XZ_OPT=-T0 "$BIN_DIR"/xz > "$file" + + shasum -a 256 "$file" > "$file".sha256 + cat "$file".sha256 +} + +function create_dmg +{ + local file=$ARTIFACT_DIR/$RELEASE_ARCHIVE + + ( # create dmg + local vol_name + vol_name=$(basename "$VER_DIR") + + cd "$WRK_DIR" || exit 1 + hdiutil create -fs HFS+ -ov -format UDBZ \ + -srcfolder "$vol_name" \ + -volname "$vol_name" \ + "$file" + ) + + ( # create and print checksum + cd "$(dirname "$file")" || exit 1 + shasum -a 256 "$(basename "$file")" > "$file".sha256 + cat "$file".sha256 + ) +} + +function mount_dmg +{ + local file=$REP_DIR/$RELEASE_ARCHIVE + local mountpoint=$VER_DIR + + if [ ! -d "$mountpoint" ]; then + mkdir -p "$mountpoint" + fi + + echo_i "mounting $(basename "$file") may take some time" + local device + device=$(hdiutil attach -nomount "$file" | grep "^/dev/disk" | + grep "Apple_HFS" | awk '{ print $1 }') + echo_i "$file attached to $device" + mount -o nobrowse,noowners,noquarantine,ro -t hfs "$device" "$mountpoint" + echo_i "$device mounted to $mountpoint" +} + +function unmount_dmg +{ + local mountpoint=$VER_DIR + + while : ; do # unmount everything (in reverse order) + local disk + disk=$(mount | grep "$mountpoint" | tail -n1 | awk '{ print $1 }') + disk=${disk%s[0-9]} # cut off slice specification + + if [ ${#disk} -eq 0 ]; then + break # nothing to do here + else + # We loop over the 'eject' since it occasionally timeouts. + while ! diskutil eject "$disk" > /dev/null; do + echo_w "retrying to eject $disk in 5 seconds" + sleep 5 + done + + echo_i "ejected $disk" + fi + done +} + +function download_dmg +{ + if [ ! -d "$REP_DIR" ]; then + mkdir -p "$REP_DIR" + fi + + for url in "${RELEASE_URLS[@]}"; do + local partial_download=$REP_DIR/${FUNCNAME[0]} # TMP_DIR not available yet + # download (at least) 100 kb of data + curl -L "$url" 2>/dev/null | head -c 100000 > "$partial_download" + # if we got 100 kb, it's not a "404 file not found" + if [ "$(stat -f%z "$partial_download")" -eq 100000 ]; then + echo_i "downloading $url" + curl -o "$REP_DIR/$RELEASE_ARCHIVE" -L -C - "$url" + break + fi + done + + rm "$partial_download" +} + +function install_dmg +{ + local overlay_size=${1:-1} # unit GiB, default 1 + + local file=$REP_DIR/$RELEASE_ARCHIVE + + # download and mount read-only disk image + if [ -f "$file" ]; then + echo_i "using $file" + else + download_dmg + fi + mount_dmg + + # create writable overlay + local device + device=$(hdiutil attach -nomount ram://$((overlay_size * 1024 * 2048)) | xargs) + newfs_hfs -v "$RELEASE_OVERLAY" "$device" >/dev/null + echo_i "$overlay_size GiB ram attached to $device" + mount -o nobrowse,rw,union -t hfs "$device" "$VER_DIR" + echo_i "$device union-mounted at $VER_DIR" + + # Sadly, there are some limitations involved with union-mounting: + # - Files are not visible to macOS' versions of 'ls' or 'find'. + # (The GNU versions do work though.) + # - You cannot write in a location without having written to its + # parent location first. That's why we need to pre-create all directories + # below. + # + # (Shadow-mounting a dmg is not a feasible alternative due to its + # bad write-performance.) + + # Create and run a script for mass-creating directories. + echo_i "setting up directories in overlay" + gfind "$VER_DIR" -mindepth 1 -type d \ + ! -path "$BLD_DIR/*" ! -path "$SRC_DIR/*" \ + -exec echo "mkdir {}" \; > "$VER_DIR"/create_dirs.sh + chmod 755 "$VER_DIR"/create_dirs.sh + "$VER_DIR"/create_dirs.sh + rm "$VER_DIR"/create_dirs.sh +} + +function uninstall_dmg +{ + unmount_dmg +} + +function main +{ + local command=$1 + local option=$2 + + case "$command" in + create_dmg) + create_dmg + ;; + create_tar) + create_tar + ;; + install_dmg) + install_dmg "$option" # option: overlay size in GiB, defaul is 1 + ;; + uninstall_dmg) + uninstall_dmg + ;; + *) + echo_e "usage: $0 {create_dmg|create_tar|install_dmg|uninstall_dmg}" + ;; + esac +} + +### main ####################################################################### + +error_trace_enable + +main "$@" diff --git a/packaging/macos/jhb/usr/bin/bootstrap b/packaging/macos/jhb/usr/bin/bootstrap new file mode 100755 index 0000000..3d46dbb --- /dev/null +++ b/packaging/macos/jhb/usr/bin/bootstrap @@ -0,0 +1,135 @@ +#!/usr/bin/env bash +# +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This script bootstraps JHBuild so it's ready to build any module. + +### shellcheck ################################################################# + +# Nothing here. + +### dependencies ############################################################### + +#------------------------------------------------------ source jhb configuration + +# You can install a custom configuration file by passing it as first +# argument. It has to be named '*.conf.sh'. + +source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh "$1" + +#------------------------------------------- source common functions from bash_d + +# bash_d is already available (it's part of jhb configuration) + +bash_d_include error + +### variables ################################################################## + +SELF_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" || exit 1; pwd) + +FORCE_BUILD_FROM_SOURCE=${FORCE_BUILD_FROM_SOURCE:-false} + +### functions ################################################################## + +function is_release_usable +{ + local url=$1 + + local partial_download="$TMP_DIR/${FUNCNAME[0]}".tar.xz + local rc=1 + + # download at least 100 kb of data + curl -L "$url" 2>/dev/null | head -c 100000 > "$partial_download" + # if we got 100 kb, it's not a "404 file not found" + if [ "$(stat -f%z "$partial_download")" -eq 100000 ]; then + # look inside: dir needs to match our VER_DIR to be usable + local dir + dir=$(basename "$(tar -tvJf "$partial_download" 2>/dev/null | + head -n 1 | awk '{ print $NF }')") + if [ "$dir" = "$(basename "$VER_DIR")" ]; then + rc=0 + fi + fi + + rm "$partial_download" + + return $rc +} + +### main ####################################################################### + +error_trace_enable + +#-------------------------------------------------------- print main directories + +echo_i "WRK_DIR = $WRK_DIR" +echo_i "VER_DIR = $VER_DIR" + +#--------------------------------------------------------- perform system checks + +if sys_wrkdir_is_usable && + sdkroot_exists && + sys_usrlocal_is_clean; then + + # these checks may issue warnings but have have no consequences otherwise + sys_macos_is_recommended || true + sys_sdk_is_recommended || true +else + exit 1 # cannot continue +fi + +#--------------------------------------------------- initialize directory layout + +if [ "$SELF_DIR" = "$USR_DIR"/bin ]; then + : # we are already running inside target directory layout +else + # sync repository into target structure, remove everything git-related + rsync -a "$SELF_DIR"/../../../jhb/ "$VER_DIR"/ + find "$VER_DIR" -type f -name ".gitignore" -delete + rm -rf "$VER_DIR"/.git + rm "$VER_DIR"/.gitmodules +fi + +#------------------------------------------- check if binary release can be used + +for URL in "${RELEASE_URLS[@]}"; do + if is_release_usable "$URL" && ! $FORCE_BUILD_FROM_SOURCE; then + echo_i "using $URL" + curl -L "$URL" | tar -C "$WRK_DIR" -xJ + exit $? # we can quit here and now, nothing further to do + fi +done + +echo_i "building everything from scratch" + +#---------------------------------------------------------------- install ccache + +ccache_install +ccache_configure + +#------------------------------------------ log relevant versions to release.log + +sys_create_log + +#------------------------------------------------- install and configure JHBuild + +jhbuild_install +jhbuild_configure + +#------------------------------------------------------- run bootstrap procedure + +jhbuild bootstrap-gtk-osx + +#--------------------------------------------------------- install GNU utilities + +# GNU versions of various utilites make life significantly easier on macOS. + +jhbuild build coreutils findutils sed tar + +#-------------------------------------------------------------- install dmgbuild + +dmgbuild_install diff --git a/packaging/macos/jhb/usr/bin/jhb b/packaging/macos/jhb/usr/bin/jhb new file mode 100755 index 0000000..b268339 --- /dev/null +++ b/packaging/macos/jhb/usr/bin/jhb @@ -0,0 +1,63 @@ +#!/usr/bin/env bash +# +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This script is a wrapper around the jhbuild binary to run it in our +# configured environment (etc/jhb.conf). + +### shellcheck ################################################################# + +# Nothing here. + +### dependencies ############################################################### + +#---------------------------------------------------------- source configuration + +source "$(dirname "${BASH_SOURCE[0]}")"/../../etc/jhb.conf.sh + +#------------------------------------------- source common functions from bash_d + +# bash_d is already available (it's part of etc/jhb.conf) + +bash_d_include error + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +# Nothing here. + +### main ####################################################################### + +if $CI; then # break in CI, otherwise we get interactive prompt by JHBuild + error_trace_enable +fi + +case "$1" in + debug) + echo_d "doing nothing" + ;; + configure) + jhbuild_configure "$2" # e.g. 'jhbuild/myapp.modules' + ccache_configure + ;; + *) + if sys_wrkdir_is_usable && + sdkroot_exists && + sys_usrlocal_is_clean; then + + # these checks may issue warnings but have have no consequences otherwise + sys_macos_is_recommended || true + sys_sdk_is_recommended || true + else + exit 1 # cannot continue + fi + "$USR_DIR"/bin/jhbuild "$@" + ;; +esac
\ No newline at end of file diff --git a/packaging/macos/jhb/usr/bin/run-parts b/packaging/macos/jhb/usr/bin/run-parts new file mode 100755 index 0000000..ff0470c --- /dev/null +++ b/packaging/macos/jhb/usr/bin/run-parts @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +### description ################################################################ + +# A partial replacement for Debian's "run-parts" tool. Execute files in a +# directory in their lexical order with the specialty of being able to +# use symlinks to create an order without executing the files twice. + +### shellcheck ################################################################# + +# Nothing here. + +### dependencies ############################################################### + +# Nothing here. + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +function main +{ + local mode=$1 + local dir=$2 + + local file_pattern + + if [ -d "$dir" ]; then + # reconstruct to make it proper (e.g. remove superfluous slashes) + dir=$(dirname "$dir")/$(basename "$dir") + else + # split into directory and file + file_pattern=$(basename "$dir") + dir=$(dirname "$dir") + fi + + file_pattern=${file_pattern:-*} # default pattern is "*" + + local linked_files + linked_files=$(find "$dir" -type l -exec readlink {} +) + + for file in "$dir"/$file_pattern; do # requires 'shopt -s nullglob' + # Only process files that have no symlinks (in that same directory) pointing + # at them. + if [[ "$linked_files" != *$(basename "$file")* ]]; then + case "$mode" in + list) + echo "$file" + ;; + run) + $file + ;; + esac + fi + done +} + +### main ####################################################################### + +set -e + +shopt -s nullglob # in case no files are found + +case "$1" in + list) + main "list" "$2" + ;; + *) + main "run" "$1" + ;; +esac diff --git a/packaging/macos/jhb/usr/src/bash_d/README.md b/packaging/macos/jhb/usr/src/bash_d/README.md new file mode 100644 index 0000000..fc97cc4 --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/README.md @@ -0,0 +1,9 @@ +# `bash_d` + +Conceived as part of my (unpublished) dotfiles on macOS, this collection of functions outgrew its originally limited scope and I began developing this into the spiritual successor of [bashlib](https://github.com/dehesselle/bashlib). + +This is far from finished and comes with no support and without documentation at this point, but I need to put this online now so I can start using this in other projects. + +## License + +[GPL](LICENSE)
\ No newline at end of file diff --git a/packaging/macos/jhb/usr/src/bash_d/ansi.sh b/packaging/macos/jhb/usr/src/bash_d/ansi.sh new file mode 100644 index 0000000..5ecc5ff --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/ansi.sh @@ -0,0 +1,76 @@ +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This file contains ANSI control codes to control terminal output. + +### shellcheck ################################################################# + +# shellcheck shell=bash # no shebang as this file is intended to be sourced +# shellcheck disable=SC2034 # there are a lot of unexported vars here + +### includes ################################################################### + +# Nothing here. + +### variables ################################################################## + +ANSI_ENABLED=${ANSI_ENABLED:-true} # allow ANSI escape sequences... +ANSI_TERM_ONLY=${ANSI_TERM_ONLY:-true} # ...but only when running in a terminal + +ANSI_CURSOR_LEFT="\033[1D" + +# 0: normal +# 1: bold +# 2: faint +# | +# \033[1;32m +# | +# color +ANSI_FG_BLACK="\033[0;30m" +ANSI_FG_BLACK_BOLD="\033[1;30m" +ANSI_FG_BLACK_BRIGHT="\033[0;90m" +ANSI_FG_BLUE="\033[0;34m" +ANSI_FG_BLUE_BOLD="\033[1;34m" +ANSI_FG_BLUE_BRIGHT="\033[0;94m" +ANSI_FG_CYAN="\033[0;36m" +ANSI_FG_CYAN_BOLD="\033[1;36m" +ANSI_FG_CYAN_BRIGHT="\033[0;96m" +ANSI_FG_GREEN="\033[0;32m" +ANSI_FG_GREEN_BOLD="\033[1;32m" +ANSI_FG_GREEN_BRIGHT="\033[0;92m" +ANSI_FG_MAGENTA="\033[0;35m" +ANSI_FG_MAGENTA_BOLD="\033[1;35m" +ANSI_FG_MAGENTA_BRIGHT="\033[0;95m" +ANSI_FG_RED="\033[0;31m" +ANSI_FG_RED_BOLD="\033[1;31m" +ANSI_FG_RED_BRIGHT="\033[0;91m" +ANSI_FG_RESET="\033[0;0m" +ANSI_FG_WHITE="\033[0;37m" +ANSI_FG_WHITE_BOLD="\033[1;37m" +ANSI_FG_WHITE_BRIGHT="\033[0;97m" +ANSI_FG_YELLOW="\033[0;33m" +ANSI_FG_YELLOW_BOLD="\033[1;33m" +ANSI_FG_YELLOW_BRIGHT="\033[0;93m" + +### functions ################################################################## + +function ansi_test_colors +{ + for color in ${!ANSI_FG_*}; do + echo -e "${!color}This is $color" + done +} + +### aliases #################################################################### + +# This performs the following check: +# - usage of ANSI is generally enabled AND +# - we are either running in a terminal OR we don't care at all +alias ansi_is_usable='$ANSI_ENABLED && ([ -t 1 ] || ! $ANSI_TERM_ONLY)' + +### main ####################################################################### + +# Nothing here. diff --git a/packaging/macos/jhb/usr/src/bash_d/assert.sh b/packaging/macos/jhb/usr/src/bash_d/assert.sh new file mode 100644 index 0000000..6b65138 --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/assert.sh @@ -0,0 +1,42 @@ +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# This file provides a mechanism to restrict sourcing a script to specific +# platforms. + +### shellcheck ################################################################# + +# shellcheck shell=bash # no shebang as this file is intended to be sourced + +### dependencies ############################################################### + +bash_d_include echo + +### variables ################################################################## + +ASSERT_RC=0 + +### functions ################################################################## + +# Nothing here. + +### aliases #################################################################### + +# Bash version +alias assert_bash4_or_above='[ ${BASH_VERSINFO[0]} -lt 4 ] && echo_e "$(basename ${BASH_SOURCE[0]}) will be unavailable (depends on bash >= 4)" && return $LINENO || true' + +# Git +alias assert_git='[ ! -x "$(command -v git)" ] && echo_e "$(basename ${BASH_SOURCE[0]}) will be unavailable (depends on git)" && return $LINENO || true' + +# Unix platforms +alias assert_darwin='[ "$(uname)" != "Darwin" ] && echo_e "Darwin required" && return $LINENO || true' +alias assert_linux='[ "$(uname)" != "Linux" ] && echo_e "Linux required" && return $LINENO || true' + +alias assert_ok='ASSERT_RC=$?; [ $ASSERT_RC -ne 0 ] && echo_e "assert_ok rc=$ASSERT_RC" && return $LINENO' + +### main ####################################################################### + +# Nothing here. diff --git a/packaging/macos/jhb/usr/src/bash_d/bash_d.sh b/packaging/macos/jhb/usr/src/bash_d/bash_d.sh new file mode 100644 index 0000000..e0715b4 --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/bash_d.sh @@ -0,0 +1,98 @@ +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# Provide an include guard to be used in every script to protect them from +# being sourced multiple times. + +### shellcheck ################################################################# + +# shellcheck shell=bash # no shebang as this file is intended to be sourced + +### dependencies ############################################################### + +# All of these need to be "or true" because they fail on the first run. + +bash_d_include echo 2>/dev/null || true +bash_d_include assert 2>/dev/null || true + +### variables ################################################################## + +BASH_D_DIR=${BASH_D_DIR:-$(dirname "${BASH_SOURCE[0]}")} + +if [ "$BASH_D_FAIL_ON_INCLUDE_ERROR" != "false" ]; then + BASH_D_FAIL_ON_INCLUDE_ERROR=true +fi + +### functions ################################################################## + +function bash_d_include_all +{ + local includes + includes=$(mktemp "$TMP/${FUNCNAME[0]}".XXXXXX) + + echo "BASH_D_FAIL_ON_INCLUDE_ERROR=false" >> "$includes" + for file in "$BASH_D_DIR"/*.sh; do + echo "bash_d_include $(basename "$file")" >> "$includes" + done + echo "BASH_D_FAIL_ON_INCLUDE_ERROR=true" >> "$includes" + + # shellcheck disable=SC1090 # dynamic sourcing on purpose + source "$includes" + rm "$includes" +} + +function bash_d_is_included +{ + local file=$1 + + #shellcheck disable=SC2076 # we want literal match, not regex + if [[ " ${BASH_D_INCLUDE_FILES[*]} " =~ \ + " $BASH_D_DIR/$(basename -s .sh "$file").sh " ]]; then + return 0 + else + return 1 + fi +} + +### aliases #################################################################### + +# shellcheck disable=SC2142 # too much trickery for shellcheck to digest +alias bash_d_include=\ +'declare -a BASH_D_INCLUDE_FILES; '\ +'BASH_D_INCLUDE_FILE=$(sed -n ${LINENO}p ${BASH_SOURCE[0]} | awk '"'"'{ print $2 }'"'"'); '\ +'BASH_D_INCLUDE_FILE=$BASH_D_DIR/$(basename -s .sh $BASH_D_INCLUDE_FILE).sh; '\ +'if [[ " ${BASH_D_INCLUDE_FILES[@]} " =~ " ${BASH_D_INCLUDE_FILE} " ]]; then '\ +' : ; '\ +'else '\ +' if [ "$BASH_D_INCLUDE_FILE" = "$BASH_D_DIR/bash_d.sh" ] && '\ +' [ ${#BASH_D_INCLUDE_FILES[@]} -gt 0 ] || '\ +' source $BASH_D_INCLUDE_FILE; then '\ +' BASH_D_INCLUDE_FILE=$(sed -n ${LINENO}p ${BASH_SOURCE[0]} | awk '"'"'{ print $2 }'"'"'); '\ +' BASH_D_INCLUDE_FILE=$BASH_D_DIR/$(basename -s .sh $BASH_D_INCLUDE_FILE).sh; '\ +' BASH_D_INCLUDE_FILES+=("$BASH_D_INCLUDE_FILE"); '\ +' else '\ +' if alias | grep "echo_e" >/dev/null; then '\ +' echo_e "$BASH_D_INCLUDE_FILE will be unavailable"; '\ +' else '\ +' >&2 echo "error: $BASH_D_INCLUDE_FILE will be unavailable"; '\ +' fi; '\ +' if [ "$BASH_D_INCLUDE_FILE" != "$BASH_D_DIR/bash_d.sh" ] && $BASH_D_FAIL_ON_INCLUDE_ERROR; then '\ +' exit 1; '\ +' fi '\ +' fi '\ +'fi '\ +'# ' + +### main ####################################################################### + +if [ ! -d "$BASH_D_DIR" ]; then + echo "error: BASH_D_DIR=$BASH_D_DIR is invalid [${BASH_SOURCE[0]}]" + exit 1 +fi + +shopt -s expand_aliases + +bash_d_include bash_d # Need to rerun so complete setting us up. diff --git a/packaging/macos/jhb/usr/src/bash_d/echo.sh b/packaging/macos/jhb/usr/src/bash_d/echo.sh new file mode 100644 index 0000000..d160db0 --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/echo.sh @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# Provide colorful convenience functions for echo. + +### shellcheck ################################################################# + +# shellcheck shell=bash # no shebang as this file is intended to be sourced + +### includes ################################################################### + +bash_d_include ansi + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +function echo_message__ +{ + local funcname=$1 # empty if outside function + local filename=$2 + local type=$3 + local color=$4 + local args=${*:5} + + if [ -z "$funcname" ] || [ "$funcname" = "source" ]; then + funcname=$(basename "$filename") + fi + + if ansi_is_usable; then + echo -e "${color}$type:$ANSI_FG_RESET $args ${ANSI_FG_BLACK_BRIGHT}[$funcname]$ANSI_FG_RESET" + else + echo "$type: $args [$funcname]" + fi +} + +### aliases #################################################################### + +alias echo_d='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "debug" "$ANSI_FG_BLUE_BOLD"' +alias echo_e='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "error" "$ANSI_FG_RED_BRIGHT"' +alias echo_i='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "info" "$ANSI_FG_BLUE_BRIGHT"' +alias echo_o='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "ok" "$ANSI_FG_GREEN_BRIGHT"' +alias echo_w='>&2 echo_message__ "$FUNCNAME" "${BASH_SOURCE[0]}" "warning" "$ANSI_FG_YELLOW_BRIGHT"' + +### main ####################################################################### + +# Nothing here. diff --git a/packaging/macos/jhb/usr/src/bash_d/error.sh b/packaging/macos/jhb/usr/src/bash_d/error.sh new file mode 100644 index 0000000..69ec0be --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/error.sh @@ -0,0 +1,45 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# https://github.com/dehesselle/bash_d + +### includes ################################################################### + +bash_d_include ansi.sh +bash_d_include echo.sh + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +function error_catch +{ + local rc=$1 + + local index=0 + local output + + while output=$(caller $index); do + if [ $index -eq 0 ]; then + if ansi_is_usable; then + echo_e "rc=$rc $ANSI_FG_YELLOW_BRIGHT$BASH_COMMAND$ANSI_FG_RESET" + else + echo "rc=$rc $BASH_COMMAND" + fi + fi + + echo_e $output + ((index+=1)) + done + + exit $rc +} + +### aliases #################################################################### + +alias error_trace_enable='set -o errtrace; trap '\''error_catch ${?}'\'' ERR' +alias error_trace_disable='trap - ERR' + +### main ####################################################################### + +# Nothing here.
\ No newline at end of file diff --git a/packaging/macos/jhb/usr/src/bash_d/lib.sh b/packaging/macos/jhb/usr/src/bash_d/lib.sh new file mode 100644 index 0000000..c1f385e --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/lib.sh @@ -0,0 +1,174 @@ +# SPDX-FileCopyrightText: 2021 René de Hesselle <dehesselle@web.de> +# +# SPDX-License-Identifier: GPL-2.0-or-later + +### description ################################################################ + +# Provide convenience wrappers for install_name_tool. + +### shellcheck ################################################################# + +# shellcheck shell=bash # no shebang as this file is intended to be sourced + +### dependencies ############################################################### + +assert_darwin +bash_d_include echo +bash_d_include readlinkf + +### variables ################################################################## + +LIB_RESET_ID=keep # options: basename, canonical, keep + +### functions ################################################################## + +function lib_change_path +{ + # Compared to install_name_tool, this function + # - requires less arguments as 'source' can be deducted from 'target' + # - can apply the requested changes to multiple binaries at once + + local target=$1 # new path to dynamically linked library + local binaries=${*:2} # binaries to modify + + local source_lib=${target##*/} # get library filename from target location + + for binary in $binaries; do # won't work if spaces in paths + if [[ $binary == *.so ]] || + [[ $binary == *.dylib ]] || + [ $(file $binary | grep "shared library" | wc -l) -eq 1 ]; then + lib_reset_id $binary + fi + + local source=$(otool -L $binary | grep "$source_lib " | awk '{ print $1 }') + if [ -z $source ]; then + echo_w "no $source_lib in $binary" + else + # Reconstructing 'target' as it might have been specified as regex. + target=$(dirname $target)/$(basename $source) + + install_name_tool -change $source $target $binary + fi + done +} + +function lib_change_paths +{ + # This is a wrapper ontop lib_change_path: given a directory 'lib_dir' that + # contains the libraries, all (matching) libraries linked in 'binary' can be + # changed at once to a specified 'target' path. + + local target=$1 # new path to dynamically linked library + local lib_dir=$2 + local binaries=${*:3} + + for binary in $binaries; do + for linked_lib in $(otool -L $binary | tail -n +2 | awk '{ print $1 }'); do + if [ "$(basename $binary)" != "$(basename $linked_lib)" ] && + [ -f $lib_dir/$(basename $linked_lib) ]; then + lib_change_path $target/$(basename $linked_lib) $binary + fi + done + done +} + +function lib_change_siblings +{ + # This is a wrapper ontop lib_change_path: all libraries inside a given + # 'lib_dir' that are linked to libraries located in that same 'lib_dir' can + # be automatically adjusted. + + local lib_dir=$1 + + for lib in $lib_dir/*.dylib; do + lib_reset_id $lib + for linked_lib in $(otool -L $lib | tail -n +2 | awk '{ print $1 }'); do + if [ "$(basename $lib)" != "$(basename $linked_lib)" ] && + [ -f $lib_dir/$(basename $linked_lib) ]; then + lib_change_path @loader_path/$(basename $linked_lib) $lib + fi + done + done +} + +function lib_reset_id +{ + local lib=$1 + + case "$LIB_RESET_ID" in + basename) + install_name_tool -id $(basename $lib) $lib + ;; + canonical) + install_name_tool -id $(readlinkf $lib) $lib + ;; + keep) + : # don't do anything + ;; + *) + echo_e "invalid value for LIB_RESET_ID: $LIB_RESET_ID" + ;; + esac +} + +function lib_add_rpath +{ + local rpath=$1 + local binary=$2 + + install_name_tool -add_rpath "$rpath" "$binary" +} + +function lib_clear_rpath +{ + local binary=$1 + + for rpath in $(otool -l $binary | grep -A2 LC_RPATH | grep -E "^[ ]+path" | awk '{ print $2 }'); do + install_name_tool -delete_rpath $rpath $binary + done +} + +function lib_replace_path +{ + local source=$1 + local target=$2 + local binary=$3 + + for lib in $(lib_get_linked $binary); do + if [[ $lib =~ $source ]]; then + lib_change_path @rpath/$(basename $lib) $binary + fi + done +} + +function lib_get_linked +{ + local binary=$1 # can be executable or library + + #echo_d "binary: $binary" + + local filter # we need to distinguish between executable and library + + local file_type + file_type=$(file "$binary") + if [[ $file_type = *"shared library"* ]]; then + filter="-v $(otool -D "$binary" | tail -n 1)" # exclude library id + elif [[ $file_type = *"executable"* ]]; then + filter="-E [.]+" # include everything + else + echo_w "neither shared library nor executable: $binary" + return 1 + fi + + # since we're not echoing this, output will be newline-separated + # shellcheck disable=SC2086 # need word splitting for arguments + otool -L "$binary" | grep " " | grep $filter | awk '{ print $1 }' +} + +### aliases #################################################################### + +# Nothing here. + +### main ####################################################################### + +# Nothing here. diff --git a/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh b/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh new file mode 100644 index 0000000..135a886 --- /dev/null +++ b/packaging/macos/jhb/usr/src/bash_d/readlinkf.sh @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# https://github.com/dehesselle/bash_d + +### description ################################################################ + +# This is a replacement for GNU's '-f' extension to 'readlink' which is not +# part of the BSD version. + +### includes ################################################################### + +# Nothing here. + +### variables ################################################################## + +# Nothing here. + +### functions ################################################################## + +# Nothing here. + +### aliases #################################################################### + +alias readlinkf='perl -e '"'"'use Cwd "abs_path"; print abs_path(@ARGV[0])'"'"' --' + +### main ####################################################################### + +# Nothing here. |