Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion src/cmakeProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ export class CMakeProject {
* Whether we use presets
*/
private _useCMakePresets = false; // The default value doesn't matter, value is set when folder is loaded

/**
* When true, doCMakeFileChangeReconfigure() will skip the automatic
* configure-on-edit triggered by the file-save event. This is set by
* maybeAutoSaveAll() around the saveAll() call so that command-initiated
* saves (build, test, etc.) don't race with the watcher-triggered
* reconfigure (see #4794).
*/
private _suppressCMakeFileReconfigure = false;
get useCMakePresets(): boolean {
return this._useCMakePresets;
}
Expand Down Expand Up @@ -1877,6 +1886,13 @@ export class CMakeProject {
log.debug(localize('saving.open.files.before', 'Saving open files before configure/build'));
}

// Suppress the automatic configure-on-edit that would otherwise be
// triggered by the save event for CMake files (CMakeLists.txt and
// included .cmake files). The caller (build, test, etc.) will
// perform its own configure if needed, so the watcher-triggered
// configure would be redundant and racy (#4794).
this._suppressCMakeFileReconfigure = true;

Comment on lines +1889 to +1895
Copy link

Copilot AI Mar 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is a user-visible regression fix (avoids “Configuration is already in progress” when a command triggers saveAll with dirty CMake files), but there doesn’t appear to be coverage for it in the existing VS Code extension end-to-end tests. Adding a test that dirties CMakeLists.txt (or an included .cmake), triggers a command that calls maybeAutoSaveAll() (e.g., runTests/build), and asserts no overlapping configure is started would help prevent regressions.

Copilot uses AI. Check for mistakes.
const cmakeConfiguration = vscode.workspace.getConfiguration('cmake');
const showSaveFailedNotificationString = "showNotAllDocumentsSavedQuestion";

Expand Down Expand Up @@ -1911,9 +1927,14 @@ export class CMakeProject {
const saved = chosen !== undefined && (chosen.title === yesButtonTitle || chosen.title === yesAndDoNotShowAgain);
if (!saved) {
this.presetsController.suppressWatcherReapply = false;
this._suppressCMakeFileReconfigure = false;
return false;
}
}

// Resume normal CMake file watcher behavior now that the
// command-initiated save is complete.
this._suppressCMakeFileReconfigure = false;
}

// After saving, explicitly refresh presets from disk so that any
Expand Down Expand Up @@ -2088,7 +2109,13 @@ export class CMakeProject {
// CMakeLists.txt change event: its creation or deletion are relevant,
// so update full/partial feature set view for this folder.
await updateFullFeatureSet();
if (driver && !driver.configOrBuildInProgress()) {
if (this._suppressCMakeFileReconfigure) {
// A command-initiated save (build, test, etc.) is in progress.
// Skip the automatic reconfigure — the calling command will
// configure if needed, avoiding the "Configuration is already
// in progress" race condition (see #4794).
log.debug(localize('cmake.file.save.suppressed', "CMake file saved by command-initiated save; skipping automatic reconfigure."));
} else if (driver && !driver.configOrBuildInProgress()) {
if (driver.config.configureOnEdit) {
log.debug(localize('cmakelists.save.trigger.reconfigure', "Detected saving of CMakeLists.txt, attempting automatic reconfigure..."));
if (this.workspaceContext.config.clearOutputBeforeBuild) {
Expand Down
Loading