Skip to content

Fix "CMake: Run Without Debugging" not changing working directory when build directory changes#4694

Merged
snehara99 merged 6 commits intomainfrom
copilot/fix-cmake-working-directory-issue
Feb 9, 2026
Merged

Fix "CMake: Run Without Debugging" not changing working directory when build directory changes#4694
snehara99 merged 6 commits intomainfrom
copilot/fix-cmake-working-directory-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Feb 3, 2026

This change addresses item #4549

This changes visible behavior

The following changes are proposed:

  • Add cwd comparison to terminal reuse logic in createTerminal()
  • Dispose and recreate terminal when working directory changes (not just environment)

The purpose of this change

When switching Configuration Presets or changing cmake.buildDirectory, the launch terminal's working directory was not updated. The terminal reuse logic only compared environment variables:

// Before: only checked env
if (JSON.stringify(creationOptions.env) !== JSON.stringify(options.env)) {
    terminal.dispose();
    break;
}

Now also checks cwd using JSON.stringify() for consistency:

// After: checks both env and cwd
if (JSON.stringify(creationOptions.env) !== JSON.stringify(options.env) ||
    JSON.stringify(creationOptions.cwd) !== JSON.stringify(options.cwd)) {
    terminal.dispose();
    break;
}

This ensures a new terminal is created with the correct working directory when the build directory changes.

Other Notes/Information

Terminal Recreation Timing: The terminal is only recreated when the user explicitly runs CMake: Run Without Debugging. The createTerminal() method is private and only called from launchTarget(). Directory changes alone do not trigger terminal recreation.

Flow:

  1. User changes preset (directory changes, but no terminal action occurs)
  2. User runs "CMake: Run Without Debugging"
  3. launchTarget() calls createTerminal()
  4. createTerminal() compares new cwd with existing terminal's cwd
  5. If different, disposes old terminal and creates new one with correct cwd
Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug] current working directory is not changed when using CMake: Run Without Debugging</issue_title>
<issue_description>### Brief Issue Summary

When binaryDir is changed by changing Configuration Preset, or by using cmake.buildDirectory in settings.json file, CMake: Run Without Debugging (from status bar or via Command Palette) doesn't change directory of Cmake/Launch terminal.

CMake Tools Diagnostics

{
  "os": "win32",
  "vscodeVersion": "1.103.1",
  "cmtVersion": "1.21.36",
  "configurations": [
    {
      "folder": "e:\\DEV\\C++\\Projects\\vscode-cmake-wrong-directory",
      "cmakeVersion": "4.1.0",
      "configured": true,
      "generator": "Ninja",
      "usesPresets": true,
      "compilers": {
        "C": "cl.exe",
        "CXX": "cl.exe"
      }
    }
  ],
  "cpptoolsIntegration": {
    "isReady": true,
    "hasCodeModel": true,
    "activeBuildType": "Release",
    "buildTypesSeen": [
      "Release"
    ],
    "requests": [],
    "responses": [],
    "partialMatches": [],
    "targetCount": 1,
    "executablesCount": 1,
    "librariesCount": 0,
    "targets": [
      {
        "name": "HelloWorld",
        "type": "EXECUTABLE"
      }
    ]
  },
  "settings": [
    {
      "communicationMode": "automatic",
      "useCMakePresets": "always",
      "configureOnOpen": true
    }
  ]
}

Debug Log

[main] Building folder: E:/DEV/C++/Projects/vscode-cmake-wrong-directory/build/Windows-MSVC-Release HelloWorld
[main] Saving open files before configure/build
[build] Starting build
[driver] Start build HelloWorld
[proc] Executing command: "C:\Program Files\CMake\bin\cmake.EXE" --build E:/DEV/C++/Projects/vscode-cmake-wrong-directory/build/Windows-MSVC-Release --config Release --target HelloWorld --
[proc]   with environment: ######################## N/A ########################
[build] ninja: no work to do.
[driver] Build completed: 00:00:00.048
[cmakefileapi-parser] Read reply folder: E:\DEV\C++\Projects\vscode-cmake-wrong-directory\build\Windows-MSVC-Release\.cmake\api\v1\reply
[cmakefileapi-parser] Found index files: ["cache-v2-f7a7b30d5606e31d8cbf.json","cmakeFiles-v1-fe9c08706dd55d49eb4d.json","codemodel-v2-376011dbf1f65144925d.json","directory-.-Release-d0094a50bb2071803777.json","index-2025-08-15T18-12-38-0913.json","target-HelloWorld-Release-ddab750cf9c9297d5e78.json","toolchains-v1-b72720c52195983157ee.json"]
[build] Build finished with exit code 0
[cache] Reading CMake cache file E:/DEV/C++/Projects/vscode-cmake-wrong-directory/build/Windows-MSVC-Release/CMakeCache.txt
[cache] Parsing CMake cache string
[extension] [7295] cmake.launchTarget finished (returned {"name":"CMake/Launch - HelloWorld","processId":{},"creationOptions":{"name":"CMake/Launch - HelloWorld","env":{"########################": "N/A ########################","CC":"cl.exe","CXX":"cl.exe","_CMAKE_TOOLS_LAUNCH_TERMINAL_TARGET_NAME":"HelloWorld","_CMAKE_TOOLS_LAUNCH_TERMINAL_PATH":"C:\\WINDOWS\\System32\\cmd.exe"},"cwd":"E:\\DEV\\C++\\Projects\\vscode-cmake-wrong-directory\\build\\Windows-MSVC-Debug"},"state":{"isInteractedWith":true,"shell":"cmd"},"dimensions":{"columns":175,"rows":20}})
[extension] [7730] cmake.logDiagnostics started
[extension] [7730] cmake.logDiagnostics finished (returned undefined)

