diff --git a/libgimp/tests/libgimp-run-c-test.sh b/libgimp/tests/libgimp-run-c-test.sh index eda39c0a97..674cd6351e 100644 --- a/libgimp/tests/libgimp-run-c-test.sh +++ b/libgimp/tests/libgimp-run-c-test.sh @@ -10,4 +10,4 @@ cmd="import os; import sys; sys.path.insert(0, '$SRC_DIR'); from pygimp.utils im cmd="$cmd proc = Gimp.get_pdb().lookup_procedure('$TEST_NAME'); gimp_c_assert('$TEST_FILE', 'Test PDB procedure does not exist: {}'.format('$TEST_NAME'), proc is not None);" cmd="$cmd result = proc.run(None);" cmd="$cmd print('SUCCESS') if result.index(0) == Gimp.PDBStatusType.SUCCESS else gimp_c_assert('$TEST_FILE', result.index(1), False);" -echo "$cmd" | "$GIMP_EXE" -nis --batch-interpreter "python-fu-eval" -b - --quit +echo "$cmd" | python3 "$GIMP_EXE" -nis --batch-interpreter "python-fu-eval" -b - --quit diff --git a/libgimp/tests/libgimp-run-python-test.sh b/libgimp/tests/libgimp-run-python-test.sh index 6973bbf334..d22b88f90f 100644 --- a/libgimp/tests/libgimp-run-python-test.sh +++ b/libgimp/tests/libgimp-run-python-test.sh @@ -24,4 +24,4 @@ fi header="import os; import sys; sys.path.insert(0, '$SRC_DIR'); from pygimp.utils import gimp_assert;" header="$header import pygimp.utils; pygimp.utils.gimp_test_filename = '$TEST_FILE'" -(echo "$header" && tail -n +2 "$TEST_FILE") | "$GIMP_EXE" -nis --batch-interpreter "python-fu-eval" -b - --quit +(echo "$header" && tail -n +2 "$TEST_FILE") | python3 "$GIMP_EXE" -nis --batch-interpreter "python-fu-eval" -b - --quit diff --git a/meson.build b/meson.build index 68d787c820..0223808918 100644 --- a/meson.build +++ b/meson.build @@ -2053,7 +2053,7 @@ else gimp_exe_depends = [] endif -gimp_exe = find_program('tools'/'in-build-gimp.sh') +gimp_exe = find_program('tools'/'in-build-gimp.py') ################################################################################ # Subdirs: part 2 diff --git a/tools/in-build-gimp.py b/tools/in-build-gimp.py new file mode 100644 index 0000000000..c7e7f55e5f --- /dev/null +++ b/tools/in-build-gimp.py @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +import os +import random +import shutil +import string +import subprocess +import sys +import tempfile +from pathlib import Path + +try: + GIMP_GLOBAL_BUILD_ROOT = os.environ.get("GIMP_GLOBAL_BUILD_ROOT", ".") + + suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=6)) + GIMP3_DIRECTORY = os.path.join(GIMP_GLOBAL_BUILD_ROOT, f".GIMP3-build-config-{suffix}") + os.makedirs(GIMP3_DIRECTORY, mode=0o700, exist_ok=False) + os.environ["GIMP3_DIRECTORY"] = GIMP3_DIRECTORY + print(f"INFO: temporary GIMP configuration directory: {GIMP3_DIRECTORY}") + + if "GIMP_TEMP_UPDATE_RPATH" in os.environ: + # Earlier code used to set DYLD_LIBRARY_PATH environment variable instead, but + # it didn't work on contributor's builds because of System Integrity + # Protection (SIP), though it did work in the CI. + for binary in os.environ["GIMP_TEMP_UPDATE_RPATH"].split(":"): + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimp", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpbase", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpcolor", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpconfig", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpmath", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpmodule", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpthumb", binary], check=True) + subprocess.run(["install_name_tool", "-add_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpwidgets", binary], check=True) + + if "GIMP_DEBUG_SELF" in os.environ and shutil.which("gdb"): + print(f"RUNNING: gdb --batch -x {os.environ['GIMP_GLOBAL_SOURCE_ROOT']}/tools/debug-in-build-gimp.py --args {os.environ['GIMP_SELF_IN_BUILD']} {' '.join(sys.argv[1:])}") + subprocess.run(["gdb","--return-child-result","--batch","-x",f"{os.environ['GIMP_GLOBAL_SOURCE_ROOT']}/tools/debug-in-build-gimp.py","--args", os.environ["GIMP_SELF_IN_BUILD"]] + sys.argv[1:], stdin=sys.stdin, check=True) + else: + print(f"RUNNING: {os.environ['GIMP_SELF_IN_BUILD']} {' '.join(sys.argv[1:])}") + subprocess.run([os.environ["GIMP_SELF_IN_BUILD"]] + sys.argv[1:],stdin=sys.stdin, check=True) + + if "GIMP_TEMP_UPDATE_RPATH" in os.environ: + for binary in os.environ["GIMP_TEMP_UPDATE_RPATH"].split(":"): + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimp", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpbase", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpcolor", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpconfig", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpmath", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpmodule", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpthumb", binary], check=True) + subprocess.run(["install_name_tool", "-delete_rpath", f"{GIMP_GLOBAL_BUILD_ROOT}/libgimpwidgets", binary], check=True) + + # Clean-up the temporary config directory after each usage, yet making sure we + # don't get tricked by weird redirections or anything of the sort. In particular + # we check that this is a directory with user permission, not a symlink, and + # that it's inside inside the project build's root. + if "GIMP3_DIRECTORY" in os.environ and os.path.isdir(GIMP3_DIRECTORY): + if os.path.islink(GIMP3_DIRECTORY): + print(f"ERROR: $GIMP3_DIRECTORY ({GIMP3_DIRECTORY}) should not be a symlink.") + sys.exit(1) + used_dir_prefix = str(Path(GIMP3_DIRECTORY).resolve().as_posix())[:-6] + tmpl_dir_prefix = f"{Path(os.environ['GIMP_GLOBAL_BUILD_ROOT']).resolve().as_posix()}/.GIMP3-build-config-" + if used_dir_prefix != tmpl_dir_prefix: + print(f"ERROR: $GIMP3_DIRECTORY ({GIMP3_DIRECTORY}) should be under the build directory with a specific prefix.") + print(f' "{used_dir_prefix}" != "{tmpl_dir_prefix}"') + sys.exit(1) + print(f"INFO: Running: shutil.rmtree({GIMP3_DIRECTORY})") + shutil.rmtree(GIMP3_DIRECTORY) + elif not os.access(GIMP3_DIRECTORY, os.W_OK): + print(f"ERROR: $GIMP3_DIRECTORY ({GIMP3_DIRECTORY}) does not belong to the user") + sys.exit(1) + else: + print(f"ERROR: $GIMP3_DIRECTORY ({GIMP3_DIRECTORY}) is not a directory") + sys.exit(1) + +except subprocess.CalledProcessError as e: + print(f"Command failed with exit code {e.returncode}: {e.cmd}") + sys.exit(e.returncode) +except Exception as e: + print(f"Error: {str(e)}") + sys.exit(1) diff --git a/tools/in-build-gimp.sh b/tools/in-build-gimp.sh deleted file mode 100755 index 878e351ccc..0000000000 --- a/tools/in-build-gimp.sh +++ /dev/null @@ -1,83 +0,0 @@ -#!/bin/sh - -set -e - -export GIMP3_DIRECTORY=$(mktemp -d ${GIMP_GLOBAL_BUILD_ROOT}/.GIMP3-build-config-XXXXXX) -echo INFO: temporary GIMP configuration directory: $GIMP3_DIRECTORY - -if [ -n "$GIMP_TEMP_UPDATE_RPATH" ]; then - # Earlier code used to set DYLD_LIBRARY_PATH environment variable instead, but - # it didn't work on contributor's builds because of System Integrity - # Protection (SIP), though it did work in the CI. - export IFS=":" - for bin in $GIMP_TEMP_UPDATE_RPATH; - do - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimp $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpbase $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpcolor $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpconfig $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpmath $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpmodule $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpthumb $bin - install_name_tool -add_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpwidgets $bin - done; - unset IFS -fi - -if [ -n "$GIMP_DEBUG_SELF" ] && command -v gdb; then - echo RUNNING: cat /dev/stdin "|" gdb --batch -x "$GIMP_GLOBAL_SOURCE_ROOT/tools/debug-in-build-gimp.py" --args $GIMP_SELF_IN_BUILD "$@" - cat /dev/stdin | gdb --return-child-result --batch -x "$GIMP_GLOBAL_SOURCE_ROOT/tools/debug-in-build-gimp.py" --args $GIMP_SELF_IN_BUILD "$@" -else - echo RUNNING: cat /dev/stdin "|" $GIMP_SELF_IN_BUILD "$@" - cat /dev/stdin | $GIMP_SELF_IN_BUILD "$@" -fi - -if [ -n "$GIMP_TEMP_UPDATE_RPATH" ]; then - export IFS=":" - for bin in $GIMP_TEMP_UPDATE_RPATH; - do - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimp $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpbase $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpcolor $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpconfig $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpmath $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpmodule $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpthumb $bin - install_name_tool -delete_rpath ${GIMP_GLOBAL_BUILD_ROOT}/libgimpwidgets $bin - done; - unset IFS -fi - -# Clean-up the temporary config directory after each usage, yet making sure we -# don't get tricked by weird redirections or anything of the sort. In particular -# we check that this is a directory with user permission, not a symlink, and -# that it's inside inside the project build's root. -if [ -n "$GIMP3_DIRECTORY" ] && [ -d "$GIMP3_DIRECTORY" ] && [ -O "$GIMP3_DIRECTORY" ]; then - if [ -L "$GIMP3_DIRECTORY" ]; then - echo "ERROR: \$GIMP3_DIRECTORY ($GIMP3_DIRECTORY) should not be a symlink." - exit 1 - fi - used_dir_prefix=$(realpath "$GIMP3_DIRECTORY") - used_dir_prefix=${used_dir_prefix%??????} - tmpl_dir_prefix=$(realpath "$GIMP_GLOBAL_BUILD_ROOT")/.GIMP3-build-config- - if [ "$used_dir_prefix" != "$tmpl_dir_prefix" ]; then - echo "ERROR: \$GIMP3_DIRECTORY ($GIMP3_DIRECTORY) should be under the build directory with a specific prefix." - echo " \"$used_dir_prefix\" != \"$tmpl_dir_prefix\"" - exit 1 - fi - RM_OPTIONS="" - if [ -z "$GIMP_TEMP_UPDATE_RPATH" ]; then - # macOS doesn't have the additional security options. - # Testing for other OS or environments (apparently these options are - # not on busybox for instance). - echo "INFO: Testing if rm supports --preserve-root" - rm --help | grep no-preserve-root && RM_OPTIONS="--no-preserve-root" - echo "INFO: Testing if rm supports --one-file-system" - rm --help | grep one-file-system && RM_OPTIONS="$RM_OPTIONS --one-file-system" - fi - echo INFO: Running: rm -fr $RM_OPTIONS \"$GIMP3_DIRECTORY\" - rm -fr $RM_OPTIONS "$GIMP3_DIRECTORY" -else - echo "ERROR: \$GIMP3_DIRECTORY ($GIMP3_DIRECTORY) is not a directory or does not belong to the user" - exit 1 -fi