use of com.google.devtools.build.lib.shell.Command in project bazel by bazelbuild.
the class AppleHostInfo method getSdkRoot.
/**
* Returns the absolute root path of the target Apple SDK on the host system for a given
* version of xcode (as defined by the given {@code developerDir}). This may spawn a
* process and use the {@code /usr/bin/xcrun} binary to locate the target SDK. This uses a local
* cache file under {@code bazel-out}, and will only spawn a new {@code xcrun} process in the case
* of a cache miss.
*
* @param execRoot the execution root path, used to locate the cache file
* @param developerDir the value of {@code DEVELOPER_DIR} for the target version of xcode
* @param sdkVersion the sdk version, for example, "9.1"
* @param appleSdkPlatform the sdk platform, for example, "iPhoneOS"
* @param productName the product name
* @throws UserExecException if there is an issue with obtaining the root from the spawned
* process, either because the SDK platform/version pair doesn't exist, or there was an
* unexpected issue finding or running the tool
*/
public static String getSdkRoot(Path execRoot, String developerDir, String sdkVersion, String appleSdkPlatform, String productName) throws UserExecException {
try {
CacheManager cacheManager = new CacheManager(execRoot.getRelative(BlazeDirectories.getRelativeOutputPath(productName)), XCRUN_CACHE_FILENAME);
String sdkString = appleSdkPlatform.toLowerCase() + sdkVersion;
String cacheResult = cacheManager.getValue(developerDir, sdkString);
if (cacheResult != null) {
return cacheResult;
} else {
Map<String, String> env = Strings.isNullOrEmpty(developerDir) ? ImmutableMap.<String, String>of() : ImmutableMap.of("DEVELOPER_DIR", developerDir);
CommandResult xcrunResult = new Command(new String[] { "/usr/bin/xcrun", "--sdk", sdkString, "--show-sdk-path" }, env, null).execute();
// calling xcrun via Command returns a value with a newline on the end.
String sdkRoot = new String(xcrunResult.getStdout(), StandardCharsets.UTF_8).trim();
cacheManager.writeEntry(ImmutableList.of(developerDir, sdkString), sdkRoot);
return sdkRoot;
}
} catch (AbnormalTerminationException e) {
TerminationStatus terminationStatus = e.getResult().getTerminationStatus();
if (terminationStatus.exited()) {
throw new UserExecException(String.format("xcrun failed with code %s.\n" + "This most likely indicates that SDK version [%s] for platform [%s] is " + "unsupported for the target version of xcode.\n" + "%s\n" + "Stderr: %s", terminationStatus.getExitCode(), sdkVersion, appleSdkPlatform, terminationStatus.toString(), new String(e.getResult().getStderr(), StandardCharsets.UTF_8)));
}
String message = String.format("xcrun failed.\n%s\n%s", e.getResult().getTerminationStatus(), new String(e.getResult().getStderr(), StandardCharsets.UTF_8));
throw new UserExecException(message, e);
} catch (CommandException | IOException e) {
throw new UserExecException(e);
}
}
use of com.google.devtools.build.lib.shell.Command in project bazel by bazelbuild.
the class AppleHostInfo method getDeveloperDir.
/**
* Returns the absolute root path of the xcode developer directory on the host system for
* the given xcode version. This may spawn a process and use the {@code xcode-locator} binary.
* This uses a local cache file under {@code bazel-out}, and will only spawn a new process in the
* case of a cache miss.
*
* @param execRoot the execution root path, used to locate the cache file
* @param version the xcode version number to look up
* @param productName the product name
* @throws UserExecException if there is an issue with obtaining the path from the spawned
* process, either because there is no installed xcode with the given version, or
* there was an unexpected issue finding or running the tool
*/
public static String getDeveloperDir(Path execRoot, DottedVersion version, String productName) throws UserExecException {
try {
CacheManager cacheManager = new CacheManager(execRoot.getRelative(BlazeDirectories.getRelativeOutputPath(productName)), XCODE_LOCATOR_CACHE_FILENAME);
String cacheResult = cacheManager.getValue(version.toString());
if (cacheResult != null) {
return cacheResult;
} else {
CommandResult xcodeLocatorResult = new Command(new String[] { execRoot.getRelative("_bin/xcode-locator").getPathString(), version.toString() }).execute();
String developerDir = new String(xcodeLocatorResult.getStdout(), StandardCharsets.UTF_8).trim();
cacheManager.writeEntry(ImmutableList.of(version.toString()), developerDir);
return developerDir;
}
} catch (AbnormalTerminationException e) {
TerminationStatus terminationStatus = e.getResult().getTerminationStatus();
String message;
if (e.getResult().getTerminationStatus().exited()) {
message = String.format("xcode-locator failed with code %s.\n" + "This most likely indicates that xcode version %s is not available on the host " + "machine.\n" + "%s\n" + "stderr: %s", terminationStatus.getExitCode(), version, terminationStatus.toString(), new String(e.getResult().getStderr(), StandardCharsets.UTF_8));
} else {
message = String.format("xcode-locator failed. %s\nstderr: %s", e.getResult().getTerminationStatus(), new String(e.getResult().getStderr(), StandardCharsets.UTF_8));
}
throw new UserExecException(message, e);
} catch (CommandException | IOException e) {
throw new UserExecException(e);
}
}
use of com.google.devtools.build.lib.shell.Command in project bazel by bazelbuild.
the class LinuxSandboxRunner method isSupported.
static boolean isSupported(CommandEnvironment commandEnv) {
Path execRoot = commandEnv.getExecRoot();
PathFragment embeddedTool = commandEnv.getBlazeWorkspace().getBinTools().getExecPath(LINUX_SANDBOX);
if (embeddedTool == null) {
// bootstrapping).
return false;
}
List<String> args = new ArrayList<>();
args.add(execRoot.getRelative(embeddedTool).getPathString());
args.add("-C");
ImmutableMap<String, String> env = ImmutableMap.of();
File cwd = execRoot.getPathFile();
Command cmd = new Command(args.toArray(new String[0]), env, cwd);
try {
cmd.execute(/* stdin */
new byte[] {}, Command.NO_OBSERVER, ByteStreams.nullOutputStream(), ByteStreams.nullOutputStream(), /* killSubprocessOnInterrupt */
true);
} catch (CommandException e) {
return false;
}
return true;
}
use of com.google.devtools.build.lib.shell.Command in project bazel by bazelbuild.
the class SandboxRunner method run.
/**
* Runs the command specified via {@code arguments} and {@code env} inside the sandbox.
*
* @param arguments - arguments of spawn to run inside the sandbox.
* @param environment - environment variables to pass to the spawn.
* @param outErr - error output to capture sandbox's and command's stderr.
* @param timeout - after how many seconds should the process be killed.
* @param allowNetwork - whether networking should be allowed for the process.
* @param sandboxDebug - whether debugging message should be printed.
* @param useFakeHostname - whether the hostname should be set to 'localhost' inside the sandbox.
*/
void run(List<String> arguments, Map<String, String> environment, OutErr outErr, int timeout, boolean allowNetwork, boolean sandboxDebug, boolean useFakeHostname) throws ExecException {
Command cmd;
try {
cmd = getCommand(arguments, environment, timeout, allowNetwork, useFakeHostname);
} catch (IOException e) {
throw new UserExecException("I/O error during sandboxed execution", e);
}
TerminationStatus status = null;
try {
cmd.execute(/* stdin */
new byte[] {}, getCommandObserver(timeout), outErr.getOutputStream(), outErr.getErrorStream(), /* killSubprocessOnInterrupt */
true);
} catch (CommandException e) {
boolean timedOut = false;
if (e instanceof AbnormalTerminationException) {
status = ((AbnormalTerminationException) e).getResult().getTerminationStatus();
timedOut = !status.exited() && (status.getTerminatingSignal() == getSignalOnTimeout());
}
String statusMessage = status + " [sandboxed]";
if (!verboseFailures) {
// simplest error message
throw new UserExecException(statusMessage, e, timedOut);
}
List<String> commandList;
if (!sandboxDebug) {
commandList = arguments;
} else {
commandList = Arrays.asList(cmd.getCommandLineElements());
}
String commandFailureMessage = CommandFailureUtils.describeCommandFailure(true, commandList, environment, null) + (sandboxDebug ? "" : SANDBOX_DEBUG_SUGGESTION);
throw new UserExecException(commandFailureMessage, e, timedOut);
}
}
use of com.google.devtools.build.lib.shell.Command in project bazel by bazelbuild.
the class BazelBuilder method buildAndGetElapsedTime.
@Override
public double buildAndGetElapsedTime(Path buildBinary, ImmutableList<String> args) throws CommandException {
List<String> cmdList = new ArrayList<>();
cmdList.add(buildBinary.toString());
cmdList.addAll(args);
String[] cmdArr = new String[cmdList.size()];
cmdArr = cmdList.toArray(cmdArr);
// Run build command
Command cmd = new Command(cmdArr, null, generatedCodeDir.toFile());
CommandResult result = cmd.execute();
// Get elapsed time from output
String output = new String(result.getStderr(), UTF_8).trim();
Matcher m = ELAPSED_TIME_PATTERN.matcher(output);
if (m.find()) {
try {
return (Double.parseDouble(m.group(0)));
} catch (NumberFormatException e) {
// Should not be here since we look for [0-9.]+
logger.log(Level.SEVERE, "Cannot parse " + m.group(0));
}
}
throw new CommandException(cmd, "Command didn't provide parsable output.");
}
Aggregations