Skip to content

Make Visual Studio CMake integration work #99584

Description

@stuartmorgan-g

Currently the flow for native debugging of a Windows project is to run flutter build windows at least once, then open the sln file that's created in build/windows/ and run from there. This is not at all intuitive, and has the downside that people may not realize that changes they make there aren't permanent.

Visual Studio also has the ability to directly open a directory with a CMake project, but currently it doesn't work (largely because when I was doing the build conversion to CMake, the VS/CMake integration was completely broken on my machine, and it was never enough of a priority to come back to.) It default to the ninja generator, which our Windows CMake files don't currently support (they are written exclusively for multi-config generators), and it looks like it also defaults to clang-cl. It looks like we should be able to add a configuration file to the template that would set:

  • the generator (we wouldn't be able to do this dynamically, but we could just set it to VS 2022 and people could change it if they needed to)
  • the compiler
  • ideally the build output folder so it's using the same destination we are
  • anything else that needs adjusting from defaults

We should see if just doing that makes it possible for someone to get a good VS experience without having to ever deal with the generated solution file. (One thing we'll need to look at is how it handles the install step, since we've co-opted that to make the self-contained bundle that's needed to run.) If so, we should add that to the template.

Activity

  1. added
    toolAffects the "flutter" command-line tool. See also t: labels.
    platform-windowsBuilding on or for Windows specifically
    on Mar 5, 2022
  2. added
    P2Important issues not at the top of the work list
    c: new featureNothing broken; request for a new capability
    P3Issues that are less important to the Flutter project
    and removed
    P2Important issues not at the top of the work list
    on Mar 10, 2022
  3. sebastianhaberey commented on May 13, 2022

    @sebastianhaberey

    That would be helpful, not only for VS 2022 but also for VS Code.

  4. baneeishaque commented on Sep 3, 2023

    @baneeishaque

    That would be helpful, not only for VS 2022 but also for VS Code.

    CLion too...

  5. added
    team-windowsOwned by the Windows platform team
    and removed on Jun 6, 2024
  6. flutter-triage-bot commented on Jun 6, 2024

    @flutter-triage-bot

    The triaged-desktop label is irrelevant if there is no team-desktop label or fyi-desktop label.

  7. Gustl22 commented on Aug 14, 2026

    @Gustl22
    Contributor

    I managed to debug in CLion (or more precisely in IntelliJ Ultimate with CLion + CMake plugin) with below patch to a flutter app project. Maybe this helps for implementing generated files CMakePresets.json (ckecked-in on project platform generation) and CMakeUserPresets.json (.gitignore'd, possibly should be generated on flutter build windows --config-only if not existent, as environments differ from system to system).
    See: https://cmake.org/cmake/help/latest/manual/cmake-presets.7.html

    • Apply the below patch to a windows project (notice: this was designed for ARM, one needs to adapt to their paths and system needs).
    • Run flutter build windows --config-only
    • Open windows directory in a new IDE window
    • Run the default ninja-debug preset in the CMake plugin
    • Select your project name in "CMake Application" run configuration
    • Hit Debug

    Depending on your setup, more work is required: e.g. installing a debugger, e.g. LLVM lldb-dap with python etc., if no built-in debugger is available.

    Patch for Debugging from Native Windows project
    Index: windows/flutter/CMakeLists.txt
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    ===================================================================
    diff --git a/windows/flutter/CMakeLists.txt b/windows/flutter/CMakeLists.txt
    --- a/windows/flutter/CMakeLists.txt	(revision 50e467711e5f23969de2bb7aaffc71fc8cf1f201)
    +++ b/windows/flutter/CMakeLists.txt	(revision 9e98d2687c04ad6fb5f9d183320259a437807b71)
    @@ -90,7 +90,7 @@
     set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
     set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
     add_custom_command(
    -  OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
    +  OUTPUT ${FLUTTER_LIBRARY} "${FLUTTER_LIBRARY}.lib" ${FLUTTER_LIBRARY_HEADERS}
         ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
         ${CPP_WRAPPER_SOURCES_APP}
         ${PHONY_OUTPUT}
    @@ -102,6 +102,7 @@
     )
     add_custom_target(flutter_assemble DEPENDS
       "${FLUTTER_LIBRARY}"
    +  "${FLUTTER_LIBRARY}.lib"
       ${FLUTTER_LIBRARY_HEADERS}
       ${CPP_WRAPPER_SOURCES_CORE}
       ${CPP_WRAPPER_SOURCES_PLUGIN}
    Index: windows/runner/CMakeLists.txt
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    ===================================================================
    diff --git a/windows/runner/CMakeLists.txt b/windows/runner/CMakeLists.txt
    --- a/windows/runner/CMakeLists.txt	(revision 50e467711e5f23969de2bb7aaffc71fc8cf1f201)
    +++ b/windows/runner/CMakeLists.txt	(revision 9e98d2687c04ad6fb5f9d183320259a437807b71)
    @@ -38,3 +38,18 @@
     
     # Run the Flutter tool portions of the build. This must not be removed.
     add_dependencies(${BINARY_NAME} flutter_assemble)
    +
    +# CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD (set in the top-level CMakeLists.txt)
    +# only affects the Visual Studio generator. Single-config generators (e.g.
    +# Ninja) have no equivalent, so building ${BINARY_NAME} alone would leave the
    +# .exe without the DLL/assets it needs to run. Run the install step itself as
    +# a post-build step so those generators end up with the same runnable,
    +# in-place bundle. (Must live here, not the top-level CMakeLists.txt: a
    +# TARGET-form POST_BUILD command can only be attached from the directory that
    +# created the target.)
    +if(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
    +  add_custom_command(TARGET ${BINARY_NAME} POST_BUILD
    +    COMMAND ${CMAKE_COMMAND} --install "${CMAKE_BINARY_DIR}" --config $<CONFIG>
    +    COMMENT "Installing runtime dependencies next to ${BINARY_NAME}"
    +  )
    +endif()
    Index: windows/.gitignore
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    ===================================================================
    diff --git a/windows/.gitignore b/windows/.gitignore
    --- a/windows/.gitignore	(revision 50e467711e5f23969de2bb7aaffc71fc8cf1f201)
    +++ b/windows/.gitignore	(revision 9e98d2687c04ad6fb5f9d183320259a437807b71)
    @@ -15,3 +15,6 @@
     *.[Cc]ache
     # but keep track of directories ending in .cache
     !*.[Cc]ache/
    +
    +# Debug build files
    +/cmake-build-debug
    \ No newline at end of file
    Index: windows/CMakePresets.json
    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    ===================================================================
    diff --git a/windows/CMakePresets.json b/windows/CMakePresets.json
    new file mode 100644
    --- /dev/null	(revision 9e98d2687c04ad6fb5f9d183320259a437807b71)
    +++ b/windows/CMakePresets.json	(revision 9e98d2687c04ad6fb5f9d183320259a437807b71)
    @@ -0,0 +1,48 @@
    +{
    +  "version": 3,
    +  "cmakeMinimumRequired": { "major": 3, "minor": 21, "patch": 0 },
    +  "configurePresets": [
    +    {
    +      "name": "base",
    +      "hidden": true,
    +      "condition": {
    +        "type": "equals",
    +        "lhs": "${hostSystemName}",
    +        "rhs": "Windows"
    +      },
    +      "cacheVariables": {
    +        "FLUTTER_TARGET_PLATFORM": "windows-arm64"
    +      }
    +    },
    +    {
    +      "name": "ninja-debug",
    +      "displayName": "Ninja - Debug",
    +      "description": "Single-config Ninja build. Run 'flutter build windows --config-only' at least once first so flutter/ephemeral exists.",
    +      "inherits": "base",
    +      "generator": "Ninja",
    +      "binaryDir": "${sourceDir}/cmake-build-debug",
    +      "cacheVariables": {
    +        "CMAKE_BUILD_TYPE": "Debug",
    +        "CMAKE_MAKE_PROGRAM": "C:/Program Files (x86)/Microsoft Visual Studio/18/BuildTools/Common7/IDE/CommonExtensions/Microsoft/CMake/Ninja/ninja.exe"
    +      }
    +    },
    +    {
    +      "name": "ninja-profile",
    +      "displayName": "Ninja - Profile",
    +      "inherits": "ninja-debug",
    +      "binaryDir": "${sourceDir}/cmake-build-profile",
    +      "cacheVariables": {
    +        "CMAKE_BUILD_TYPE": "Profile"
    +      }
    +    },
    +    {
    +      "name": "ninja-release",
    +      "displayName": "Ninja - Release",
    +      "inherits": "ninja-debug",
    +      "binaryDir": "${sourceDir}/cmake-build-release",
    +      "cacheVariables": {
    +        "CMAKE_BUILD_TYPE": "Release"
    +      }
    +    }
    +  ]
    +}
    

    I supect a similar approach is possible on Visual Studio and VSCode.

    Edit: And this patch also must land first: #190873, but can also be applied just to your current project.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projecta: desktopRunning on desktopc: new featureNothing broken; request for a new capabilityplatform-windowsBuilding on or for Windows specificallyteam-windowsOwned by the Windows platform teamtoolAffects the "flutter" command-line tool. See also t: labels.triaged-windowsTriaged by the Windows platform team

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions