aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools/build/lib/bazel/rules/BazelStrategyModule.java
blob: 0229f14d7abe50fefc00b9f1d9992e36696430fe (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
// 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.bazel.rules;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.actions.FileWriteActionContext;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionContext;
import com.google.devtools.build.lib.buildtool.BuildRequest;
import com.google.devtools.build.lib.exec.ExecutorBuilder;
import com.google.devtools.build.lib.exec.SpawnCache;
import com.google.devtools.build.lib.rules.android.WriteAdbArgsActionContext;
import com.google.devtools.build.lib.rules.cpp.CppCompileActionContext;
import com.google.devtools.build.lib.rules.cpp.CppIncludeExtractionContext;
import com.google.devtools.build.lib.rules.cpp.CppIncludeScanningContext;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.Command;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.common.options.Converters.AssignmentConverter;
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.OptionsBase;
import java.util.List;
import java.util.Map;

/** Module which registers the strategy options for Bazel. */
public class BazelStrategyModule extends BlazeModule {
  /**
   * Execution options affecting how we execute the build actions (but not their semantics).
   */
  public static class BazelExecutionOptions extends OptionsBase {
    @Option(
      name = "spawn_strategy",
      defaultValue = "",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Specify how spawn actions are executed by default. "
              + "'standalone' means run all of them locally without any kind of sandboxing. "
              + "'sandboxed' means to run them in a sandboxed environment with limited privileges "
              + "(details depend on platform support)."
    )
    public String spawnStrategy;

    @Option(
      name = "genrule_strategy",
      defaultValue = "",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Specify how to execute genrules. "
              + "'standalone' means run all of them locally. "
              + "'sandboxed' means run them in namespaces based sandbox (available only on Linux)"
    )
    public String genruleStrategy;

    @Option(
      name = "strategy",
      allowMultiple = true,
      converter = AssignmentConverter.class,
      defaultValue = "",
      documentationCategory = OptionDocumentationCategory.UNCATEGORIZED,
      effectTags = {OptionEffectTag.UNKNOWN},
      help =
          "Specify how to distribute compilation of other spawn actions. "
              + "Example: 'Javac=local' means to spawn Java compilation locally. "
              + "'JavaIjar=sandboxed' means to spawn Java Ijar actions in a sandbox. "
    )
    public List<Map.Entry<String, String>> strategy;
  }

  @Override
  public Iterable<Class<? extends OptionsBase>> getCommandOptions(Command command) {
    return "build".equals(command.name())
        ? ImmutableList.<Class<? extends OptionsBase>>of(BazelExecutionOptions.class)
        : ImmutableList.<Class<? extends OptionsBase>>of();
  }

  @Override
  public void executorInit(CommandEnvironment env, BuildRequest request, ExecutorBuilder builder) {
    builder.addActionContext(new WriteAdbArgsActionContext(env.getClientEnv().get("HOME")));
    BazelExecutionOptions options = env.getOptions().getOptions(BazelExecutionOptions.class);

    // Default strategies for certain mnemonics - they can be overridden by --strategy= flags.
    builder.addStrategyByMnemonic("Javac", "worker");
    builder.addStrategyByMnemonic("Closure", "worker");
    builder.addStrategyByMnemonic("DexBuilder", "worker");

    for (Map.Entry<String, String> strategy : options.strategy) {
      String strategyName = strategy.getValue();
      // TODO(philwo) - remove this when the standalone / local mess is cleaned up.
      // Some flag expansions use "local" as the strategy name, but the strategy is now called
      // "standalone", so we'll translate it here.
      if (strategyName.equals("local")) {
        strategyName = "standalone";
      }
      builder.addStrategyByMnemonic(strategy.getKey(), strategyName);
    }

    if (!options.genruleStrategy.isEmpty()) {
      builder.addStrategyByMnemonic("Genrule", options.genruleStrategy);
    }

    // TODO(bazel-team): put this in getActionContexts (key=SpawnActionContext.class) instead
    if (!options.spawnStrategy.isEmpty()) {
      builder.addStrategyByMnemonic("", options.spawnStrategy);
    }

    builder
        .addStrategyByContext(CppCompileActionContext.class, "")
        .addStrategyByContext(CppIncludeExtractionContext.class, "")
        .addStrategyByContext(CppIncludeScanningContext.class, "")
        .addStrategyByContext(FileWriteActionContext.class, "")
        .addStrategyByContext(TemplateExpansionContext.class, "")
        .addStrategyByContext(WriteAdbArgsActionContext.class, "")
        .addStrategyByContext(SpawnCache.class, "");
  }
}