Make JDK not need tools/jdk/jdk symlinked

--
MOS_MIGRATED_REVID=88742425
diff --git a/compile.sh b/compile.sh
index e6e1514..acfee06 100755
--- a/compile.sh
+++ b/compile.sh
@@ -84,6 +84,9 @@
         touch fromhost/empty.c
         # For use with Homebrew.
         archive_dir=$(dirname $(dirname $homebrew_header))
+        ARCHIVE_CFLAGS="-I${archive_dir}/include"
+        LDFLAGS="-L${archive_dir}/lib -larchive $LDFLAGS"
+
         cp ${archive_dir}/lib/*.a ${archive_dir}/include/*.h fromhost/
         cat << EOF > fromhost/BUILD
 package(default_visibility = ["//visibility:public"])
@@ -103,6 +106,14 @@
         cp /opt/local/include/archive.h  /opt/local/include/archive_entry.h fromhost/
         cp /opt/local/lib/{libarchive,liblzo2,liblzma,libcharset,libbz2,libxml2,libz,libiconv}.a \
           fromhost/
+
+        ARCHIVE_CFLAGS="-Ifromhost"
+        # Link libarchive statically
+        LDFLAGS="fromhost/libarchive.a fromhost/liblzo2.a \
+             fromhost/liblzma.a fromhost/libcharset.a \
+             fromhost/libbz2.a fromhost/libxml2.a \
+             fromhost/libz.a fromhost/libiconv.a \
+             $LDFLAGS"
         cat << EOF > fromhost/BUILD
 package(default_visibility = ["//visibility:public"])
 cc_library(
@@ -112,6 +123,8 @@
   includes  = ["."],
 )
 EOF
+      else
+        log "WARNING: Could not find libarchive installation, proceeding bravely."
       fi
   esac
 }
@@ -144,27 +157,6 @@
       || fail "Could not find JAVA_HOME, please ensure a JDK (version 1.8+) is installed."
   fi
   PROTOC=${PROTOC:-third_party/protobuf/protoc.darwin}
-
-  homebrew_header=$(ls -1 $(brew --prefix 2>/dev/null)/Cellar/libarchive/*/include/archive.h 2>/dev/null | head -n1)
-  if [[ -e $homebrew_header ]]; then
-      # For use with Homebrew.
-      archive_dir=$(dirname $(dirname $homebrew_header))
-      ARCHIVE_CFLAGS="-I${archive_dir}/include"
-      LDFLAGS="-L${archive_dir}/lib -larchive $LDFLAGS"
-
-  elif [[ -e /opt/local/include/archive.h ]]; then
-      # For use with Macports.
-      ARCHIVE_CFLAGS="-Ifromhost"
-      # Link libarchive statically
-      LDFLAGS="fromhost/libarchive.a fromhost/liblzo2.a \
-             fromhost/liblzma.a fromhost/libcharset.a \
-             fromhost/libbz2.a fromhost/libxml2.a \
-             fromhost/libz.a fromhost/libiconv.a \
-             $LDFLAGS"
-  else
-      log "WARNING: Could not find libarchive installation, proceeding bravely."
-  fi
-
   ;;
 
 msys*|mingw*)
@@ -428,13 +420,13 @@
 fi
 
 cp src/main/tools/build_interface_so output/build_interface_so
-cp src/main/tools/jdk.WORKSPACE output/jdk.WORKSPACE
+cp src/main/tools/jdk.* output
 
 touch output/client_info
 chmod 755 output/client_info
 
 log "Creating Bazel self-extracting archive..."
-TO_ZIP="libblaze.jar ${JNILIB} build-runfiles${EXE_EXT} process-wrapper${EXE_EXT} client_info build_interface_so ${MSYS_DLLS} jdk.WORKSPACE"
+TO_ZIP="libblaze.jar ${JNILIB} build-runfiles${EXE_EXT} process-wrapper${EXE_EXT} client_info build_interface_so ${MSYS_DLLS} jdk.WORKSPACE jdk.BUILD"
 if [[ $PLATFORM == "linux" ]]; then
     TO_ZIP="$TO_ZIP namespace-sandbox${EXE_EXT}"
 fi
diff --git a/src/BUILD b/src/BUILD
index 2fcde8d..1341906 100644
--- a/src/BUILD
+++ b/src/BUILD
@@ -54,7 +54,7 @@
         ":libunix",
         "//src/main/tools:build-runfiles",
         "//src/main/tools:process-wrapper",
-        "//src/main/tools:jdk.WORKSPACE",
+        "//src/main/tools:jdk-support",
         ":namespace-sandbox",
         "client_info",
         "//src/main/tools:build_interface_so",
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java
index 71d0059..8f03ac4 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/repository/NewLocalRepositoryFunction.java
@@ -114,11 +114,11 @@
     // Link x/BUILD to <build_root>/x.BUILD.
     PathFragment buildFile = new PathFragment(mapper.get("build_file", Type.STRING));
     Path buildFileTarget = getWorkspace().getRelative(buildFile);
