How to build for Win32 by default when using Visual Studio 2019 generator?

a.k.a. "How to force architecture of the build in the project itself?"

I am currently porting to CMake a VS project that can be built only as 32-bit application. Yet for modern VS versions the default bitness is “same-as-host” - so when the project is configured and built on a regular x64 system with simple cmake -B builddir && cmake --build builddir, everything falls apart. The correct incantation for configuration should be cmake -B builddir -A Win32. But the less flags you have to remember for the build - the better.

As I am for a moment not limited by a CMake Version, I figured I could finally try out CMake Presets. This CMakePreset.json seems to do the job:

{
  "version": 2,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 20,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "generator": "Visual Studio 16 2019",
      "architecture": "Win32",
      "binaryDir": "${sourceDir}/build/default"
    }
  ],
  "buildPresets": [
    {
      "name": "default",
      "configurePreset": "default"
    }
  ]
}

, so the project now can be built like this:

cmake --preset default
cmake --build --preset default

This kinda pins the VS to 2019, so for 2022 and further I would have to also create other presets, but it is okay for now.

However, suppose I am stuck with some older version, say 3.18 - just before the presets were introduced. What would be my options then?

- There is CMAKE_GENERATOR_PLATFORM - “Generator-specific target platform specification provided by user”. If I use this in my project:

cmake_minimum_required(VERSION 3.10.0)
set(CMAKE_GENERATOR_PLATFORM Win32)
project(Stuff)

, then the solution created actually contains Win32 platform instead of x64 - but building it causes error:

$ cmake -B build/2
...
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x86/cl.exe - skipped
...
$ cmake --build build/2
...
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppBuild.targets(436,5): error MSB8013: This project doesn't contain the Configuration and Platform combination of Debug|x64. [S:\build\2\ZERO_CHECK.vcxproj]

- The doc says that "The value of this variable should never be modified by project code. A toolchain file specified by the CMAKE_TOOLCHAIN_FILE variable may initialize CMAKE_GENERATOR_PLATFORM". But even if I do this:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.10.0)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake-default-toolchain.cmake)
project(Stuff)

# cmake-default-toolchain.cmake
set(CMAKE_GENERATOR_PLATFORM Win32)

, the result is still the same.

- Finally, there is the mention that “On Visual Studio Generators the selected platform name is provided in the CMAKE_VS_PLATFORM_NAME variable.”. If I replace setting CMAKE_GENERATOR_PLATFORM with CMAKE_VS_PLATFORM_NAME, the variable is seemingly ignored. CMAKE_VS_PLATFORM_NAME_DEFAULT also does not help, leading me to believe they are read-only variables used simply to indicate from inside CMake itself, which platform was used.

- However, if I pass -DCMAKE_GENERATOR_PLATFORM=Win32 during configuration from the commandline, the build works fine! But that is literally same as -A Win32, even more verbose.

Any suggestions?

Short answer: you don’t. The user gets to choose the toolchain and target. All you can (and should) do is check it and message:

  • error if you know it isn’t supported (e.g., some Unix platform)
  • warn if it is some adjacent platform (e.g., Windows Phone)

You can certainly indicate that the user should use --preset vs2019 or --preset vs2022 for easier usage.

Alas! But thanks for clarification. SO replies juggling around toolchains and CMAKE_GENERATOR_PLATFORM made me think it was still possible and I was just looking in the wrong directions.