#!/usr/bin/env bash set -eu SCRIPT="$(realpath $(dirname "${BASH_SOURCE[0]}"))" if [ -z "${SERENITY_STRIPPED_ENV:-}" ]; then exec "${SCRIPT}/.strip_env.sh" "${@}" fi unset SERENITY_STRIPPED_ENV export MAKEJOBS="${MAKEJOBS:-$(nproc)}" export CMAKE_BUILD_PARALLEL_LEVEL="$MAKEJOBS" buildstep() { local buildstep_name=$1 shift if [ "$#" -eq '0' ]; then "${buildstep_name}" else "$@" fi 2>&1 | sed $'s|^|\x1b[34m['"${port}/${buildstep_name}"$']\x1b[39m |' local return_code=${PIPESTATUS[0]} if [ ${return_code} != 0 ]; then echo -e "\x1b[1;31mError in step ${port}/${buildstep_name} (status=${return_code})\x1b[0m" fi return ${return_code} } buildstep_intro() { echo -e "\x1b[1;32m=> $@\x1b[0m" } target_env() { if [ -f "${SCRIPT}/.hosted_defs.sh" ]; then . "${SCRIPT}/.hosted_defs.sh" elif [ "$(uname -s)" = "SerenityOS" ]; then export SERENITY_ARCH="$(uname -m)" export SERENITY_INSTALL_ROOT="" else >&2 echo "Error: .hosted_defs.sh is missing and we are not running on Serenity." exit 1 fi } target_env DESTDIR="${SERENITY_INSTALL_ROOT}" enable_ccache() { if [ "${USE_CCACHE:-true}" = "true" ] && command -v ccache &>/dev/null; then ccache_tooldir="${SERENITY_BUILD_DIR}/ccache" mkdir -p "$ccache_tooldir" for tool in cc clang gcc c++ clang++ g++; do name="${SERENITY_ARCH}-pc-serenity-${tool}" if ! command -v "${name}" >/dev/null; then continue fi ln -sf "$(command -v ccache)" "${ccache_tooldir}/${name}" done export PATH="${ccache_tooldir}:$PATH" fi } enable_ccache host_env() { export CC="${HOST_CC}" export CXX="${HOST_CXX}" export LD="${HOST_LD}" export AR="${HOST_AR}" export RANLIB="${HOST_RANLIB}" export PATH="${HOST_PATH}" export READELF="${HOST_READELF}" export OBJCOPY="${HOST_OBJCOPY}" export STRIP="${HOST_STRIP}" export CXXFILT="${HOST_CXXFILT}" export PKG_CONFIG_DIR="${HOST_PKG_CONFIG_DIR}" export PKG_CONFIG_SYSROOT_DIR="${HOST_PKG_CONFIG_SYSROOT_DIR}" export PKG_CONFIG_LIBDIR="${HOST_PKG_CONFIG_LIBDIR}" enable_ccache } installedpackagesdb="${DESTDIR}/usr/Ports/installed.db" makeopts=("-j${MAKEJOBS}") installopts=() configscript=configure configopts=() useconfigure=false config_sub_paths=("config.sub") config_guess_paths=("config.guess") use_fresh_config_sub=false use_fresh_config_guess=false depends=() patchlevel=1 launcher_name= launcher_category= launcher_command= launcher_workdir= launcher_run_in_terminal=false icon_file= . "$@" shift : "${workdir:=$port-$version}" PORT_META_DIR="$(pwd)" if [[ -z ${SERENITY_BUILD_DIR:-} ]]; then PORT_BUILD_DIR="${PORT_META_DIR}" else PORT_BUILD_DIR="${SERENITY_BUILD_DIR}/Ports/${port}" fi mkdir -p "${PORT_BUILD_DIR}" cd "${PORT_BUILD_DIR}" cleanup_git() { echo "WARNING: Reverting changes to $workdir as we are in dev mode!" run git clean -xffd >/dev/null 2>&1 } # Make sure to clean up the git repository of the port afterwards. if [ -n "${IN_SERENITY_PORT_DEV:-}" ]; then echo "WARNING: All changes to the workdir in the current state (inside ./package.sh dev) are temporary!" echo " They will be reverted once the command exits!" trap "run cleanup_git" EXIT fi run_nocd() { echo "+ $@ (nocd)" >&2 ("$@") } run() { echo "+ $@" (cd "$workdir" && "$@") } run_replace_in_file() { if [ "$(uname -s)" = "SerenityOS" ]; then run sed -i "$1" $2 else run perl -p -i -e "$1" $2 fi } sed_in_place() { if [ "$(uname -s)" = "Darwin" ]; then sed -i '' "${@}" else sed -i "${@}" fi } get_new_config_sub() { config_sub="${1:-config.sub}" if [ ! -f "$workdir/$config_sub" ]; then >&2 echo "Error: Downloaded $config_sub does not replace an existing file!" exit 1 fi if ! run grep -q serenity "$config_sub"; then run do_download_file "https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub" "${config_sub}" false fi } get_new_config_guess() { config_guess="${1:-config.guess}" if [ ! -f "$workdir/$config_guess" ]; then >&2 echo "Error: Downloaded $config_guess does not replace an existing file!" exit 1 fi if ! run grep -q SerenityOS "$config_guess"; then run do_download_file "https://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess" "${config_guess}" false fi } ensure_new_config_sub() { for path in "${config_sub_paths[@]}"; do get_new_config_sub "${path}" done } ensure_new_config_guess() { for path in "${config_guess_paths[@]}"; do get_new_config_guess "${path}" done } ensure_build() { # Sanity check. if [ ! -f "${DESTDIR}/usr/lib/libc.so" ]; then echo "libc.so could not be found. This likely means that SerenityOS:" echo "- has not been built and/or installed yet" echo "- has been installed in an unexpected location" echo "The currently configured build directory is ${SERENITY_BUILD_DIR}. Resolve this issue and try again." exit 1 fi } install_main_icon() { if [ -n "$icon_file" ] && [ -n "$launcher_command" ]; then local launcher_binary="${launcher_command%% *}" install_icon "$icon_file" "${launcher_binary}" fi } install_icon() { if [ "$#" -lt 2 ]; then echo "Syntax: install_icon " exit 1 fi local icon="$1" local launcher="$2" command -v convert >/dev/null || true local convert_exists=$? command -v identify >/dev/null || true local identify_exists=$? if [ "${convert_exists}" != "0" ] || [ "${identify_exists}" != 0 ]; then echo 'Unable to install icon: missing convert or identify, did you install ImageMagick?' return fi for icon_size in "16x16" "32x32"; do index=$(run identify -format '%p;%wx%h\n' "$icon" | grep "$icon_size" | cut -d";" -f1 | head -n1) if [ -n "$index" ]; then run convert "${icon}[${index}]" "app-${icon_size}.png" else run convert "$icon[0]" -resize $icon_size "app-${icon_size}.png" fi done run $OBJCOPY --add-section serenity_icon_s="app-16x16.png" "${DESTDIR}${launcher}" run $OBJCOPY --add-section serenity_icon_m="app-32x32.png" "${DESTDIR}${launcher}" } install_main_launcher() { if [ -n "$launcher_name" ] && [ -n "$launcher_category" ] && [ -n "$launcher_command" ]; then install_launcher "$launcher_name" "$launcher_category" "$launcher_command" "$launcher_workdir" fi } install_launcher() { if [ "$#" -lt 4 ]; then echo "Syntax: install_launcher " exit 1 fi local launcher_name="$1" local launcher_category="$2" local launcher_command="$3" local launcher_workdir="$4" local launcher_filename="${launcher_name,,}" launcher_filename="${launcher_filename// /}" local icon_override="" case "$launcher_command" in *\ *) mkdir -p $DESTDIR/usr/local/libexec launcher_executable="/usr/local/libexec/$launcher_filename" cat >"$DESTDIR/$launcher_executable" <