-    if (buildFile.equals(PathFragment.EMPTY_FRAGMENT) || buildFile.isAbsolute()
-        || !buildFileTarget.exists()) {
+    if (!buildFileTarget.exists()) {
       throw new RepositoryFunctionException(
           new EvalException(rule.getLocation(), "In " + rule
-              + " the 'build_file' attribute must specify a relative path to an existing file"),
+              + " the 'build_file' attribute does not specify an existing file ("
+              + buildFile + " does not exist)"),
           Transience.PERSISTENT);
     }
     Path buildFilePath = repositoryDirectory.getRelative("BUILD");
diff --git a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
index 572c163..3b702ce 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java
@@ -33,7 +33,9 @@
  * This creates the //external package, where targets not homed in this repository can be bound.
  */
 public class ExternalPackage extends Package {
+  public static final String NAME = "external";
 
+  private Map<Label, Binding> bindMap;
   private Map<RepositoryName, Rule> repositoryMap;
 
   ExternalPackage() {
@@ -49,6 +51,24 @@
   }
 
   /**
+   * If the given label is bound, returns the (fully resolved) label it is bound to. Otherwise,
+   * returns null.
+   */
+  public Label getActualLabel(Label label) {
+    if (bindMap.containsKey(label)) {
+      return bindMap.get(label).getActual();
+    }
+    return null;
+  }
+
+  /**
+   * Checks if the given package is //external.
+   */
+  public static boolean isExternal(Package pkg) {
+    return pkg != null && pkg.getName().equals(NAME);
+  }
+
+  /**
    * Holder for a binding's actual label and location.
    */
   public static class Binding {
@@ -97,6 +117,7 @@
 
     @Override
     public ExternalPackage build() {
+      pkg.bindMap = ImmutableMap.copyOf(bindMap);
       pkg.repositoryMap = ImmutableMap.copyOf(repositoryMap);
       return super.build();
     }
diff --git a/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java b/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
index 7483f88..ec7e926 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/java/JvmConfigurationLoader.java
@@ -109,7 +109,14 @@
             if (jvmTarget == null) {
               return null;
             }
-            PathFragment javaHomePath = jvmLabel.getPackageFragment();
+
+            PathFragment javaHomePath;
+            if (jvmTarget.getLabel().getPackageIdentifier().getRepository().isDefault()) {
+              javaHomePath = jvmLabel.getPackageFragment();
+            } else {
+              javaHomePath = jvmTarget.getLabel().getPackageFragment();
+            }
+
             if ((jvmTarget instanceof Rule) &&
                 "filegroup".equals(((Rule) jvmTarget).getRuleClass())) {
               RawAttributeMapper jvmTargetAttributes = RawAttributeMapper.of((Rule) jvmTarget);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java
index e467ae0..9478daf 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframePackageLoaderWithValueEnvironment.java
@@ -18,6 +18,7 @@
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.analysis.config.PackageProviderForConfigurations;
+import com.google.devtools.build.lib.packages.ExternalPackage;
 import com.google.devtools.build.lib.packages.NoSuchPackageException;
 import com.google.devtools.build.lib.packages.NoSuchTargetException;
 import com.google.devtools.build.lib.packages.Package;
@@ -77,6 +78,12 @@
   public Target getLoadedTarget(Label label) throws NoSuchPackageException,
       NoSuchTargetException {
     Package pkg = getLoadedPackage(label.getPackageIdentifier());
+    if (ExternalPackage.isExternal(pkg)) {
+      label = ((ExternalPackage) pkg).getActualLabel(label);
+      if (label != null) {
+        pkg = getLoadedPackage(label.getPackageIdentifier());
+      }
+    }
     return pkg == null ? null : pkg.getTarget(label.getName());
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
index 839a9ea..5378af5 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java
@@ -48,6 +48,7 @@
 import com.google.devtools.build.skyframe.SkyKey;
 import com.google.devtools.build.skyframe.SkyValue;
 
+import java.io.File;
 import java.io.IOException;
 import java.util.List;
 import java.util.Map;
@@ -212,6 +213,11 @@
       workspaceEnv.update(ruleClass, ruleFunction);
     }
 
+    workspaceEnv.update("__embedded_dir__", this.installDir.toString());
+    // TODO(kchodorow): Get all the toolchain rules and load this from there.
+    File jreDirectory = new File(System.getProperty("java.home"));
+    workspaceEnv.update("DEFAULT_SERVER_JAVABASE", jreDirectory.getParentFile().toString());
+
     workspaceEnv.update(BIND, newBindFunction(builder));
     workspaceEnv.update("workspace", newWorkspaceNameFunction(builder));
 
diff --git a/src/main/tools/BUILD b/src/main/tools/BUILD
index 2f1f8be..9fd1a78 100644
--- a/src/main/tools/BUILD
+++ b/src/main/tools/BUILD
@@ -20,7 +20,14 @@
     copts = ["-std=c99"],
 )
 
+filegroup(
+    name = "jdk-support",
+    srcs = [
+        "jdk.BUILD",
+        "jdk.WORKSPACE",
+    ],
+)
+
 exports_files([
     "build_interface_so",
-    "jdk.WORKSPACE",
 ])
diff --git a/src/main/tools/jdk.BUILD b/src/main/tools/jdk.BUILD
new file mode 100644
index 0000000..5da15f1
--- /dev/null
+++ b/src/main/tools/jdk.BUILD
@@ -0,0 +1,50 @@
+package(default_visibility = ["//visibility:public"])
+
+filegroup(
+    name = "jni_header",
+    srcs = ["include/jni.h"],
+)
+
+filegroup(
+    name = "jni_md_header-darwin",
+    srcs = ["include/darwin/jni_md.h"],
+)
+
+filegroup(
+    name = "jni_md_header-linux",
+    srcs = ["include/linux/jni_md.h"],
+)
+
+filegroup(
+    name = "java",
+    srcs = ["bin/java"],
+)
+
+BOOTCLASS_JARS = [
+    "rt.jar",
+    "resources.jar",
+    "jsse.jar",
+    "jce.jar",
+    "charsets.jar",
+]
+
+filegroup(
+    name = "bootclasspath",
+    srcs = ["jre/lib/%s" % jar for jar in BOOTCLASS_JARS],
+)
+
+filegroup(
+    name = "jdk-default",
+    srcs = glob(["bin/*"]),
+)
+
+filegroup(
+    name = "langtools",
+    srcs = ["lib/tools.jar"],
+)
+
+java_import(
+    name = "langtools-neverlink",
+    jars = ["lib/tools.jar"],
+    neverlink = 1,
+)
diff --git a/src/main/tools/jdk.WORKSPACE b/src/main/tools/jdk.WORKSPACE
index 8b6a3cd..9f69602 100644
--- a/src/main/tools/jdk.WORKSPACE
+++ b/src/main/tools/jdk.WORKSPACE
@@ -1,6 +1,44 @@
 # External dependencies for the java_* rules.
 
+new_local_repository(
+    name = "local-jdk",
+    path = DEFAULT_SERVER_JAVABASE,
+    build_file = __embedded_dir__ + "/jdk.BUILD",
+)
+
 bind(
-    name = "jdk",
-    actual = "//tools/jdk:jdk",
+    name = "bootclasspath",
+    actual = "@local-jdk//:bootclasspath",
+)
+bind(
+    name = "langtools",
+    actual = "@local-jdk//:langtools",
+)
+bind(
+    name = "langtools-neverlink",
+    actual = "@local-jdk//:langtools-neverlink",
+)
+bind(
+    name = "jni_header",
+    actual = "@local-jdk//:jni_header",
+)
+
+bind(
+    name = "jni_md_header-darwin",
+    actual = "@local-jdk//:jni_md_header-darwin",
+)
+
+bind(
+    name = "jni_md_header-linux",
+    actual = "@local-jdk//:jni_md_header-linux",
+)
+
+bind(
+    name = "java",
+    actual = "@local-jdk//:java",
+)
+
+bind(
+    name = "jdk-default",
+    actual = "@local-jdk//:jdk-default",
 )
diff --git a/tools/jdk/BUILD b/tools/jdk/BUILD
index 1577063..67b22c3 100644
--- a/tools/jdk/BUILD
+++ b/tools/jdk/BUILD
@@ -2,22 +2,22 @@
 
 filegroup(
     name = "jni_header",
-    srcs = ["jdk/include/jni.h"],
+    srcs = ["//external:jni_header"],
 )
 
 filegroup(
     name = "jni_md_header-darwin",
-    srcs = ["jdk/include/darwin/jni_md.h"],
+    srcs = ["//external:jni_md_header-darwin"],
 )
 
 filegroup(
     name = "jni_md_header-linux",
-    srcs = ["jdk/include/linux/jni_md.h"],
+    srcs = ["//external:jni_md_header-linux"],
 )
 
 filegroup(
     name = "java",
-    srcs = ["jdk/bin/java"],
+    srcs = ["//external:java"],
 )
 
 BOOTCLASS_JARS = [
@@ -30,17 +30,17 @@
 
 filegroup(
     name = "bootclasspath",
-    srcs = ["jdk/jre/lib/%s" % jar for jar in BOOTCLASS_JARS],
+    srcs = ["//external:bootclasspath"],
 )
 
 filegroup(
     name = "langtools",
-    srcs = ["jdk/lib/tools.jar"],
+    srcs = ["//external:langtools"],
 )
 
 java_import(
     name = "langtools-neverlink",
-    jars = ["jdk/lib/tools.jar"],
+    jars = ["//external:langtools"],
     neverlink = 1,
 )
 
@@ -48,16 +48,10 @@
 filegroup(name = "jdk-null")
 
 filegroup(
-    name = "jdk-default",
-    srcs = glob(["jdk/bin/*"]),
-    path = "jdk",
-)
-
-filegroup(
     name = "jdk",
     srcs = [
-        ":jdk-default",
         ":jdk-null",
+        "//external:jdk-default",
     ],
 )