Skip to content

Commit 7f975bb

Browse files
committed
added BazelDebugFlagsBuilder
1 parent c44de25 commit 7f975bb

File tree

3 files changed

+71
-140
lines changed

3 files changed

+71
-140
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,62 @@
1+
/*
2+
* Copyright 2025 The Bazel Authors. All rights reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
116
package com.google.idea.blaze.clwb.run
217

318
import com.google.common.collect.ImmutableList
4-
import com.google.idea.blaze.clwb.run.BlazeGDBServerProvider.GDBSERVER_WRAPPER
19+
import com.intellij.openapi.util.registry.Registry
520
import com.intellij.util.system.OS
6-
import com.jetbrains.cidr.lang.workspace.compiler.ClangClCompilerKind
7-
import com.jetbrains.cidr.lang.workspace.compiler.ClangClSwitchBuilder
8-
import com.jetbrains.cidr.lang.workspace.compiler.ClangCompilerKind
9-
import com.jetbrains.cidr.lang.workspace.compiler.ClangSwitchBuilder
10-
import com.jetbrains.cidr.lang.workspace.compiler.GCCSwitchBuilder
11-
import com.jetbrains.cidr.lang.workspace.compiler.MSVCCompilerKind
12-
import com.jetbrains.cidr.lang.workspace.compiler.MSVCSwitchBuilder
13-
import com.jetbrains.cidr.lang.workspace.compiler.OCCompilerKind
14-
21+
import com.jetbrains.cidr.lang.workspace.compiler.*
22+
23+
/**
24+
* Builds flags for debugging a blaze target, flags are either used for just
25+
* building a binary [BlazeCidrRunConfigurationRunner] or for running actually
26+
* running the binary [BlazeGDBServerProvider].
27+
*
28+
* In theory we would like to have one builder that builds a BlazeCommand to
29+
* have full control over the environment in the builder.
30+
*/
1531
class BazelDebugFlagsBuilder(
1632
private val debuggerKind: BlazeDebuggerKind,
1733
private val compilerKind: OCCompilerKind,
18-
private val workspaceRoot: String,
1934
private val targetOS: OS,
20-
private val withDefaultFlags: Boolean = false,
2135
private val withClangTrimPaths: Boolean = true,
2236
private val withFissionFlag: Boolean = false,
2337
) {
2438

25-
private val flags = ImmutableList.builder<String>()
26-
27-
init {
28-
withBazelFlags()
29-
withCoptFlags()
39+
companion object {
40+
41+
@JvmStatic
42+
fun fromDefaults(
43+
debuggerKind: BlazeDebuggerKind,
44+
compilerKind: OCCompilerKind,
45+
) = BazelDebugFlagsBuilder(
46+
debuggerKind,
47+
compilerKind,
48+
OS.CURRENT,
49+
withClangTrimPaths = Registry.`is`("bazel.trim.absolute.path.disabled"),
50+
withFissionFlag = Registry.`is`("bazel.clwb.debug.fission.disabled"),
51+
)
3052
}
3153

32-
/**
33-
* Adds Bazel specific flags required for debug builds. They will invalidate
34-
* the cache, so only apply them when the [withDefaultFlags] is false.
35-
*/
36-
private fun withBazelFlags() {
37-
if (withDefaultFlags) return
54+
private val flags = ImmutableList.builder<String>()
3855

56+
fun withBuildFlags(workspaceRoot: String? = null) {
3957
flags.add("--compilation_mode=dbg")
4058
flags.add("--strip=never")
4159
flags.add("--dynamic_mode=off")
42-
}
43-
44-
private fun withCoptFlags() {
45-
if (withDefaultFlags) return
4660

4761
val switchBuilder = when (compilerKind) {
4862
MSVCCompilerKind -> MSVCSwitchBuilder()
@@ -54,7 +68,7 @@ class BazelDebugFlagsBuilder(
5468
switchBuilder.withDebugInfo(2) // ignored for msvc/clangcl
5569
switchBuilder.withDisableOptimization()
5670

57-
if (debuggerKind == BlazeDebuggerKind.BUNDLED_LLDB && withClangTrimPaths) {
71+
if (debuggerKind == BlazeDebuggerKind.BUNDLED_LLDB && withClangTrimPaths && workspaceRoot != null) {
5872
switchBuilder.withSwitch("-fdebug-compilation-dir=$workspaceRoot")
5973
}
6074

@@ -81,9 +95,11 @@ class BazelDebugFlagsBuilder(
8195

8296
fun withRunUnderGDBServer(gdbserver: String, port: Int, wrapperScript: String?) {
8397
if (wrapperScript != null) {
84-
flags.add("--run_under='bash' 'wrapperScript' 'gdbserver' --once localhost:$port --target")
98+
flags.add("--run_under='bash' '$wrapperScript' '$gdbserver' --once localhost:$port --target")
8599
} else {
86100
flags.add("--run_under='$gdbserver' --once localhost:$port")
87101
}
88102
}
103+
104+
fun build(): ImmutableList<String> = flags.build()
89105
}

clwb/src/com/google/idea/blaze/clwb/run/BlazeCidrRunConfigurationRunner.java

Lines changed: 17 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package com.google.idea.blaze.clwb.run;
1717

1818
import com.google.common.collect.ImmutableList;
19-
import com.google.common.util.concurrent.ListenableFuture;
2019
import com.google.idea.blaze.base.command.BlazeCommandName;
2120
import com.google.idea.blaze.base.command.BlazeInvocationContext;
2221
import com.google.idea.blaze.base.command.buildresult.GetArtifactsException;
@@ -38,7 +37,6 @@
3837
import com.intellij.execution.executors.DefaultDebugExecutor;
3938
import com.intellij.execution.runners.ExecutionEnvironment;
4039
import com.intellij.execution.runners.ExecutionUtil;
41-
import com.intellij.openapi.util.SystemInfo;
4240
import com.intellij.openapi.util.registry.Registry;
4341
import com.intellij.util.PathUtil;
4442
import com.jetbrains.cidr.execution.CidrCommandLineState;
@@ -98,36 +96,6 @@ private static Label getSingleTarget(BlazeCommandRunConfiguration config)
9896
return (Label) targets.get(0);
9997
}
10098

101-
private ImmutableList<String> getExtraDebugFlags(ExecutionEnvironment env) {
102-
if (Registry.is("bazel.clwb.debug.extraflags.disabled")) {
103-
return ImmutableList.of();
104-
}
105-
106-
final var debuggerKind = RunConfigurationUtils.getDebuggerKind(configuration);
107-
if (debuggerKind == BlazeDebuggerKind.GDB_SERVER) {
108-
return BlazeGDBServerProvider.getFlagsForDebugging(configuration.getHandler().getState());
109-
}
110-
111-
final var flagsBuilder = ImmutableList.<String>builder();
112-
113-
if (debuggerKind == BlazeDebuggerKind.BUNDLED_LLDB && !Registry.is("bazel.trim.absolute.path.disabled")) {
114-
flagsBuilder.add("--copt=-fdebug-compilation-dir=" + WorkspaceRoot.fromProject(env.getProject()));
115-
116-
if (SystemInfo.isMac) {
117-
flagsBuilder.add("--linkopt=-Wl,-oso_prefix,.");
118-
}
119-
}
120-
121-
flagsBuilder.add("--compilation_mode=dbg");
122-
flagsBuilder.add("--copt=-O0");
123-
flagsBuilder.add("--copt=-g");
124-
flagsBuilder.add("--strip=never");
125-
flagsBuilder.add("--dynamic_mode=off");
126-
flagsBuilder.addAll(BlazeGDBServerProvider.getOptionalFissionArguments());
127-
128-
return flagsBuilder.build();
129-
}
130-
13199
/**
132100
* Builds blaze C/C++ target in debug mode, and returns the output build artifact.
133101
*
@@ -136,15 +104,23 @@ private ImmutableList<String> getExtraDebugFlags(ExecutionEnvironment env) {
136104
private File getExecutableToDebug(ExecutionEnvironment env) throws ExecutionException {
137105
SaveUtil.saveAllFiles();
138106

139-
ListenableFuture<BuildEventStreamProvider> streamProviderFuture =
140-
BlazeBeforeRunCommandHelper.runBlazeCommand(
141-
BlazeCommandName.BUILD,
142-
configuration,
143-
ImmutableList.of(),
144-
getExtraDebugFlags(env),
145-
BlazeInvocationContext.runConfigContext(
146-
ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), true),
147-
"Building debug binary");
107+
final var flagsBuilder = BazelDebugFlagsBuilder.fromDefaults(
108+
RunConfigurationUtils.getDebuggerKind(configuration),
109+
RunConfigurationUtils.getCompilerKind(configuration)
110+
);
111+
112+
if (!Registry.is("bazel.clwb.debug.extraflags.disabled")) {
113+
flagsBuilder.withBuildFlags(WorkspaceRoot.fromProject(env.getProject()).toString());
114+
}
115+
116+
final var streamProviderFuture = BlazeBeforeRunCommandHelper.runBlazeCommand(
117+
BlazeCommandName.BUILD,
118+
configuration,
119+
ImmutableList.of(),
120+
flagsBuilder.build(),
121+
BlazeInvocationContext.runConfigContext(ExecutorType.fromExecutor(env.getExecutor()), configuration.getType(), true),
122+
"Building debug binary"
123+
);
148124

149125
Label target = getSingleTarget(configuration);
150126
try (BuildEventStreamProvider streamProvider = streamProviderFuture.get()) {

clwb/src/com/google/idea/blaze/clwb/run/BlazeGDBServerProvider.kt

Lines changed: 9 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,20 @@ package com.google.idea.blaze.clwb.run
1717

1818
import com.google.common.collect.ImmutableList
1919
import com.google.idea.blaze.base.command.BlazeCommandName
20-
import com.google.idea.blaze.base.command.BlazeFlags
2120
import com.google.idea.blaze.base.run.state.RunConfigurationState
2221
import com.google.idea.blaze.clwb.ToolchainUtils
23-
import com.google.idea.common.experiments.BoolExperiment
2422
import com.google.idea.sdkcompat.clion.debug.CidrDebuggerPathManagerAdapter
2523
import com.intellij.openapi.diagnostic.logger
26-
import com.intellij.openapi.util.registry.Registry
2724
import com.intellij.util.PathUtil
2825
import com.jetbrains.cidr.cpp.toolchains.CPPDebugger
2926
import com.jetbrains.cidr.cpp.toolchains.CPPToolchains
30-
import com.jetbrains.cidr.execution.debugger.CidrDebuggerPathManager
27+
import com.jetbrains.cidr.lang.workspace.compiler.GCCCompilerKind
3128
import java.nio.file.Files
3229
import java.nio.file.Path
3330
import kotlin.io.path.absolutePathString
3431

3532
private val LOG = logger<BlazeGDBServerProvider>()
3633

37-
private val USE_REMOTE_DEBUGGING_WRAPPER: BoolExperiment = BoolExperiment("cc.remote.debugging.wrapper", true)
38-
3934
private const val GDB_SERVER_PROPERTY = "clwb.gdbserverPath"
4035

4136
/** CLion-specific class that provides the slightly customized Toolchain for use with gdbserver */
@@ -55,80 +50,24 @@ object BlazeGDBServerProvider {
5550
}
5651
}
5752

58-
// These flags are used when debugging cc_binary targets when remote debugging
59-
// is enabled (cc.remote.debugging)
60-
private val EXTRA_FLAGS_FOR_DEBUG_RUN = ImmutableList.of<String>(
61-
"--compilation_mode=dbg", "--strip=never", "--dynamic_mode=off"
62-
)
63-
64-
// These flags are used when debugging cc_test targets when remote debugging
65-
// is enabled (cc.remote.debugging)
66-
private val EXTRA_FLAGS_FOR_DEBUG_TEST = ImmutableList.of<String>(
67-
"--compilation_mode=dbg",
68-
"--strip=never",
69-
"--dynamic_mode=off",
70-
"--test_timeout=3600",
71-
BlazeFlags.NO_CACHE_TEST_RESULTS,
72-
BlazeFlags.EXCLUSIVE_TEST_EXECUTION,
73-
BlazeFlags.DISABLE_TEST_SHARDING
74-
)
75-
76-
// Allows the fission flag to be disabled as workaround for
77-
@JvmStatic
78-
fun getOptionalFissionArguments(): ImmutableList<String> {
79-
return if (Registry.`is`("bazel.clwb.debug.fission.disabled")) {
80-
ImmutableList.of()
81-
} else {
82-
ImmutableList.of("--fission=yes")
83-
}
84-
}
85-
8653
@JvmStatic
8754
fun getFlagsForDebugging(state: RunConfigurationState?): ImmutableList<String> {
8855
if (state !is BlazeCidrRunConfigState) {
8956
return ImmutableList.of()
9057
}
9158

92-
val commandName = state.commandState.command
93-
val builder = ImmutableList.builder<String>()
59+
val builder = BazelDebugFlagsBuilder.fromDefaults(BlazeDebuggerKind.GDB_SERVER, GCCCompilerKind)
60+
builder.withBuildFlags()
9461

95-
val toolchain = ToolchainUtils.getToolchain()
96-
97-
// if gdbserver could not be found, fall back to trying PATH
98-
val gdbServerPath = getGDBServerPath(toolchain) ?: "gdbserver"
99-
100-
if (USE_REMOTE_DEBUGGING_WRAPPER.value) {
101-
builder.add(
102-
String.format(
103-
"--run_under='bash' '%s' '%s' --once localhost:%d --target",
104-
GDBSERVER_WRAPPER,
105-
gdbServerPath,
106-
state.getDebugPortState().port,
107-
)
108-
)
109-
} else {
110-
builder.add(
111-
String.format(
112-
"--run_under='%s' --once localhost:%d",
113-
gdbServerPath,
114-
state.getDebugPortState().port,
115-
)
116-
)
62+
if (state.commandState.command == BlazeCommandName.TEST) {
63+
builder.withTestFlags()
11764
}
11865

119-
if (BlazeCommandName.RUN == commandName) {
120-
builder.addAll(EXTRA_FLAGS_FOR_DEBUG_RUN)
121-
builder.addAll(getOptionalFissionArguments())
122-
return builder.build()
123-
}
124-
125-
if (BlazeCommandName.TEST == commandName) {
126-
builder.addAll(EXTRA_FLAGS_FOR_DEBUG_TEST)
127-
builder.addAll(getOptionalFissionArguments())
128-
return builder.build()
129-
}
66+
// if gdbserver could not be found, fall back to trying PATH
67+
val gdbServerPath = getGDBServerPath(ToolchainUtils.getToolchain()) ?: "gdbserver"
68+
builder.withRunUnderGDBServer(gdbServerPath, state.getDebugPortState().port, GDBSERVER_WRAPPER)
13069

131-
return ImmutableList.of()
70+
return builder.build()
13271
}
13372

13473
private fun getGDBServerPath(toolchain: CPPToolchains.Toolchain): String? {

0 commit comments

Comments
 (0)