diff options
-rwxr-xr-x | chrome/chrome.gyp | 58 | ||||
-rwxr-xr-x | chrome/tools/build/mac/copy_framework_unversioned | 109 | ||||
-rwxr-xr-x | chrome/tools/build/mac/remove_headers_from_framework | 31 | ||||
-rw-r--r-- | chrome/tools/build/mac/sign.sh.in | 8 |
4 files changed, 138 insertions, 68 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index b36b2dc..87c52a4 100755 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -3446,10 +3446,6 @@ ['mac_keystone==1', { 'copies': [ { - 'destination': '<(PRODUCT_DIR)/<(mac_product_name).app/Contents/Frameworks/', - 'files': ['../third_party/googlemac/Releases/Keystone/KeystoneRegistration.framework'], - }, - { # Put keystone_install.sh where the packaging system will # find it. The packager will copy this script to the # correct location on the disk image. @@ -3468,7 +3464,7 @@ 'action_name': 'Make sign.sh', 'variables': { 'make_sign_sh_path': 'tools/build/mac/make_sign_sh', - 'sign_sh_in_path': 'tools/build/mac/make_sign_sh', + 'sign_sh_in_path': 'tools/build/mac/sign.sh.in', 'app_resource_rules_in_path': 'tools/build/mac/app_resource_rules.plist.in', }, @@ -3558,13 +3554,20 @@ { 'destination': '<(PRODUCT_DIR)/<(mac_product_name).app/Contents/Versions/<(version_full)', 'files': [ - '<(PRODUCT_DIR)/<(mac_product_name) Framework.framework', '<(PRODUCT_DIR)/<(mac_product_name) Helper.app', ], }, ], 'postbuilds': [ { + 'postbuild_name': 'Copy <(mac_product_name) Framework.framework', + 'action': [ + 'tools/build/mac/copy_framework_unversioned', + '${BUILT_PRODUCTS_DIR}/<(mac_product_name) Framework.framework', + '${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/Versions/<(version_full)', + ], + }, + { # Modify the Info.plist as needed. The script explains why this # is needed. This is also done in the helper_app and chrome_dll # targets. Use -b0 and -k0 to not include any Breakpad or @@ -5045,6 +5048,7 @@ 'product_name': '<(mac_product_name) Framework', 'mac_bundle': 1, 'xcode_settings': { + 'CHROMIUM_BUNDLE_ID': '<(mac_bundle_id)', # The dylib versions are of the form a[.b[.c]], where a is a # 16-bit unsigned integer, and b and c are 8-bit unsigned # integers. Any missing component is taken to be 0. The @@ -5055,20 +5059,14 @@ # version numbers. 'DYLIB_COMPATIBILITY_VERSION': '<(version_build_patch)', 'DYLIB_CURRENT_VERSION': '<(version_build_patch)', + # See tools/build/mac/copy_framework_unversioned for + # The framework is placed within the .app's versioned + # directory. 'DYLIB_INSTALL_NAME_BASE': '@executable_path/../Versions/<(version_full)', - # FRAMEWORK_VERSION is used as the name of the directory in - # the framework's Versions directory that the Current symbolic - # link points to. Unfortunately, Xcode does not create this - # symbolic link properly: in a non-clobber build, if the - # version changes, Xcode won't adjust the Current link to point - # to the new version. Instead of setting FRAMEWORK_VERSION - # to correspond to the application version, just leave it at - # its default, 'A'. This is more than sufficient for our - # purposes, because the framework does not need to maintain - # any sort of stable public interface. - # 'FRAMEWORK_VERSION': '<(version_full)', - 'CHROMIUM_BUNDLE_ID': '<(mac_bundle_id)', + # information on LD_DYLIB_INSTALL_NAME. + 'LD_DYLIB_INSTALL_NAME': + '$(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(WRAPPER_NAME)/$(PRODUCT_NAME)', 'INFOPLIST_FILE': 'app/framework-Info.plist', }, 'sources': [ @@ -5303,21 +5301,13 @@ ], }], # mac_breakpad ['mac_keystone==1', { - 'copies': [ - { - 'destination': - '<(PRODUCT_DIR)/$(CONTENTS_FOLDER_PATH)/Frameworks', - 'files': [ - '../third_party/googlemac/Releases/Keystone/KeystoneRegistration.framework' - ], - }, - ], 'postbuilds': [ { - 'postbuild_name': 'Remove Keystone Headers', + 'postbuild_name': 'Copy KeystoneRegistration.framework', 'action': [ - 'tools/build/mac/remove_headers_from_framework', - '${BUILT_PRODUCTS_DIR}/${WRAPPER_NAME}/Frameworks/KeystoneRegistration.framework', + 'tools/build/mac/copy_framework_unversioned', + '../third_party/googlemac/Releases/Keystone/KeystoneRegistration.framework', + '${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}/Frameworks', ], }, { @@ -5465,8 +5455,8 @@ 'action': [ 'install_name_tool', '-change', - '@executable_path/../Versions/<(version_full)/<(mac_product_name) Framework.framework/Versions/A/<(mac_product_name) Framework', - '@executable_path/../../../<(mac_product_name) Framework.framework/Versions/A/<(mac_product_name) Framework', + '@executable_path/../Versions/<(version_full)/<(mac_product_name) Framework.framework/<(mac_product_name) Framework', + '@executable_path/../../../<(mac_product_name) Framework.framework/<(mac_product_name) Framework', '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' ], }, @@ -5582,8 +5572,8 @@ 'action': [ 'install_name_tool', '-change', - '@executable_path/../Versions/<(version_full)/<(mac_product_name) Framework.framework/Versions/A/<(mac_product_name) Framework', - '@executable_path/../../../<(mac_product_name) Framework.framework/Versions/A/<(mac_product_name) Framework', + '@executable_path/../Versions/<(version_full)/<(mac_product_name) Framework.framework/<(mac_product_name) Framework', + '@executable_path/../../../<(mac_product_name) Framework.framework/<(mac_product_name) Framework', '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' ], }, diff --git a/chrome/tools/build/mac/copy_framework_unversioned b/chrome/tools/build/mac/copy_framework_unversioned new file mode 100755 index 0000000..4223f67 --- /dev/null +++ b/chrome/tools/build/mac/copy_framework_unversioned @@ -0,0 +1,109 @@ +#!/bin/bash + +# Copyright (c) 2009 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +# Copies a framework to its new home, "unversioning" it. +# +# Normally, frameworks are versioned bundles. The contents of a framework are +# stored in a versioned directory within the bundle, and symbolic links +# provide access to the actual code and resources. See +# http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html +# +# The symbolic links usually found in frameworks create problems. Symbolic +# links are excluded from code signatures. That means that it's possible to +# remove or retarget a symbolic link within a framework without affecting the +# seal. In Chrome's case, the outer .app bundle contains a framework where +# all application code and resources live. In order for the signature on the +# .app to be meaningful, it encompasses the framework. Because framework +# resources are accessed through the framework's symbolic links, this +# arrangement results in a case where the resources can be altered without +# affecting the .app signature's validity. +# +# Indirection through symbolic links also carries a runtime performance +# penalty on open() operations, although open() typically completes so quickly +# that this is not considered a major performance problem. +# +# To resolve these problems, the frameworks that ship within Chrome's .app +# bundle are unversioned. Unversioning is simple: instead of using the +# original outer .framework directory as the framework that ships within the +# .app, the inner versioned directory is used. Instead of accessing bundled +# resources through symbolic links, they are accessed directly. In normal +# situations, the only hard-coded use of the versioned directory is by dyld, +# when loading the framework's code, but this is handled through a normal +# Mach-O load command, and it is easy to adjust the load command to point to +# the unversioned framework code rather than the versioned counterpart. +# +# The resulting framework bundles aren't strictly conforming, but they work +# as well as normal versioned framework bundles. + +set -e + +if [ $# -ne 2 ] ; then + echo "usage: ${0} FRAMEWORK DESTINATION_DIR" >& 2 + exit 1 +fi + +# FRAMEWORK should be a path to a versioned framework bundle, ending in +# .framework. DESTINATION_DIR is the directory that the unversioned framework +# bundle will be copied to. + +FRAMEWORK="${1}" +DESTINATION_DIR="${2}" + +FRAMEWORK_NAME="$(basename "${FRAMEWORK}")" +if [ "${FRAMEWORK_NAME: -10}" != ".framework" ] ; then + echo "${0}: ${FRAMEWORK_NAME} does not end in .framework" >& 2 + exit 1 +fi +FRAMEWORK_NAME_NOEXT="${FRAMEWORK_NAME:0:$((${#FRAMEWORK_NAME} - 10))}" + +# Find the current version. +VERSIONS="${FRAMEWORK}/Versions" +CURRENT_VERSION_LINK="${VERSIONS}/Current" +CURRENT_VERSION_ID="$(readlink "${VERSIONS}/Current")" +CURRENT_VERSION="${VERSIONS}/${CURRENT_VERSION_ID}" + +# Make sure that the framework's structure makes sense as a versioned bundle. +if [ ! -e "${CURRENT_VERSION}/${FRAMEWORK_NAME_NOEXT}" ] ; then + echo "${0}: ${FRAMEWORK_NAME} does not contain a dylib" >& 2 + exit 1 +fi + +DESTINATION="${DESTINATION_DIR}/${FRAMEWORK_NAME}" + +# Copy the versioned directory within the versioned framework to its +# destination location. +mkdir -p "${DESTINATION_DIR}" +rsync -ac --delete --exclude Headers --exclude PrivateHeaders \ + "${CURRENT_VERSION}/" "${DESTINATION}" + +# The --exclude will prevent Headers and PrivateHeaders from showing up in +# ${DESTINATION} in clobber builds, but if they are already present in older +# builds, they will not be removed. Remove them manually. +# TODO(mark): Remove this after October 28, 2009, allowing two weeks for the +# transition. +rm -rf -- "${DESTINATION}/Headers" "${DESTINATION}/PrivateHeaders" + +# Adjust the Mach-O LC_ID_DYLIB load command in the framework. This does not +# change the LC_LOAD_DYLIB load commands in anything that may have already +# linked against the framework. Not all frameworks will actually need this +# to be changed. Some frameworks may already be built with the proper +# LC_ID_DYLIB for use as an unversioned framework. Xcode users can do this +# by setting LD_DYLIB_INSTALL_NAME to +# $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(WRAPPER_NAME)/$(PRODUCT_NAME) +# If invoking ld via gcc or g++, pass the desired path to -Wl,-install_name +# at link time. +FRAMEWORK_DYLIB="${DESTINATION}/${FRAMEWORK_NAME_NOEXT}" +LC_ID_DYLIB_OLD="$(otool -l "${FRAMEWORK_DYLIB}" | + grep -A10 "^ *cmd LC_ID_DYLIB$" | + grep -m1 "^ *name" | + sed -Ee 's/^ *name (.*) \(offset [0-9]+\)$/\1/')" +VERSION_PATH="/Versions/${CURRENT_VERSION_ID}/${FRAMEWORK_NAME_NOEXT}" +LC_ID_DYLIB_NEW="$(echo "${LC_ID_DYLIB_OLD}" | + sed -Ee "s%${VERSION_PATH}$%/${FRAMEWORK_NAME_NOEXT}%")" + +if [ "${LC_ID_DYLIB_NEW}" != "${LC_ID_DYLIB_OLD}" ] ; then + install_name_tool -id "${LC_ID_DYLIB_NEW}" "${FRAMEWORK_DYLIB}" +fi diff --git a/chrome/tools/build/mac/remove_headers_from_framework b/chrome/tools/build/mac/remove_headers_from_framework deleted file mode 100755 index c48fd1f..0000000 --- a/chrome/tools/build/mac/remove_headers_from_framework +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/sh - -# Copyright (c) 2009 The Chromium Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -# Frameworks included in an application for distribution aren't used for -# development, and don't need to bundle any headers. - -set -e - -if [ $# -ne 1 ] ; then - echo "usage: ${0} FRAMEWORK" >& 2 - exit 1 -fi - -FRAMEWORK="${1}" - -rm -rf -- "${FRAMEWORK}/Versions/Current/Headers" \ - "${FRAMEWORK}/Versions/Current/PrivateHeaders" \ - "${FRAMEWORK}/Headers" \ - "${FRAMEWORK}/PrivateHeaders" - -# Remove other-versioned headers after current-version headers, in case Current -# is a symbolic link to another version, as is the usual case. If everything -# was done in a single invocation, the shell would do the wildcard expansion -# first, and rm would try (and fail) to remove the same directory twice, such -# as Versions/Current/Headers and Versions/A/Headers when Versions/Current is -# a symbolic link for A. -rm -rf -- "${FRAMEWORK}"/Versions/*/Headers \ - "${FRAMEWORK}"/Versions/*/PrivateHeaders diff --git a/chrome/tools/build/mac/sign.sh.in b/chrome/tools/build/mac/sign.sh.in index 07a7593..18c8197 100644 --- a/chrome/tools/build/mac/sign.sh.in +++ b/chrome/tools/build/mac/sign.sh.in @@ -21,12 +21,14 @@ CODESIGN_ID="${3}" # Use custom resource rules for the browser application. BROWSER_APP_RULES="$(dirname "${0}")/app_resource_rules.plist" -# An .app bundle to be signed can be signed directly. Signging a framework -# bundle requires that each version within be signed individually. +# An .app bundle to be signed can be signed directly. Normally, signging a +# framework bundle requires that each version within be signed individually. # http://developer.apple.com/mac/library/technotes/tn2007/tn2206.html#TNTAG13 +# In Chrome's case, the framework bundle is unversioned, so it too can be +# signed directly. See copy_framework_unversioned. BROWSER_APP="${APP_PATH}" -FRAMEWORK="${BROWSER_APP}/Contents/Versions/@VERSION@/@MAC_PRODUCT_NAME@ Framework.framework/Versions/A" +FRAMEWORK="${BROWSER_APP}/Contents/Versions/@VERSION@/@MAC_PRODUCT_NAME@ Framework.framework" HELPER_APP="${BROWSER_APP}/Contents/Versions/@VERSION@/@MAC_PRODUCT_NAME@ Helper.app" echo "${0}: signing..." |