This is a rollback of both https://github.com/bazelbuild/bazel/commit/a038c818f51b619f795dfefacd62fac75e23f1bd and https://github.com/bazelbuild/bazel/commit/6300c7eb70622b55bbc5f73ec1ffe8116d55c9cd

Automated rollback of commit a038c818f51b619f795dfefacd62fac75e23f1bd.

*** Reason for rollback ***

Breaks many projects on GitHub

*** Original change description ***

Remove all code related to //tools/defaults:* package

After disabling in-memory //tools/defaults:* package by option flag in PackageCacheOptions class, all code can be removed.

RELNOTES:none
PiperOrigin-RevId: 209407232
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
index 35562f2..d5c537e 100644
--- a/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java
@@ -32,6 +32,7 @@
 import com.google.devtools.build.lib.analysis.config.BuildOptions.OptionsDiff;
 import com.google.devtools.build.lib.analysis.config.ComposingRuleTransitionFactory;
 import com.google.devtools.build.lib.analysis.config.ConfigurationFragmentFactory;
+import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
 import com.google.devtools.build.lib.analysis.config.FragmentOptions;
 import com.google.devtools.build.lib.analysis.constraints.ConstraintSemantics;
 import com.google.devtools.build.lib.analysis.skylark.SkylarkModules;
@@ -51,6 +52,7 @@
 import com.google.devtools.build.lib.packages.RuleErrorConsumer;
 import com.google.devtools.build.lib.packages.RuleTransitionFactory;
 import com.google.devtools.build.lib.packages.Target;
+import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
 import com.google.devtools.build.lib.skyframe.ConfiguredTargetAndData;
 import com.google.devtools.build.lib.skylarkbuildapi.Bootstrap;
 import com.google.devtools.build.lib.skylarkinterface.SkylarkInterfaceUtils;
