Skip to content

Commit 140a888

Browse files
CopilotOmotola
andauthored
Add "Delete Build Directory and Reconfigure" commands (#4826)
* Initial plan * Add "Delete Build Directory and Reconfigure" commands Add new commands that remove the entire build directory before reconfiguring, providing a completely clean state beyond what "Delete Cache and Reconfigure" offers. New commands: - cmake.fullCleanConfigure - cmake.fullCleanConfigureAll - cmake.fullCleanConfigureAndBuild - cmake.fullCleanConfigureAndBuildAll - cmake.outline.fullCleanConfigureAll - cmake.outline.fullCleanConfigureAndBuildAll Resolves #4833 Co-authored-by: Omotola <[email protected]> * Restore .npmrc and yarn.lock (undo build-time modifications) Co-authored-by: Omotola <[email protected]> * Fix duplicate outline context menu entry and group position collision Co-authored-by: Omotola <[email protected]> * Update changelog entry to reference PR #4826 Co-authored-by: Omotola <[email protected]> Agent-Logs-Url: https://github.com/microsoft/vscode-cmake-tools/sessions/d042c8d9-2cdd-4735-9748-aef1b41aa9b5 --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: Omotola <[email protected]> Co-authored-by: Omotola <[email protected]>
1 parent a12ba8d commit 140a888

7 files changed

Lines changed: 171 additions & 1 deletion

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## 1.23
44

55
Features:
6+
- Add "Delete Build Directory and Reconfigure" command that removes the entire build directory before reconfiguring, ensuring a completely clean state. [#4826](https://github.com/microsoft/vscode-cmake-tools/pull/4826)
67
- Add `cmake.shell` setting to route CMake/CTest/CPack subprocess invocations through a custom shell (e.g., Git Bash, MSYS2), enabling embedded toolchains that require POSIX path translation on Windows. [#1750](https://github.com/microsoft/vscode-cmake-tools/issues/1750)
78
- triple: Add riscv32be riscv64be support. [#4648](https://github.com/microsoft/vscode-cmake-tools/pull/4648) [@lygstate](https://github.com/lygstate)
89
- Add command to clear build diagnostics from the Problems pane. [#4691](https://github.com/microsoft/vscode-cmake-tools/pull/4691)

docs/configure.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ A clean configure is required for certain build system changes, such as when the
5656

5757
CMake Tools will do a clean configure automatically if you change the active kit.
5858

59+
## Full clean configure
60+
61+
To get CMake Tools to do a full clean configure, run **CMake: Delete Build Directory and Reconfigure** from the command palette in VS Code.
62+
63+
A full clean configure deletes the entire build directory before reconfiguring. This goes beyond the standard clean configure by removing all build artifacts, not just CMake's cache and internal files. This is useful when CMake reuses stale build artifacts that cause unexpected errors, or when third-party tools write extra files into the build directory.
64+
5965
## Configure with CMake Debugger
6066

6167
In order to investigate errors with Configuring your CMake project, you can add breakpoints in your CMakeLists.txt and .cmake files and run **CMake: Configure with CMake Debugger** from the command palette in VS Code.

package.json

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,20 @@
575575
"title": "%cmake-tools.command.cmake.outline.cleanConfigureAllWithDebugger.title%",
576576
"enablement": "cmake:cmakeDebuggerAvailable"
577577
},
578+
{
579+
"command": "cmake.fullCleanConfigure",
580+
"title": "%cmake-tools.command.cmake.fullCleanConfigure.title%",
581+
"category": "CMake"
582+
},
583+
{
584+
"command": "cmake.fullCleanConfigureAll",
585+
"title": "%cmake-tools.command.cmake.fullCleanConfigureAll.title%",
586+
"category": "CMake"
587+
},
588+
{
589+
"command": "cmake.outline.fullCleanConfigureAll",
590+
"title": "%cmake-tools.command.cmake.outline.fullCleanConfigureAll.title%"
591+
},
578592
{
579593
"command": "cmake.clean",
580594
"title": "%cmake-tools.command.cmake.clean.title%",
@@ -638,6 +652,20 @@
638652
"command": "cmake.outline.cleanConfigureAndBuildAll",
639653
"title": "%cmake-tools.command.cmake.outline.cleanConfigureAndBuildAll.title%"
640654
},
655+
{
656+
"command": "cmake.fullCleanConfigureAndBuild",
657+
"title": "%cmake-tools.command.cmake.fullCleanConfigureAndBuild.title%",
658+
"category": "CMake"
659+
},
660+
{
661+
"command": "cmake.fullCleanConfigureAndBuildAll",
662+
"title": "%cmake-tools.command.cmake.fullCleanConfigureAndBuildAll.title%",
663+
"category": "CMake"
664+
},
665+
{
666+
"command": "cmake.outline.fullCleanConfigureAndBuildAll",
667+
"title": "%cmake-tools.command.cmake.outline.fullCleanConfigureAndBuildAll.title%"
668+
},
641669
{
642670
"command": "cmake.editCacheUI",
643671
"when": "cmake:enableFullFeatureSet",
@@ -1361,6 +1389,13 @@
13611389
"command": "cmake.cleanConfigureAllWithDebugger",
13621390
"when": "cmake:multiProject && cmake:cmakeDebuggerAvailable"
13631391
},
1392+
{
1393+
"command": "cmake.fullCleanConfigure"
1394+
},
1395+
{
1396+
"command": "cmake.fullCleanConfigureAll",
1397+
"when": "cmake:multiProject"
1398+
},
13641399
{
13651400
"command": "cmake.clean",
13661401
"when": "cmake:enableFullFeatureSet"
@@ -1384,6 +1419,13 @@
13841419
"command": "cmake.cleanConfigureAndBuildAll",
13851420
"when": "cmake:multiProject"
13861421
},
1422+
{
1423+
"command": "cmake.fullCleanConfigureAndBuild"
1424+
},
1425+
{
1426+
"command": "cmake.fullCleanConfigureAndBuildAll",
1427+
"when": "cmake:multiProject"
1428+
},
13871429
{
13881430
"command": "cmake.editCacheUI",
13891431
"when": "cmake:enableFullFeatureSet"
@@ -1512,6 +1554,10 @@
15121554
"command": "cmake.outline.cleanConfigureAllWithDebugger",
15131555
"when": "never"
15141556
},
1557+
{
1558+
"command": "cmake.outline.fullCleanConfigureAll",
1559+
"when": "never"
1560+
},
15151561
{
15161562
"command": "cmake.outline.clean",
15171563
"when": "never"
@@ -1536,6 +1582,10 @@
15361582
"command": "cmake.outline.cleanConfigureAndBuildAll",
15371583
"when": "never"
15381584
},
1585+
{
1586+
"command": "cmake.outline.fullCleanConfigureAndBuildAll",
1587+
"when": "never"
1588+
},
15391589
{
15401590
"command": "cmake.outline.editCacheUI",
15411591
"when": "never"
@@ -1770,6 +1820,11 @@
17701820
"when": "view == cmake.outline && cmake:cmakeDebuggerAvailable",
17711821
"group": "1_cmakeOutline"
17721822
},
1823+
{
1824+
"command": "cmake.outline.fullCleanConfigureAll",
1825+
"when": "view == cmake.outline",
1826+
"group": "1_cmakeOutline"
1827+
},
17731828
{
17741829
"command": "cmake.outline.cleanRebuildAll",
17751830
"when": "view == cmake.outline && cmake:enableFullFeatureSet",
@@ -1780,6 +1835,11 @@
17801835
"when": "view == cmake.outline",
17811836
"group": "1_cmakeOutline"
17821837
},
1838+
{
1839+
"command": "cmake.outline.fullCleanConfigureAndBuildAll",
1840+
"when": "view == cmake.outline",
1841+
"group": "1_cmakeOutline"
1842+
},
17831843
{
17841844
"command": "cmake.outline.editCacheUI",
17851845
"when": "view == cmake.outline && cmake:enableFullFeatureSet",
@@ -2059,6 +2119,16 @@
20592119
"when": "view == cmake.outline && viewItem =~ /nodeType=file/ && viewItem =~ /cmakelists=true/",
20602120
"group": "1_fileActions@7"
20612121
},
2122+
{
2123+
"command": "cmake.outline.fullCleanConfigureAll",
2124+
"when": "view == cmake.outline && viewItem =~ /nodeType=file/ && viewItem =~ /cmakelists=true/",
2125+
"group": "1_fileActions@8"
2126+
},
2127+
{
2128+
"command": "cmake.outline.fullCleanConfigureAndBuildAll",
2129+
"when": "view == cmake.outline && viewItem =~ /nodeType=file/ && viewItem =~ /cmakelists=true/",
2130+
"group": "1_fileActions@9"
2131+
},
20622132
{
20632133
"command": "cmake.outline.compileFile",
20642134
"when": "cmake:enableFullFeatureSet && view == cmake.outline && viewItem =~ /nodeType=file/ && viewItem =~ /compilable=true/",
@@ -2212,6 +2282,14 @@
22122282
{
22132283
"command": "cmake.outline.cleanConfigureAndBuildAll",
22142284
"when": "resourceFilename == CMakeLists.txt"
2285+
},
2286+
{
2287+
"command": "cmake.outline.fullCleanConfigureAll",
2288+
"when": "resourceFilename == CMakeLists.txt"
2289+
},
2290+
{
2291+
"command": "cmake.outline.fullCleanConfigureAndBuildAll",
2292+
"when": "resourceFilename == CMakeLists.txt"
22152293
}
22162294
],
22172295
"touchBar": [

package.nls.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@
4646
"cmake-tools.command.cmake.cleanConfigureWithDebugger.title": "Delete Cache and Reconfigure with CMake Debugger",
4747
"cmake-tools.command.cmake.cleanConfigureAll.title": "Delete Cache and Reconfigure All Projects",
4848
"cmake-tools.command.cmake.cleanConfigureAllWithDebugger.title": "Delete Cache and Reconfigure All Projects with CMake Debugger",
49+
"cmake-tools.command.cmake.fullCleanConfigure.title": "Delete Build Directory and Reconfigure",
50+
"cmake-tools.command.cmake.fullCleanConfigureAll.title": "Delete Build Directory and Reconfigure All Projects",
51+
"cmake-tools.command.cmake.outline.fullCleanConfigureAll.title": "Full Clean Reconfigure All Projects",
4952
"cmake-tools.command.cmake.editCacheUI.title": "Edit CMake Cache (UI)",
5053
"cmake-tools.command.cmake.outline.cleanConfigure.title": "Clean Reconfigure",
5154
"cmake-tools.command.cmake.outline.cleanConfigureWithDebugger.title": "Clean Reconfigure with CMake Debugger",
@@ -58,6 +61,9 @@
5861
"cmake-tools.command.cmake.cleanConfigureAndBuild.title": "Delete Cache, Reconfigure and Build",
5962
"cmake-tools.command.cmake.cleanConfigureAndBuildAll.title": "Delete Cache, Reconfigure and Build All Projects",
6063
"cmake-tools.command.cmake.outline.cleanConfigureAndBuildAll.title": "Clean Reconfigure and Build All Projects",
64+
"cmake-tools.command.cmake.fullCleanConfigureAndBuild.title": "Delete Build Directory, Reconfigure and Build",
65+
"cmake-tools.command.cmake.fullCleanConfigureAndBuildAll.title": "Delete Build Directory, Reconfigure and Build All Projects",
66+
"cmake-tools.command.cmake.outline.fullCleanConfigureAndBuildAll.title": "Full Clean Reconfigure and Build All Projects",
6167
"cmake-tools.command.cmake.ctest.title": "Run Tests",
6268
"cmake-tools.command.cmake.ctestAll.title": "Run Tests for All Projects",
6369
"cmake-tools.command.cmake.cpack.title": "Run CPack",

src/cmakeProject.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ export enum ConfigureType {
7070
Cache,
7171
ShowCommandOnly,
7272
NormalWithDebugger,
73-
CleanWithDebugger
73+
CleanWithDebugger,
74+
FullClean
7475
}
7576

7677
export enum ConfigureTrigger {
@@ -100,6 +101,8 @@ export enum ConfigureTrigger {
100101
commandCleanConfigureAll = "commandCleanConfigureAll",
101102
commandCleanConfigureAllWithDebugger = "commandConfigureAllWithDebugger",
102103
projectOutlineCleanConfigureAllWithDebugger = "projectOutlineCleanConfigureAllWithDebugger",
104+
commandFullCleanConfigure = "commandFullCleanConfigure",
105+
commandFullCleanConfigureAll = "commandFullCleanConfigureAll",
103106
configureFailedConfigureWithDebuggerButton = "configureFailedConfigureWithDebuggerButton",
104107
taskProvider = "taskProvider",
105108
selectConfigurePreset = "selectConfigurePreset",
@@ -1740,6 +1743,9 @@ export class CMakeProject {
17401743
case ConfigureType.ShowCommandOnly:
17411744
result = await drv.configure(trigger, extraArgs, consumer, cancelInformation, undefined, false, true);
17421745
break;
1746+
case ConfigureType.FullClean:
1747+
result = await drv.fullCleanConfigure(trigger, extraArgs, consumer, cancelInformation);
1748+
break;
17431749
default:
17441750
rollbar.error(localize('unexpected.configure.type', 'Unexpected configure type'), { type });
17451751
result = await this.configureInternal(trigger, extraArgs, ConfigureType.Normal);
@@ -1840,6 +1846,14 @@ export class CMakeProject {
18401846
return this.configureInternal(trigger, [], ConfigureType.CleanWithDebugger, debuggerInformation);
18411847
}
18421848

1849+
/**
1850+
* Implementation of `cmake.fullCleanConfigure()`
1851+
* Removes the entire build directory contents before reconfiguring.
1852+
*/
1853+
fullCleanConfigure(trigger: ConfigureTrigger = ConfigureTrigger.api, cancellationToken?: vscode.CancellationToken) {
1854+
return this.configureInternal(trigger, [], ConfigureType.FullClean, undefined, cancellationToken);
1855+
}
1856+
18431857
/**
18441858
* Save all open files. "maybe" because the user may have disabled auto-saving
18451859
* with `config.saveBeforeBuild`.
@@ -2507,6 +2521,14 @@ export class CMakeProject {
25072521
return (await this.build()).exitCode;
25082522
}
25092523

2524+
async fullCleanConfigureAndBuild(trigger: ConfigureTrigger = ConfigureTrigger.api): Promise<number> {
2525+
const configureResult = (await this.fullCleanConfigure(trigger)).exitCode;
2526+
if (configureResult !== 0) {
2527+
return configureResult;
2528+
}
2529+
return (await this.build()).exitCode;
2530+
}
2531+
25102532
public async runCTestCustomized(driver: CMakeDriver, testPreset?: preset.TestPreset, consumer?: proc.CommandConsumer) {
25112533
return this.cTestController.runCTest(driver, true, testPreset, consumer);
25122534
}

src/drivers/cmakeDriver.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,17 @@ export abstract class CMakeDriver implements vscode.Disposable {
616616
}
617617
}
618618

619+
/**
620+
* Remove the entire build directory.
621+
*/
622+
protected async _cleanBuildDirectory() {
623+
const build_dir = this.binaryDir;
624+
if (await fs.exists(build_dir)) {
625+
log.info(localize('removing', 'Removing {0}', encodeURI(build_dir)));
626+
await fs.rmdir(build_dir);
627+
}
628+
}
629+
619630
/**
620631
* Change the current configure preset. This lets the driver reload, if necessary.
621632
* @param configurePreset The new configure preset
@@ -1131,6 +1142,26 @@ export abstract class CMakeDriver implements vscode.Disposable {
11311142
return this.configure(trigger, extra_args, consumer, cancelInformation, debuggerInformation);
11321143
}
11331144

1145+
/**
1146+
* Perform a full clean configure. Deletes the entire build directory before running the config.
1147+
* @param consumer The output consumer
1148+
*/
1149+
public async fullCleanConfigure(trigger: ConfigureTrigger, extra_args: string[], consumer?: proc.OutputConsumer, cancelInformation?: ConfigureCancelInformation): Promise<ConfigureResult> {
1150+
if (this.isConfigInProgress) {
1151+
await this.preconditionHandler(CMakePreconditionProblems.ConfigureIsAlreadyRunning);
1152+
return { exitCode: -1, resultType: ConfigureResultType.ForcedCancel };
1153+
}
1154+
if (this.cmakeBuildRunner.isBuildInProgress()) {
1155+
await this.preconditionHandler(CMakePreconditionProblems.BuildIsAlreadyRunning);
1156+
return { exitCode: -1, resultType: ConfigureResultType.ConfigureInProgress };
1157+
}
1158+
this.isConfigInProgress = true;
1159+
await this._cleanBuildDirectory();
1160+
this.isConfigInProgress = false;
1161+
1162+
return this.configure(trigger, extra_args, consumer, cancelInformation);
1163+
}
1164+
11341165
async testCompilerVersion(program: string, cwd: string, arg: string | undefined, regexp: RegExp, captureGroup: number): Promise<string | undefined> {
11351166
const args = [];
11361167
if (arg) {

src/extension.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,16 @@ export class ExtensionManager implements vscode.Disposable {
14361436
return this.runCMakeCommandForAll(async cmakeProject => (await cmakeProject.cleanConfigure(ConfigureTrigger.commandCleanConfigureAll)).exitCode, undefined, true);
14371437
}
14381438

1439+
fullCleanConfigure(folder?: vscode.WorkspaceFolder) {
1440+
telemetry.logEvent("deleteBuildDirAndReconfigure");
1441+
return this.runCMakeCommand(async cmakeProject => (await cmakeProject.fullCleanConfigure(ConfigureTrigger.commandFullCleanConfigure)).exitCode, folder, undefined, true);
1442+
}
1443+
1444+
fullCleanConfigureAll() {
1445+
telemetry.logEvent("deleteBuildDirAndReconfigure");
1446+
return this.runCMakeCommandForAll(async cmakeProject => (await cmakeProject.fullCleanConfigure(ConfigureTrigger.commandFullCleanConfigureAll)).exitCode, undefined, true);
1447+
}
1448+
14391449
cleanConfigureAllWithDebugger(trigger?: ConfigureTrigger) {
14401450
return vscode.debug.startDebugging(undefined, {
14411451
name: localize("cmake.debug.name", "CMake Debugger"),
@@ -1605,6 +1615,16 @@ export class ExtensionManager implements vscode.Disposable {
16051615
return this.runCMakeCommandForAll(cmakeProject => cmakeProject.cleanConfigureAndBuild(ConfigureTrigger.commandCleanConfigureAll), this.ensureActiveBuildPreset, true);
16061616
}
16071617

1618+
fullCleanConfigureAndBuild(folder?: vscode.WorkspaceFolder) {
1619+
telemetry.logEvent("deleteBuildDirReconfigureAndBuild", { all: "false"});
1620+
return this.runCMakeCommand(cmakeProject => cmakeProject.fullCleanConfigureAndBuild(ConfigureTrigger.commandFullCleanConfigure), folder, this.ensureActiveBuildPreset, true);
1621+
}
1622+
1623+
fullCleanConfigureAndBuildAll() {
1624+
telemetry.logEvent("deleteBuildDirReconfigureAndBuild", { all: "true"});
1625+
return this.runCMakeCommandForAll(cmakeProject => cmakeProject.fullCleanConfigureAndBuild(ConfigureTrigger.commandFullCleanConfigureAll), this.ensureActiveBuildPreset, true);
1626+
}
1627+
16081628
async buildWithTarget(target?: string) {
16091629
telemetry.logEvent("build", { command: "buildWithTarget", all: "false"});
16101630
this.cleanOutputChannel();
@@ -2461,10 +2481,14 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
24612481
'cleanConfigureWithDebugger',
24622482
'cleanConfigureAll',
24632483
'cleanConfigureAllWithDebugger',
2484+
'fullCleanConfigure',
2485+
'fullCleanConfigureAll',
24642486
'cleanRebuild',
24652487
'cleanRebuildAll',
24662488
'cleanConfigureAndBuild',
24672489
'cleanConfigureAndBuildAll',
2490+
'fullCleanConfigureAndBuild',
2491+
'fullCleanConfigureAndBuildAll',
24682492
'configure',
24692493
'configureWithDebugger',
24702494
'showConfigureCommand',
@@ -2643,9 +2667,11 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
26432667
vscode.commands.registerCommand('cmake.outline.cleanAll', () => runCommand('cleanAll')),
26442668
vscode.commands.registerCommand('cmake.outline.cleanConfigureAll', () => runCommand('cleanConfigureAll')),
26452669
vscode.commands.registerCommand('cmake.outline.cleanConfigureAllWithDebugger', () => runCommand('cleanConfigureAllWithDebugger', ConfigureTrigger.projectOutlineCleanConfigureAllWithDebugger)),
2670+
vscode.commands.registerCommand('cmake.outline.fullCleanConfigureAll', () => runCommand('fullCleanConfigureAll')),
26462671
vscode.commands.registerCommand('cmake.outline.editCacheUI', () => runCommand('editCacheUI')),
26472672
vscode.commands.registerCommand('cmake.outline.cleanRebuildAll', () => runCommand('cleanRebuildAll')),
26482673
vscode.commands.registerCommand('cmake.outline.cleanConfigureAndBuildAll', () => runCommand('cleanConfigureAndBuildAll')),
2674+
vscode.commands.registerCommand('cmake.outline.fullCleanConfigureAndBuildAll', () => runCommand('fullCleanConfigureAndBuildAll')),
26492675
// Commands for outline items
26502676
vscode.commands.registerCommand('cmake.outline.configure', async (what: ProjectNode|SourceFileNode) => {
26512677
if (what instanceof ProjectNode) {

0 commit comments

Comments
 (0)