1#************************************************************** 2# 3# Licensed to the Apache Software Foundation (ASF) under one 4# or more contributor license agreements. See the NOTICE file 5# distributed with this work for additional information 6# regarding copyright ownership. The ASF licenses this file 7# to you under the Apache License, Version 2.0 (the 8# "License"); you may not use this file except in compliance 9# with the License. You may obtain a copy of the License at 10# 11# http://www.apache.org/licenses/LICENSE-2.0 12# 13# Unless required by applicable law or agreed to in writing, 14# software distributed under the License is distributed on an 15# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16# KIND, either express or implied. See the License for the 17# specific language governing permissions and limitations 18# under the License. 19# 20#************************************************************** 21 22 23 24package macosxotoolhelper; 25require Exporter; 26our @ISA = Exporter; 27our @EXPORT = otoolD; 28 29use File::Basename; 30$::CC_PATH=(fileparse( $ENV{"CC"}))[1]; 31 32sub otoolD($) { 33 my ($file) = @_; 34 my $call = "otool -D $file"; 35 open(IN, "-|", $call) or die "cannot $call"; 36 my @lines = <IN>; 37 close(IN); 38 39 # A fat/universal binary (e.g. a Homebrew-installed library bundling 40 # x86_64 and arm64 slices) makes otool -D print one 41 # "<path> (architecture <arch>):" stanza per slice instead of the 42 # single "<path>:" header a thin binary gets. Every slice of the same 43 # library reports the same install name, so take it from the first 44 # stanza and ignore the rest. 45 # 46 # A slice with no install name (e.g. a loadable module/bundle, such as 47 # a PKCS#11 provider that is only ever dlopen()ed) prints its header 48 # with nothing after it -- callers rely on getting undef back for that 49 # case, same as otool -D on a thin file with no install name. 50 my $header_re = qr/^\Q$file\E(?: \(architecture [^)]+\))?:\n$/; 51 my @names; 52 my $i = 0; 53 while ($i < @lines) { 54 $lines[$i] =~ $header_re or 55 die "unexpected otool -D output (\"$lines[$i]\", expecting \"$file:\")"; 56 ++$i; 57 if ($i < @lines && $lines[$i] !~ $header_re) { 58 push @names, $lines[$i]; 59 ++$i; 60 } 61 } 62 return undef unless @names; 63 grep($_ ne $names[0], @names) and 64 die "otool -D reported differing install names across architectures for $file"; 65 return $names[0]; 66} 67