diff --git a/dev/release/verify-release-candidate.sh b/dev/release/verify-release-candidate.sh index f4d2800eaf0..9b18a251490 100755 --- a/dev/release/verify-release-candidate.sh +++ b/dev/release/verify-release-candidate.sh @@ -460,6 +460,47 @@ test_and_install_cpp() { DEFAULT_DEPENDENCY_SOURCE="AUTO" fi + # TEMP - remove before merge: VERIFY_RC_DEBUG=1 probes the libLLVM @rpath cause. + # set +e: this is expected to abort (exit 134) and must not kill the script + if [ "${VERIFY_RC_DEBUG:-0}" -gt 0 ] && [ "$(uname)" = "Darwin" ] && [ -n "${CONDA_PREFIX:-}" ]; then + set +e + echo "===== VERIFY_RC_DEBUG: libLLVM @rpath probe =====" + echo "CONDA_PREFIX=${CONDA_PREFIX}" + echo "ARROW_HOME=${ARROW_HOME:-}" + + envlib=$(ls -d "${CONDA_PREFIX}"/lib/libLLVM.*.dylib 2>/dev/null | head -1) + echo "env libLLVM : ${envlib:-MISSING}" + if [ -n "${envlib}" ]; then + otool -L "${envlib}" >/dev/null 2>&1 && echo "env libLLVM loadable : yes" + fi + + # env binary resolving into the env = hardlinked (safe) vs. into pkgs = vulnerable + for tool in llvm-link llvm-ranlib; do + envln="${CONDA_PREFIX}/bin/${tool}" + [ -e "${envln}" ] || continue + real=$(python3 -c 'import os,sys;print(os.path.realpath(sys.argv[1]))' "${envln}" 2>/dev/null) + echo "env ${tool} realpath: ${real}" + case "${real}" in + "${CONDA_PREFIX}"/*) echo " -> INTO env (safe)" ;; + *) echo " -> pkgs cache (VULNERABLE)" ;; + esac + done + + # controlled comparison on the pkgs binary (its @loader_path is always the pkgs cache) + pkgbin=$(ls -d "${CONDA_PREFIX}"/../../pkgs/llvm-tools-*/bin/llvm-link-* 2>/dev/null | head -1) + echo "pkgs llvm-link : ${pkgbin:-MISSING}" + if [ -n "${pkgbin}" ]; then + DYLD_LIBRARY_PATH="${ARROW_HOME}/lib" "${pkgbin}" --version >/dev/null 2>&1 + echo "A) no conda lib : exit=$? (134 or 0, pkgs binary varies by run)" + DYLD_LIBRARY_PATH="${CONDA_PREFIX}/lib:${ARROW_HOME}/lib" "${pkgbin}" --version >/dev/null 2>&1 + echo "B) conda lib via DYLD_LIBRARY_PATH : exit=$? (expect 0)" + DYLD_LIBRARY_PATH="${ARROW_HOME}/lib" DYLD_FALLBACK_LIBRARY_PATH="${CONDA_PREFIX}/lib" "${pkgbin}" --version >/dev/null 2>&1 + echo "C) conda lib via DYLD_FALLBACK (fix) : exit=$? (expect 0)" + fi + echo "===== end VERIFY_RC_DEBUG =====" + set -e + fi + mkdir -p $ARROW_TMPDIR/cpp-build pushd $ARROW_TMPDIR/cpp-build @@ -519,7 +560,14 @@ test_and_install_cpp() { ${ARROW_CMAKE_OPTIONS:-} \ ${ARROW_SOURCE_DIR}/cpp export CMAKE_BUILD_PARALLEL_LEVEL=${CMAKE_BUILD_PARALLEL_LEVEL:-${NPROC}} - cmake --build . --target install + # Expose conda's lib on the *fallback* path so the LLVM tools (llvm-link, + # llvm-ranlib) find libLLVM.*.dylib on flaky @rpath miss on macOS. (Fallback is searched last, + # so it doesn't shadow system libs like libiconv during the build or leak into tests.) + if [ "$(uname)" = "Darwin" ] && [ "${USE_CONDA}" -gt 0 ] && [ -n "${CONDA_PREFIX:-}" ]; then + DYLD_FALLBACK_LIBRARY_PATH="${CONDA_PREFIX}/lib:${DYLD_FALLBACK_LIBRARY_PATH:-/usr/local/lib:/usr/lib}" cmake --build . --target install + else + cmake --build . --target install + fi if [ ${TEST_CPP} -gt 0 ]; then LD_LIBRARY_PATH=$PWD/release:$LD_LIBRARY_PATH ctest \ @@ -779,10 +827,10 @@ test_source_distribution() { if [ "$(uname)" == "Darwin" ]; then NPROC=$(sysctl -n hw.ncpu) - export DYLD_LIBRARY_PATH=$ARROW_HOME/lib:${DYLD_LIBRARY_PATH:-} + export DYLD_LIBRARY_PATH=$ARROW_HOME/lib${DYLD_LIBRARY_PATH:+:${DYLD_LIBRARY_PATH}} else NPROC=$(nproc) - export LD_LIBRARY_PATH=$ARROW_HOME/lib:${LD_LIBRARY_PATH:-} + export LD_LIBRARY_PATH=$ARROW_HOME/lib${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}} fi pushd $ARROW_SOURCE_DIR diff --git a/dev/tasks/tasks.yml b/dev/tasks/tasks.yml index 56a9ce1472a..8e7b403e8d0 100644 --- a/dev/tasks/tasks.yml +++ b/dev/tasks/tasks.yml @@ -298,6 +298,9 @@ tasks: ci: github template: verify-rc/github.macos.yml params: + # TEMP - remove before merge: enable the libLLVM @rpath probe + env: + VERIFY_RC_DEBUG: 1 target: {{ target }} use_conda: True github_runner: "macos-15-intel"