You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ji...@apache.org on 2014/05/01 13:43:45 UTC

svn commit: r1591622 [5/33] - in /httpd/mod_spdy/trunk: ./ base/ base/base.xcodeproj/ base/metrics/ build/ build/all.xcodeproj/ build/build_util.xcodeproj/ build/install.xcodeproj/ build/internal/ build/linux/ build/mac/ build/util/ build/win/ install/...

Added: httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh (added)
+++ httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh Thu May  1 11:43:36 2014
@@ -0,0 +1,118 @@
+#!/bin/bash
+
+# Copyright (c) 2012 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.
+#
+# An option to skip running install_name_tool is available. By passing -I as
+# the first argument to this script, install_name_tool will be skipped. This
+# is only suitable for copied frameworks that will not be linked against, or
+# when install_name_tool will be run on any linker output when something is
+# linked against the copied framework. This option exists to allow signed
+# frameworks to pass through without subjecting them to any modifications that
+# would break their signatures.
+
+set -e
+
+RUN_INSTALL_NAME_TOOL=1
+if [ $# -eq 3 ] && [ "${1}" = "-I" ] ; then
+  shift
+  RUN_INSTALL_NAME_TOOL=
+fi
+
+if [ $# -ne 2 ] ; then
+  echo "usage: ${0} [-I] 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 -acC --delete --exclude Headers --exclude PrivateHeaders \
+    --include '*.so' "${CURRENT_VERSION}/" "${DESTINATION}"
+
+if [[ -n "${RUN_INSTALL_NAME_TOOL}" ]]; then
+  # 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
+fi

Propchange: httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/mac/copy_framework_unversioned.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh (added)
+++ httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh Thu May  1 11:43:36 2014
@@ -0,0 +1,91 @@
+#!/bin/bash
+
+# Copyright (c) 2012 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.
+
+# Usage: make_more_helpers.sh <directory_within_contents> <app_name>
+#
+# This script creates additional helper .app bundles for Chromium, based on
+# the existing helper .app bundle, changing their Mach-O header's flags to
+# enable and disable various features. Based on Chromium Helper.app, it will
+# create Chromium Helper EH.app, which has the MH_NO_HEAP_EXECUTION bit
+# cleared to support Chromium child processes that require an executable heap,
+# and Chromium Helper NP.app, which has the MH_PIE bit cleared to support
+# Chromium child processes that cannot tolerate ASLR.
+#
+# This script expects to be called from the chrome_exe target as a postbuild,
+# and operates directly within the built-up browser app's versioned directory.
+#
+# Each helper is adjusted by giving it the proper bundle name, renaming the
+# executable, adjusting several Info.plist keys, and changing the executable's
+# Mach-O flags.
+
+set -eu
+
+make_helper() {
+  local containing_dir="${1}"
+  local app_name="${2}"
+  local feature="${3}"
+  local flags="${4}"
+
+  local helper_name="${app_name} Helper"
+  local helper_stem="${containing_dir}/${helper_name}"
+  local original_helper="${helper_stem}.app"
+  if [[ ! -d "${original_helper}" ]]; then
+    echo "${0}: error: ${original_helper} is a required directory" >& 2
+    exit 1
+  fi
+  local original_helper_exe="${original_helper}/Contents/MacOS/${helper_name}"
+  if [[ ! -f "${original_helper_exe}" ]]; then
+    echo "${0}: error: ${original_helper_exe} is a required file" >& 2
+    exit 1
+  fi
+
+  local feature_helper="${helper_stem} ${feature}.app"
+
+  rsync -acC --delete --include '*.so' "${original_helper}/" "${feature_helper}"
+
+  local helper_feature="${helper_name} ${feature}"
+  local helper_feature_exe="${feature_helper}/Contents/MacOS/${helper_feature}"
+  mv "${feature_helper}/Contents/MacOS/${helper_name}" "${helper_feature_exe}"
+
+  local change_flags="$(dirname "${0}")/change_mach_o_flags.py"
+  "${change_flags}" ${flags} "${helper_feature_exe}"
+
+  local feature_info="${feature_helper}/Contents/Info"
+  local feature_info_plist="${feature_info}.plist"
+
+  defaults write "${feature_info}" "CFBundleDisplayName" "${helper_feature}"
+  defaults write "${feature_info}" "CFBundleExecutable" "${helper_feature}"
+
+  cfbundleid="$(defaults read "${feature_info}" "CFBundleIdentifier")"
+  feature_cfbundleid="${cfbundleid}.${feature}"
+  defaults write "${feature_info}" "CFBundleIdentifier" "${feature_cfbundleid}"
+
+  cfbundlename="$(defaults read "${feature_info}" "CFBundleName")"
+  feature_cfbundlename="${cfbundlename} ${feature}"
+  defaults write "${feature_info}" "CFBundleName" "${feature_cfbundlename}"
+
+  # As usual, defaults might have put the plist into whatever format excites
+  # it, but Info.plists get converted back to the expected XML format.
+  plutil -convert xml1 "${feature_info_plist}"
+
+  # `defaults` also changes the file permissions, so make the file
+  # world-readable again.
+  chmod a+r "${feature_info_plist}"
+}
+
+if [[ ${#} -ne 2 ]]; then
+  echo "usage: ${0} <directory_within_contents> <app_name>" >& 2
+  exit 1
+fi
+
+DIRECTORY_WITHIN_CONTENTS="${1}"
+APP_NAME="${2}"
+
+CONTENTS_DIR="${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}"
+CONTAINING_DIR="${CONTENTS_DIR}/${DIRECTORY_WITHIN_CONTENTS}"
+
+make_helper "${CONTAINING_DIR}" "${APP_NAME}" "EH" "--executable-heap"
+make_helper "${CONTAINING_DIR}" "${APP_NAME}" "NP" "--no-pie"

Propchange: httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/mac/make_more_helpers.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mac/strip_from_xcode
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/strip_from_xcode?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/strip_from_xcode (added)
+++ httpd/mod_spdy/trunk/build/mac/strip_from_xcode Thu May  1 11:43:36 2014
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+# Copyright (c) 2008 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.
+
+# This is a handy wrapper script that figures out how to call the strip
+# utility (strip_save_dsym in this case), if it even needs to be called at all,
+# and then does it.  This script should be called by a post-link phase in
+# targets that might generate Mach-O executables, dynamic libraries, or
+# loadable bundles.
+#
+# An example "Strip If Needed" build phase placed after "Link Binary With
+# Libraries" would do:
+# exec "${XCODEPROJ_DEPTH}/build/mac/strip_from_xcode"
+
+if [ "${CONFIGURATION}" != "Release" ] ; then
+  # Only strip in release mode.
+  exit 0
+fi
+
+declare -a FLAGS
+
+# MACH_O_TYPE is not set for a command-line tool, so check PRODUCT_TYPE too.
+# Weird.
+if [ "${MACH_O_TYPE}" = "mh_execute" ] || \
+   [ "${PRODUCT_TYPE}" = "com.apple.product-type.tool" ] ; then
+  # Strip everything (no special flags).  No-op.
+  true
+elif [ "${MACH_O_TYPE}" = "mh_dylib" ] || \
+     [ "${MACH_O_TYPE}" = "mh_bundle" ]; then
+  # Strip debugging symbols and local symbols
+  FLAGS[${#FLAGS[@]}]=-S
+  FLAGS[${#FLAGS[@]}]=-x
+elif [ "${MACH_O_TYPE}" = "staticlib" ] ; then
+  # Don't strip static libraries.
+  exit 0
+else
+  # Warn, but don't treat this as an error.
+  echo $0: warning: unrecognized MACH_O_TYPE ${MACH_O_TYPE}
+  exit 0
+fi
+
+if [ -n "${STRIPFLAGS}" ] ; then
+  # Pick up the standard STRIPFLAGS Xcode setting, used for "Additional Strip
+  # Flags".
+  for stripflag in "${STRIPFLAGS}" ; do
+    FLAGS[${#FLAGS[@]}]="${stripflag}"
+  done
+fi
+
+if [ -n "${CHROMIUM_STRIP_SAVE_FILE}" ] ; then
+  # An Xcode project can communicate a file listing symbols to saved in this
+  # environment variable by setting it as a build setting.  This isn't a
+  # standard Xcode setting.  It's used in preference to STRIPFLAGS to
+  # eliminate quoting ambiguity concerns.
+  FLAGS[${#FLAGS[@]}]=-s
+  FLAGS[${#FLAGS[@]}]="${CHROMIUM_STRIP_SAVE_FILE}"
+fi
+
+exec "$(dirname ${0})/strip_save_dsym" "${FLAGS[@]}" \
+     "${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"

Propchange: httpd/mod_spdy/trunk/build/mac/strip_from_xcode
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mac/strip_save_dsym
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/strip_save_dsym?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/strip_save_dsym (added)
+++ httpd/mod_spdy/trunk/build/mac/strip_save_dsym Thu May  1 11:43:36 2014
@@ -0,0 +1,341 @@
+#!/usr/bin/python
+
+# Copyright (c) 2011 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.
+
+# Usage: strip_save_dsym <whatever-arguments-you-would-pass-to-strip>
+#
+# strip_save_dsym is a wrapper around the standard strip utility.  Given an
+# input Mach-O file, strip_save_dsym will save a copy of the file in a "fake"
+# .dSYM bundle for debugging, and then call strip to strip the Mach-O file.
+# Note that the .dSYM file is a "fake" in that it's not a self-contained
+# .dSYM bundle, it just contains a copy of the original (unstripped) Mach-O
+# file, and therefore contains references to object files on the filesystem.
+# The generated .dSYM bundle is therefore unsuitable for debugging in the
+# absence of these .o files.
+#
+# If a .dSYM already exists and has a newer timestamp than the Mach-O file,
+# this utility does nothing.  That allows strip_save_dsym to be run on a file
+# that has already been stripped without trashing the .dSYM.
+#
+# Rationale: the "right" way to generate dSYM bundles, dsymutil, is incredibly
+# slow.  On the other hand, doing a file copy (which is really all that
+# dsymutil does) is comparatively fast.  Since we usually just want to strip
+# a release-mode executable but still be able to debug it, and we don't care
+# so much about generating a hermetic dSYM bundle, we'll prefer the file copy.
+# If a real dSYM is ever needed, it's still possible to create one by running
+# dsymutil and pointing it at the original Mach-O file inside the "fake"
+# bundle, provided that the object files are available.
+
+import errno
+import os
+import re
+import shutil
+import subprocess
+import sys
+import time
+
+# Returns a list of architectures contained in a Mach-O file.  The file can be
+# a universal (fat) file, in which case there will be one list element for
+# each contained architecture, or it can be a thin single-architecture Mach-O
+# file, in which case the list will contain a single element identifying the
+# architecture.  On error, returns an empty list.  Determines the architecture
+# list by calling file.
+def macho_archs(macho):
+  macho_types = ["executable",
+                 "dynamically linked shared library",
+                 "bundle"]
+  macho_types_re = "Mach-O (?:64-bit )?(?:" + "|".join(macho_types) + ")"
+
+  file_cmd = subprocess.Popen(["/usr/bin/file", "-b", "--", macho],
+                              stdout=subprocess.PIPE)
+
+  archs = []
+
+  type_line = file_cmd.stdout.readline()
+  type_match = re.match("^%s (.*)$" % macho_types_re, type_line)
+  if type_match:
+    archs.append(type_match.group(1))
+    return [type_match.group(1)]
+  else:
+    type_match = re.match("^Mach-O universal binary with (.*) architectures$",
+                          type_line)
+    if type_match:
+      for i in range(0, int(type_match.group(1))):
+        arch_line = file_cmd.stdout.readline()
+        arch_match = re.match(
+                     "^.* \(for architecture (.*)\):\t%s .*$" % macho_types_re,
+                     arch_line)
+        if arch_match:
+          archs.append(arch_match.group(1))
+
+  if file_cmd.wait() != 0:
+    archs = []
+
+  if len(archs) == 0:
+    print >> sys.stderr, "No architectures in %s" % macho
+
+  return archs
+
+# Returns a dictionary mapping architectures contained in the file as returned
+# by macho_archs to the LC_UUID load command for that architecture.
+# Architectures with no LC_UUID load command are omitted from the dictionary.
+# Determines the UUID value by calling otool.
+def macho_uuids(macho):
+  uuids = {}
+
+  archs = macho_archs(macho)
+  if len(archs) == 0:
+    return uuids
+
+  for arch in archs:
+    if arch == "":
+      continue
+
+    otool_cmd = subprocess.Popen(["/usr/bin/otool", "-arch", arch, "-l", "-",
+                                  macho],
+                                 stdout=subprocess.PIPE)
+    # state 0 is when nothing UUID-related has been seen yet.  State 1 is
+    # entered after a load command begins, but it may not be an LC_UUID load
+    # command.  States 2, 3, and 4 are intermediate states while reading an
+    # LC_UUID command.  State 5 is the terminal state for a successful LC_UUID
+    # read.  State 6 is the error state.
+    state = 0
+    uuid = ""
+    for otool_line in otool_cmd.stdout:
+      if state == 0:
+        if re.match("^Load command .*$", otool_line):
+          state = 1
+      elif state == 1:
+        if re.match("^     cmd LC_UUID$", otool_line):
+          state = 2
+        else:
+          state = 0
+      elif state == 2:
+        if re.match("^ cmdsize 24$", otool_line):
+          state = 3
+        else:
+          state = 6
+      elif state == 3:
+        # The UUID display format changed in the version of otool shipping
+        # with the Xcode 3.2.2 prerelease.  The new format is traditional:
+        #    uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
+        # and with Xcode 3.2.6, then line is indented one more space:
+        #     uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
+        # The old format, from cctools-750 and older's otool, breaks the UUID
+        # up into a sequence of bytes:
+        #    uuid 0x4d 0x71 0x35 0xb2 0x9c 0x56 0xc5 0xf5
+        #         0x5f 0x49 0xa9 0x94 0x25 0x8e 0x09 0x55
+        new_uuid_match = re.match("^ {3,4}uuid (.{8}-.{4}-.{4}-.{4}-.{12})$",
+                                  otool_line)
+        if new_uuid_match:
+          uuid = new_uuid_match.group(1)
+
+          # Skip state 4, there is no second line to read.
+          state = 5
+        else:
+          old_uuid_match = re.match("^   uuid 0x(..) 0x(..) 0x(..) 0x(..) "
+                                    "0x(..) 0x(..) 0x(..) 0x(..)$",
+                                    otool_line)
+          if old_uuid_match:
+            state = 4
+            uuid = old_uuid_match.group(1) + old_uuid_match.group(2) + \
+                   old_uuid_match.group(3) + old_uuid_match.group(4) + "-" + \
+                   old_uuid_match.group(5) + old_uuid_match.group(6) + "-" + \
+                   old_uuid_match.group(7) + old_uuid_match.group(8) + "-"
+          else:
+            state = 6
+      elif state == 4:
+        old_uuid_match = re.match("^        0x(..) 0x(..) 0x(..) 0x(..) "
+                                  "0x(..) 0x(..) 0x(..) 0x(..)$",
+                                  otool_line)
+        if old_uuid_match:
+          state = 5
+          uuid += old_uuid_match.group(1) + old_uuid_match.group(2) + "-" + \
+                  old_uuid_match.group(3) + old_uuid_match.group(4) + \
+                  old_uuid_match.group(5) + old_uuid_match.group(6) + \
+                  old_uuid_match.group(7) + old_uuid_match.group(8)
+        else:
+          state = 6
+
+    if otool_cmd.wait() != 0:
+      state = 6
+
+    if state == 5:
+      uuids[arch] = uuid.upper()
+
+  if len(uuids) == 0:
+    print >> sys.stderr, "No UUIDs in %s" % macho
+
+  return uuids
+
+# Given a path to a Mach-O file and possible information from the environment,
+# determines the desired path to the .dSYM.
+def dsym_path(macho):
+  # If building a bundle, the .dSYM should be placed next to the bundle.  Use
+  # WRAPPER_NAME to make this determination.  If called from xcodebuild,
+  # WRAPPER_NAME will be set to the name of the bundle.
+  dsym = ""
+  if "WRAPPER_NAME" in os.environ:
+    if "BUILT_PRODUCTS_DIR" in os.environ:
+      dsym = os.path.join(os.environ["BUILT_PRODUCTS_DIR"],
+                          os.environ["WRAPPER_NAME"])
+    else:
+      dsym = os.environ["WRAPPER_NAME"]
+  else:
+    dsym = macho
+
+  dsym += ".dSYM"
+
+  return dsym
+
+# Creates a fake .dSYM bundle at dsym for macho, a Mach-O image with the
+# architectures and UUIDs specified by the uuids map.
+def make_fake_dsym(macho, dsym):
+  uuids = macho_uuids(macho)
+  if len(uuids) == 0:
+    return False
+
+  dwarf_dir = os.path.join(dsym, "Contents", "Resources", "DWARF")
+  dwarf_file = os.path.join(dwarf_dir, os.path.basename(macho))
+  try:
+    os.makedirs(dwarf_dir)
+  except OSError, (err, error_string):
+    if err != errno.EEXIST:
+      raise
+  shutil.copyfile(macho, dwarf_file)
+
+  # info_template is the same as what dsymutil would have written, with the
+  # addition of the fake_dsym key.
+  info_template = \
+'''<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+	<dict>
+		<key>CFBundleDevelopmentRegion</key>
+		<string>English</string>
+		<key>CFBundleIdentifier</key>
+		<string>com.apple.xcode.dsym.%(root_name)s</string>
+		<key>CFBundleInfoDictionaryVersion</key>
+		<string>6.0</string>
+		<key>CFBundlePackageType</key>
+		<string>dSYM</string>
+		<key>CFBundleSignature</key>
+		<string>????</string>
+		<key>CFBundleShortVersionString</key>
+		<string>1.0</string>
+		<key>CFBundleVersion</key>
+		<string>1</string>
+		<key>dSYM_UUID</key>
+		<dict>
+%(uuid_dict)s		</dict>
+		<key>fake_dsym</key>
+		<true/>
+	</dict>
+</plist>
+'''
+
+  root_name = os.path.basename(dsym)[:-5]  # whatever.dSYM without .dSYM
+  uuid_dict = ""
+  for arch in sorted(uuids):
+    uuid_dict += "\t\t\t<key>" + arch + "</key>\n"\
+                 "\t\t\t<string>" + uuids[arch] + "</string>\n"
+  info_dict = {
+    "root_name": root_name,
+    "uuid_dict": uuid_dict,
+  }
+  info_contents = info_template % info_dict
+  info_file = os.path.join(dsym, "Contents", "Info.plist")
+  info_fd = open(info_file, "w")
+  info_fd.write(info_contents)
+  info_fd.close()
+
+  return True
+
+# For a Mach-O file, determines where the .dSYM bundle should be located.  If
+# the bundle does not exist or has a modification time older than the Mach-O
+# file, calls make_fake_dsym to create a fake .dSYM bundle there, then strips
+# the Mach-O file and sets the modification time on the .dSYM bundle and Mach-O
+# file to be identical.
+def strip_and_make_fake_dsym(macho):
+  dsym = dsym_path(macho)
+  macho_stat = os.stat(macho)
+  dsym_stat = None
+  try:
+    dsym_stat = os.stat(dsym)
+  except OSError, (err, error_string):
+    if err != errno.ENOENT:
+      raise
+
+  if dsym_stat is None or dsym_stat.st_mtime < macho_stat.st_mtime:
+    # Make a .dSYM bundle
+    if not make_fake_dsym(macho, dsym):
+      return False
+
+    # Strip the Mach-O file
+    remove_dsym = True
+    try:
+      strip_path = ""
+      if "SYSTEM_DEVELOPER_BIN_DIR" in os.environ:
+        strip_path = os.environ["SYSTEM_DEVELOPER_BIN_DIR"]
+      else:
+        strip_path = "/usr/bin"
+      strip_path = os.path.join(strip_path, "strip")
+      strip_cmdline = [strip_path] + sys.argv[1:]
+      strip_cmd = subprocess.Popen(strip_cmdline)
+      if strip_cmd.wait() == 0:
+        remove_dsym = False
+    finally:
+      if remove_dsym:
+        shutil.rmtree(dsym)
+
+    # Update modification time on the Mach-O file and .dSYM bundle
+    now = time.time()
+    os.utime(macho, (now, now))
+    os.utime(dsym, (now, now))
+
+  return True
+
+def main(argv=None):
+  if argv is None:
+    argv = sys.argv
+
+  # This only supports operating on one file at a time.  Look at the arguments
+  # to strip to figure out what the source to be stripped is.  Arguments are
+  # processed in the same way that strip does, although to reduce complexity,
+  # this doesn't do all of the same checking as strip.  For example, strip
+  # has no -Z switch and would treat -Z on the command line as an error.  For
+  # the purposes this is needed for, that's fine.
+  macho = None
+  process_switches = True
+  ignore_argument = False
+  for arg in argv[1:]:
+    if ignore_argument:
+      ignore_argument = False
+      continue
+    if process_switches:
+      if arg == "-":
+        process_switches = False
+      # strip has these switches accept an argument:
+      if arg in ["-s", "-R", "-d", "-o", "-arch"]:
+        ignore_argument = True
+      if arg[0] == "-":
+        continue
+    if macho is None:
+      macho = arg
+    else:
+      print >> sys.stderr, "Too many things to strip"
+      return 1
+
+  if macho is None:
+    print >> sys.stderr, "Nothing to strip"
+    return 1
+
+  if not strip_and_make_fake_dsym(macho):
+    return 1
+
+  return 0
+
+if __name__ == "__main__":
+  sys.exit(main(sys.argv))

Propchange: httpd/mod_spdy/trunk/build/mac/strip_save_dsym
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py (added)
+++ httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py Thu May  1 11:43:36 2014
@@ -0,0 +1,293 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2012 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.
+
+#
+# Xcode supports build variable substitutions and CPP; sadly, that doesn't work
+# because:
+#
+# 1. Xcode wants to do the Info.plist work before it runs any build phases,
+#    this means if we were to generate a .h file for INFOPLIST_PREFIX_HEADER
+#    we'd have to put it in another target so it runs in time.
+# 2. Xcode also doesn't check to see if the header being used as a prefix for
+#    the Info.plist has changed.  So even if we updated it, it's only looking
+#    at the modtime of the info.plist to see if that's changed.
+#
+# So, we work around all of this by making a script build phase that will run
+# during the app build, and simply update the info.plist in place.  This way
+# by the time the app target is done, the info.plist is correct.
+#
+
+import optparse
+import os
+from os import environ as env
+import plistlib
+import re
+import subprocess
+import sys
+import tempfile
+
+TOP = os.path.join(env['SRCROOT'], '..')
+
+sys.path.insert(0, os.path.join(TOP, "build/util"))
+import lastchange
+
+
+def _GetOutput(args):
+  """Runs a subprocess and waits for termination. Returns (stdout, returncode)
+  of the process. stderr is attached to the parent."""
+  proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+  (stdout, stderr) = proc.communicate()
+  return (stdout, proc.returncode)
+
+
+def _GetOutputNoError(args):
+  """Similar to _GetOutput() but ignores stderr. If there's an error launching
+  the child (like file not found), the exception will be caught and (None, 1)
+  will be returned to mimic quiet failure."""
+  try:
+    proc = subprocess.Popen(args, stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE)
+  except OSError:
+    return (None, 1)
+  (stdout, stderr) = proc.communicate()
+  return (stdout, proc.returncode)
+
+
+def _RemoveKeys(plist, *keys):
+  """Removes a varargs of keys from the plist."""
+  for key in keys:
+    try:
+      del plist[key]
+    except KeyError:
+      pass
+
+
+def _AddVersionKeys(plist):
+  """Adds the product version number into the plist. Returns True on success and
+  False on error. The error will be printed to stderr."""
+  # Pull in the Chrome version number.
+  VERSION_TOOL = os.path.join(TOP, 'chrome/tools/build/version.py')
+  VERSION_FILE = os.path.join(TOP, 'chrome/VERSION')
+
+  (stdout, retval1) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
+                                  '@MAJOR@.@MINOR@.@BUILD@.@PATCH@'])
+  full_version = stdout.rstrip()
+
+  (stdout, retval2) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
+                                  '@BUILD@.@PATCH@'])
+  bundle_version = stdout.rstrip()
+
+  # If either of the two version commands finished with non-zero returncode,
+  # report the error up.
+  if retval1 or retval2:
+    return False
+
+  # Add public version info so "Get Info" works.
+  plist['CFBundleShortVersionString'] = full_version
+
+  # Honor the 429496.72.95 limit.  The maximum comes from splitting 2^32 - 1
+  # into  6, 2, 2 digits.  The limitation was present in Tiger, but it could
+  # have been fixed in later OS release, but hasn't been tested (it's easy
+  # enough to find out with "lsregister -dump).
+  # http://lists.apple.com/archives/carbon-dev/2006/Jun/msg00139.html
+  # BUILD will always be an increasing value, so BUILD_PATH gives us something
+  # unique that meetings what LS wants.
+  plist['CFBundleVersion'] = bundle_version
+
+  # Return with no error.
+  return True
+
+
+def _DoSVNKeys(plist, add_keys):
+  """Adds the SVN information, visible in about:version, to property list. If
+  |add_keys| is True, it will insert the keys, otherwise it will remove them."""
+  scm_path, scm_revision = None, None
+  if add_keys:
+    version_info = lastchange.FetchVersionInfo(
+        default_lastchange=None, directory=TOP)
+    scm_path, scm_revision = version_info.url, version_info.revision
+
+  # See if the operation failed.
+  _RemoveKeys(plist, 'SVNRevision')
+  if scm_revision != None:
+    plist['SVNRevision'] = scm_revision
+  elif add_keys:
+    print >>sys.stderr, 'Could not determine svn revision.  This may be OK.'
+
+  if scm_path != None:
+    plist['SVNPath'] = scm_path
+  else:
+    _RemoveKeys(plist, 'SVNPath')
+
+
+def _DoPDFKeys(plist, add_keys):
+  """Adds PDF support to the document types list. If add_keys is True, it will
+  add the type information dictionary. If it is False, it will remove it if
+  present."""
+
+  PDF_FILE_EXTENSION = 'pdf'
+
+  def __AddPDFKeys(sub_plist):
+    """Writes the keys into a sub-dictionary of the plist."""
+    sub_plist['CFBundleTypeExtensions'] = [PDF_FILE_EXTENSION]
+    sub_plist['CFBundleTypeIconFile'] = 'document.icns'
+    sub_plist['CFBundleTypeMIMETypes'] = 'application/pdf'
+    sub_plist['CFBundleTypeName'] = 'PDF Document'
+    sub_plist['CFBundleTypeRole'] = 'Viewer'
+
+  DOCUMENT_TYPES_KEY = 'CFBundleDocumentTypes'
+
+  # First get the list of document types, creating it if necessary.
+  try:
+    extensions = plist[DOCUMENT_TYPES_KEY]
+  except KeyError:
+    # If this plist doesn't have a type dictionary, create one if set to add the
+    # keys. If not, bail.
+    if not add_keys:
+      return
+    extensions = plist[DOCUMENT_TYPES_KEY] = []
+
+  # Loop over each entry in the list, looking for one that handles PDF types.
+  for i, ext in enumerate(extensions):
+    # If an entry for .pdf files is found...
+    if 'CFBundleTypeExtensions' not in ext:
+      continue
+    if PDF_FILE_EXTENSION in ext['CFBundleTypeExtensions']:
+      if add_keys:
+        # Overwrite the existing keys with new ones.
+        __AddPDFKeys(ext)
+      else:
+        # Otherwise, delete the entry entirely.
+        del extensions[i]
+      return
+
+  # No PDF entry exists. If one needs to be added, do so now.
+  if add_keys:
+    pdf_entry = {}
+    __AddPDFKeys(pdf_entry)
+    extensions.append(pdf_entry)
+
+
+def _AddBreakpadKeys(plist, branding):
+  """Adds the Breakpad keys. This must be called AFTER _AddVersionKeys() and
+  also requires the |branding| argument."""
+  plist['BreakpadReportInterval'] = '3600'  # Deliberately a string.
+  plist['BreakpadProduct'] = '%s_Mac' % branding
+  plist['BreakpadProductDisplay'] = branding
+  plist['BreakpadVersion'] = plist['CFBundleShortVersionString']
+  # These are both deliberately strings and not boolean.
+  plist['BreakpadSendAndExit'] = 'YES'
+  plist['BreakpadSkipConfirm'] = 'YES'
+
+
+def _RemoveBreakpadKeys(plist):
+  """Removes any set Breakpad keys."""
+  _RemoveKeys(plist,
+      'BreakpadURL',
+      'BreakpadReportInterval',
+      'BreakpadProduct',
+      'BreakpadProductDisplay',
+      'BreakpadVersion',
+      'BreakpadSendAndExit',
+      'BreakpadSkipConfirm')
+
+
+def _AddKeystoneKeys(plist, bundle_identifier):
+  """Adds the Keystone keys. This must be called AFTER _AddVersionKeys() and
+  also requires the |bundle_identifier| argument (com.example.product)."""
+  plist['KSVersion'] = plist['CFBundleShortVersionString']
+  plist['KSProductID'] = bundle_identifier
+  plist['KSUpdateURL'] = 'https://tools.google.com/service/update2'
+
+
+def _RemoveKeystoneKeys(plist):
+  """Removes any set Keystone keys."""
+  _RemoveKeys(plist,
+      'KSVersion',
+      'KSProductID',
+      'KSUpdateURL')
+
+
+def Main(argv):
+  parser = optparse.OptionParser('%prog [options]')
+  parser.add_option('--breakpad', dest='use_breakpad', action='store',
+      type='int', default=False, help='Enable Breakpad [1 or 0]')
+  parser.add_option('--breakpad_uploads', dest='breakpad_uploads',
+      action='store', type='int', default=False,
+      help='Enable Breakpad\'s uploading of crash dumps [1 or 0]')
+  parser.add_option('--keystone', dest='use_keystone', action='store',
+      type='int', default=False, help='Enable Keystone [1 or 0]')
+  parser.add_option('--svn', dest='add_svn_info', action='store', type='int',
+      default=True, help='Add SVN metadata [1 or 0]')
+  parser.add_option('--pdf', dest='add_pdf_support', action='store', type='int',
+      default=False, help='Add PDF file handler support [1 or 0]')
+  parser.add_option('--branding', dest='branding', action='store',
+      type='string', default=None, help='The branding of the binary')
+  parser.add_option('--bundle_id', dest='bundle_identifier',
+      action='store', type='string', default=None,
+      help='The bundle id of the binary')
+  (options, args) = parser.parse_args(argv)
+
+  if len(args) > 0:
+    print >>sys.stderr, parser.get_usage()
+    return 1
+
+  # Read the plist into its parsed format.
+  DEST_INFO_PLIST = os.path.join(env['TARGET_BUILD_DIR'], env['INFOPLIST_PATH'])
+  plist = plistlib.readPlist(DEST_INFO_PLIST)
+
+  # Insert the product version.
+  if not _AddVersionKeys(plist):
+    return 2
+
+  # Add Breakpad if configured to do so.
+  if options.use_breakpad:
+    if options.branding is None:
+      print >>sys.stderr, 'Use of Breakpad requires branding.'
+      return 1
+    _AddBreakpadKeys(plist, options.branding)
+    if options.breakpad_uploads:
+      plist['BreakpadURL'] = 'https://clients2.google.com/cr/report'
+    else:
+      # This allows crash dumping to a file without uploading the
+      # dump, for testing purposes.  Breakpad does not recognise
+      # "none" as a special value, but this does stop crash dump
+      # uploading from happening.  We need to specify something
+      # because if "BreakpadURL" is not present, Breakpad will not
+      # register its crash handler and no crash dumping will occur.
+      plist['BreakpadURL'] = 'none'
+  else:
+    _RemoveBreakpadKeys(plist)
+
+  # Only add Keystone in Release builds.
+  if options.use_keystone and env['CONFIGURATION'] == 'Release':
+    if options.bundle_identifier is None:
+      print >>sys.stderr, 'Use of Keystone requires the bundle id.'
+      return 1
+    _AddKeystoneKeys(plist, options.bundle_identifier)
+  else:
+    _RemoveKeystoneKeys(plist)
+
+  # Adds or removes any SVN keys.
+  _DoSVNKeys(plist, options.add_svn_info)
+
+  # Adds or removes the PDF file handler entry.
+  _DoPDFKeys(plist, options.add_pdf_support)
+
+  # Now that all keys have been mutated, rewrite the file.
+  temp_info_plist = tempfile.NamedTemporaryFile()
+  plistlib.writePlist(plist, temp_info_plist.name)
+
+  # Info.plist will work perfectly well in any plist format, but traditionally
+  # applications use xml1 for this, so convert it to ensure that it's valid.
+  proc = subprocess.Popen(['plutil', '-convert', 'xml1', '-o', DEST_INFO_PLIST,
+                           temp_info_plist.name])
+  proc.wait()
+  return proc.returncode
+
+
+if __name__ == '__main__':
+  sys.exit(Main(sys.argv[1:]))

Propchange: httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/mac/tweak_info_plist.py
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh (added)
+++ httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh Thu May  1 11:43:36 2014
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Copyright (c) 2011 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.
+
+# This script makes sure that no __OBJC,__image_info section appears in the
+# executable file built by the Xcode target that runs the script. If such a
+# section appears, the script prints an error message and exits nonzero.
+#
+# Why is this important?
+#
+# On 10.5, there's a bug in CFBundlePreflightExecutable that causes it to
+# crash when operating in an executable that has not loaded at its default
+# address (that is, when it's a position-independent executable with the
+# MH_PIE bit set in its mach_header) and the executable has an
+# __OBJC,__image_info section. See http://crbug.com/88697.
+#
+# Chrome's main executables don't use any Objective-C at all, and don't need
+# to carry this section around. Not linking them as Objective-C when they
+# don't need it anyway saves about 4kB in the linked executable, although most
+# of that 4kB is just filled with zeroes.
+#
+# This script makes sure that nobody goofs and accidentally introduces these
+# sections into the main executables.
+
+set -eu
+
+otool="${DEVELOPER_BIN_DIR:-/usr/bin}/otool"
+executable="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"
+
+if "${otool}" -arch i386 -o "${executable}" | grep -q '^Contents.*section$'; \
+then
+  echo "${0}: ${executable} has an __OBJC,__image_info section" 2>&1
+  exit 1
+fi
+
+if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
+  echo "${0}: otool failed" 2>&1
+  exit 1
+fi
+
+exit 0

Propchange: httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/mac/verify_no_objc.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/mod_spdy_version_header.target.mk
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/mod_spdy_version_header.target.mk?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/mod_spdy_version_header.target.mk (added)
+++ httpd/mod_spdy/trunk/build/mod_spdy_version_header.target.mk Thu May  1 11:43:36 2014
@@ -0,0 +1,38 @@
+# This file is generated by gyp; do not edit.
+
+TOOLSET := target
+TARGET := mod_spdy_version_header
+### Rules for action "version_header":
+quiet_cmd_build_build_util_gyp_mod_spdy_version_header_target_version_header = ACTION Generating version header file: "$(obj)/gen/mod_spdy/common/version.h" $@
+cmd_build_build_util_gyp_mod_spdy_version_header_target_version_header = LD_LIBRARY_PATH=$(builddir)/lib.host:$(builddir)/lib.target:$$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; cd build; mkdir -p $(obj)/gen/mod_spdy/common; python version.py -f ../mod_spdy/common/VERSION -f "$(obj)/gen/build/LASTCHANGE" ../mod_spdy/common/version.h.in "$(obj)/gen/mod_spdy/common/version.h"
+
+$(obj)/gen/mod_spdy/common/version.h: obj := $(abs_obj)
+$(obj)/gen/mod_spdy/common/version.h: builddir := $(abs_builddir)
+$(obj)/gen/mod_spdy/common/version.h: TOOLSET := $(TOOLSET)
+$(obj)/gen/mod_spdy/common/version.h: mod_spdy/common/VERSION $(obj)/gen/build/LASTCHANGE mod_spdy/common/version.h.in FORCE_DO_CMD
+	$(call do_cmd,build_build_util_gyp_mod_spdy_version_header_target_version_header)
+
+all_deps += $(obj)/gen/mod_spdy/common/version.h
+action_build_build_util_gyp_mod_spdy_version_header_target_version_header_outputs := $(obj)/gen/mod_spdy/common/version.h
+
+
+### Rules for final target.
+# Build our special outputs first.
+$(obj).target/build/mod_spdy_version_header.stamp: | $(action_build_build_util_gyp_mod_spdy_version_header_target_version_header_outputs)
+
+# Preserve order dependency of special output on deps.
+$(action_build_build_util_gyp_mod_spdy_version_header_target_version_header_outputs): | $(obj).target/build/lastchange.stamp
+
+$(obj).target/build/mod_spdy_version_header.stamp: TOOLSET := $(TOOLSET)
+$(obj).target/build/mod_spdy_version_header.stamp: $(obj).target/build/lastchange.stamp FORCE_DO_CMD
+	$(call do_cmd,touch)
+
+all_deps += $(obj).target/build/mod_spdy_version_header.stamp
+# Add target alias
+.PHONY: mod_spdy_version_header
+mod_spdy_version_header: $(obj).target/build/mod_spdy_version_header.stamp
+
+# Add target alias to "all" target.
+.PHONY: all
+all: mod_spdy_version_header
+

Added: httpd/mod_spdy/trunk/build/output_dll_copy.rules
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/output_dll_copy.rules?rev=1591622&view=auto
==============================================================================
Binary file - no diff available.

Propchange: httpd/mod_spdy/trunk/build/output_dll_copy.rules
------------------------------------------------------------------------------
    svn:mime-type = application/xml

Added: httpd/mod_spdy/trunk/build/release.gypi
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/release.gypi?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/release.gypi (added)
+++ httpd/mod_spdy/trunk/build/release.gypi Thu May  1 11:43:36 2014
@@ -0,0 +1,19 @@
+{
+  'conditions': [
+    # Handle build types.
+    ['buildtype=="Dev"', {
+      'includes': ['internal/release_impl.gypi'],
+    }],
+    ['buildtype=="Official"', {
+      'includes': ['internal/release_impl_official.gypi'],
+    }],
+    # TODO(bradnelson): may also need:
+    #     checksenabled
+    #     coverage
+    #     dom_stats
+    #     pgo_instrument
+    #     pgo_optimize
+    #     purify
+  ],
+}
+

Added: httpd/mod_spdy/trunk/build/util/lastchange.py
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/util/lastchange.py?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/util/lastchange.py (added)
+++ httpd/mod_spdy/trunk/build/util/lastchange.py Thu May  1 11:43:36 2014
@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+# Copyright (c) 2011 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.
+
+"""
+lastchange.py -- Chromium revision fetching utility.
+"""
+
+import re
+import optparse
+import os
+import subprocess
+import sys
+
+class VersionInfo(object):
+  def __init__(self, url, root, revision):
+    self.url = url
+    self.root = root
+    self.revision = revision
+
+
+def FetchSVNRevision(directory):
+  """
+  Fetch the Subversion branch and revision for a given directory.
+
+  Errors are swallowed.
+
+  Returns:
+    a VersionInfo object or None on error.
+  """
+  try:
+    proc = subprocess.Popen(['svn', 'info'],
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE,
+                            cwd=directory,
+                            shell=(sys.platform=='win32'))
+  except OSError:
+    # command is apparently either not installed or not executable.
+    return None
+  if not proc:
+    return None
+
+  attrs = {}
+  for line in proc.stdout:
+    line = line.strip()
+    if not line:
+      continue
+    key, val = line.split(': ', 1)
+    attrs[key] = val
+
+  try:
+    url = attrs['URL']
+    root = attrs['Repository Root']
+    revision = attrs['Revision']
+  except KeyError:
+    return None
+
+  return VersionInfo(url, root, revision)
+
+
+def RunGitCommand(directory, command):
+  """
+  Launches git subcommand.
+
+  Errors are swallowed.
+
+  Returns:
+    process object or None.
+  """
+  command = ['git'] + command
+  # Force shell usage under cygwin & win32. This is a workaround for
+  # mysterious loss of cwd while invoking cygwin's git.
+  # We can't just pass shell=True to Popen, as under win32 this will
+  # cause CMD to be used, while we explicitly want a cygwin shell.
+  if sys.platform in ('cygwin', 'win32'):
+    command = ['sh', '-c', ' '.join(command)]
+  try:
+    proc = subprocess.Popen(command,
+                            stdout=subprocess.PIPE,
+                            stderr=subprocess.PIPE,
+                            cwd=directory)
+    return proc
+  except OSError:
+    return None
+
+
+def FetchGitRevision(directory):
+  """
+  Fetch the Git hash for a given directory.
+
+  Errors are swallowed.
+
+  Returns:
+    a VersionInfo object or None on error.
+  """
+  proc = RunGitCommand(directory, ['rev-parse', 'HEAD'])
+  if proc:
+    output = proc.communicate()[0].strip()
+    if proc.returncode == 0 and output:
+      return VersionInfo('git', 'git', output[:7])
+  return None
+
+
+def IsGitSVN(directory):
+  """
+  Checks whether git-svn has been set up.
+
+  Errors are swallowed.
+
+  Returns:
+    whether git-svn has been set up.
+  """
+  # To test whether git-svn has been set up, query the config for any
+  # svn-related configuration.  This command exits with an error code
+  # if there aren't any matches, so ignore its output.
+  proc = RunGitCommand(directory, ['config', '--get-regexp', '^svn'])
+  if proc:
+    return (proc.wait() == 0)
+  return False
+
+
+def FetchGitSVNURL(directory):
+  """
+  Fetch URL of SVN repository bound to git.
+
+  Errors are swallowed.
+
+  Returns:
+    SVN URL.
+  """
+  if IsGitSVN(directory):
+    proc = RunGitCommand(directory, ['svn', 'info', '--url'])
+    if proc:
+      output = proc.communicate()[0].strip()
+      if proc.returncode == 0:
+        match = re.search(r'^\w+://.*$', output, re.M)
+        if match:
+          return match.group(0)
+  return ''
+
+
+def FetchGitSVNRoot(directory):
+  """
+  Fetch root of SVN repository bound to git.
+
+  Errors are swallowed.
+
+  Returns:
+    SVN root repository.
+  """
+  if IsGitSVN(directory):
+    git_command = ['config', '--get-regexp', '^svn-remote.svn.url$']
+    proc = RunGitCommand(directory, git_command)
+    if proc:
+      output = proc.communicate()[0].strip()
+      if proc.returncode == 0:
+        # Zero return code implies presence of requested configuration variable.
+        # Its value is second (last) field of output.
+        match = re.search(r'\S+$', output)
+        if match:
+          return match.group(0)
+  return ''
+
+
+def LookupGitSVNRevision(directory, depth):
+  """
+  Fetch the Git-SVN identifier for the local tree.
+  Parses first |depth| commit messages.
+
+  Errors are swallowed.
+  """
+  if not IsGitSVN(directory):
+    return None
+  git_re = re.compile(r'^\s*git-svn-id:\s+(\S+)@(\d+)')
+  proc = RunGitCommand(directory, ['log', '-' + str(depth)])
+  if proc:
+    for line in proc.stdout:
+      match = git_re.match(line)
+      if match:
+        id = match.group(2)
+        if id:
+          proc.stdout.close()  # Cut pipe for fast exit.
+          return id
+  return None
+
+
+def IsGitSVNDirty(directory):
+  """
+  Checks whether our git-svn tree contains clean trunk or some branch.
+
+  Errors are swallowed.
+  """
+  # For git branches the last commit message is either
+  # some local commit or a merge.
+  return LookupGitSVNRevision(directory, 1) is None
+
+
+def FetchGitSVNRevision(directory):
+  """
+  Fetch the Git-SVN identifier for the local tree.
+
+  Errors are swallowed.
+  """
+  # We assume that at least first 999 commit messages contain svn evidence.
+  revision = LookupGitSVNRevision(directory, 999)
+  if not revision:
+    return None
+  if IsGitSVNDirty(directory):
+    revision = revision + '-dirty'
+  url = FetchGitSVNURL(directory)
+  root = FetchGitSVNRoot(directory)
+  return VersionInfo(url, root, revision)
+
+
+def FetchVersionInfo(default_lastchange, directory=None):
+  """
+  Returns the last change (in the form of a branch, revision tuple),
+  from some appropriate revision control system.
+  """
+  version_info = (FetchSVNRevision(directory) or
+      FetchGitSVNRevision(directory) or FetchGitRevision(directory))
+  if not version_info:
+    if default_lastchange and os.path.exists(default_lastchange):
+      revision = open(default_lastchange, 'r').read().strip()
+      version_info = VersionInfo(None, None, revision)
+    else:
+      version_info = VersionInfo('unknown', '', '0')
+  return version_info
+
+
+def WriteIfChanged(file_name, contents):
+  """
+  Writes the specified contents to the specified file_name
+  iff the contents are different than the current contents.
+  """
+  try:
+    old_contents = open(file_name, 'r').read()
+  except EnvironmentError:
+    pass
+  else:
+    if contents == old_contents:
+      return
+    os.unlink(file_name)
+  open(file_name, 'w').write(contents)
+
+
+def main(argv=None):
+  if argv is None:
+    argv = sys.argv
+
+  parser = optparse.OptionParser(usage="lastchange.py [options]")
+  parser.add_option("-d", "--default-lastchange", metavar="FILE",
+                    help="default last change input FILE")
+  parser.add_option("-o", "--output", metavar="FILE",
+                    help="write last change to FILE")
+  parser.add_option("--revision-only", action='store_true',
+                    help="just print the SVN revision number")
+  opts, args = parser.parse_args(argv[1:])
+
+  out_file = opts.output
+
+  while len(args) and out_file is None:
+    if out_file is None:
+      out_file = args.pop(0)
+  if args:
+    sys.stderr.write('Unexpected arguments: %r\n\n' % args)
+    parser.print_help()
+    sys.exit(2)
+
+  version_info = FetchVersionInfo(opts.default_lastchange)
+
+  if opts.revision_only:
+    print version_info.revision
+  else:
+    contents = "LASTCHANGE=%s\n" % version_info.revision
+    if out_file:
+      WriteIfChanged(out_file, contents)
+    else:
+      sys.stdout.write(contents)
+
+  return 0
+
+
+if __name__ == '__main__':
+  sys.exit(main())

Propchange: httpd/mod_spdy/trunk/build/util/lastchange.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/util/lastchange.py
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/version.py
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/version.py?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/version.py (added)
+++ httpd/mod_spdy/trunk/build/version.py Thu May  1 11:43:36 2014
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+
+# Copyright 2010 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# This script is wrapper for the Chromium version of compiler_version.py.
+
+import os
+
+script_dir = os.path.dirname(__file__)
+chrome_src = os.path.normpath(os.path.join(script_dir, os.pardir, 'third_party',
+                                           'chromium', 'src'))
+
+execfile(os.path.join(chrome_src, 'chrome', 'tools', 'build', 'version.py'))

Propchange: httpd/mod_spdy/trunk/build/version.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/version.py
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/win/chrome_win.croc
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/win/chrome_win.croc?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/win/chrome_win.croc (added)
+++ httpd/mod_spdy/trunk/build/win/chrome_win.croc Thu May  1 11:43:36 2014
@@ -0,0 +1,26 @@
+# -*- python -*-
+# Crocodile config file for Chromium windows
+
+{
+  # List of rules, applied in order
+  'rules' : [
+    # Specify inclusions before exclusions, since rules are in order.
+
+    # Don't include chromeos, posix, or linux specific files
+    {
+      'regexp' : '.*(_|/)(chromeos|linux|posix)(\\.|_)',
+      'include' : 0,
+    },
+    # Don't include ChromeOS dirs
+    {
+      'regexp' : '.*/chromeos/',
+      'include' : 0,
+    },
+
+    # Groups
+    {
+      'regexp' : '.*_test_win\\.',
+      'group' : 'test',
+    },
+  ],
+}

Added: httpd/mod_spdy/trunk/build/win/install-build-deps.py
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/win/install-build-deps.py?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/win/install-build-deps.py (added)
+++ httpd/mod_spdy/trunk/build/win/install-build-deps.py Thu May  1 11:43:36 2014
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+# Copyright (c) 2012 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.
+
+import shutil
+import sys
+import os
+
+def patch_msbuild():
+  """VS2010 MSBuild has a ULDI bug that we patch here. See http://goo.gl/Pn8tj.
+  """
+  source_path = os.path.join(os.environ['ProgramFiles(x86)'],
+                             "MSBuild",
+                             "Microsoft.Cpp",
+                             "v4.0",
+                             "Microsoft.CppBuild.targets")
+  backup_path = source_path + ".backup"
+  if not os.path.exists(backup_path):
+    try:
+      print "Backing up %s..." % source_path
+      shutil.copyfile(source_path, backup_path)
+    except IOError:
+      print "Could not back up %s to %s. Run as Administrator?" % (
+          source_path, backup_path)
+      return 1
+
+  source = open(source_path).read()
+  base = ('''<Target Name="GetResolvedLinkObjs" Returns="@(ObjFullPath)" '''
+          '''DependsOnTargets="$(CommonBuildOnlyTargets);ComputeCLOutputs;'''
+          '''ResolvedLinkObjs"''')
+  find = base + '>'
+  replace = base + ''' Condition="'$(ConfigurationType)'=='StaticLibrary'">'''
+  result = source.replace(find, replace)
+
+  if result != source:
+    open(source_path, "w").write(result)
+    print "Patched %s." % source_path
+  return 0
+
+
+def main():
+  return patch_msbuild()
+
+
+if __name__ == "__main__":
+  sys.exit(main())

Propchange: httpd/mod_spdy/trunk/build/win/install-build-deps.py
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build/win/install-build-deps.py
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/build/win/setup_cygwin_mount.py
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build/win/setup_cygwin_mount.py?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build/win/setup_cygwin_mount.py (added)
+++ httpd/mod_spdy/trunk/build/win/setup_cygwin_mount.py Thu May  1 11:43:36 2014
@@ -0,0 +1,20 @@
+# Copyright (c) 2012 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.
+
+import os
+import sys
+
+def main():
+  if len(sys.argv) != 2 or sys.argv[1] != '--win-only':
+    return 1
+  if sys.platform in ('win32', 'cygwin'):
+    self_dir = os.path.dirname(sys.argv[0])
+    mount_path = os.path.join(self_dir, "../../third_party/cygwin")
+    batch_path = os.path.join(mount_path, "setup_mount.bat")
+    return os.system(os.path.normpath(batch_path) + ">nul")
+  return 0
+
+
+if __name__ == "__main__":
+  sys.exit(main())

Propchange: httpd/mod_spdy/trunk/build/win/setup_cygwin_mount.py
------------------------------------------------------------------------------
    svn:eol-style = native

Added: httpd/mod_spdy/trunk/build_modssl_with_npn.sh
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/build_modssl_with_npn.sh?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/build_modssl_with_npn.sh (added)
+++ httpd/mod_spdy/trunk/build_modssl_with_npn.sh Thu May  1 11:43:36 2014
@@ -0,0 +1,252 @@
+#!/bin/bash
+#
+# This script builds mod_ssl.so for Apache 2.2.x, with SSL NPN
+# support.
+#
+# NPN is not yet supported in Apache HTTPD mod_ssl. A patch has been
+# submitted to Apache to enable NPN in mod_ssl:
+# https://issues.apache.org/bugzilla/show_bug.cgi?id=52210
+#
+# Thus, we download the 1.0.1 release of OpenSSL and the most recent
+# release of Apache 2.2, and apply a patch to enable NPN support in
+# Apache mod_ssl.
+#
+# We currently statically link OpenSSL with mod_ssl, which results in
+# a large (several megabyte) mod_ssl.so. If you prefer, you can
+# install NPN-enabled OpenSSL as a shared library system-wide, by
+# building OpenSSL like so:
+#
+# ./config shared -fPIC  # -fPIC is only needed on some architectures
+# make
+# sudo make install
+#
+# And Apache like so (after applying the NPN patch):
+#
+# ./configure --enable-ssl=shared
+# make
+
+MODSSL_SO_DESTPATH=$(pwd)/mod_ssl.so
+
+if [ -f $MODSSL_SO_DESTPATH ]; then
+  echo "mod_ssl already exists at $MODSSL_SO_DESTPATH. Please remove."
+  exit 1
+fi
+
+if [ -z "$BUILDROOT" ]; then
+  BUILDROOT=$(pwd)/mod_ssl
+fi
+
+REMOVE_BUILDROOT=0
+
+if [ ! -d "$BUILDROOT" ]; then
+  echo "Not a directory: $BUILDROOT"
+  echo "Attempting to create: $BUILDROOT"
+  mkdir -p $BUILDROOT
+  if [ "$?" != "0" ]; then
+    echo "Failed to create: $BUILDROOT"
+    exit 1
+  fi
+fi
+
+# Convert BUILDROOT to an absolute path.
+BUILDROOT="$(cd $(dirname $BUILDROOT); pwd)/$(basename $BUILDROOT)"
+echo "Using buildroot: $BUILDROOT"
+echo ""
+
+function do_cleanup {
+  echo ""
+  echo "Build aborted."
+  if [ $REMOVE_BUILDROOT -eq 1 ]; then
+    echo -n "Cleaning up ... "
+    rm -rf "$BUILDROOT"
+    echo "done"
+  fi
+  exit 1
+}
+
+trap 'do_cleanup' SIGINT SIGTERM
+
+PROGRESS_DIR=$BUILDROOT/progress
+mkdir -p $PROGRESS_DIR
+if [ $? -ne 0 ]; then
+  do_cleanup
+fi
+
+function download_file {
+  if [ ! -f "$PROGRESS_DIR/$2.downloaded" ]; then
+    echo "Downloading $1"
+    curl -f -# "$1" -o $2 
+    if [ "$?" != "0" ]; then
+      echo "First attempt failed.. trying once more."
+      curl -f -# "$1" -o $2
+      if [ "$?" != "0" ]; then
+        do_cleanup
+      fi
+    fi
+    if [[ $(md5sum $2 | cut -d\  -f1) != $3 ]]; then
+      echo "md5sum mismatch for $2"
+      do_cleanup
+    fi
+    touch "$PROGRESS_DIR/$2.downloaded"
+  else
+    echo "Already downloaded $1"
+  fi
+}
+
+function uncompress_file {
+  if [ ! -f "$PROGRESS_DIR/$1.uncompressed" ]; then
+    echo -n "Uncompressing $1 ... "
+    tar xzf $1 || do_cleanup
+    echo "done"
+    touch "$PROGRESS_DIR/$1.uncompressed"
+  else
+    echo "Already uncompressed $1"
+  fi
+}
+
+OPENSSL_SRC_TGZ_URL="http://www.openssl.org/source/openssl-1.0.1g.tar.gz"
+APACHE_HTTPD_SRC_TGZ_URL="http://archive.apache.org/dist/httpd/httpd-2.4.7.tar.gz"
+APACHE_HTTPD_MODSSL_NPN_PATCH_PATH="$(dirname $0)/scripts/mod_ssl_with_npn.patch"
+
+OPENSSL_SRC_TGZ=$(basename $OPENSSL_SRC_TGZ_URL)
+APACHE_HTTPD_SRC_TGZ=$(basename $APACHE_HTTPD_SRC_TGZ_URL)
+APACHE_HTTPD_MODSSL_NPN_PATCH="mod_ssl_npn.patch"
+
+OPENSSL_SRC_ROOT=${OPENSSL_SRC_TGZ%.tar.gz}
+OPENSSL_INST_ROOT=${OPENSSL_SRC_ROOT}_install
+APACHE_HTTPD_SRC_ROOT=${APACHE_HTTPD_SRC_TGZ%.tar.gz}
+
+OPENSSL_BUILDLOG=$(mktemp -p /tmp openssl_buildlog.XXXXXXXXXX)
+APACHE_HTTPD_BUILDLOG=$(mktemp -p /tmp httpd_buildlog.XXXXXXXXXX)
+
+cp $APACHE_HTTPD_MODSSL_NPN_PATCH_PATH $BUILDROOT/$APACHE_HTTPD_MODSSL_NPN_PATCH
+
+pushd $BUILDROOT >/dev/null
+
+download_file $OPENSSL_SRC_TGZ_URL $OPENSSL_SRC_TGZ de62b43dfcd858e66a74bee1c834e959
+download_file $APACHE_HTTPD_SRC_TGZ_URL $APACHE_HTTPD_SRC_TGZ 9272aadaa2d702f6ae5758641d830d7f
+
+echo ""
+
+uncompress_file $OPENSSL_SRC_TGZ
+uncompress_file $APACHE_HTTPD_SRC_TGZ
+
+if [ ! -f "$PROGRESS_DIR/modssl_patched" ]; then
+  pushd $APACHE_HTTPD_SRC_ROOT >/dev/null
+  echo "Applying Apache mod_ssl NPN patch ... "
+  patch -p0 < $BUILDROOT/$APACHE_HTTPD_MODSSL_NPN_PATCH
+  if [ $? -ne 0 ]; then
+    echo "Failed to patch."
+    do_cleanup
+  fi
+  echo "done"
+  popd >/dev/null  # $APACHE_HTTPD_SRC_ROOT
+  touch "$PROGRESS_DIR/modssl_patched"
+else
+  echo "Already applied Apache mod_ssl NPN patch."
+fi
+
+echo ""
+
+if [ ! -f "$PROGRESS_DIR/openssl_configured" ]; then
+  pushd $OPENSSL_SRC_ROOT >/dev/null
+  echo -n "Configuring OpenSSL ... "
+  ./config no-shared -fPIC --openssldir=$BUILDROOT/$OPENSSL_INST_ROOT >> $OPENSSL_BUILDLOG
+  if [ $? -ne 0 ]; then
+    echo "Failed. Build log at $OPENSSL_BUILDLOG."
+    do_cleanup
+  fi
+  echo "done"
+  popd >/dev/null  # $OPENSSL_SRC_ROOT
+  touch "$PROGRESS_DIR/openssl_configured"
+else
+  echo "Already configured OpenSSL."
+fi
+
+if [ ! -f "$PROGRESS_DIR/openssl_built" ]; then
+  pushd $OPENSSL_SRC_ROOT >/dev/null
+  echo -n "Building OpenSSL (this may take a while) ... "
+  make >> $OPENSSL_BUILDLOG 2>&1
+  make install_sw >> $OPENSSL_BUILDLOG 2>&1
+  if [ $? -ne 0 ]; then
+    echo "Failed. Build log at $OPENSSL_BUILDLOG."
+    do_cleanup
+  fi
+  # A hacky fix that helps things build on CentOS:
+  if grep -q CentOS /etc/issue; then
+    sed --in-place 's/^Libs\.private: -ldl$/& -lcrypto/' \
+      $BUILDROOT/$OPENSSL_INST_ROOT/lib/pkgconfig/openssl.pc
+  fi
+  echo "done"
+  popd >/dev/null  # $OPENSSL_SRC_ROOT
+  touch "$PROGRESS_DIR/openssl_built"
+else
+  echo "Already built OpenSSL."
+fi
+
+rm -f "$OPENSSL_BUILDLOG"
+
+echo ""
+
+if [ ! -f "$PROGRESS_DIR/modssl_configured" ]; then
+  pushd $APACHE_HTTPD_SRC_ROOT >/dev/null
+  echo -n "Configuring Apache mod_ssl ... "
+
+  # OpenSSL, as of version 1.0.1, changed its pkg-config file to list
+  # its dependent libraries in Libs.private. Prior to this, dependent
+  # libraries were listed in Libs. This change in 1.0.1 is the right
+  # thing for OpenSSL, but it breaks the Apache 2.2.x configure when
+  # linking statically against OpenSSL, since it assumes that all
+  # dependent libs are provided in the pkg config Libs directive. We
+  # run a search-replace on the configure script to tell it to include
+  # not only libraries in Libs, but also those in Libs.private:
+  mv configure configure.bak
+  sed 's/--libs-only-l openssl/--libs-only-l --static openssl/' configure.bak > configure
+  chmod --reference=configure.bak configure
+
+  LDFLAGS="-ldl" ./configure --enable-ssl=shared --with-ssl=$BUILDROOT/$OPENSSL_INST_ROOT &>> $APACHE_HTTPD_BUILDLOG
+  if [ $? -ne 0 ]; then
+    echo "Failed. Build log at $APACHE_HTTPD_BUILDLOG."
+    do_cleanup
+  fi
+  echo "done"
+  popd >/dev/null  # $APACHE_HTTPD_SRC_ROOT
+  touch "$PROGRESS_DIR/modssl_configured"
+else
+  echo "Already configured Apache mod_ssl."
+fi
+
+if [ ! -f "$PROGRESS_DIR/modssl_built" ]; then
+  pushd $APACHE_HTTPD_SRC_ROOT >/dev/null
+  echo -n "Building Apache mod_ssl (this may take a while) ... "
+  make >> $APACHE_HTTPD_BUILDLOG 2>&1
+  if [ $? -ne 0 ]; then
+    echo "Failed. Build log at $APACHE_HTTPD_BUILDLOG."
+    do_cleanup
+  fi
+  echo "done"
+  popd >/dev/null  # $APACHE_HTTPD_SRC_ROOT
+  touch "$PROGRESS_DIR/modssl_built"
+else
+  echo "Already built Apache mod_ssl."
+fi
+
+rm -f "$APACHE_HTTPD_BUILDLOG"
+
+popd >/dev/null  # $BUILDROOT
+
+MODSSL_SO_SRCPATH=$(find $BUILDROOT/$APACHE_HTTPD_SRC_ROOT -name mod_ssl.so)
+if [ $(echo $MODSSL_SO_SRCPATH | wc -l) -ne 1 ]; then
+  echo "Found multiple mod_ssl.so's:"
+  echo $MODSSL_SO_SRCPATH
+  do_cleanup
+fi
+
+cp $MODSSL_SO_SRCPATH $MODSSL_SO_DESTPATH
+
+if [ $REMOVE_BUILDROOT -eq 1 ]; then
+  rm -rf "$BUILDROOT"
+fi
+
+echo ""
+echo "Generated mod_ssl.so at $MODSSL_SO_DESTPATH."

Propchange: httpd/mod_spdy/trunk/build_modssl_with_npn.sh
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: httpd/mod_spdy/trunk/build_modssl_with_npn.sh
------------------------------------------------------------------------------
    svn:executable = *

Added: httpd/mod_spdy/trunk/install/common/BRANDING
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/install/common/BRANDING?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/install/common/BRANDING (added)
+++ httpd/mod_spdy/trunk/install/common/BRANDING Thu May  1 11:43:36 2014
@@ -0,0 +1,5 @@
+COMPANY_FULLNAME=Google Inc.
+COMPANY_SHORTNAME=Google Inc.
+PRODUCT_FULLNAME=mod_spdy
+PRODUCT_SHORTNAME=mod_spdy
+COPYRIGHT=Copyright (C) 2012.

Added: httpd/mod_spdy/trunk/install/common/apt.include
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/install/common/apt.include?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/install/common/apt.include (added)
+++ httpd/mod_spdy/trunk/install/common/apt.include Thu May  1 11:43:36 2014
@@ -0,0 +1,188 @@
+@@include@@variables.include
+
+APT_GET="`which apt-get 2> /dev/null`"
+APT_CONFIG="`which apt-config 2> /dev/null`"
+
+SOURCES_PREAMBLE="### THIS FILE IS AUTOMATICALLY CONFIGURED ###
+# You may comment out this entry, but any other modifications may be lost.\n"
+
+# Parse apt configuration and return requested variable value.
+apt_config_val() {
+  APTVAR="$1"
+  if [ -x "$APT_CONFIG" ]; then
+    "$APT_CONFIG" dump | sed -e "/^$APTVAR /"'!d' -e "s/^$APTVAR \"\(.*\)\".*/\1/"
+  fi
+}
+
+# Install the repository signing key (see also:
+# http://www.google.com/linuxrepositories/aboutkey.html)
+install_key() {
+  APT_KEY="`which apt-key 2> /dev/null`"
+  if [ -x "$APT_KEY" ]; then
+    "$APT_KEY" add - >/dev/null 2>&1 <<KEYDATA
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: GnuPG v1.4.2.2 (GNU/Linux)
+
+mQGiBEXwb0YRBADQva2NLpYXxgjNkbuP0LnPoEXruGmvi3XMIxjEUFuGNCP4Rj/a
+kv2E5VixBP1vcQFDRJ+p1puh8NU0XERlhpyZrVMzzS/RdWdyXf7E5S8oqNXsoD1z
+fvmI+i9b2EhHAA19Kgw7ifV8vMa4tkwslEmcTiwiw8lyUl28Wh4Et8SxzwCggDcA
+feGqtn3PP5YAdD0km4S4XeMEAJjlrqPoPv2Gf//tfznY2UyS9PUqFCPLHgFLe80u
+QhI2U5jt6jUKN4fHauvR6z3seSAsh1YyzyZCKxJFEKXCCqnrFSoh4WSJsbFNc4PN
+b0V0SqiTCkWADZyLT5wll8sWuQ5ylTf3z1ENoHf+G3um3/wk/+xmEHvj9HCTBEXP
+78X0A/0Tqlhc2RBnEf+AqxWvM8sk8LzJI/XGjwBvKfXe+l3rnSR2kEAvGzj5Sg0X
+4XmfTg4Jl8BNjWyvm2Wmjfet41LPmYJKsux3g0b8yzQxeOA4pQKKAU3Z4+rgzGmf
+HdwCG5MNT2A5XxD/eDd+L4fRx0HbFkIQoAi1J3YWQSiTk15fw7RMR29vZ2xlLCBJ
+bmMuIExpbnV4IFBhY2thZ2UgU2lnbmluZyBLZXkgPGxpbnV4LXBhY2thZ2VzLWtl
+eW1hc3RlckBnb29nbGUuY29tPohjBBMRAgAjAhsDBgsJCAcDAgQVAggDBBYCAwEC
+HgECF4AFAkYVdn8CGQEACgkQoECDD3+sWZHKSgCfdq3HtNYJLv+XZleb6HN4zOcF
+AJEAniSFbuv8V5FSHxeRimHx25671az+uQINBEXwb0sQCACuA8HT2nr+FM5y/kzI
+A51ZcC46KFtIDgjQJ31Q3OrkYP8LbxOpKMRIzvOZrsjOlFmDVqitiVc7qj3lYp6U
+rgNVaFv6Qu4bo2/ctjNHDDBdv6nufmusJUWq/9TwieepM/cwnXd+HMxu1XBKRVk9
+XyAZ9SvfcW4EtxVgysI+XlptKFa5JCqFM3qJllVohMmr7lMwO8+sxTWTXqxsptJo
+pZeKz+UBEEqPyw7CUIVYGC9ENEtIMFvAvPqnhj1GS96REMpry+5s9WKuLEaclWpd
+K3krttbDlY1NaeQUCRvBYZ8iAG9YSLHUHMTuI2oea07Rh4dtIAqPwAX8xn36JAYG
+2vgLAAMFB/wKqaycjWAZwIe98Yt0qHsdkpmIbarD9fGiA6kfkK/UxjL/k7tmS4Vm
+CljrrDZkPSQ/19mpdRcGXtb0NI9+nyM5trweTvtPw+HPkDiJlTaiCcx+izg79Fj9
+KcofuNb3lPdXZb9tzf5oDnmm/B+4vkeTuEZJ//IFty8cmvCpzvY+DAz1Vo9rA+Zn
+cpWY1n6z6oSS9AsyT/IFlWWBZZ17SpMHu+h4Bxy62+AbPHKGSujEGQhWq8ZRoJAT
+G0KSObnmZ7FwFWu1e9XFoUCt0bSjiJWTIyaObMrWu/LvJ3e9I87HseSJStfw6fki
+5og9qFEkMrIrBCp3QGuQWBq/rTdMuwNFiEkEGBECAAkFAkXwb0sCGwwACgkQoECD
+D3+sWZF/WACfeNAu1/1hwZtUo1bR+MWiCjpvHtwAnA1R3IHqFLQ2X3xJ40XPuAyY
+/FJG
+=Quqp
+-----END PGP PUBLIC KEY BLOCK-----
+KEYDATA
+  fi
+}
+
+# Set variables for the locations of the apt sources lists.
+find_apt_sources() {
+  APTDIR=$(apt_config_val Dir)
+  APTETC=$(apt_config_val 'Dir::Etc')
+  APT_SOURCES="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourcelist')"
+  APT_SOURCESDIR="$APTDIR$APTETC$(apt_config_val 'Dir::Etc::sourceparts')"
+}
+
+# Update the Google repository if it's not set correctly.
+# Note: this doesn't necessarily enable the repository, it just makes sure the
+# correct settings are available in the sources list.
+# Returns:
+# 0 - no update necessary
+# 2 - error
+update_bad_sources() {
+  if [ ! "$REPOCONFIG" ]; then
+    return 0
+  fi
+
+  find_apt_sources
+
+  SOURCELIST="$APT_SOURCESDIR/@@PACKAGE@@.list"
+  # Don't do anything if the file isn't there, since that probably means the
+  # user disabled it.
+  if [ ! -r "$SOURCELIST" ]; then
+    return 0
+  fi
+
+  # Basic check for active configurations (non-blank, non-comment lines).
+  ACTIVECONFIGS=$(grep -v "^[[:space:]]*\(#.*\)\?$" "$SOURCELIST" 2>/dev/null)
+
+  # Check if the correct repository configuration is in there.
+  REPOMATCH=$(grep "^[[:space:]#]*\b$REPOCONFIG\b" "$SOURCELIST" \
+    2>/dev/null)
+
+  # Check if the correct repository is disabled.
+  MATCH_DISABLED=$(echo "$REPOMATCH" | grep "^[[:space:]]*#" 2>/dev/null)
+
+  # Now figure out if we need to fix things.
+  BADCONFIG=1
+  if [ "$REPOMATCH" ]; then
+    # If it's there and active, that's ideal, so nothing to do.
+    if [ ! "$MATCH_DISABLED" ]; then
+      BADCONFIG=0
+    else
+      # If it's not active, but neither is anything else, that's fine too.
+      if [ ! "$ACTIVECONFIGS" ]; then
+        BADCONFIG=0
+      fi
+    fi
+  fi
+
+  if [ $BADCONFIG -eq 0 ]; then
+    return 0
+  fi
+
+  # At this point, either the correct configuration is completely missing, or
+  # the wrong configuration is active. In that case, just abandon the mess and
+  # recreate the file with the correct configuration. If there were no active
+  # configurations before, create the new configuration disabled.
+  DISABLE=""
+  if [ ! "$ACTIVECONFIGS" ]; then
+    DISABLE="#"
+  fi
+  printf "$SOURCES_PREAMBLE" > "$SOURCELIST"
+  printf "$DISABLE$REPOCONFIG\n" >> "$SOURCELIST"
+  if [ $? -eq 0 ]; then
+    return 0
+  fi
+  return 2
+}
+
+# Add the Google repository to the apt sources.
+# Returns:
+# 0 - sources list was created
+# 2 - error
+create_sources_lists() {
+  if [ ! "$REPOCONFIG" ]; then
+    return 0
+  fi
+
+  find_apt_sources
+
+  SOURCELIST="$APT_SOURCESDIR/@@PACKAGE@@.list"
+  if [ -d "$APT_SOURCESDIR" ]; then
+    printf "$SOURCES_PREAMBLE" > "$SOURCELIST"
+    printf "$REPOCONFIG\n" >> "$SOURCELIST"
+    if [ $? -eq 0 ]; then
+      return 0
+    fi
+  fi
+  return 2
+}
+
+# Remove our custom sources list file.
+# Returns:
+# 0 - successfully removed, or not configured
+# !0 - failed to remove
+clean_sources_lists() {
+  if [ ! "$REPOCONFIG" ]; then
+    return 0
+  fi
+
+  find_apt_sources
+
+  rm -f "$APT_SOURCESDIR/@@PACKAGE@@.list" \
+        "$APT_SOURCESDIR/@@PACKAGE@@-@@CHANNEL@@.list"
+}
+
+# Detect if the repo config was disabled by distro upgrade and enable if
+# necessary.
+handle_distro_upgrade() {
+  if [ ! "$REPOCONFIG" ]; then
+    return 0
+  fi
+
+  find_apt_sources
+  SOURCELIST="$APT_SOURCESDIR/@@PACKAGE@@.list"
+  if [ -r "$SOURCELIST" ]; then
+    REPOLINE=$(grep -E "^[[:space:]]*#[[:space:]]*$REPOCONFIG[[:space:]]*# disabled on upgrade to .*" "$SOURCELIST")
+    if [ $? -eq 0 ]; then
+      sed -i -e "s,^[[:space:]]*#[[:space:]]*\($REPOCONFIG\)[[:space:]]*# disabled on upgrade to .*,\1," \
+        "$SOURCELIST"
+      LOGGER=$(which logger 2> /dev/null)
+      if [ "$LOGGER" ]; then
+        "$LOGGER" -t "$0" "Reverted repository modification: $REPOLINE."
+      fi
+    fi
+  fi
+}
+

Added: httpd/mod_spdy/trunk/install/common/installer.include
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/install/common/installer.include?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/install/common/installer.include (added)
+++ httpd/mod_spdy/trunk/install/common/installer.include Thu May  1 11:43:36 2014
@@ -0,0 +1,116 @@
+# Recursively replace @@include@@ template variables with the referenced file,
+# and write the resulting text to stdout.
+process_template_includes() {
+  INCSTACK+="$1->"
+  # Includes are relative to the file that does the include.
+  INCDIR=$(dirname $1)
+  # Clear IFS so 'read' doesn't trim whitespace
+  local OLDIFS="$IFS"
+  IFS=''
+  while read -r LINE
+  do
+    INCLINE=$(sed -e '/^[[:space:]]*@@include@@/!d' <<<$LINE)
+    if [ -n "$INCLINE" ]; then
+      INCFILE=$(echo $INCLINE | sed -e "s#@@include@@\(.*\)#\1#")
+      # Simple filename match to detect cyclic includes.
+      CYCLE=$(sed -e "\#$INCFILE#"'!d' <<<$INCSTACK)
+      if [ "$CYCLE" ]; then
+        echo "ERROR: Possible cyclic include detected." 1>&2
+        echo "$INCSTACK$INCFILE" 1>&2
+        exit 1
+      fi
+      if [ ! -r "$INCDIR/$INCFILE" ]; then
+        echo "ERROR: Couldn't read include file: $INCDIR/$INCFILE" 1>&2
+        exit 1
+      fi
+      process_template_includes "$INCDIR/$INCFILE"
+    else
+      echo "$LINE"
+    fi
+  done < "$1"
+  IFS="$OLDIFS"
+  INCSTACK=${INCSTACK%"$1->"}
+}
+
+# Replace template variables (@@VARNAME@@) in the given template file. If a
+# second argument is given, save the processed text to that filename, otherwise
+# modify the template file in place.
+process_template() (
+  # Don't worry if some of these substitution variables aren't set.
+  # Note that this function is run in a sub-shell so we don't leak this
+  # setting, since we still want unbound variables to be an error elsewhere.
+  set +u
+
+  local TMPLIN="$1"
+  if [ -z "$2" ]; then
+    local TMPLOUT="$TMPLIN"
+  else
+    local TMPLOUT="$2"
+  fi
+  # Process includes first so included text also gets substitutions.
+  TMPLINCL="$(process_template_includes "$TMPLIN")"
+  sed \
+    -e "s#@@PACKAGE@@#${PACKAGE}#g" \
+    -e "s#@@CHANNEL@@#${CHANNEL}#g" \
+    -e "s#@@COMPANY_FULLNAME@@#${COMPANY_FULLNAME}#g" \
+    -e "s#@@VERSION@@#${VERSION}#g" \
+    -e "s#@@REVISION@@#${REVISION}#g" \
+    -e "s#@@VERSIONFULL@@#${VERSIONFULL}#g" \
+    -e "s#@@BUILDDIR@@#${BUILDDIR}#g" \
+    -e "s#@@STAGEDIR@@#${STAGEDIR}#g" \
+    -e "s#@@SCRIPTDIR@@#${SCRIPTDIR}#g" \
+    -e "s#@@PRODUCTURL@@#${PRODUCTURL}#g" \
+    -e "s#@@PREDEPENDS@@#${PREDEPENDS}#g" \
+    -e "s#@@DEPENDS@@#${DEPENDS}#g" \
+    -e "s#@@PROVIDES@@#${PROVIDES}#g" \
+    -e "s#@@REPLACES@@#${REPLACES}#g" \
+    -e "s#@@CONFLICTS@@#${CONFLICTS}#g" \
+    -e "s#@@ARCHITECTURE@@#${HOST_ARCH}#g" \
+    -e "s#@@MAINTNAME@@#${MAINTNAME}#g" \
+    -e "s#@@MAINTMAIL@@#${MAINTMAIL}#g" \
+    -e "s#@@REPOCONFIG@@#${REPOCONFIG}#g" \
+    -e "s#@@SHORTDESC@@#${SHORTDESC}#g" \
+    -e "s#@@FULLDESC@@#${FULLDESC}#g" \
+    -e "s#@@APACHE_CONFDIR@@#${APACHE_CONFDIR}#g" \
+    -e "s#@@APACHE_MODULEDIR@@#${APACHE_MODULEDIR}#g" \
+    -e "s#@@APACHE_USER@@#${APACHE_USER}#g" \
+    -e "s#@@MODSPDY_ENABLE_UPDATES@@#${MODSPDY_ENABLE_UPDATES}#g" \
+    -e "s#@@COMMENT_OUT_DEFLATE@@#${COMMENT_OUT_DEFLATE}#g" \
+    > "$TMPLOUT" <<< "$TMPLINCL"
+)
+
+# Setup the installation directory hierachy in the package staging area.
+prep_staging_common() {
+  install -m 755 -d \
+    "${STAGEDIR}${APACHE_CONFDIR}" \
+    "${STAGEDIR}${APACHE_MODULEDIR}"
+}
+
+get_version_info() {
+  # Default to a bogus low version, so if somebody creates and installs
+  # a package with no version info, it won't prevent upgrading when
+  # trying to install a properly versioned package (i.e. a proper
+  # package will always be "newer").
+  VERSION="0.0.0.0"
+  # Use epoch timestamp so packages with bogus versions still increment
+  # and will upgrade older bogus-versioned packages.
+  REVISION=$(date +"%s")
+  # Default to non-official build since official builds set this
+  # properly.
+  OFFICIAL_BUILD=0
+
+  VERSIONFILE="${BUILDDIR}/installer/version.txt"
+  if [ -f "${VERSIONFILE}" ]; then
+    source "${VERSIONFILE}"
+    VERSION="${MAJOR}.${MINOR}.${BUILD}.${PATCH}"
+    REVISION="${LASTCHANGE}"
+  fi
+}
+
+stage_install_common() {
+  echo "Staging common install files in '${STAGEDIR}'..."
+
+  # app and resources
+  install -m 644 -s "${BUILDDIR}/libmod_spdy.so" "${STAGEDIR}${APACHE_MODULEDIR}/mod_spdy.so"
+  install -m 644 -s "${BUILDDIR}/mod_ssl.so" "${STAGEDIR}${APACHE_MODULEDIR}/mod_ssl_with_npn.so"
+}

Added: httpd/mod_spdy/trunk/install/common/mod-spdy.info
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/install/common/mod-spdy.info?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/install/common/mod-spdy.info (added)
+++ httpd/mod_spdy/trunk/install/common/mod-spdy.info Thu May  1 11:43:36 2014
@@ -0,0 +1,20 @@
+# 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.
+#
+# This file provides common configuration information for building
+# mod-spdy packages for various platforms.
+
+# Base name of the package.
+PACKAGE="mod-spdy"
+
+# Brief package description.
+SHORTDESC="Apache 2 module to enable SPDY support."
+
+# Detailed package description.
+FULLDESC="mod_spdy is an Apache module that allows an Apache server to support the SPDY protocol for serving HTTP resources."
+
+# Package maintainer information.
+MAINTNAME="mod_spdy developers"
+MAINTMAIL="mod-spdy-dev@googlegroups.com"
+PRODUCTURL="http://code.google.com/p/mod-spdy/"

Added: httpd/mod_spdy/trunk/install/common/repo.cron
URL: http://svn.apache.org/viewvc/httpd/mod_spdy/trunk/install/common/repo.cron?rev=1591622&view=auto
==============================================================================
--- httpd/mod_spdy/trunk/install/common/repo.cron (added)
+++ httpd/mod_spdy/trunk/install/common/repo.cron Thu May  1 11:43:36 2014
@@ -0,0 +1,42 @@
+#!/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.
+#
+# This script is part of the @@PACKAGE@@ package.
+#
+# It creates the repository configuration file for package updates, and it
+# monitors that config to see if it has been disabled by the overly aggressive
+# distro upgrade process (e.g.  intrepid -> jaunty). When this situation is
+# detected, the respository will be re-enabled. If the respository is disabled
+# for any other reason, this won't re-enable it.
+#
+# This functionality can be controlled by creating the $DEFAULTS_FILE and
+# setting "repo_add_once" and/or "repo_reenable_on_distupgrade" to "true" or
+# "false" as desired. An empty $DEFAULTS_FILE is the same as setting both values
+# to "false".
+
+@@include@@apt.include
+
+## MAIN ##
+DEFAULTS_FILE="/etc/default/@@PACKAGE@@"
+if [ -r "$DEFAULTS_FILE" ]; then
+  . "$DEFAULTS_FILE"
+fi
+
+if [ "$repo_add_once" = "true" ]; then
+  install_key
+  create_sources_lists
+  RES=$?
+  # Sources creation succeeded, so stop trying.
+  if [ $RES -ne 2 ]; then
+    sed -i -e 's/[[:space:]]*repo_add_once=.*/repo_add_once="false"/' "$DEFAULTS_FILE"
+  fi
+else
+  update_bad_sources
+fi
+
+if [ "$repo_reenable_on_distupgrade" = "true" ]; then
+  handle_distro_upgrade
+fi