in golang/src/com/google/idea/blaze/golang/run/BlazeGoRunConfigurationRunner.java [271:382]
private static ExecutableInfo getExecutableToDebug(ExecutionEnvironment env)
throws ExecutionException {
BlazeCommandRunConfiguration configuration =
BlazeCommandRunConfigurationRunner.getConfiguration(env);
Project project = configuration.getProject();
BlazeProjectData blazeProjectData =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData();
if (blazeProjectData == null) {
throw new ExecutionException("Not synced yet, please sync project");
}
Label label = getSingleTarget(configuration);
SaveUtil.saveAllFiles();
// Explicitly create local build helper, because the debuggable script is expected to be present
// locally
try (BuildResultHelper buildResultHelper =
BuildResultHelperProvider.createForLocalBuild(project)) {
ImmutableList.Builder<String> flags = ImmutableList.builder();
if (Blaze.getBuildSystem(project) == BuildSystem.Blaze) {
// $ go tool compile
// -N disable optimizations
// -l disable inlining
flags.add("--gc_goopt=-N").add("--gc_goopt=-l");
} else {
// bazel build adds these flags themselves with -c dbg
// https://github.com/bazelbuild/rules_go/issues/741
flags.add("--compilation_mode=dbg");
}
Optional<Path> scriptPath = Optional.empty();
if (scriptPathEnabled.getValue()) {
try {
scriptPath = Optional.of(BlazeBeforeRunCommandHelper.createScriptPathFile());
flags.add("--script_path=" + scriptPath.get());
} catch (IOException e) {
// Could still work without script path.
// Script path is only needed to parse arguments from target.
logger.warn("Failed to create script path file. Target arguments will not be parsed.", e);
}
}
ListenableFuture<BuildResult> buildOperation =
BlazeBeforeRunCommandHelper.runBlazeCommand(
scriptPath.isPresent() ? BlazeCommandName.RUN : BlazeCommandName.BUILD,
configuration,
buildResultHelper,
flags.build(),
ImmutableList.of("--dynamic_mode=off", "--test_sharding_strategy=disabled"),
BlazeInvocationContext.runConfigContext(
ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), true),
"Building debug binary");
try {
BuildResult result = buildOperation.get();
if (result.outOfMemory()) {
throw new ExecutionException("Out of memory while trying to build debug target");
} else if (result.status == Status.BUILD_ERROR) {
throw new ExecutionException("Build error while trying to build debug target");
} else if (result.status == Status.FATAL_ERROR) {
throw new ExecutionException(
String.format(
"Fatal error (%d) while trying to build debug target", result.exitCode));
}
} catch (InterruptedException | CancellationException e) {
buildOperation.cancel(true);
throw new RunCanceledByUserException();
} catch (java.util.concurrent.ExecutionException e) {
throw new ExecutionException(e);
}
if (scriptPath.isPresent()) {
if (!Files.exists(scriptPath.get())) {
throw new ExecutionException(
String.format(
"No debugger executable script path file produced. Expected file at: %s",
scriptPath.get()));
}
WorkspaceRoot workspaceRoot = WorkspaceRoot.fromProject(project);
BlazeInfo blazeInfo =
BlazeProjectDataManager.getInstance(project).getBlazeProjectData().getBlazeInfo();
return parseScriptPathFile(workspaceRoot, blazeInfo.getExecutionRoot(), scriptPath.get());
} else {
List<File> candidateFiles;
try {
candidateFiles =
BlazeArtifact.getLocalFiles(
buildResultHelper.getBuildArtifactsForTarget(label, file -> true))
.stream()
.filter(File::canExecute)
.collect(Collectors.toList());
} catch (GetArtifactsException e) {
throw new ExecutionException(
String.format(
"Failed to get output artifacts when building %s: %s", label, e.getMessage()));
}
if (candidateFiles.isEmpty()) {
throw new ExecutionException(
String.format("No output artifacts found when building %s", label));
}
File binary = findExecutable(label, candidateFiles);
if (binary == null) {
throw new ExecutionException(
String.format(
"More than 1 executable was produced when building %s; "
+ "don't know which one to debug",
label));
}
LocalFileSystem.getInstance().refreshIoFiles(ImmutableList.of(binary));
File workingDir = getWorkingDirectory(WorkspaceRoot.fromProject(project), binary);
return new ExecutableInfo(binary, workingDir, ImmutableList.of(), ImmutableMap.of());
}
}
}