aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/main/java/com/google/devtools
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/java/com/google/devtools')
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/ExecException.java6
-rw-r--r--src/main/java/com/google/devtools/build/lib/actions/UserExecException.java4
-rw-r--r--src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java12
-rw-r--r--src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java69
4 files changed, 88 insertions, 3 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/actions/ExecException.java b/src/main/java/com/google/devtools/build/lib/actions/ExecException.java
index 9592880b3a..9c81cc22a1 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/ExecException.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/ExecException.java
@@ -54,6 +54,12 @@ public abstract class ExecException extends Exception {
public ExecException(String message) {
this(message, false);
}
+
+ public ExecException(Throwable cause) {
+ super(cause);
+ this.catastrophe = false;
+ this.timedOut = false;
+ }
public ExecException(String message, Throwable cause, boolean catastrophe) {
super(message + ": " + cause.getMessage(), cause);
diff --git a/src/main/java/com/google/devtools/build/lib/actions/UserExecException.java b/src/main/java/com/google/devtools/build/lib/actions/UserExecException.java
index 7de2a13c95..d79d6f582e 100644
--- a/src/main/java/com/google/devtools/build/lib/actions/UserExecException.java
+++ b/src/main/java/com/google/devtools/build/lib/actions/UserExecException.java
@@ -23,6 +23,10 @@ public class UserExecException extends ExecException {
public UserExecException(String message) {
super(message);
}
+
+ public UserExecException(Throwable cause) {
+ super(cause);
+ }
public UserExecException(String message, boolean timedOut) {
super(message, false, timedOut);
diff --git a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
index 3af0e97d6c..b420b47848 100644
--- a/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
+++ b/src/main/java/com/google/devtools/build/lib/rules/objc/ObjcConfiguration.java
@@ -49,8 +49,16 @@ public class ObjcConfiguration extends BuildConfiguration.Fragment {
"-Os", "-DNDEBUG=1", "-Wno-unused-variable", "-Winit-self", "-Wno-extra");
private static final String XCODE_VERSION_ENV_NAME = "XCODE_VERSION_OVERRIDE";
- private static final String IOS_SDK_VERSION_ENV_NAME = "IOS_SDK_VERSION_OVERRIDE";
- private static final String APPLE_SDK_PLATFORM_ENV_NAME = "APPLE_SDK_PLATFORM";
+ /**
+ * Environment variable name for the iOS SDK version. If unset, uses the system default of the
+ * host.
+ **/
+ public static final String IOS_SDK_VERSION_ENV_NAME = "IOS_SDK_VERSION_OVERRIDE";
+ /**
+ * Environment variable name for the apple SDK platform. This should be set for all actions that
+ * require an apple SDK. The valid values consist of {@link Platform} names.
+ **/
+ public static final String APPLE_SDK_PLATFORM_ENV_NAME = "APPLE_SDK_PLATFORM";
private final String iosSdkVersion;
private final String iosMinimumOs;
diff --git a/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java b/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java
index 5a90260bf2..64d3cd15f4 100644
--- a/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java
+++ b/src/main/java/com/google/devtools/build/lib/standalone/StandaloneSpawnStrategy.java
@@ -13,6 +13,7 @@
// limitations under the License.
package com.google.devtools.build.lib.standalone;
+import com.google.common.collect.ImmutableMap;
import com.google.devtools.build.lib.actions.ActionExecutionContext;
import com.google.devtools.build.lib.actions.ExecException;
import com.google.devtools.build.lib.actions.ExecutionStrategy;
@@ -21,9 +22,11 @@ import com.google.devtools.build.lib.actions.Spawn;
import com.google.devtools.build.lib.actions.SpawnActionContext;
import com.google.devtools.build.lib.actions.UserExecException;
import com.google.devtools.build.lib.cmdline.Label;
+import com.google.devtools.build.lib.rules.objc.ObjcConfiguration;
import com.google.devtools.build.lib.shell.AbnormalTerminationException;
import com.google.devtools.build.lib.shell.Command;
import com.google.devtools.build.lib.shell.CommandException;
+import com.google.devtools.build.lib.shell.CommandResult;
import com.google.devtools.build.lib.shell.TerminationStatus;
import com.google.devtools.build.lib.util.CommandFailureUtils;
import com.google.devtools.build.lib.util.OS;
@@ -32,6 +35,7 @@ import com.google.devtools.build.lib.util.io.FileOutErr;
import com.google.devtools.build.lib.vfs.Path;
import java.io.File;
+import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
@@ -94,7 +98,8 @@ public class StandaloneSpawnStrategy implements SpawnActionContext {
args.addAll(spawn.getArguments());
String cwd = executor.getExecRoot().getPathString();
- Command cmd = new Command(args.toArray(new String[]{}), spawn.getEnvironment(), new File(cwd));
+ Command cmd = new Command(args.toArray(new String[]{}),
+ locallyDeterminedEnv(spawn.getEnvironment()), new File(cwd));
FileOutErr outErr = actionExecutionContext.getFileOutErr();
try {
@@ -127,4 +132,66 @@ public class StandaloneSpawnStrategy implements SpawnActionContext {
public boolean isRemotable(String mnemonic, boolean remotable) {
return false;
}
+
+ /**
+ * Adds to the given environment all variables that are dependent on system state of the host
+ * machine.
+ *
+ * <p> Admittedly, hermeticity is "best effort" in such cases; these environment values
+ * should be as tied to configuration parameters as possible.
+ *
+ * <p>For example, underlying iOS toolchains require that SDKROOT resolve to an absolute
+ * system path, but, when selecting which SDK to resolve, the version number comes from
+ * build configuration.
+ *
+ * @return the new environment, comprised of the old environment plus any new variables
+ * @throws UserExecException if any variables dependent on system state could not be
+ * resolved
+ */
+ private ImmutableMap<String, String> locallyDeterminedEnv(ImmutableMap<String, String> env)
+ throws UserExecException {
+ ImmutableMap.Builder<String, String> newEnvBuilder = ImmutableMap.builder();
+ newEnvBuilder.putAll(env);
+ if (env.containsKey(ObjcConfiguration.IOS_SDK_VERSION_ENV_NAME)) {
+ // The Apple platform is needed to select the appropriate SDK.
+ if (!env.containsKey(ObjcConfiguration.APPLE_SDK_PLATFORM_ENV_NAME)) {
+ throw new UserExecException("Could not resolve apple platform for determining SDK");
+ }
+ String iosSdkVersion = env.get(ObjcConfiguration.IOS_SDK_VERSION_ENV_NAME);
+ String appleSdkPlatform = env.get(ObjcConfiguration.APPLE_SDK_PLATFORM_ENV_NAME);
+ // TODO(bazel-team): Determine and set DEVELOPER_DIR.
+ addSdkRootEnv(newEnvBuilder, iosSdkVersion, appleSdkPlatform);
+ }
+ return newEnvBuilder.build();
+ }
+
+ private void addSdkRootEnv(
+ ImmutableMap.Builder<String, String> envBuilder, String iosSdkVersion,
+ String appleSdkPlatform) throws UserExecException {
+ // Sanity check, also presents a less cryptic error message.
+ if (OS.getCurrent() != OS.DARWIN) {
+ throw new UserExecException("Cannot locate iOS SDK on non-darwin operating system");
+ }
+
+ try {
+ // TODO(bazel-team): Propagate DEVELOPER_DIR for the xcrun call.
+ CommandResult xcrunResult = new Command(new String[] {"/usr/bin/xcrun", "--sdk",
+ String.format("%s%s", appleSdkPlatform.toLowerCase(), iosSdkVersion),
+ "--show-sdk-path"}).execute();
+
+ TerminationStatus xcrunStatus = xcrunResult.getTerminationStatus();
+ if (!xcrunResult.getTerminationStatus().exited()) {
+ throw new UserExecException(String.format("xcrun failed.\n%s\nStderr: %s",
+ xcrunStatus.toString(), new String(xcrunResult.getStderr(), StandardCharsets.UTF_8)));
+ }
+
+ envBuilder.put("SDKROOT", new String(xcrunResult.getStdout(), StandardCharsets.UTF_8));
+ } catch (AbnormalTerminationException e) {
+ String message = String.format("%s : %s",
+ e.getResult().getTerminationStatus(), new String(e.getResult().getStderr()));
+ throw new UserExecException(message, e);
+ } catch (CommandException e) {
+ throw new UserExecException(e);
+ }
+ }
}