C++ SDK: Add a script the builds and uploads a tarball of the SDK to GCS.

R=vardhan@google.com

Review URL: https://codereview.chromium.org/1766093003 .
diff --git a/sdk_build/build_and_upload_cpp_sdk.sh b/sdk_build/build_and_upload_cpp_sdk.sh
new file mode 100755
index 0000000..680e08b
--- /dev/null
+++ b/sdk_build/build_and_upload_cpp_sdk.sh
@@ -0,0 +1,54 @@
+#!/bin/bash
+# Copyright 2016 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.
+
+# Script that "builds" and uploads a C++ SDK to GCS.
+
+set -e
+
+SCRIPT_DIR=$(dirname $0)
+BUILD_SDK=${SCRIPT_DIR}/build_sdk.py
+
+WORK_DIR=$(mktemp -d -t build_cpp_sdk.XXXXXXXX)
+function cleanup_work_dir {
+  rm -rf "$WORK_DIR"
+}
+trap cleanup_work_dir EXIT
+
+# Build the SDK.
+SDK_DIRNAME=mojo_cpp_sdk
+SDK_DIR=${WORK_DIR}/${SDK_DIRNAME}
+"$BUILD_SDK" "${SCRIPT_DIR}/data/cpp/cpp.sdk" "$SDK_DIR"
+
+# Get the version (hash).
+VERSION=$(cat "${SDK_DIR}/MOJO_SDK_VERSION")
+# Abbreviate it to 12 hex digits.
+SHORT_VERSION=${VERSION:0:12}
+echo "SDK version (hash): ${VERSION} (${SHORT_VERSION})"
+
+# Make a tarball.
+TARBALL_FILENAME=mojo_cpp_sdk-${SHORT_VERSION}.tar.gz
+TARBALL_FILE=${WORK_DIR}/${TARBALL_FILENAME}
+# In a subshell, change to WORK_DIR so that the tarball will only have the
+# mojo_cpp_sdk part of the path.
+(
+  cd "${WORK_DIR}"
+  tar c --owner=root --group=root -z -f "$TARBALL_FILENAME" "$SDK_DIRNAME"
+)
+
+# Assume that we're the "latest". Make a file containing the abbreviated hash.
+LATEST_FILENAME=LATEST
+LATEST_FILE=${WORK_DIR}/${LATEST_FILENAME}
+echo "$SHORT_VERSION" > "$LATEST_FILE"
+
+echo "Press enter to upload ${TARBALL_FILENAME} to GCS"
+read
+
+GCS_BASE_URL="gs://mojo/sdk/cpp"
+# Don't clobber existing tarballs.
+gsutil cp -n "$TARBALL_FILE" "${GCS_BASE_URL}/${TARBALL_FILENAME}"
+# But allow "LATEST" to be clobbered.
+gsutil cp "$LATEST_FILE" "${GCS_BASE_URL}/${LATEST_FILENAME}"
+
+echo "Done!"
diff --git a/sdk_build/build_sdk.py b/sdk_build/build_sdk.py
index 340bfee..74c46fd 100755
--- a/sdk_build/build_sdk.py
+++ b/sdk_build/build_sdk.py
@@ -24,6 +24,17 @@
     pass
 
 
+def _CopyHelper(source_file, dest_file):
+  """Copies |source_file| to |dest_file|. If |source_file| is user-executable,
+  it will set |dest_file|'s mode to 0755 (user: rwx, group/other: rx);
+  otherwise, it will set it to 0644 (user: rw, group/other: r)."""
+  shutil.copy(source_file, dest_file)
+  if os.stat(source_file).st_mode & 0100:
+    os.chmod(dest_file, 0755)
+  else:
+    os.chmod(dest_file, 0644)
+
+
 def _CopyDir(source_path, dest_path, **kwargs):
   """Copies directories from the source git repository (the current working
   directory should be the root of this repository) to the destination path.
@@ -39,7 +50,7 @@
     rel_path = source_file[len(source_path) + 1:]
     dest_file = os.path.join(dest_path, rel_path)
     _MakeDirs(os.path.dirname(dest_file))
-    shutil.copy(source_file, dest_file)
+    _CopyHelper(source_file, dest_file)
 
 
 def _CopyFiles(source_files, dest_path):
@@ -54,7 +65,7 @@
     source_files = [source_files]
   _MakeDirs(dest_path)
   for source_file in source_files:
-    shutil.copy(source_file,
+    _CopyHelper(source_file,
                 os.path.join(dest_path, os.path.basename(source_file)))
 
 
@@ -106,6 +117,10 @@
   if not args.allow_dirty_tree and IsGitTreeDirty():
     FatalError("tree appears to be dirty")
 
+  # Set the umask, so that files/directories we create will be world- (and
+  # group-) readable (and executable, for directories).
+  os.umask(0022)
+
   try:
     os.mkdir(target_dir)
   except OSError: