Improve platform and CPU detection, use the correct protoc binary for the running system.

Tested on OS X 10.10, Debian 8.1 (x86_64) and Debian 8.1 (i686).

--
MOS_MIGRATED_REVID=95819163
diff --git a/compile.sh b/compile.sh
index c2b467e..163eb5c 100755
--- a/compile.sh
+++ b/compile.sh
@@ -26,7 +26,6 @@
 
 source scripts/bootstrap/buildenv.sh
 
-
 function usage() {
   [ -n "${1:-build}" ] && echo "Invalid command(s): $1" >&2
   echo "syntax: $0 [command[,command]* [BAZEL_BIN [BAZEL_SUM]]]" >&2
diff --git a/scripts/bootstrap/buildenv.sh b/scripts/bootstrap/buildenv.sh
index 2a64d8c..d59370d 100755
--- a/scripts/bootstrap/buildenv.sh
+++ b/scripts/bootstrap/buildenv.sh
@@ -1,3 +1,5 @@
+#!/bin/bash
+
 # Copyright 2015 Google Inc. All rights reserved.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -23,6 +25,12 @@
 BAZELRC=${BAZELRC:-"/dev/null"}
 PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"
 
+MACHINE_TYPE="$(uname -m)"
+MACHINE_IS_64BIT='no'
+if [ "${MACHINE_TYPE}" = 'amd64' -o "${MACHINE_TYPE}" = 'x86_64' ]; then
+  MACHINE_IS_64BIT='yes'
+fi
+
 ATEXIT_=""
 function atexit() {
   ATEXIT_="$1; ${ATEXIT_}"
diff --git a/scripts/bootstrap/compile.sh b/scripts/bootstrap/compile.sh
index 1bb3a62..f377f4a 100755
--- a/scripts/bootstrap/compile.sh
+++ b/scripts/bootstrap/compile.sh
@@ -78,7 +78,11 @@
   MD5SUM="md5sum"
   # JAVA_HOME must point to a Java installation.
   JAVA_HOME="${JAVA_HOME:-$(readlink -f $(which javac) | sed 's_/bin/javac__')}"
-  PROTOC=${PROTOC:-third_party/protobuf/protoc-linux-x86_32.exe}
+  if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then
+    PROTOC=${PROTOC:-third_party/protobuf/protoc-linux-x86_64.exe}
+  else
+    PROTOC=${PROTOC:-third_party/protobuf/protoc-linux-x86_32.exe}
+  fi
   ;;
 
 darwin)
@@ -89,7 +93,11 @@
     JAVA_HOME="$(/usr/libexec/java_home -v ${JAVA_VERSION}+ 2> /dev/null)" \
       || fail "Could not find JAVA_HOME, please ensure a JDK (version ${JAVA_VERSION}+) is installed."
   fi
-  PROTOC=${PROTOC:-third_party/protobuf/protoc-osx-x86_32.exe}
+  if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then
+    PROTOC=${PROTOC:-third_party/protobuf/protoc-osx-x86_64.exe}
+  else
+    PROTOC=${PROTOC:-third_party/protobuf/protoc-osx-x86_32.exe}
+  fi
   ;;
 
 msys*|mingw*)
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
index 0a5a088..7a2e1ad 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/BuildConfiguration.java
@@ -48,6 +48,7 @@
 import com.google.devtools.build.lib.syntax.Label.SyntaxException;
 import com.google.devtools.build.lib.syntax.SkylarkCallable;
 import com.google.devtools.build.lib.syntax.SkylarkModule;
+import com.google.devtools.build.lib.util.CPU;
 import com.google.devtools.build.lib.util.Fingerprint;
 import com.google.devtools.build.lib.util.OS;
 import com.google.devtools.build.lib.util.RegexFilter;
@@ -403,12 +404,20 @@
     @Override
     public String convert(String input) throws OptionsParsingException {
       if (input.isEmpty()) {
+        // TODO(philwo) - replace these deprecated names with more logical ones (e.g. k8 becomes
+        // linux-x86_64, darwin includes the CPU architecture, ...).
         switch (OS.getCurrent()) {
           case DARWIN:
             return "darwin";
-          default:
-            return "k8";
+          case LINUX:
+            switch (CPU.getCurrent()) {
+              case X86_32:
+                return "piii";
+              case X86_64:
+                return "k8";
+            }
         }
+        return "unknown";
       }
       return input;
     }
diff --git a/src/main/java/com/google/devtools/build/lib/util/CPU.java b/src/main/java/com/google/devtools/build/lib/util/CPU.java
new file mode 100644
index 0000000..fd54ddd
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/util/CPU.java
@@ -0,0 +1,60 @@
+// Copyright 2015 Google Inc. All rights reserved.
+//
+// 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.
+package com.google.devtools.build.lib.util;
+
+import com.google.common.collect.ImmutableSet;
+
+import java.util.Set;
+
+/**
+ * Detects the CPU of the running JVM and returns a describing enum value.
+ */
+public enum CPU {
+  X86_32("x86_32", ImmutableSet.of("i386", "i486", "i586", "i686", "i786", "x86")),
+  X86_64("x86_64", ImmutableSet.of("amd64", "x86_64", "x64")),
+  UNKNOWN("unknown", ImmutableSet.<String>of());
+
+  private final String canonicalName;
+  private final Set<String> archs;
+
+  CPU(String canonicalName, Set<String> archs) {
+    this.canonicalName = canonicalName;
+    this.archs = archs;
+  }
+
+  /**
+   * The current CPU.
+   */
+  public static CPU getCurrent() {
+    return HOST_CPU;
+  }
+
+  public String getCanonicalName() {
+    return canonicalName;
+  }
+
+  private static CPU determineCurrentCpu() {
+    String currentArch = System.getProperty("os.arch");
+
+    for (CPU cpu : CPU.values()) {
+      if (cpu.archs.contains(currentArch)) {
+        return cpu;
+      }
+    }
+
+    return CPU.UNKNOWN;
+  }
+
+  private static final CPU HOST_CPU = determineCurrentCpu();
+}
diff --git a/src/main/java/com/google/devtools/build/lib/util/OS.java b/src/main/java/com/google/devtools/build/lib/util/OS.java
index b19bd7e..ee2e6d4 100644
--- a/src/main/java/com/google/devtools/build/lib/util/OS.java
+++ b/src/main/java/com/google/devtools/build/lib/util/OS.java
@@ -14,13 +14,21 @@
 package com.google.devtools.build.lib.util;
 
 /**
- * An operating system.
+ * Detects the running operating system and returns a describing enum value.
  */
 public enum OS {
-  DARWIN,
-  LINUX,
-  WINDOWS,
-  UNKNOWN;
+  DARWIN("osx", "Mac OS X"),
+  LINUX("linux", "Linux"),
+  WINDOWS("windows", "Windows"),
+  UNKNOWN("", "");
+
+  private final String canonicalName;
+  private final String detectionName;
+
+  OS(String canonicalName, String detectionName) {
+    this.canonicalName = canonicalName;
+    this.detectionName = detectionName;
+  }
 
   /**
    * The current operating system.
@@ -28,16 +36,27 @@
   public static OS getCurrent() {
     return HOST_SYSTEM;
   }
-  // We inject a the OS name through blaze.os, so we can have
-  // some coverage for Windows specific code on Linux.
-  private static String getOsName() {
-    String override = System.getProperty("blaze.os");
-    return override == null ? System.getProperty("os.name") : override;
+
+  public String getCanonicalName() {
+    return canonicalName;
   }
 
-  private static final OS HOST_SYSTEM =
-      "Mac OS X".equals(getOsName()) ? OS.DARWIN : (
-      "Linux".equals(getOsName()) ? OS.LINUX : (
-          getOsName().contains("Windows") ? OS.WINDOWS : OS.UNKNOWN));
-}
+  // We inject a the OS name through blaze.os, so we can have
+  // some coverage for Windows specific code on Linux.
+  private static OS determineCurrentOs() {
+    String osName = System.getProperty("blaze.os");
+    if (osName == null) {
+      osName = System.getProperty("os.name");
+    }
 
+    for (OS os : OS.values()) {
+      if (os.detectionName.equals(osName)) {
+        return os;
+      }
+    }
+
+    return OS.UNKNOWN;
+  }
+
+  private static final OS HOST_SYSTEM = determineCurrentOs();
+}
diff --git a/src/test/shell/bazel/testenv.sh b/src/test/shell/bazel/testenv.sh
index 83dc339..47e5317 100755
--- a/src/test/shell/bazel/testenv.sh
+++ b/src/test/shell/bazel/testenv.sh
@@ -41,12 +41,25 @@
 
 # Third-party
 PLATFORM="$(uname -s | tr 'A-Z' 'a-z')"
+MACHINE_TYPE="$(uname -m)"
+MACHINE_IS_64BIT='no'
+if [ "${MACHINE_TYPE}" = 'amd64' -o "${MACHINE_TYPE}" = 'x86_64' ]; then
+  MACHINE_IS_64BIT='yes'
+fi
 case "${PLATFORM}" in
   darwin)
-    protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-osx-x86_32.exe"
+    if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then
+      protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-osx-x86_64.exe"
+    else
+      protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-osx-x86_32.exe"
+    fi
     ;;
   *)
-    protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-linux-x86_32.exe"
+    if [ "${MACHINE_IS_64BIT}" = 'yes' ]; then
+      protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-linux-x86_64.exe"
+    else
+      protoc_compiler="${TEST_SRCDIR}/third_party/protobuf/protoc-linux-x86_32.exe"
+    fi
     ;;
 esac
 protoc_jar="${TEST_SRCDIR}/third_party/protobuf/protobuf-*.jar"
diff --git a/third_party/BUILD b/third_party/BUILD
index 0f11d72..38e6e3d 100644
--- a/third_party/BUILD
+++ b/third_party/BUILD
@@ -12,7 +12,8 @@
         ":windows_msys64_mingw64": ["protobuf/protoc-windows-x86_64.exe"],
         ":windows_clang": ["protobuf/protoc-windows-x86_32.exe"],
         ":darwin": ["protobuf/protoc-osx-x86_32.exe"],
-        "//conditions:default": ["protobuf/protoc-linux-x86_32.exe"],
+        ":k8": ["protobuf/protoc-linux-x86_64.exe"],
+        ":piii": ["protobuf/protoc-linux-x86_32.exe"],
     }),
 )
 
@@ -284,5 +285,15 @@
 
 config_setting(
     name = "darwin",
-    values = {"cpu": "darwin"},
+    values = {"host_cpu": "darwin"},
+)
+
+config_setting(
+    name = "k8",
+    values = {"host_cpu": "k8"},
+)
+
+config_setting(
+    name = "piii",
+    values = {"host_cpu": "piii"},
 )
diff --git a/tools/cpp/CROSSTOOL b/tools/cpp/CROSSTOOL
index b2ed04e..cf39954 100644
--- a/tools/cpp/CROSSTOOL
+++ b/tools/cpp/CROSSTOOL
@@ -1,11 +1,16 @@
 major_version: "local"
 minor_version: ""
 default_target_cpu: "same_as_host"
+
 default_toolchain {
   cpu: "k8"
   toolchain_identifier: "local_linux"
 }
 default_toolchain {
+  cpu: "piii"
+  toolchain_identifier: "local_linux"
+}
+default_toolchain {
   cpu: "darwin"
   toolchain_identifier: "local_darwin"
 }