@@ -761,6 +763,21 @@
   }
 
   /**
+   * Returns the defaults package for the default settings.
+   */
+  public String getDefaultsPackageContent(InvocationPolicy invocationPolicy) {
+    return DefaultsPackage.getDefaultsPackageContent(configurationOptions, invocationPolicy);
+  }
+
+  /**
+   * Returns the defaults package for the given options taken from an optionsProvider.
+   */
+  public String getDefaultsPackageContent(OptionsProvider optionsProvider) {
+    return DefaultsPackage.getDefaultsPackageContent(
+        BuildOptions.of(configurationOptions, optionsProvider));
+  }
+
+  /**
    * Creates a BuildOptions class for the given options taken from an optionsProvider.
    */
   public BuildOptions createBuildOptions(OptionsProvider optionsProvider) {
diff --git a/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java b/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java
new file mode 100644
index 0000000..90e74b3
--- /dev/null
+++ b/src/main/java/com/google/devtools/build/lib/analysis/config/DefaultsPackage.java
@@ -0,0 +1,150 @@
+// Copyright 2014 The Bazel Authors. 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.analysis.config;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.ImmutableSet;
+import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.cmdline.LabelSyntaxException;
+import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * A helper class to compute and inject a defaults package into the package cache.
+ *
+ * <p>The <code>//tools/defaults</code> package provides a mechanism let tool locations be specified
+ * over the commandline, without requiring any special support in the rule code. As such, it can be
+ * used in genrule <code>$(location)</code> substitutions.
+ *
+ * <p>It works as follows:
+ *
+ * <ul>
+ *   <li>SomeLanguage.createCompileAction will refer to a host-configured target for the compiler by
+ *       looking for <code>env.getHostPrerequisiteArtifact("$somelanguage_compiler")</code>.
+ *   <li>the attribute <code>$somelanguage_compiler</code> is defined in the {@link RuleDefinition}
+ *       subclass for that language.
+ *   <li>if the attribute cannot be set on the command-line, its value may be a normal label.
+ *   <li>if the attribute can be set on the command-line, its value will be <code>
+ *       //tools/defaults:somelanguage_compiler</code>.
+ *   <li>in the latter case, the {@link BuildConfiguration.Fragment} subclass will define the option
+ *       (with an existing target, eg. <code>//third_party/somelanguage:compiler</code>), and return
+ *       the name in its implementation of {@link FragmentOptions#getDefaultsLabels}.
+ *   <li>On startup, the rule is wired up with <code>//tools/defaults:somelanguage_compiler</code>.
+ *   <li>On starting a build, the <code>//tools/defaults</code> package is synthesized, using the
+ *       values as specified on the command-line. The contents of <code>tools/defaults/BUILD</code>
+ *       is ignored.
+ *   <li>Hence, changes in the command line values for tools are now handled exactly as if they were
+ *       changes in a BUILD file.
+ *   <li>The file <code>tools/defaults/BUILD</code> must exist, so we create a package in that
+ *       location.
+ *   <li>The code in {@link DefaultsPackage} can dump the synthesized package as a BUILD file, so
+ *       external tooling does not need to understand the intricacies of handling command-line
+ *       options.
+ * </ul>
+ *
+ * <p>For built-in rules (as opposed to genrules), late-bound labels provide an alternative method
+ * of depending on command-line values. These work by declaring attribute default values to be
+ * {@link LateBoundDefault} instances, whose <code>resolve(Rule rule, AttributeMap attributes,
+ * FragmentT configuration)</code> method will have access to a {@link BuildConfiguration.Fragment},
+ * which in turn may depend on command line flag values.
+ */
+public final class DefaultsPackage {
+
+  // The template contents are broken into lines such that the resulting file has no more than 80
+  // characters per line.
+  private static final String HEADER = ""
+      + "# DO NOT EDIT THIS FILE!\n"
+      + "#\n"
+      + "# Bazel does not read this file. Instead, it internally replaces the targets in\n"
+      + "# this package with the correct packages as given on the command line.\n"
+      + "#\n"
+      + "# If these options are not given on the command line, Bazel will use the exact\n"
+      + "# same targets as given here."
+      + "\n"
+      + "package(default_visibility = ['//visibility:public'])\n";
+
+  /**
+   * The map from entries to their values.
+   */
+  private ImmutableMap<String, ImmutableSet<Label>> values;
+
+  private DefaultsPackage(BuildOptions buildOptions) {
+    values = buildOptions.getDefaultsLabels();
+  }
+
+  private String labelsToString(Set<Label> labels) {
+    StringBuilder result = new StringBuilder();
+    for (Label label : labels) {
+      if (result.length() != 0) {
+        result.append(", ");
+      }
+      result.append("'").append(label).append("'");
+    }
+    return result.toString();
+  }
+
+  /**
+   * Returns a string of the defaults package with the given settings.
+   */
+  private String getContent() {
+    Preconditions.checkState(!values.isEmpty());
+    StringBuilder result = new StringBuilder(HEADER);
+    for (Map.Entry<String, ImmutableSet<Label>> entry : values.entrySet()) {
+      result
+          .append("filegroup(name = '")
+          .append(entry.getKey().toLowerCase(Locale.US)).append("',\n")
+          .append("          srcs = [")
+          .append(labelsToString(entry.getValue())).append("])\n");
+    }
+
+    return result.toString();
+  }
+
+  /**
+   * Returns the defaults package for the default settings.
+   */
+  public static String getDefaultsPackageContent(
+      Iterable<Class<? extends FragmentOptions>> options, InvocationPolicy invocationPolicy) {
+    return getDefaultsPackageContent(BuildOptions.createDefaults(options, invocationPolicy));
+  }
+
+  /**
+   * Returns the defaults package for the given options.
+   */
+  public static String getDefaultsPackageContent(BuildOptions buildOptions) {
+    return new DefaultsPackage(buildOptions).getContent();
+  }
+
+  public static void parseAndAdd(Set<Label> labels, String optionalLabel) {
+    if (optionalLabel != null) {
+      Label label = parseOptionalLabel(optionalLabel);
+      if (label != null) {
+        labels.add(label);
+      }
+    }
+  }
+
+  public static Label parseOptionalLabel(String value) {
+    try {
+      return Label.parseAbsolute(value, ImmutableMap.of());
+    } catch (LabelSyntaxException e) {
+      // We ignore this exception here - it will cause an error message at a later time.
+      return null;
+    }
+  }
+}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java b/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
index 43fe429..60fe650 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/commands/FetchCommand.java
@@ -29,6 +29,7 @@
 import com.google.devtools.build.lib.query2.engine.ThreadSafeOutputFormatterCallback;
 import com.google.devtools.build.lib.runtime.BlazeCommand;
 import com.google.devtools.build.lib.runtime.BlazeCommandResult;
+import com.google.devtools.build.lib.runtime.BlazeRuntime;
 import com.google.devtools.build.lib.runtime.Command;
 import com.google.devtools.build.lib.runtime.CommandEnvironment;
 import com.google.devtools.build.lib.runtime.KeepGoingOption;
@@ -61,6 +62,7 @@
 
   @Override
   public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult options) {
+    BlazeRuntime runtime = env.getRuntime();
     if (options.getResidue().isEmpty()) {
       env.getReporter().handle(Event.error(String.format(
           "missing fetch expression. Type '%s help fetch' for syntax and help",
@@ -69,7 +71,7 @@
     }
 
     try {
-      env.setupPackageCache(options);
+      env.setupPackageCache(options, runtime.getDefaultsPackageContent());
     } catch (InterruptedException e) {
       env.getReporter().handle(Event.error("fetch interrupted"));
       return BlazeCommandResult.exitCode(ExitCode.INTERRUPTED);
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java b/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
index 6a0d558..1f4cf12 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/commands/SyncCommand.java
@@ -65,7 +65,7 @@
   @Override
   public BlazeCommandResult exec(CommandEnvironment env, OptionsParsingResult options) {
     try {
-      env.setupPackageCache(options);
+      env.setupPackageCache(options, env.getRuntime().getDefaultsPackageContent());
       SkyframeExecutor skyframeExecutor = env.getSkyframeExecutor();
       skyframeExecutor.injectExtraPrecomputedValues(
           ImmutableList.of(
diff --git a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
index a45abf3..92fa1b7 100644
--- a/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
+++ b/src/main/java/com/google/devtools/build/lib/buildtool/BuildTool.java
@@ -24,6 +24,7 @@
 import com.google.devtools.build.lib.analysis.BuildView;
 import com.google.devtools.build.lib.analysis.ViewCreationFailedException;
 import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
 import com.google.devtools.build.lib.analysis.config.InvalidConfigurationException;
 import com.google.devtools.build.lib.buildeventstream.BuildEventId;
 import com.google.devtools.build.lib.buildtool.PostAnalysisQueryBuildTool.PostAnalysisQueryCommandLineException;
@@ -109,7 +110,7 @@
     }
     // Sync the package manager before sending the BuildStartingEvent in runLoadingPhase()
     try (SilentCloseable c = Profiler.instance().profile("setupPackageCache")) {
-      env.setupPackageCache(request);
+      env.setupPackageCache(request, DefaultsPackage.getDefaultsPackageContent(buildOptions));
     }
 
     ExecutionTool executionTool = null;
diff --git a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
index 423a4a1..43d9846 100644
--- a/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
+++ b/src/main/java/com/google/devtools/build/lib/cmdline/Label.java
@@ -70,6 +70,8 @@
       ImmutableSet.of(
           // Used for select
           PathFragment.create("conditions"),
+          // dependencies that are a function of the configuration
+          PathFragment.create("tools/defaults"),
           // Visibility is labels aren't actually targets
           PathFragment.create("visibility"),
           // There is only one //external package
diff --git a/src/main/java/com/google/devtools/build/lib/pkgcache/PackageCacheOptions.java b/src/main/java/com/google/devtools/build/lib/pkgcache/PackageCacheOptions.java
index d0955e6..dc4aa71 100644
--- a/src/main/java/com/google/devtools/build/lib/pkgcache/PackageCacheOptions.java
+++ b/src/main/java/com/google/devtools/build/lib/pkgcache/PackageCacheOptions.java
@@ -27,6 +27,7 @@
 import com.google.devtools.common.options.Option;
 import com.google.devtools.common.options.OptionDocumentationCategory;
 import com.google.devtools.common.options.OptionEffectTag;
+import com.google.devtools.common.options.OptionMetadataTag;
 import com.google.devtools.common.options.OptionsBase;
 import com.google.devtools.common.options.OptionsParsingException;
 import java.util.List;
@@ -150,6 +151,17 @@
   )
   public boolean checkOutputFiles;
 
+  @Option(
+      name = "experimental_enable_tools_defaults_package",
+      defaultValue = "true",
+      documentationCategory = OptionDocumentationCategory.UNDOCUMENTED,
+      effectTags = {OptionEffectTag.AFFECTS_OUTPUTS},
+      metadataTags = {OptionMetadataTag.EXPERIMENTAL},
+      help =
+          "If true, Blaze constructs an in-memory //tools/defaults package based on the command"
+              + " line options. If false, //tools/defaults is resolved as a regular package.")
+  public boolean experimentalInMemoryToolsDefaultsPackage;
+
   /**
    * A converter from strings containing comma-separated names of packages to lists of strings.
    */
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
index d2d7146..3a7e9b5 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/BlazeRuntime.java
@@ -153,6 +153,7 @@
 
   private final ProjectFile.Provider projectFileProvider;
   @Nullable private final InvocationPolicy moduleInvocationPolicy;
+  private final String defaultsPackageContent;
   private final SubscriberExceptionHandler eventBusExceptionHandler;
   private final String productName;
   private final BuildEventArtifactUploaderFactoryMap buildEventArtifactUploaderFactoryMap;
@@ -202,6 +203,8 @@
     this.queryOutputFormatters = queryOutputFormatters;
     this.eventBusExceptionHandler = eventBusExceptionHandler;
 
+    this.defaultsPackageContent =
+        ruleClassProvider.getDefaultsPackageContent(getModuleInvocationPolicy());
     CommandNameCache.CommandNameCacheInstance.INSTANCE.setCommandNameCache(
         new CommandNameCacheImpl(getCommandMap()));
     this.productName = productName;
@@ -584,7 +587,25 @@
     }
   }
 
-  /** Creates a BuildOptions class for the given options taken from an optionsProvider. */
+  /**
+   * Returns the defaults package for the default settings. Should only be called by commands that
+   * do <i>not</i> process {@link BuildOptions}, since build options can alter the contents of the
+   * defaults package, which will not be reflected here.
+   */
+  public String getDefaultsPackageContent() {
+    return defaultsPackageContent;
+  }
+
+  /**
+   * Returns the defaults package for the given options taken from an optionsProvider.
+   */
+  public String getDefaultsPackageContent(OptionsProvider optionsProvider) {
+    return ruleClassProvider.getDefaultsPackageContent(optionsProvider);
+  }
+
+  /**
+   * Creates a BuildOptions class for the given options taken from an optionsProvider.
+   */
   public BuildOptions createBuildOptions(OptionsProvider optionsProvider) {
     return ruleClassProvider.createBuildOptions(optionsProvider);
   }
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
index 8d5d7c6..a5e948b 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/CommandEnvironment.java
@@ -23,6 +23,7 @@
 import com.google.devtools.build.lib.analysis.BlazeDirectories;
 import com.google.devtools.build.lib.analysis.SkyframePackageRootResolver;
 import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
 import com.google.devtools.build.lib.cmdline.Label;
 import com.google.devtools.build.lib.events.Reporter;
 import com.google.devtools.build.lib.packages.NoSuchThingException;
@@ -506,9 +507,15 @@
     }
   }
 
-  /** Initializes the package cache using the given options, and syncs the package cache. */
-  public void setupPackageCache(OptionsProvider options)
-      throws InterruptedException, AbruptExitException {
+  /**
+   * Initializes the package cache using the given options, and syncs the package cache. Also
+   * injects a defaults package and the skylark semantics using the options for the {@link
+   * BuildConfiguration}.
+   *
+   * @see DefaultsPackage
+   */
+  public void setupPackageCache(OptionsProvider options,
+      String defaultsPackageContents) throws InterruptedException, AbruptExitException {
     getSkyframeExecutor()
         .sync(
             reporter,
@@ -516,6 +523,7 @@
             options.getOptions(SkylarkSemanticsOptions.class),
             getOutputBase(),
             getWorkingDirectory(),
+            defaultsPackageContents,
             getCommandId(),
             clientEnv,
             timestampGranularityMonitor,
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
index 6a13f20..5e65c97 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoCommand.java
@@ -127,7 +127,8 @@
                 // In order to be able to answer configuration-specific queries, we need to set up
                 // the package path. Since info inherits all the build options, all the necessary
                 // information is available here.
-                env.setupPackageCache(optionsParsingResult);
+                env.setupPackageCache(
+                    optionsParsingResult, runtime.getDefaultsPackageContent(optionsParsingResult));
                 env.getSkyframeExecutor()
                     .setConfigurationFragmentFactories(runtime.getConfigurationFragmentFactories());
                 // TODO(bazel-team): What if there are multiple configurations? [multi-config]
@@ -231,6 +232,7 @@
             new InfoItem.JavaVirtualMachineInfoItem(),
             new InfoItem.JavaHomeInfoItem(),
             new InfoItem.CharacterEncodingInfoItem(),
+            new InfoItem.DefaultsPackageInfoItem(),
             new InfoItem.BuildLanguageInfoItem(),
             new InfoItem.DefaultPackagePathInfoItem(commandOptions));
     ImmutableMap.Builder<String, InfoItem> result = new ImmutableMap.Builder<>();
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
index c500397..b209a5d0 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/InfoItem.java
@@ -550,6 +550,28 @@
     }
   }
 
+  /**
+   * Info item for the default package. It is deprecated, it still works, when
+   * explicitly requested, but are not shown by default. It prints multi-line messages and thus
+   * don't play well with grep. We don't print them unless explicitly requested.
+   * @deprecated
+   */
+  @Deprecated
+  public static final class DefaultsPackageInfoItem extends InfoItem {
+    public DefaultsPackageInfoItem() {
+      super("defaults-package",
+          "Default packages used as implicit dependencies",
+          true);
+    }
+
+    @Override
+    public byte[] get(Supplier<BuildConfiguration> configurationSupplier, CommandEnvironment env)
+        throws AbruptExitException {
+      checkNotNull(env);
+      return print(env.getRuntime().getDefaultsPackageContent());
+    }
+  }
+
   private static AllowedRuleClassInfo getAllowedRuleClasses(
       Collection<RuleClass> ruleClasses, Attribute attr) {
     AllowedRuleClassInfo.Builder info = AllowedRuleClassInfo.newBuilder();
diff --git a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
index ba6ac96..659d6c5 100644
--- a/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
+++ b/src/main/java/com/google/devtools/build/lib/runtime/commands/QueryCommand.java
@@ -94,7 +94,7 @@
     QueryOptions queryOptions = options.getOptions(QueryOptions.class);
 
     try {
-      env.setupPackageCache(options);
+      env.setupPackageCache(options, runtime.getDefaultsPackageContent());
     } catch (InterruptedException e) {
       env.getReporter().handle(Event.error("query interrupted"));
       return BlazeCommandResult.exitCode(ExitCode.INTERRUPTED);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
index 88825cc..405ef5e 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageFunction.java
@@ -110,6 +110,8 @@
 
   private final IncrementalityIntent incrementalityIntent;
 
+  static final PathFragment DEFAULTS_PACKAGE_NAME = PathFragment.create("tools/defaults");
+
   public PackageFunction(
       PackageFactory packageFactory,
       CachingPackageLocator pkgLocator,
@@ -436,9 +438,16 @@
     Path buildFilePath = buildFileRootedPath.asPath();
     String replacementContents = null;
 
-    buildFileValue = getBuildFileValue(env, buildFileRootedPath);
-    if (buildFileValue == null) {
-      return null;
+    if (isDefaultsPackage(packageId) && PrecomputedValue.isInMemoryToolsDefaults(env)) {
+      replacementContents = PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.get(env);
+      if (replacementContents == null) {
+        return null;
+      }
+    } else {
+      buildFileValue = getBuildFileValue(env, buildFileRootedPath);
+      if (buildFileValue == null) {
+        return null;
+      }
     }
 
     RuleVisibility defaultVisibility = PrecomputedValue.DEFAULT_VISIBILITY.get(env);
@@ -1330,4 +1339,9 @@
       this.fileDependencies = fileDependencies;
     }
   }
+
+  public static boolean isDefaultsPackage(PackageIdentifier packageIdentifier) {
+    return packageIdentifier.getRepository().isMain()
+        && packageIdentifier.getPackageFragment().equals(DEFAULTS_PACKAGE_NAME);
+  }
 }
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
index a291409..b3496b0 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PackageLookupFunction.java
@@ -72,6 +72,11 @@
 
     PackageIdentifier packageKey = (PackageIdentifier) skyKey.argument();
 
+    if (PackageFunction.isDefaultsPackage(packageKey)
+        && PrecomputedValue.isInMemoryToolsDefaults(env)) {
+      return PackageLookupValue.success(pkgLocator.getPathEntries().get(0), BuildFileName.BUILD);
+    }
+
     if (!packageKey.getRepository().isMain()) {
       return computeExternalPackageLookupValue(skyKey, env, packageKey);
     } else if (packageKey.equals(Label.EXTERNAL_PACKAGE_IDENTIFIER)) {
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java
index 826413a..937e59c 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/PrecomputedValue.java
@@ -79,6 +79,20 @@
     return new Injected(precomputed, Suppliers.ofInstance(value));
   }
 
+  public static final Precomputed<Boolean> ENABLE_DEFAULTS_PACKAGE =
+      new Precomputed<>(Key.create("enable_default_pkg"));
+
+  // TODO(dbabkin): better to move this code to PrecomputedValueUtils.
+  // It will gone soon after removing tools/defaults
+  public static boolean isInMemoryToolsDefaults(SkyFunction.Environment env)
+      throws InterruptedException {
+    Boolean enableDefaultsPackage = PrecomputedValue.ENABLE_DEFAULTS_PACKAGE.get(env);
+    return Preconditions.checkNotNull(enableDefaultsPackage);
+  }
+
+  public static final Precomputed<String> DEFAULTS_PACKAGE_CONTENTS =
+      new Precomputed<>(Key.create("default_pkg"));
+
   public static final Precomputed<RuleVisibility> DEFAULT_VISIBILITY =
       new Precomputed<>(Key.create("default_visibility"));
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
index 22968b3..82ef528 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SequencedSkyframeExecutor.java
@@ -284,6 +284,7 @@
       SkylarkSemanticsOptions skylarkSemanticsOptions,
       Path outputBase,
       Path workingDirectory,
+      String defaultsPackageContents,
       UUID commandId,
       Map<String, String> clientEnv,
       TimestampGranularityMonitor tsgm,
@@ -295,16 +296,8 @@
       resetEvaluator();
       evaluatorNeedsReset = false;
     }
-    super.sync(
-        eventHandler,
-        packageCacheOptions,
-        skylarkSemanticsOptions,
-        outputBase,
-        workingDirectory,
-        commandId,
-        clientEnv,
-        tsgm,
-        options);
+    super.sync(eventHandler, packageCacheOptions, skylarkSemanticsOptions, outputBase,
+        workingDirectory, defaultsPackageContents, commandId, clientEnv, tsgm, options);
     handleDiffs(eventHandler, packageCacheOptions.checkOutputFiles, options);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
index 6fc5730..b06815b 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java
@@ -852,6 +852,14 @@
   public abstract void clearAnalysisCache(
       Collection<ConfiguredTarget> topLevelTargets, Collection<AspectValue> topLevelAspects);
 
+  /**
+   * Injects the contents of the computed tools/defaults package.
+   */
+  @VisibleForTesting
+  public void setupDefaultPackage(String defaultsPackageContents) {
+    PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.set(injectable(), defaultsPackageContents);
+  }
+
   private WorkspaceStatusAction makeWorkspaceStatusAction(String workspaceName) {
     return workspaceStatusActionFactory.createWorkspaceStatusAction(
         artifactFactory.get(), WorkspaceStatusValue.BUILD_INFO_KEY, workspaceName);
@@ -1146,6 +1154,7 @@
       PathPackageLocator pkgLocator,
       PackageCacheOptions packageCacheOptions,
       SkylarkSemanticsOptions skylarkSemanticsOptions,
+      String defaultsPackageContents,
       UUID commandId,
       Map<String, String> clientEnv,
       TimestampGranularityMonitor tsgm) {
@@ -1159,6 +1168,14 @@
     setShowLoadingProgress(packageCacheOptions.showLoadingProgress);
     setDefaultVisibility(packageCacheOptions.defaultVisibility);
     setSkylarkSemantics(skylarkSemanticsOptions.toSkylarkSemantics());
+    if (packageCacheOptions.experimentalInMemoryToolsDefaultsPackage) {
+      setupDefaultPackage(defaultsPackageContents);
+      PrecomputedValue.ENABLE_DEFAULTS_PACKAGE.set(injectable(), true);
+    } else {
+      setupDefaultPackage("# //tools/defaults in-memory package is not enabled.");
+      PrecomputedValue.ENABLE_DEFAULTS_PACKAGE.set(injectable(), false);
+    }
+
     setPackageLocator(pkgLocator);
 
     syscalls.set(getPerBuildSyscallCache(packageCacheOptions.globbingThreads));
@@ -2115,6 +2132,7 @@
       SkylarkSemanticsOptions skylarkSemanticsOptions,
       Path outputBase,
       Path workingDirectory,
+      String defaultsPackageContents,
       UUID commandId,
       Map<String, String> clientEnv,
       TimestampGranularityMonitor tsgm,
@@ -2127,6 +2145,7 @@
         skylarkSemanticsOptions,
         outputBase,
         workingDirectory,
+        defaultsPackageContents,
         commandId,
         clientEnv,
         tsgm);
@@ -2138,6 +2157,7 @@
       SkylarkSemanticsOptions skylarkSemanticsOptions,
       Path outputBase,
       Path workingDirectory,
+      String defaultsPackageContents,
       UUID commandId,
       Map<String, String> clientEnv,
       TimestampGranularityMonitor tsgm)
@@ -2151,6 +2171,7 @@
             workingDirectory),
         packageCacheOptions,
         skylarkSemanticsOptions,
+        defaultsPackageContents,
         commandId,
         clientEnv,
         tsgm);
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
index 1e05dd04..41ad785 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/AbstractPackageLoader.java
@@ -142,6 +142,7 @@
     protected Reporter reporter = new Reporter(new EventBus());
     protected Map<SkyFunctionName, SkyFunction> extraSkyFunctions = new HashMap<>();
     List<PrecomputedValue.Injected> extraPrecomputedValues = new ArrayList<>();
+    String defaultsPackageContents = getDefaultDefaultPackageContents();
     int legacyGlobbingThreads = 1;
     int skyframeThreads = 1;
 
@@ -230,6 +231,8 @@
     protected abstract PackageLoader buildImpl();
 
     protected abstract ConfiguredRuleClassProvider getDefaultRuleClassProvider();
+
+    protected abstract String getDefaultDefaultPackageContents();
   }
 
   AbstractPackageLoader(Builder builder) {
@@ -248,6 +251,7 @@
         makePreinjectedDiff(
             skylarkSemantics,
             builder.pkgLocator,
+            builder.defaultsPackageContents,
             ImmutableList.copyOf(builder.extraPrecomputedValues));
     pkgFactory =
         new PackageFactory(
@@ -261,6 +265,7 @@
   private static ImmutableDiff makePreinjectedDiff(
       SkylarkSemantics skylarkSemantics,
       PathPackageLocator pkgLocator,
+      String defaultsPackageContents,
       ImmutableList<PrecomputedValue.Injected> extraPrecomputedValues) {
     final Map<SkyKey, SkyValue> valuesToInject = new HashMap<>();
     Injectable injectable =
@@ -281,6 +286,8 @@
     PrecomputedValue.PATH_PACKAGE_LOCATOR.set(injectable, pkgLocator);
     PrecomputedValue.DEFAULT_VISIBILITY.set(injectable, ConstantRuleVisibility.PRIVATE);
     PrecomputedValue.SKYLARK_SEMANTICS.set(injectable, skylarkSemantics);
+    PrecomputedValue.DEFAULTS_PACKAGE_CONTENTS.set(injectable, defaultsPackageContents);
+    PrecomputedValue.ENABLE_DEFAULTS_PACKAGE.set(injectable, true);
     return new ImmutableDiff(ImmutableList.of(), valuesToInject);
   }
 
diff --git a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java
index d299418..b0d1aab 100644
--- a/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java
+++ b/src/main/java/com/google/devtools/build/lib/skyframe/packages/BazelPackageLoader.java
@@ -29,6 +29,7 @@
 import com.google.devtools.build.lib.rules.repository.RepositoryDelegatorFunction;
 import com.google.devtools.build.lib.rules.repository.RepositoryFunction;
 import com.google.devtools.build.lib.rules.repository.RepositoryLoaderFunction;
+import com.google.devtools.build.lib.runtime.proto.InvocationPolicyOuterClass.InvocationPolicy;
 import com.google.devtools.build.lib.skyframe.ActionEnvironmentFunction;
 import com.google.devtools.build.lib.skyframe.BazelSkyframeExecutorConstants;
 import com.google.devtools.build.lib.skyframe.ClientEnvironmentFunction;
@@ -130,6 +131,12 @@
       return DEFAULT_RULE_CLASS_PROVIDER;
     }
 
+    @Override
+    protected String getDefaultDefaultPackageContents() {
+      return DEFAULT_RULE_CLASS_PROVIDER.getDefaultsPackageContent(
+          InvocationPolicy.getDefaultInstance());
+    }
+
     Builder setFetchForTesting() {
       this.isFetch.set(true);
       return this;
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/EnableDefaultsPackageOptionTest.java b/src/test/java/com/google/devtools/build/lib/analysis/EnableDefaultsPackageOptionTest.java
new file mode 100644
index 0000000..92d149a
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/analysis/EnableDefaultsPackageOptionTest.java
@@ -0,0 +1,77 @@
+// Copyright 2018 The Bazel Authors. 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.analysis;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.devtools.build.lib.analysis.util.BuildViewTestCase;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for experimental_enable_tools_defaults_package flag. TODO(dbabkin): remove after
+ * //tools/defaults package gone.
+ */
+@RunWith(JUnit4.class)
+public class EnableDefaultsPackageOptionTest extends BuildViewTestCase {
+
+  @Test
+  public void testEnableDefaultsPackageOptionWorks() throws Exception {
+
+    setPackageCacheOptions("--experimental_enable_tools_defaults_package=true");
+
+    ConfiguredTarget target = getConfiguredTarget("//tools/defaults:jdk");
+
+    assertThat(target.getLabel().toString()).isEqualTo("//tools/defaults:jdk");
+  }
+
+  @Test
+  public void testDisabledDefaultsPackageOptionWorks() throws Exception {
+
+    scratch.file(
+        "a/BUILD",
+        "filegroup(",
+        "  name = 'my_filegroup',",
+        "  srcs = ['//tools/defaults:jdk'],",
+        ")");
+
+    reporter.removeHandler(failFastHandler);
+    setPackageCacheOptions("--experimental_enable_tools_defaults_package=false");
+    ConfiguredTarget target = getConfiguredTarget("//a:my_filegroup");
+
+    assertThat(target).isNull();
+    assertContainsEvent(
+        "no such package 'tools/defaults': "
+            + "BUILD file not found on package path and referenced by '//a:my_filegroup'");
+  }
+
+  @Test
+  public void testFlipFlagOnFly() throws Exception {
+
+    setPackageCacheOptions("--experimental_enable_tools_defaults_package=false");
+    ConfiguredTarget defaultsJDKtarget = getConfiguredTarget("//tools/defaults:jdk");
+    assertThat(defaultsJDKtarget).isNull();
+
+    setPackageCacheOptions("--experimental_enable_tools_defaults_package=true");
+    defaultsJDKtarget = getConfiguredTarget("//tools/defaults:jdk");
+    assertThat(defaultsJDKtarget).isNotNull();
+    assertThat(defaultsJDKtarget.getLabel().toString()).isEqualTo("//tools/defaults:jdk");
+
+    setPackageCacheOptions("--experimental_enable_tools_defaults_package=false");
+    defaultsJDKtarget = getConfiguredTarget("//tools/defaults:jdk");
+    assertThat(defaultsJDKtarget).isNull();
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
index c834494..3aefeff 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisMock.java
@@ -79,6 +79,12 @@
     return new InvocationPolicyEnforcer(TestConstants.TEST_INVOCATION_POLICY);
   }
 
+  @Override
+  public String getDefaultsPackageContent() {
+    return createRuleClassProvider()
+        .getDefaultsPackageContent(getInvocationPolicyEnforcer().getInvocationPolicy());
+  }
+
   /**
    * This is called from test setup to create the mock directory layout needed to create the
    * configuration.
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
index 17d0723..eb4b9cf 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/AnalysisTestCase.java
@@ -210,6 +210,8 @@
         pkgLocator,
         packageCacheOptions,
         Options.getDefaults(SkylarkSemanticsOptions.class),
+        ruleClassProvider.getDefaultsPackageContent(
+            analysisMock.getInvocationPolicyEnforcer().getInvocationPolicy()),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
@@ -338,6 +340,8 @@
         pathPackageLocator,
         packageCacheOptions,
         skylarkSemanticsOptions,
+        ruleClassProvider.getDefaultsPackageContent(
+            analysisMock.getInvocationPolicyEnforcer().getInvocationPolicy()),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
index 71a6a8c..9a18168 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/BuildViewTestCase.java
@@ -283,6 +283,7 @@
             BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
         packageCacheOptions,
         skylarkSemanticsOptions,
+        "",
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         tsgm);
@@ -401,6 +402,7 @@
         pkgLocator,
         packageCacheOptions,
         skylarkSemanticsOptions,
+        ruleClassProvider.getDefaultsPackageContent(optionsParser),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         tsgm);
@@ -509,10 +511,11 @@
   }
 
   /**
-   * Creates BuildView using current hostConfig/targetConfig values. Ensures that hostConfig is
-   * either identical to the targetConfig or has 'host' short name.
+   * Creates BuildView using current hostConfig/targetConfig values.
+   * Ensures that hostConfig is either identical to the targetConfig or has
+   * 'host' short name.
    */
-  protected final void createBuildView() {
+  protected final void createBuildView() throws Exception {
     Preconditions.checkNotNull(masterConfig);
     Preconditions.checkState(getHostConfiguration().equals(getTargetConfiguration())
         || getHostConfiguration().isHostConfiguration(),
@@ -520,6 +523,8 @@
         + "and does not match target configuration %s",
         getHostConfiguration(), getTargetConfiguration());
 
+    String defaultsPackageContent = ruleClassProvider.getDefaultsPackageContent(optionsParser);
+    skyframeExecutor.setupDefaultPackage(defaultsPackageContent);
     skyframeExecutor.handleConfiguredTargetChange();
 
     view = new BuildViewForTesting(directories, ruleClassProvider, skyframeExecutor, null);
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
index 0567ac6..b927391 100644
--- a/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/ConfigurationTestCase.java
@@ -148,6 +148,8 @@
         pkgLocator,
         packageCacheOptions,
         Options.getDefaults(SkylarkSemanticsOptions.class),
+        ruleClassProvider.getDefaultsPackageContent(
+            analysisMock.getInvocationPolicyEnforcer().getInvocationPolicy()),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/analysis/util/DefaultsPackageUtil.java b/src/test/java/com/google/devtools/build/lib/analysis/util/DefaultsPackageUtil.java
new file mode 100644
index 0000000..38bb434
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/analysis/util/DefaultsPackageUtil.java
@@ -0,0 +1,45 @@
+// Copyright 2015 The Bazel Authors. 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.analysis.util;
+
+import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
+import com.google.devtools.build.lib.analysis.config.BuildOptions;
+import com.google.devtools.build.lib.analysis.config.DefaultsPackage;
+import com.google.devtools.build.lib.analysis.config.FragmentOptions;
+import com.google.devtools.common.options.InvocationPolicyEnforcer;
+import com.google.devtools.common.options.OptionsBase;
+import com.google.devtools.common.options.OptionsParser;
+import com.google.devtools.common.options.OptionsParsingException;
+
+/**
+ * Helper class for testing {@link DefaultsPackage}.
+ */
+public class DefaultsPackageUtil {
+
+  public static String getDefaultsPackageForOptions(Class<? extends FragmentOptions> optionsClass,
+      String... options) throws OptionsParsingException {
+    OptionsParser parser = OptionsParser.newOptionsParser(
+        ImmutableList.<Class<? extends OptionsBase>>of(
+            BuildConfiguration.Options.class, optionsClass));
+    parser.parse(options);
+
+    InvocationPolicyEnforcer enforcer = AnalysisMock.get().getInvocationPolicyEnforcer();
+    enforcer.enforce(parser);
+
+    return DefaultsPackage.getDefaultsPackageContent(BuildOptions.of(
+        ImmutableList.<Class<? extends FragmentOptions>>of(
+            BuildConfiguration.Options.class, optionsClass), parser));
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/LoadingMock.java b/src/test/java/com/google/devtools/build/lib/packages/util/LoadingMock.java
index bba1eb1..d50b43d 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/LoadingMock.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/LoadingMock.java
@@ -43,4 +43,13 @@
   public InvocationPolicyEnforcer getInvocationPolicyEnforcer() {
     return new InvocationPolicyEnforcer(TestConstants.TEST_INVOCATION_POLICY);
   }
+
+  /**
+   * Returns the defaults package for the default settings using {@link #createRuleClassProvider}
+   * and applying {@link #getInvocationPolicyEnforcer}.
+   */
+  public String getDefaultsPackageContent() {
+    return createRuleClassProvider()
+        .getDefaultsPackageContent(getInvocationPolicyEnforcer().getInvocationPolicy());
+  }
 }
diff --git a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
index 337bb2d..85e4864 100644
--- a/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/packages/util/PackageLoadingTestCase.java
@@ -137,7 +137,7 @@
     return ImmutableList.<EnvironmentExtension>of();
   }
 
-  protected void setUpSkyframe(RuleVisibility defaultVisibility) {
+  protected void setUpSkyframe(RuleVisibility defaultVisibility, String defaultsPackageContents) {
     PackageCacheOptions packageCacheOptions = Options.getDefaults(PackageCacheOptions.class);
     packageCacheOptions.defaultVisibility = defaultVisibility;
     packageCacheOptions.showLoadingProgress = true;
@@ -149,6 +149,7 @@
             BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
         packageCacheOptions,
         Options.getDefaults(SkylarkSemanticsOptions.class),
+        defaultsPackageContents,
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
@@ -170,6 +171,7 @@
         pkgLocator,
         packageCacheOptions,
         skylarkSemanticsOptions,
+        loadingMock.getDefaultsPackageContent(),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/AbstractTargetPatternEvaluatorTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/AbstractTargetPatternEvaluatorTest.java
index bf8acad..1bc7460 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/AbstractTargetPatternEvaluatorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/AbstractTargetPatternEvaluatorTest.java
@@ -101,7 +101,7 @@
 
   @Before
   public final void initializeParser() throws Exception {
-    setUpSkyframe(ConstantRuleVisibility.PRIVATE);
+    setUpSkyframe(ConstantRuleVisibility.PRIVATE, loadingMock.getDefaultsPackageContent());
     parser = skyframeExecutor.newTargetPatternEvaluator();
     parsingListener = new RecordingParsingListener(reporter);
   }
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/BuildFileModificationTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/BuildFileModificationTest.java
index d8b59ee..d25e255 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/BuildFileModificationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/BuildFileModificationTest.java
@@ -123,6 +123,7 @@
         pkgLocator,
         packageCacheOptions,
         skylarkSemanticsOptions,
+        analysisMock.getDefaultsPackageContent(),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(clock));
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
index 8d56fed..de8e71b 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/IOExceptionsTest.java
@@ -62,7 +62,7 @@
 
   @Before
   public final void initializeVisitor() throws Exception {
-    setUpSkyframe(ConstantRuleVisibility.PRIVATE);
+    setUpSkyframe(ConstantRuleVisibility.PRIVATE, loadingMock.getDefaultsPackageContent());
   }
 
   private boolean visitTransitively(Label label) throws InterruptedException {
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
index 72445ef..bca7677 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/IncrementalLoadingTest.java
@@ -503,6 +503,7 @@
               BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
           packageCacheOptions,
           Options.getDefaults(SkylarkSemanticsOptions.class),
+          "",
           UUID.randomUUID(),
           ImmutableMap.<String, String>of(),
           new TimestampGranularityMonitor(BlazeClock.instance()));
@@ -593,6 +594,7 @@
               BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
           packageCacheOptions,
           Options.getDefaults(SkylarkSemanticsOptions.class),
+          "",
           UUID.randomUUID(),
           ImmutableMap.<String, String>of(),
           new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
index 6a7a944..29ff98f 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/LoadingPhaseRunnerTest.java
@@ -800,6 +800,7 @@
           pkgLocator,
           packageCacheOptions,
           Options.getDefaults(SkylarkSemanticsOptions.class),
+          analysisMock.getDefaultsPackageContent(),
           UUID.randomUUID(),
           ImmutableMap.<String, String>of(),
           new TimestampGranularityMonitor(clock));
@@ -872,6 +873,8 @@
     }
 
     private void sync() throws InterruptedException {
+      String pkgContents = analysisMock.getDefaultsPackageContent();
+      skyframeExecutor.setupDefaultPackage(pkgContents);
       clock.advanceMillis(1);
       ModifiedFileSet.Builder builder = ModifiedFileSet.builder();
       for (Path path : changes) {
diff --git a/src/test/java/com/google/devtools/build/lib/pkgcache/PackageCacheTest.java b/src/test/java/com/google/devtools/build/lib/pkgcache/PackageCacheTest.java
index 1408a94..97c4f2e2 100644
--- a/src/test/java/com/google/devtools/build/lib/pkgcache/PackageCacheTest.java
+++ b/src/test/java/com/google/devtools/build/lib/pkgcache/PackageCacheTest.java
@@ -136,6 +136,7 @@
         pkgLocator,
         packageCacheOptions,
         skylarkSemanticsOptions,
+        analysisMock.getDefaultsPackageContent(),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/rules/cpp/CppOptionsTest.java b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppOptionsTest.java
new file mode 100644
index 0000000..c34e0cf
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/rules/cpp/CppOptionsTest.java
@@ -0,0 +1,52 @@
+// Copyright 2015 The Bazel Authors. 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.rules.cpp;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.devtools.build.lib.analysis.util.DefaultsPackageUtil;
+import com.google.devtools.build.lib.testutil.TestConstants;
+import com.google.devtools.common.options.OptionsParsingException;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests {@link CppOptions}.
+ */
+@RunWith(JUnit4.class)
+public class CppOptionsTest {
+
+  @Test
+  public void testGetDefaultsPackage() throws Exception {
+    String content = DefaultsPackageUtil.getDefaultsPackageForOptions(CppOptions.class);
+    assertThat(content).contains("filegroup(name = 'crosstool',\n"
+        + "          srcs = ['" + TestConstants.TOOLS_REPOSITORY + "//tools/cpp:toolchain'])");
+  }
+
+  @Test
+  public void testGetDefaultsPackageHostCrosstoolTop() throws OptionsParsingException {
+    String content = DefaultsPackageUtil.getDefaultsPackageForOptions(
+        CppOptions.class, "--host_crosstool_top=//some/package:crosstool");
+    assertThat(content).contains("//some/package:crosstool");
+  }
+
+  @Test
+  public void testGetDefaultsPackageGrteTop() throws OptionsParsingException {
+    String content = DefaultsPackageUtil.getDefaultsPackageForOptions(
+        CppOptions.class, "--grte_top=//some/grte:other");
+    assertThat(content).contains("//some/grte:everything");
+  }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
index 1ce0c22..1a3dcdd 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PackageFunctionTest.java
@@ -88,6 +88,7 @@
                 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
             packageCacheOptions,
             Options.getDefaults(SkylarkSemanticsOptions.class),
+            "",
             UUID.randomUUID(),
             ImmutableMap.<String, String>of(),
             new TimestampGranularityMonitor(BlazeClock.instance()));
@@ -319,6 +320,7 @@
                 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
             packageCacheOptions,
             Options.getDefaults(SkylarkSemanticsOptions.class),
+            "",
             UUID.randomUUID(),
             ImmutableMap.<String, String>of(),
             tsgm);
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
index 56efe49..18e5ae4 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/PrepareDepsOfPatternsFunctionSmartNegationTest.java
@@ -104,6 +104,7 @@
             BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
         Options.getDefaults(PackageCacheOptions.class),
         Options.getDefaults(SkylarkSemanticsOptions.class),
+        AnalysisMock.get().getDefaultsPackageContent(),
         UUID.randomUUID(),
         ImmutableMap.<String, String>of(),
         new TimestampGranularityMonitor(null));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
index f892ae6..bb30090 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTest.java
@@ -412,6 +412,7 @@
                 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
             packageCacheOptions,
             Options.getDefaults(SkylarkSemanticsOptions.class),
+            loadingMock.getDefaultsPackageContent(),
             UUID.randomUUID(),
             ImmutableMap.<String, String>of(),
             new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTestCase.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTestCase.java
index 19ee7e9..fae9d22 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTestCase.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkyframeLabelVisitorTestCase.java
@@ -237,7 +237,7 @@
 
   @Before
   public final void initializeVisitor() throws Exception {
-    setUpSkyframe(ConstantRuleVisibility.PRIVATE);
+    setUpSkyframe(ConstantRuleVisibility.PRIVATE, loadingMock.getDefaultsPackageContent());
     this.visitor = skyframeExecutor.pkgLoader();
   }
 
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkFileContentHashTests.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkFileContentHashTests.java
index 0d7024d..58107d6 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkFileContentHashTests.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkFileContentHashTests.java
@@ -170,6 +170,7 @@
                 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
             packageCacheOptions,
             Options.getDefaults(SkylarkSemanticsOptions.class),
+            "",
             UUID.randomUUID(),
             ImmutableMap.<String, String>of(),
             new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunctionTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunctionTest.java
index a695207..7ffc718 100644
--- a/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunctionTest.java
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/SkylarkImportLookupFunctionTest.java
@@ -62,6 +62,7 @@
                 BazelSkyframeExecutorConstants.BUILD_FILES_BY_PRIORITY),
             packageCacheOptions,
             Options.getDefaults(SkylarkSemanticsOptions.class),
+            "",
             UUID.randomUUID(),
             ImmutableMap.<String, String>of(),
             new TimestampGranularityMonitor(BlazeClock.instance()));
diff --git a/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java b/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java
index 601d6fe..e27bc4d 100644
--- a/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java
+++ b/src/test/java/com/google/devtools/build/lib/testutil/BazelPackageBuilderHelperForTesting.java
@@ -89,6 +89,18 @@
             Iterables.transform(newlyLoadedPkg.getTargets().values(), TARGET_TO_LABEL));
     if (!targetsInPkg.equals(targetsInNewlyLoadedPkg)) {
       Sets.SetView<Label> unsatisfied = Sets.difference(targetsInPkg, targetsInNewlyLoadedPkg);
+      if (pkgId.compareTo(PackageIdentifier.createInMainRepo("tools/defaults")) == 0
+          && unsatisfied.isEmpty()) {
+        // The tools/defaults package is populated from command-line options
+        // (=configuration fragments) which the user specifies in tests using
+        // BuildViewTestCase.useConfiguration().
+        // We'd like PackageLoader to work as much as possible without duplicating the entire
+        // configuration of Bazel, so we prefer not to pass these flags to PackageLoader.
+        // As a result, the contents of tools/defaults might differ.
+        // As long as PackageLoader returns a superset of what Bazel returns, everything should load
+        // fine.
+        return;
+      }
       Sets.SetView<Label> unexpected = Sets.difference(targetsInNewlyLoadedPkg, targetsInPkg);
       throw new IllegalStateException(
           String.format(