How to set Release mode directly in CMakeLists.txt / CMakePresets.json? "Visual Studio 18 2026", vcpkg, case example with library "google/benchmark"

What would be the way to specify the compilation in Release mode when working with CMake, ideally in “CMakeLists.txt”, but if not then in “CMakePresets.json”.

Looking for a solution mainly without commands because this question is about when working with VSCode, launching the compilation with the Launch/Build buttons at the bottom editor window frame. So, a “command solution” only would be a complement if needed for other editors. The goal is to be able to specify the setting directly in CMakeLists.txt or CMakePresets.json.

I’ve read about this in multiple threads but none of the options have worked, either showing compilation errors, or compiling in Debug mode and only generating the path “build > Debug”.


Extra context:
  • Compilation on Windows with “Visual Studio 18 2026”, for the moment, however the ideal solution is a cross-platform way to specify Release compilation mode (and also other modes like Debug mode, when needed).

  • Tests shown in the files below have not worked with a simple “Hello World!” program with just a “main.cpp”. However, the idea is to extend the solution when working with a package manager like vcpkg.

  • A practical case example would be when working with the library “google/benchmark” downloaded with vcpkg, which, for reference, is compiling but in Debug mode as the rest of the other programs, so for that reason showing the message:
    WARNING Library was built as DEBUG. Timings may be affected.”


CMakeLists.txt

cmake_minimum_required(VERSION 3.30)

project(project_A VERSION 1.0 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# set(CMAKE_BUILD_TYPE Release)
# set(CMAKE_BUILD_TYPE release)
# set(cacheVariables.CMAKE_BUILD_TYPE Release)
# set(CMAKE_BUILD_TYPE "Release")
# set(CMAKE_BUILD_TYPE Debug)
# SET(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "" FORCE)
# set(CMAKE_CONFIGURATION_TYPES "Release" CACHE STRING "Build types" FORCE)
# set(CMAKE_CONFIGURATION_TYPES Release)
# set(CMAKE_CONFIGURATION_TYPES "Release")
# set(CMAKE_DEFAULT_BUILD_TYPE Release)

# if(MSVC)
#   # set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /O2 /DNDEBUG")
#   # if (BENCHMARK_ENABLE_LTO)
#   set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /GL")
#   set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} /LTCG")
#   set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /LTCG")
#   set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /LTCG")
#   # endif()
# endif()

# find_package(benchmark REQUIRED)

add_executable(${PROJECT_NAME} main.cpp)

# target_compile_options(${PROJECT_NAME} PRIVATE
#   $<$<CONFIG:Release>:/O2 /DNDEBUG>  # MSVC Release flags
#   #$<$<CONFIG:Debug>:/Od /Zi>         # MSVC Debug flags (optional)
# )

# target_compile_definitions(${PROJECT_NAME} PRIVATE RELEASE_BUILD)

# target_link_libraries(${PROJECT_NAME} PRIVATE benchmark::benchmark)

CMakePresets.json

{
  "version": 9,
  "configurePresets": [
    {
      "name": "VS and vcpkg",
      "displayName": "VS and vcpkg",
      "generator": "Visual Studio 18 2026",
      "architecture": "x64",
      "binaryDir": "${sourceDir}/build",
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": ".../vcpkg.cmake",
        "VCPKG_TARGET_TRIPLET": "x64-windows"
      }
    }
  ]
}

Also trying with the next in “CMakePresets.json”:

...
      "cacheVariables": {
        "CMAKE_TOOLCHAIN_FILE": ".../vcpkg.cmake",
        "VCPKG_TARGET_TRIPLET": "x64-windows",
        "CMAKE_BUILD_TYPE": "Release",
        "CMAKE_CONFIGURATION_TYPES": "Release"
      }
...

Some threads about this topic already visited:

and other threads…

way to specify the compilation in Release mode when working with CMake […] in CMakePresets.json

The CMAKE_BUILD_TYPE in cacheVariables inside CMakePresets.json is the way, and you already have that, and that would have worked for Ninja generator, but Visual Studio generators do not(?) care about that variable - the Debug/Release type of build is specified with --config Debug (or --config Release) when running cmake --build, so after the project has already been configured. Setting CMAKE_BUILD_TYPE in CMakeLists.txt instead of CMakePresets.json wouldn’t make a difference either (for Visual Studio generators).

So in addition to the configuration preset, for Visual Studio generators you will also need to add a build preset, which can specify configuration to be Release. And while at it, you most likely will also want to pass the /m option in nativeToolOptions, as MSBuild does not(?) parallelize building by default. So, everything together:

{
    "name": "some-windows-vs-build",
    "configurePreset": "some-windows-vs-configuration",
    "configuration": "Release",
    "targets": "install",
    "nativeToolOptions":
    [
        "/m"
    ]
}

The "targets": "install" is here because I am assuming that you have a proper installation procedure in your project.

library […] downloaded with vcpkg […] is compiling but in Debug mode

Dependencies/packages that are resolved with vcpkg are built in both Debug and Release configurations (so they are built twice), regardless of whichever build type you’ve set for your project. Well, unless you have modified the triplet and restricted the build type to just the Debug (or just the Release).

Looking for a solution mainly without commands because this question is about when working with VSCode, launching the compilation with the Launch/Build buttons

From what I know about VS Code, you can compose custom tasks, which can be CMake calls with whatever commands you might want. And those tasks likely can be tied to buttons, or at the very least they will be callable from the Command Palette.

It’s not so much Visual Studio, as any generator that is “multi-config”. This applies to multiple generators on multiple platforms and not just Visual Studio.