|
|
|||
File indexing completed on 2026-08-16 08:16:24
0001 #!/usr/bin/env bash 0002 # Repair wrapper for the macOS PyPI wheels, invoked as 0003 # CIBW_REPAIR_WHEEL_COMMAND_MACOS with: $1 = wheel, $2 = dest_dir, $3 = archs. 0004 # 0005 # Root cause (diagnosed with delocate-listdeps --all --depending, and confirmed 0006 # against spack's thrift package.py and thrift's own build/cmake/ 0007 # DefineOptions.cmake): 0008 # * libActsPluginArrow.dylib (static Arrow) links spack's openssl: 0009 # .../spack/opt/spack/.../openssl-<hash>/lib/libssl.3.dylib 0010 # * spack's libthrift (an Arrow dependency) concretizes `~openssl` (its spack 0011 # "openssl" variant is off, so spack never wires in spack's openssl for 0012 # it). But thrift builds with build_system=cmake, and unlike thrift's 0013 # AutotoolsBuilder, its CMakeBuilder.cmake_args() never passes 0014 # -DWITH_OPENSSL. Thrift's own DefineOptions.cmake then runs a bare 0015 # find_package(OpenSSL) regardless of the variant and auto-links whatever 0016 # it finds on the runner's default search path — the python.org 0017 # framework's copy: 0018 # /Library/Frameworks/Python.framework/Versions/<X>/lib/libssl.3.dylib 0019 # delocate then sees two different libssl.3.dylib (and libcrypto.3.dylib) with 0020 # the same basename and aborts: 0021 # DelocationError: Already planning to copy library with same basename as: 0022 # libssl.3.dylib 0023 # 0024 # Workaround: before delocation, repoint libthrift's framework openssl 0025 # references at spack's openssl, so the graph resolves to a single copy that 0026 # delocate can vendor. Both are openssl 3.x, and ACTS' Parquet usage does not 0027 # touch TLS. Scoped to libthrift specifically — the only known offender — 0028 # rather than scanning/mutating the whole spack store, to keep this local. 0029 # 0030 # How long this is needed: until thrift's spack package (spack/spack-packages, 0031 # repos/spack_repo/builtin/packages/thrift/package.py) wires its "openssl" 0032 # variant into CMakeBuilder.cmake_args() the way it already does for 0033 # AutotoolsBuilder — a one-line upstream fix 0034 # (self.define_from_variant("WITH_OPENSSL", "openssl")). Once that lands and 0035 # ci-dependencies picks up the updated spack-packages, thrift stops linking the 0036 # framework openssl and the rewrite below finds nothing to do on its own; the 0037 # script can then be deleted. 0038 # 0039 # This modifies the spack store on the (ephemeral) CI runner. delocate re-signs 0040 # the copies it vendors into the wheel, so the invalidated store-lib signatures 0041 # do not matter, and the wheel's tests run against the self-contained wheel. 0042 set -euo pipefail 0043 0044 wheel="$1" 0045 dest_dir="$2" 0046 archs="$3" 0047 0048 # Any framework-provided openssl, regardless of soversion. 0049 fw_re='/Library/Frameworks/Python\.framework/.*/lib(ssl|crypto)\.[0-9.]*dylib' 0050 0051 delocate() { 0052 if ! delocate-wheel --require-archs "$archs" -w "$dest_dir" -v "$wheel"; then 0053 echo "::group::delocate failed — dependency tree" 0054 delocate-listdeps --all --depending "$wheel" || true 0055 echo "::endgroup::" 0056 exit 1 0057 fi 0058 } 0059 0060 inspect_dir="$(mktemp -d)" 0061 trap 'rm -rf "$inspect_dir"' EXIT 0062 unzip -q "$wheel" -d "$inspect_dir" 0063 0064 # Derive the spack store root from whatever absolute spack path the wheel's own 0065 # binaries link against. If the wheel does not reference spack at all there is 0066 # nothing to normalize. 0067 spack_root="" 0068 while IFS= read -r bin; do 0069 ref="$(otool -L "$bin" 2>/dev/null | awk '/\/opt\/spack\//{print $1; exit}')" || true 0070 if [ -n "${ref:-}" ]; then 0071 spack_root="${ref%/opt/spack/*}" 0072 break 0073 fi 0074 done < <(find "$inspect_dir" \( -name '*.dylib' -o -name '*.so' \) -type f) 0075 0076 if [ -z "$spack_root" ]; then 0077 echo "wheel does not link the spack store; delocating as-is" 0078 delocate 0079 exit 0 0080 fi 0081 echo "spack root: ${spack_root}" 0082 0083 # Locate spack's own openssl, which is the copy we consolidate onto. 0084 spack_ssl="$(find "${spack_root}/opt/spack" -path '*/openssl-*/lib/libssl.*.dylib' \ 0085 -type f 2>/dev/null | head -1)" 0086 if [ -z "${spack_ssl:-}" ]; then 0087 echo "no spack openssl found; delocating as-is" 0088 delocate 0089 exit 0 0090 fi 0091 spack_ssl_dir="$(dirname "$spack_ssl")" 0092 echo "spack openssl dir: ${spack_ssl_dir}" 0093 0094 # libthrift is the only known offender (see root cause above); scope the 0095 # rewrite to it instead of scanning/mutating the whole spack store. 0096 libthrift="$(find "${spack_root}/opt/spack" -name 'libthrift*.dylib' \ 0097 -type f 2>/dev/null | head -1)" 0098 if [ -z "${libthrift:-}" ]; then 0099 echo "no libthrift in spack store; delocating as-is" 0100 delocate 0101 exit 0 0102 fi 0103 0104 echo "::group::Repoint libthrift's framework openssl references to spack openssl" 0105 # `|| true`: grep exits 1 when there is no framework reference (the expected 0106 # steady state once the upstream thrift package is fixed), which would 0107 # otherwise trip `set -e` under pipefail. 0108 fw_refs="$(otool -L "$libthrift" 2>/dev/null | awk 'NR>1{print $1}' \ 0109 | grep -E "$fw_re" || true)" 0110 rewrote=0 0111 if [ -n "$fw_refs" ]; then 0112 while IFS= read -r fw; do 0113 target="${spack_ssl_dir}/$(basename "$fw")" 0114 if [ ! -f "$target" ]; then 0115 echo "ERROR: ${libthrift} references ${fw}, but ${target} does not exist" >&2 0116 exit 1 0117 fi 0118 echo " ${libthrift}: ${fw} -> ${target}" 0119 if ! install_name_tool -change "$fw" "$target" "$libthrift"; then 0120 echo "ERROR: install_name_tool failed to rewrite ${libthrift}" >&2 0121 exit 1 0122 fi 0123 rewrote=$((rewrote + 1)) 0124 done <<< "$fw_refs" 0125 fi 0126 echo "rewrote ${rewrote} framework openssl reference(s) in libthrift" 0127 echo "::endgroup::" 0128 0129 delocate
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|