aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools/build/lib')
-rw-r--r--src/main/java/com/google/devtools/build/lib/analysis/ConfiguredRuleClassProvider.java20
-rw-r--r--src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java11
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/ExternalPackage.java27
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java9
-rw-r--r--src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java3
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/SkyframeExecutor.java2
-rw-r--r--src/main/java/com/google/devtools/build/lib/skyframe/WorkspaceFileFunction.java81
7 files changed, 108 insertions, 45 deletions
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 e84f9aa187..26e0617454 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
@@ -40,6 +40,7 @@ import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
import com.google.devtools.build.lib.syntax.SkylarkModule;
import com.google.devtools.build.lib.syntax.SkylarkType;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
+import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.common.options.OptionsClassProvider;
import java.lang.reflect.Constructor;
@@ -76,6 +77,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
* Builder for {@link ConfiguredRuleClassProvider}.
*/
public static class Builder implements RuleDefinitionEnvironment {
+ private final List<PathFragment> defaultWorkspaceFiles = new ArrayList<>();
private final List<ConfigurationFragmentFactory> configurationFragments = new ArrayList<>();
private final List<BuildInfoFactory> buildInfoFactories = new ArrayList<>();
private final List<Class<? extends FragmentOptions>> configurationOptions = new ArrayList<>();
@@ -90,6 +92,10 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
private PrerequisiteValidator prerequisiteValidator;
private ImmutableMap<String, SkylarkType> skylarkAccessibleJavaClasses = ImmutableMap.of();
+ public void addWorkspaceFile(PathFragment defaultWorkspace) {
+ defaultWorkspaceFiles.add(defaultWorkspace);
+ }
+
public Builder setPrerequisiteValidator(PrerequisiteValidator prerequisiteValidator) {
this.prerequisiteValidator = prerequisiteValidator;
return this;
@@ -194,6 +200,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
return new ConfiguredRuleClassProvider(
ImmutableMap.copyOf(ruleClassMap),
ImmutableMap.copyOf(ruleDefinitionMap),
+ ImmutableList.copyOf(defaultWorkspaceFiles),
ImmutableList.copyOf(buildInfoFactories),
ImmutableList.copyOf(configurationOptions),
ImmutableList.copyOf(configurationFragments),
@@ -225,6 +232,12 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
});
/**
+ * A list of relative paths to the WORKSPACE files needed to provide external dependencies for
+ * the rule classes.
+ */
+ private ImmutableList<PathFragment> defaultWorkspaceFiles;
+
+ /**
* Maps rule class name to the metaclass instance for that rule.
*/
private final ImmutableMap<String, RuleClass> ruleClassMap;
@@ -260,6 +273,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
public ConfiguredRuleClassProvider(
ImmutableMap<String, RuleClass> ruleClassMap,
ImmutableMap<String, Class<? extends RuleDefinition>> ruleDefinitionMap,
+ ImmutableList<PathFragment> defaultWorkspaceFiles,
ImmutableList<BuildInfoFactory> buildInfoFactories,
ImmutableList<Class<? extends FragmentOptions>> configurationOptions,
ImmutableList<ConfigurationFragmentFactory> configurationFragments,
@@ -269,6 +283,7 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
this.ruleClassMap = ruleClassMap;
this.ruleDefinitionMap = ruleDefinitionMap;
+ this.defaultWorkspaceFiles = defaultWorkspaceFiles;
this.buildInfoFactories = buildInfoFactories;
this.configurationOptions = configurationOptions;
this.configurationFragments = configurationFragments;
@@ -373,4 +388,9 @@ public class ConfiguredRuleClassProvider implements RuleClassProvider {
public Object getNativeModule() {
return nativeModule;
}
+
+ @Override
+ public List<PathFragment> getWorkspaceFiles() {
+ return defaultWorkspaceFiles;
+ }
}
diff --git a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
index 663b82ac92..f5d928d011 100644
--- a/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
+++ b/src/main/java/com/google/devtools/build/lib/bazel/rules/java/BazelJavaRuleClasses.java
@@ -40,6 +40,7 @@ import com.google.devtools.build.lib.packages.RuleClass.PackageNameConstraint;
import com.google.devtools.build.lib.packages.TriState;
import com.google.devtools.build.lib.rules.java.JavaSemantics;
import com.google.devtools.build.lib.util.FileTypeSet;
+import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Set;
@@ -52,7 +53,7 @@ public class BazelJavaRuleClasses {
PackageNameConstraint.ANY_SEGMENT, "java", "javatests");
public static final ImplicitOutputsFunction JAVA_BINARY_IMPLICIT_OUTPUTS =
- fromFunctions(JavaSemantics.JAVA_BINARY_CLASS_JAR, JavaSemantics.JAVA_BINARY_SOURCE_JAR,
+ fromFunctions(JavaSemantics.JAVA_BINARY_CLASS_JAR, JavaSemantics.JAVA_BINARY_SOURCE_JAR,
JavaSemantics.JAVA_BINARY_DEPLOY_JAR, JavaSemantics.JAVA_BINARY_DEPLOY_SOURCE_JAR);
static final ImplicitOutputsFunction JAVA_LIBRARY_IMPLICIT_OUTPUTS =
@@ -170,4 +171,12 @@ public class BazelJavaRuleClasses {
.build();
}
}
+
+ /**
+ * Returns the relative path to the WORKSPACE file describing the external dependencies necessary
+ * for the Java rules.
+ */
+ public static PathFragment getDefaultWorkspace() {
+ return new PathFragment("jdk.WORKSPACE");
+ }
}
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 9c92b338b2..ac4920ce2e 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
@@ -34,6 +34,7 @@ import java.util.Map.Entry;
*/
public class ExternalPackage extends Package {
+ private String workspaceName;
private Map<RepositoryName, Rule> repositoryMap;
ExternalPackage() {
@@ -41,6 +42,13 @@ public class ExternalPackage extends Package {
}
/**
+ * Returns the name for this repository.
+ */
+ public String getWorkspaceName() {
+ return workspaceName;
+ }
+
+ /**
* Returns a description of the repository with the given name, or null if there's no such
* repository.
*/
@@ -79,28 +87,37 @@ public class ExternalPackage extends Package {
/**
* Given a workspace file path, creates an ExternalPackage.
*/
- public static class ExternalPackageBuilder
- extends AbstractBuilder<ExternalPackage, ExternalPackageBuilder> {
+ public static class Builder
+ extends AbstractBuilder<ExternalPackage, Builder> {
+ private String workspaceName;
private Map<Label, Binding> bindMap = Maps.newHashMap();
private Map<RepositoryName, Rule> repositoryMap = Maps.newHashMap();
- public ExternalPackageBuilder(Path workspacePath) {
+ public Builder(Path workspacePath) {
super(new ExternalPackage());
setFilename(workspacePath);
setMakeEnv(new MakeEnvironment.Builder());
}
@Override
- protected ExternalPackageBuilder self() {
+ protected Builder self() {
return this;
}
@Override
public ExternalPackage build() {
+ pkg.workspaceName = workspaceName;
pkg.repositoryMap = ImmutableMap.copyOf(repositoryMap);
return super.build();
}
+ /**
+ * Sets the name for this repository.
+ */
+ public void setWorkspaceName(String name) {
+ workspaceName = name;
+ }
+
public void addBinding(Label label, Binding binding) {
bindMap.put(label, binding);
}
@@ -178,7 +195,7 @@ public class ExternalPackage extends Package {
* Creates an external repository rule.
* @throws SyntaxException if the repository name is invalid.
*/
- public ExternalPackageBuilder createAndAddRepositoryRule(RuleClass ruleClass,
+ public Builder createAndAddRepositoryRule(RuleClass ruleClass,
Map<String, Object> kwargs, FuncallExpression ast)
throws InvalidRuleException, NameConflictException, SyntaxException {
StoredEventHandler eventHandler = new StoredEventHandler();
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
index 90fdfca393..07b1b18dd9 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleClassProvider.java
@@ -17,7 +17,9 @@ package com.google.devtools.build.lib.packages;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.syntax.SkylarkEnvironment;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
+import com.google.devtools.build.lib.vfs.PathFragment;
+import java.util.List;
import java.util.Map;
/**
@@ -46,4 +48,11 @@ public interface RuleClassProvider {
* Returns the Skylark module to register the native rules with.
*/
Object getNativeModule();
+
+ /**
+ * Returns paths to the WORKSPACE files needed to provide external dependencies for built-in
+ * rules. The PathFragments are relative to Bazel's install directory. Returns an empty list if
+ * there are none defined.
+ */
+ List<PathFragment> getWorkspaceFiles();
}
diff --git a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
index c79bbaa395..cffef503fe 100644
--- a/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
+++ b/src/main/java/com/google/devtools/build/lib/packages/RuleFactory.java
@@ -23,7 +23,6 @@ import com.google.devtools.build.lib.packages.PackageFactory.PackageContext;
import com.google.devtools.build.lib.syntax.FuncallExpression;
import com.google.devtools.build.lib.syntax.Label;
import com.google.devtools.build.lib.syntax.Label.SyntaxException;
-import com.google.devtools.build.lib.vfs.PathFragment;
import java.util.Map;
import java.util.Set;
@@ -106,7 +105,7 @@ public class RuleFactory {
throw new InvalidRuleException("illegal rule name: " + name + ": " + e.getMessage());
}
boolean inWorkspaceFile = location.getPath() != null
- && location.getPath().endsWith(new PathFragment("WORKSPACE"));
+ && location.getPath().getBaseName().contains("WORKSPACE");
if (ruleClass.getWorkspaceOnly() && !inWorkspaceFile) {
throw new RuleFactory.InvalidRuleException(ruleClass + " must be in the WORKSPACE file "
+ "(used by " + label + ")");
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 a30b5c7343..b7d638528d 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
@@ -303,7 +303,7 @@ public abstract class SkyframeExecutor {
configurationFactory, clientEnv, configurationPackages));
map.put(SkyFunctions.CONFIGURATION_FRAGMENT, new ConfigurationFragmentFunction(
configurationFragments, configurationPackages));
- map.put(SkyFunctions.WORKSPACE_FILE, new WorkspaceFileFunction(pkgFactory));
+ map.put(SkyFunctions.WORKSPACE_FILE, new WorkspaceFileFunction(pkgFactory, directories));
map.put(SkyFunctions.TARGET_COMPLETION, new TargetCompletionFunction(eventBus));
map.put(SkyFunctions.TEST_COMPLETION, new TestCompletionFunction());
map.put(SkyFunctions.ARTIFACT, new ArtifactFunction(allowedMissingInputs));
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 f518b8a388..89126cb73d 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
@@ -17,12 +17,14 @@ package com.google.devtools.build.lib.skyframe;
import static com.google.devtools.build.lib.syntax.Environment.NONE;
import com.google.common.collect.ImmutableList;
+import com.google.devtools.build.lib.analysis.BlazeDirectories;
import com.google.devtools.build.lib.cmdline.LabelValidator;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.StoredEventHandler;
+import com.google.devtools.build.lib.packages.ExternalPackage;
import com.google.devtools.build.lib.packages.ExternalPackage.Binding;
-import com.google.devtools.build.lib.packages.ExternalPackage.ExternalPackageBuilder;
-import com.google.devtools.build.lib.packages.ExternalPackage.ExternalPackageBuilder.NoSuchBindingException;
+import com.google.devtools.build.lib.packages.ExternalPackage.Builder;
+import com.google.devtools.build.lib.packages.ExternalPackage.Builder.NoSuchBindingException;
import com.google.devtools.build.lib.packages.Package.NameConflictException;
import com.google.devtools.build.lib.packages.PackageFactory;
import com.google.devtools.build.lib.packages.RuleClass;
@@ -39,6 +41,7 @@ import com.google.devtools.build.lib.syntax.Label.SyntaxException;
import com.google.devtools.build.lib.syntax.MixedModeFunction;
import com.google.devtools.build.lib.syntax.ParserInputSource;
import com.google.devtools.build.lib.vfs.Path;
+import com.google.devtools.build.lib.vfs.PathFragment;
import com.google.devtools.build.lib.vfs.RootedPath;
import com.google.devtools.build.skyframe.SkyFunction;
import com.google.devtools.build.skyframe.SkyFunctionException;
@@ -58,22 +61,46 @@ public class WorkspaceFileFunction implements SkyFunction {
private static final String BIND = "bind";
private final PackageFactory packageFactory;
+ private final Path installDir;
- WorkspaceFileFunction(PackageFactory packageFactory) {
+ WorkspaceFileFunction(PackageFactory packageFactory, BlazeDirectories directories) {
this.packageFactory = packageFactory;
+ this.installDir = directories.getEmbeddedBinariesRoot();
}
@Override
public SkyValue compute(SkyKey skyKey, Environment env) throws WorkspaceFileFunctionException,
InterruptedException {
RootedPath workspaceRoot = (RootedPath) skyKey.argument();
- // Explicitly make skyframe load this file.
if (env.getValue(FileValue.key(workspaceRoot)) == null) {
return null;
}
- Path workspaceFilePath = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath());
- WorkspaceNameHolder holder = new WorkspaceNameHolder();
- ExternalPackageBuilder builder = new ExternalPackageBuilder(workspaceFilePath);
+
+ Path repoWorkspace = workspaceRoot.getRoot().getRelative(workspaceRoot.getRelativePath());
+ Builder builder = new Builder(repoWorkspace);
+ List<PathFragment> workspaceFiles = packageFactory.getRuleClassProvider().getWorkspaceFiles();
+ for (PathFragment workspaceFile : workspaceFiles) {
+ workspaceRoot = RootedPath.toRootedPath(installDir, workspaceFile);
+ if (env.getValue(FileValue.key(workspaceRoot)) == null) {
+ return null;
+ }
+ parseWorkspaceFile(installDir.getRelative(workspaceFile), builder);
+ }
+ parseWorkspaceFile(repoWorkspace, builder);
+ try {
+ builder.resolveBindTargets(packageFactory.getRuleClass(BIND));
+ } catch (NoSuchBindingException e) {
+ throw new WorkspaceFileFunctionException(e);
+ } catch (EvalException e) {
+ throw new WorkspaceFileFunctionException(e);
+ }
+
+ ExternalPackage pkg = builder.build();
+ return new WorkspaceFileValue(pkg.getWorkspaceName(), pkg);
+ }
+
+ private void parseWorkspaceFile(Path workspaceFilePath, Builder builder)
+ throws WorkspaceFileFunctionException, InterruptedException {
StoredEventHandler localReporter = new StoredEventHandler();
BuildFileAST buildFileAST;
ParserInputSource inputSource = null;
@@ -87,13 +114,9 @@ public class WorkspaceFileFunction implements SkyFunction {
if (buildFileAST.containsErrors()) {
localReporter.handle(Event.error("WORKSPACE file could not be parsed"));
} else {
- try {
- if (!evaluateWorkspaceFile(buildFileAST, holder, builder)) {
- localReporter.handle(
- Event.error("Error evaluating WORKSPACE file " + workspaceFilePath));
- }
- } catch (EvalException e) {
- throw new WorkspaceFileFunctionException(e);
+ if (!evaluateWorkspaceFile(buildFileAST, builder)) {
+ localReporter.handle(
+ Event.error("Error evaluating WORKSPACE file " + workspaceFilePath));
}
}
@@ -101,7 +124,6 @@ public class WorkspaceFileFunction implements SkyFunction {
if (localReporter.hasErrors()) {
builder.setContainsErrors();
}
- return new WorkspaceFileValue(holder.workspaceName, builder.build());
}
@Override
@@ -109,7 +131,7 @@ public class WorkspaceFileFunction implements SkyFunction {
return null;
}
- private static Function newWorkspaceNameFunction(final WorkspaceNameHolder holder) {
+ private static Function newWorkspaceNameFunction(final Builder builder) {
List<String> params = ImmutableList.of("name");
return new MixedModeFunction("workspace", params, 1, true) {
@Override
@@ -120,13 +142,13 @@ public class WorkspaceFileFunction implements SkyFunction {
if (errorMessage != null) {
throw new EvalException(ast.getLocation(), errorMessage);
}
- holder.workspaceName = name;
+ builder.setWorkspaceName(name);
return NONE;
}
};
}
- private static Function newBindFunction(final ExternalPackageBuilder builder) {
+ private static Function newBindFunction(final Builder builder) {
List<String> params = ImmutableList.of("name", "actual");
return new MixedModeFunction(BIND, params, 2, true) {
@Override
@@ -154,7 +176,7 @@ public class WorkspaceFileFunction implements SkyFunction {
* specified package context.
*/
private static Function newRuleFunction(final RuleFactory ruleFactory,
- final ExternalPackageBuilder builder, final String ruleClassName) {
+ final Builder builder, final String ruleClassName) {
return new AbstractFunction(ruleClassName) {
@Override
public Object call(List<Object> args, Map<String, Object> kwargs, FuncallExpression ast,
@@ -176,9 +198,8 @@ public class WorkspaceFileFunction implements SkyFunction {
};
}
- public boolean evaluateWorkspaceFile(BuildFileAST buildFileAST, WorkspaceNameHolder holder,
- ExternalPackageBuilder builder)
- throws InterruptedException, EvalException, WorkspaceFileFunctionException {
+ public boolean evaluateWorkspaceFile(BuildFileAST buildFileAST, Builder builder)
+ throws InterruptedException {
// Environment is defined in SkyFunction and the syntax package.
com.google.devtools.build.lib.syntax.Environment workspaceEnv =
new com.google.devtools.build.lib.syntax.Environment();
@@ -190,22 +211,10 @@ public class WorkspaceFileFunction implements SkyFunction {
}
workspaceEnv.update(BIND, newBindFunction(builder));
- workspaceEnv.update("workspace", newWorkspaceNameFunction(holder));
+ workspaceEnv.update("workspace", newWorkspaceNameFunction(builder));
StoredEventHandler eventHandler = new StoredEventHandler();
- if (!buildFileAST.exec(workspaceEnv, eventHandler)) {
- return false;
- }
- try {
- builder.resolveBindTargets(packageFactory.getRuleClass(BIND));
- } catch (NoSuchBindingException e) {
- throw new WorkspaceFileFunctionException(e);
- }
- return true;
- }
-
- private static final class WorkspaceNameHolder {
- String workspaceName;
+ return buildFileAST.exec(workspaceEnv, eventHandler);
}
private static final class WorkspaceFileFunctionException extends SkyFunctionException {