| #!/usr/bin/env sh | |
| # | |
| # Copyright (C) 2025 Igalia S.L. | |
| # | |
| # Redistribution and use in source and binary forms, with or without | |
| # modification, are permitted provided that the following conditions are met: | |
| # | |
| # 1. Redistributions of source code must retain the above copyright notice, this | |
| # list of conditions and the following disclaimer. | |
| # 2. Redistributions in binary form must reproduce the above copyright notice, | |
| # this list of conditions and the following disclaimer in the documentation | |
| # and/or other materials provided with the distribution. | |
| # | |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |
| # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | |
| # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |
| # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | |
| # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | |
| # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | |
| # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |
| # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
| # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| # | |
| set -eu | |
| SCRIPTPATH="$(realpath -- "${0}")" | |
| SCRIPTDIR="$(dirname -- "${SCRIPTPATH}")" | |
| WEBKITDIR="$(realpath -- "${SCRIPTDIR}/../..")" | |
| WEBKIT_SOURCE_DIR="${WEBKIT_SOURCE_DIR:-${WEBKITDIR}}" | |
| WEBKIT_SOURCE_DIR="$(realpath -m -- "${WEBKIT_SOURCE_DIR}")" | |
| help() { | |
| cat <<EOF | |
| Usage: ${0} program-to-execute [arguments...] | |
| ${0} --create-symlink | |
| This script is used by the WebKit tooling when running inside the | |
| webkit-container-sdk for GTK/WPE port development. It enables building | |
| WebKit and running tests inside a common path at /sdk/webkit. | |
| Options: | |
| -h, --help Show this help message | |
| --create-symlink Create /sdk/webkit as a symlink to ${WEBKIT_SOURCE_DIR} | |
| and exit. Useful for tools not executed through this | |
| wrapper (like gdb) that need to resolve /sdk/webkit paths. | |
| Default behavior: | |
| Creates a private mount namespace where /sdk/webkit is a bind-mount | |
| to ${WEBKIT_SOURCE_DIR}, then executes the specified program. | |
| Examples: | |
| ${0} Tools/Scripts/build-webkit --wpe --release | |
| ${0} --create-symlink | |
| EOF | |
| exit 0 | |
| } | |
| error() { | |
| printf '%s\n' "${@}" 1>&2 | |
| exit 1 | |
| } | |
| # If path starts with ${WEBKIT_SOURCE_DIR}, replace that prefix with /sdk/webkit. | |
| maybe_replace_path_prefix_to_rootsdk() { | |
| case "${1}" in | |
| "${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*) | |
| printf '%s\n' "/sdk/webkit${1#"${WEBKIT_SOURCE_DIR}"}" | |
| ;; | |
| *) | |
| printf '%s\n' "${1}" | |
| ;; | |
| esac | |
| } | |
| resolve_relpath_to_abs_if_outside() { | |
| abs=$(realpath -m -- "${ORGPWD}/${1}") | |
| case "${abs}" in | |
| "${WEBKIT_SOURCE_DIR}"|"${WEBKIT_SOURCE_DIR}"/*) | |
| # Inside the tree: keep original relative value | |
| printf '%s\n' "${1}" | |
| ;; | |
| *) # relative path outside the tree: make it absolute | |
| printf '%s\n' "${abs}" | |
| ;; | |
| esac | |
| } | |
| maybe_update_relpath_to_abs_if_outside() { | |
| case "${1}" in | |
| ""|/*|*://*) | |
| # do not touch if is empty or looks like an abs path or a URL | |
| printf '%s\n' "${1}" | |
| ;; | |
| .|..|./*|../*|*/*) | |
| resolve_relpath_to_abs_if_outside "${1}" | |
| ;; | |
| *) | |
| if [ -L "${1}" ]; then | |
| resolve_relpath_to_abs_if_outside "${1}" | |
| else | |
| printf '%s\n' "${1}" | |
| fi | |
| ;; | |
| esac | |
| } | |
| # Convert relative paths to absolute if they point outside ${WEBKIT_SOURCE_DIR} | |
| args_maybe_update_outside_relpaths() { | |
| for arg in "${@}"; do | |
| case "${arg}" in | |
| --*=*) # handle arguments like "--option=value" | |
| key="${arg%%=*}" | |
| val="${arg#*=}" | |
| val="$(maybe_update_relpath_to_abs_if_outside "${val}")" | |
| arg="${key}=${val}" | |
| ;; | |
| *) | |
| arg="$(maybe_update_relpath_to_abs_if_outside "${arg}")" | |
| ;; | |
| esac | |
| printf "'" | |
| printf '%s' "${arg}" | sed "s/'/'\\\\''/g" | |
| printf "' " | |
| done | |
| } | |
| [ "$#" -ge 1 ] || help | |
| [ "${1}" = "--help" ] && help | |
| [ "${1}" = "-h" ] && help | |
| [ -d "${WEBKIT_SOURCE_DIR}" ] || error "Can't find directory: ${WEBKIT_SOURCE_DIR}" | |
| [ -d /sdk ] || error "Can't find /sdk directory" | |
| [ -w /sdk ] || error "Directory /sdk is not writable for user $(whoami)" | |
| case "${WEBKIT_SOURCE_DIR}" in | |
| /sdk|/sdk/*) error "${0} should not be invoked with WEBKIT_SOURCE_DIR under /sdk directory" ;; | |
| esac | |
| if [ "${1}" = "--create-symlink" ]; then | |
| [ "$#" -ge 2 ] && error "No extra arguments can be passed with --create-symlink" | |
| if [ -L "/sdk/webkit" ]; then | |
| CURSYMLINKDEST="$(realpath -m -- /sdk/webkit)" | |
| if [ "${CURSYMLINKDEST}" != "${WEBKIT_SOURCE_DIR}" ]; then | |
| rm -f "/sdk/webkit" | |
| ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit" | |
| echo "Symlink at /sdk/webkit changed from ${CURSYMLINKDEST} to ${WEBKIT_SOURCE_DIR}" | |
| fi | |
| elif ! [ -e "/sdk/webkit" ]; then | |
| ln -s "${WEBKIT_SOURCE_DIR}" "/sdk/webkit" | |
| else | |
| error "ERROR: /sdk/webkit exists and is not a symlink. This is unexpected" | |
| fi | |
| exit 0 | |
| fi | |
| CURUID="$(id -u)" | |
| CURGID="$(id -g)" | |
| ORGPWD="$(pwd)" | |
| SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")" | |
| # Try also with the realpath, just in case pwd is inside a symlinked dir. | |
| if [ "${ORGPWD}" = "${SDKPWD}" ]; then | |
| ORGPWD="$(realpath -- "${ORGPWD}")" | |
| SDKPWD="$(maybe_replace_path_prefix_to_rootsdk "${ORGPWD}")" | |
| fi | |
| # When $(pwd) is inside ${WEBKIT_SOURCE_DIR}, switch (cd) to the equivalent bind-mount path | |
| # under /sdk/webkit. Any relative path arguments that point outside ${WEBKIT_SOURCE_DIR} are | |
| # converted to absolute paths first, since they wouldn't resolve correctly after the switch. | |
| [ "${ORGPWD}" != "${SDKPWD}" ] && eval "set -- $(args_maybe_update_outside_relpaths "${@}")" | |
| # Since util-linux 2.27 is not needed to execute mount --make-rprivate / | |
| # because unshare does that automatically by default for new mount namespaces | |
| exec unshare -rm sh -c ' | |
| set -eu | |
| WEBKIT_SOURCE_DIR="${1}" | |
| SDKPWD="${2}" | |
| CURUID="${3}" | |
| CURGID="${4}" | |
| shift 4 | |
| mount -t tmpfs -o size=16M tmpfs /sdk | |
| mkdir /sdk/webkit | |
| mount --bind "${WEBKIT_SOURCE_DIR}" /sdk/webkit | |
| cd "${SDKPWD}" | |
| export WEBKIT_CONTAINER_SDK_INSIDE_MOUNT_NAMESPACE=1 | |
| exec unshare --map-user="${CURUID}" --map-group="${CURGID}" -- "${@}" | |
| ' -- "${WEBKIT_SOURCE_DIR}" "${SDKPWD}" "${CURUID}" "${CURGID}" "${@}" |