1#!/bin/bash 2#************************************************************** 3# 4# Licensed to the Apache Software Foundation (ASF) under one 5# or more contributor license agreements. See the NOTICE file 6# distributed with this work for additional information 7# regarding copyright ownership. The ASF licenses this file 8# to you under the Apache License, Version 2.0 (the 9# "License"); you may not use this file except in compliance 10# with the License. You may obtain a copy of the License at 11# 12# http://www.apache.org/licenses/LICENSE-2.0 13# 14# Unless required by applicable law or agreed to in writing, 15# software distributed under the License is distributed on an 16# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17# KIND, either express or implied. See the License for the 18# specific language governing permissions and limitations 19# under the License. 20# 21#************************************************************** 22# 23# Fail when a Mach-O under the given paths still loads from or searches a 24# build-time location: the CPython staging prefix or an unresolved @_______ 25# placeholder that macosx-change-install-names.pl should have rewritten. 26# 27# ./solenv/bin/macosx-check-load-commands.sh <bundle-or-file> ... 28 29set -euo pipefail 30 31[ $# -gt 0 ] || { echo "usage: $(basename "$0") <bundle-or-file> ..." >&2; exit 2; } 32 33machos=() 34while IFS= read -r -d '' f && IFS= read -r type; do 35 case "$type" in ": Mach-O"*) machos+=("$f") ;; esac 36done < <(find "$@" -type f -print0 | xargs -0 file --no-pad --print0 -- 2>/dev/null) 37# Every caller passes a real app bundle or binary that is expected to contain 38# Mach-O content; zero matches means a wrong path or missing build output, not 39# "nothing to check" - fail loudly instead of silently passing. 40if [ ${#machos[@]} -eq 0 ]; then 41 echo "no Mach-O files found under: $*" >&2 42 exit 1 43fi 44 45# A dylib's own ID (LC_ID_DYLIB) is never used to locate it at runtime. 46bad=$(printf '%s\0' "${machos[@]}" | xargs -0 otool -l | awk ' 47 /^[^[:space:]].*:$/ { file = $0; next } 48 $1 == "cmd" { cmd = $2; next } 49 cmd != "LC_ID_DYLIB" && ($1 == "name" || $1 == "path") && /python-inst|@_______/ { 50 print file " " cmd " " $2 51 }') 52if [ -n "$bad" ]; then 53 echo "unrelocated Mach-O load commands:" >&2 54 echo "$bad" >&2 55 exit 1 56fi 57