Additional Information

Using a simple c++ program to print current path:
Image
Image

Steps to reproduce:

  1. vscode-cmake-wrong-directory.zip
  2. set preset to "GCC-Debug" run with status bar or via CMake: Run Without Debugging
  3. set preset to "GCC-Release" run with status bar or via CMake: Run Without Debugging
  4. set preset to "Clang-Debug" run with status bar or via CMake: Run Without Debugging
  5. set preset to "Clang-Release" run with status bar or via CMake: Run Without Debugging
  6. see that all are run inside GCC-Debug directory

Also, I noticed that changing compiler to or from MSVC resets CMake/launch terminal (probably to set up environment) and because of this reset changing compiler to or from MSVC doesn't cause this issue. (changing configuration while in MSVC still causes this issue though)
Changing compiler between GCC and Clang causes this issue because terminal is not reset.</issue_description>

<agent_instructions>You are Copilot coding agent acting as a senior maintainer/contributor for the VS Code extension repository microsoft/vscode-cmake-tools.

You are deeply familiar with CMake, CMake Presets, CTest, kit/toolchain selection, VS Code extension APIs, and the architecture of this repo.

Your job is to resolve the...


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix working directory not changing in CMake Fix "CMake: Run Without Debugging" not changing working directory when build directory changes Feb 3, 2026
Copilot AI requested a review from snehara99 February 3, 2026 20:55
@snehara99
Copy link
Copy Markdown
Contributor

@copilot a new terminal is only needed once CMake: Run Without Debugging is called. We don't want a new terminal every directory change unless that command is called.

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot a new terminal is only needed once CMake: Run Without Debugging is called. We don't want a new terminal every directory change unless that command is called.

The implementation only checks and recreates the terminal when CMake: Run Without Debugging is called. The createTerminal method is private and only invoked from launchTarget(). The terminal isn't disposed on directory change events - it's only checked (and disposed if cwd differs) when the user explicitly runs the launch command.

Flow:

  1. User changes preset (directory changes, but no terminal action)
  2. User runs "CMake: Run Without Debugging"
  3. launchTarget() calls createTerminal()
  4. createTerminal() compares new cwd with existing terminal's cwd
  5. If different, disposes old terminal and creates new one with correct cwd

@snehara99
Copy link
Copy Markdown
Contributor

@copilot a new terminal is only needed once CMake: Run Without Debugging is called. We don't want a new terminal every directory change unless that command is called.

The implementation only checks and recreates the terminal when CMake: Run Without Debugging is called. The createTerminal method is private and only invoked from launchTarget(). The terminal isn't disposed on directory change events - it's only checked (and disposed if cwd differs) when the user explicitly runs the launch command.

Flow:

  1. User changes preset (directory changes, but no terminal action)
  2. User runs "CMake: Run Without Debugging"
  3. launchTarget() calls createTerminal()
  4. createTerminal() compares new cwd with existing terminal's cwd
  5. If different, disposes old terminal and creates new one with correct cwd

@copilot can you update the PR description clarifying this?

Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot a new terminal is only needed once CMake: Run Without Debugging is called. We don't want a new terminal every directory change unless that command is called.

The implementation o...

Updated the PR description with a new "Important: Terminal Recreation Timing" section that clarifies this behavior.

@snehara99
Copy link
Copy Markdown
Contributor

@copilot you linked the wrong issue in this PR and in the changelog. #4549 is the correct issue

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Feb 3, 2026

@copilot you linked the wrong issue in this PR and in the changelog. #4549 is the correct issue

Fixed in 7b6c064. Updated both the CHANGELOG.md and PR description to reference #4549.

@snehara99 snehara99 marked this pull request as ready for review February 9, 2026 19:28
Copy link
Copy Markdown
Contributor

@snehara99 snehara99 left a comment

Choose a reason for hiding this comment

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

Tested locally, and the fix appropriately updates the directory path.

@snehara99 snehara99 enabled auto-merge (squash) February 9, 2026 19:32
@snehara99
Copy link
Copy Markdown
Contributor

@copilot can you use JSON.stringify() for the conditional you added to be consistent with the other one?

Co-authored-by: snehara99 <113148726+snehara99@users.noreply.github.com>
Copilot AI requested a review from snehara99 February 9, 2026 19:36
@snehara99 snehara99 merged commit a462db4 into main Feb 9, 2026
4 checks passed
@snehara99 snehara99 deleted the copilot/fix-cmake-working-directory-issue branch February 9, 2026 20:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] current working directory is not changed when using CMake: Run Without Debugging

3 participants