| OLD | NEW |
| (Empty) |
| 1 #!/bin/bash | |
| 2 | |
| 3 # Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
| 4 # Use of this source code is governed by a BSD-style license that can be | |
| 5 # found in the LICENSE file. | |
| 6 | |
| 7 # Copies a framework to its new home, "unversioning" it. | |
| 8 # | |
| 9 # Normally, frameworks are versioned bundles. The contents of a framework are | |
| 10 # stored in a versioned directory within the bundle, and symbolic links | |
| 11 # provide access to the actual code and resources. See | |
| 12 # http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPFrame
works/Concepts/FrameworkAnatomy.html | |
| 13 # | |
| 14 # The symbolic links usually found in frameworks create problems. Symbolic | |
| 15 # links are excluded from code signatures. That means that it's possible to | |
| 16 # remove or retarget a symbolic link within a framework without affecting the | |
| 17 # seal. In Chrome's case, the outer .app bundle contains a framework where | |
| 18 # all application code and resources live. In order for the signature on the | |
| 19 # .app to be meaningful, it encompasses the framework. Because framework | |
| 20 # resources are accessed through the framework's symbolic links, this | |
| 21 # arrangement results in a case where the resources can be altered without | |
| 22 # affecting the .app signature's validity. | |
| 23 # | |
| 24 # Indirection through symbolic links also carries a runtime performance | |
| 25 # penalty on open() operations, although open() typically completes so quickly | |
| 26 # that this is not considered a major performance problem. | |
| 27 # | |
| 28 # To resolve these problems, the frameworks that ship within Chrome's .app | |
| 29 # bundle are unversioned. Unversioning is simple: instead of using the | |
| 30 # original outer .framework directory as the framework that ships within the | |
| 31 # .app, the inner versioned directory is used. Instead of accessing bundled | |
| 32 # resources through symbolic links, they are accessed directly. In normal | |
| 33 # situations, the only hard-coded use of the versioned directory is by dyld, | |
| 34 # when loading the framework's code, but this is handled through a normal | |
| 35 # Mach-O load command, and it is easy to adjust the load command to point to | |
| 36 # the unversioned framework code rather than the versioned counterpart. | |
| 37 # | |
| 38 # The resulting framework bundles aren't strictly conforming, but they work | |
| 39 # as well as normal versioned framework bundles. | |
| 40 | |
| 41 set -e | |
| 42 | |
| 43 if [ $# -ne 2 ] ; then | |
| 44 echo "usage: ${0} FRAMEWORK DESTINATION_DIR" >& 2 | |
| 45 exit 1 | |
| 46 fi | |
| 47 | |
| 48 # FRAMEWORK should be a path to a versioned framework bundle, ending in | |
| 49 # .framework. DESTINATION_DIR is the directory that the unversioned framework | |
| 50 # bundle will be copied to. | |
| 51 | |
| 52 FRAMEWORK="${1}" | |
| 53 DESTINATION_DIR="${2}" | |
| 54 | |
| 55 FRAMEWORK_NAME="$(basename "${FRAMEWORK}")" | |
| 56 if [ "${FRAMEWORK_NAME: -10}" != ".framework" ] ; then | |
| 57 echo "${0}: ${FRAMEWORK_NAME} does not end in .framework" >& 2 | |
| 58 exit 1 | |
| 59 fi | |
| 60 FRAMEWORK_NAME_NOEXT="${FRAMEWORK_NAME:0:$((${#FRAMEWORK_NAME} - 10))}" | |
| 61 | |
| 62 # Find the current version. | |
| 63 VERSIONS="${FRAMEWORK}/Versions" | |
| 64 CURRENT_VERSION_LINK="${VERSIONS}/Current" | |
| 65 CURRENT_VERSION_ID="$(readlink "${VERSIONS}/Current")" | |
| 66 CURRENT_VERSION="${VERSIONS}/${CURRENT_VERSION_ID}" | |
| 67 | |
| 68 # Make sure that the framework's structure makes sense as a versioned bundle. | |
| 69 if [ ! -e "${CURRENT_VERSION}/${FRAMEWORK_NAME_NOEXT}" ] ; then | |
| 70 echo "${0}: ${FRAMEWORK_NAME} does not contain a dylib" >& 2 | |
| 71 exit 1 | |
| 72 fi | |
| 73 | |
| 74 DESTINATION="${DESTINATION_DIR}/${FRAMEWORK_NAME}" | |
| 75 | |
| 76 # Copy the versioned directory within the versioned framework to its | |
| 77 # destination location. | |
| 78 mkdir -p "${DESTINATION_DIR}" | |
| 79 rsync -acC --delete --exclude Headers --exclude PrivateHeaders \ | |
| 80 --include '*.so' "${CURRENT_VERSION}/" "${DESTINATION}" | |
| 81 | |
| 82 # Adjust the Mach-O LC_ID_DYLIB load command in the framework. This does not | |
| 83 # change the LC_LOAD_DYLIB load commands in anything that may have already | |
| 84 # linked against the framework. Not all frameworks will actually need this | |
| 85 # to be changed. Some frameworks may already be built with the proper | |
| 86 # LC_ID_DYLIB for use as an unversioned framework. Xcode users can do this | |
| 87 # by setting LD_DYLIB_INSTALL_NAME to | |
| 88 # $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(WRAPPER_NAME)/$(PRODUCT_NAME) | |
| 89 # If invoking ld via gcc or g++, pass the desired path to -Wl,-install_name | |
| 90 # at link time. | |
| 91 FRAMEWORK_DYLIB="${DESTINATION}/${FRAMEWORK_NAME_NOEXT}" | |
| 92 LC_ID_DYLIB_OLD="$(otool -l "${FRAMEWORK_DYLIB}" | | |
| 93 grep -A10 "^ *cmd LC_ID_DYLIB$" | | |
| 94 grep -m1 "^ *name" | | |
| 95 sed -Ee 's/^ *name (.*) \(offset [0-9]+\)$/\1/')" | |
| 96 VERSION_PATH="/Versions/${CURRENT_VERSION_ID}/${FRAMEWORK_NAME_NOEXT}" | |
| 97 LC_ID_DYLIB_NEW="$(echo "${LC_ID_DYLIB_OLD}" | | |
| 98 sed -Ee "s%${VERSION_PATH}$%/${FRAMEWORK_NAME_NOEXT}%")" | |
| 99 | |
| 100 if [ "${LC_ID_DYLIB_NEW}" != "${LC_ID_DYLIB_OLD}" ] ; then | |
| 101 install_name_tool -id "${LC_ID_DYLIB_NEW}" "${FRAMEWORK_DYLIB}" | |
| 102 fi | |
| OLD | NEW |