Setting CMAKE_C(XX)_FLAGS_DEBUG to "" in CMakePresets.json makes it compile for x32

As the title says, setting CMAKE_C(XX)_FLAGS_DEBUG to the empty string “” in a CMakePresets.json, even if architecture is specified to ‘external’ and x64, will make compile for x32.
Is this intended behaviour? Something I am missing?

My CMakePresets.json:

{
  "version": 2,
  "configurePresets": [
    {
      "name": "base",
      "description": "For more information: http://aka.ms/cmakepresetsvs",
      "hidden": true,
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/o/${presetName}",
      "cmakeExecutable": "${sourceDir}/Tools/CMake/Windows/bin/cmake.exe"
    },
    {
      "name": "windows-debug",
      "displayName": "Windows Release",
      "description": "Sets windows build type and x64 arch",
      "inherits": "base",
      "architecture":
      {
        "value": "x64",
        "strategy": "external"
      },
      "cacheVariables":
      {
        "CMAKE_BUILD_TYPE": "Debug",
        "CMAKE_CXX_COMPILER": "${sourceDir}/Tools/Compilers/llvm-12.0.1/WIN64/bin/clang++.exe",
        "CMAKE_C_COMPILER": "${sourceDir}/Tools/Compilers/llvm-12.0.1/WIN64/bin/clang.exe",
        "CMAKE_CXX_FLAGS_DEBUG": ""
      },
    },
    {
      "name": "windows-release",
      "displayName": "Windows",
      "inherits": "windows-debug",
      "cacheVariables":
      {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ]
}

CMakeError.log:

Detecting C compiler ABI info failed to compile with the following output:
Change Dir: C:/ws/progrmaming/o/windows-release/CMakeFiles/CMakeTmp

Run Build Command(s):C:/PROGRA~2/MICROS~2/2019/PROFES~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_bab84 && [1/2] Building C object CMakeFiles/cmTC_bab84.dir/CMakeCCompilerABI.c.obj
[2/2] Linking C executable cmTC_bab84.exe
FAILED: cmTC_bab84.exe 
cmd.exe /C "cd . && C:\ws\progrmaming\Tools\Compilers\llvm-12.0.1\WIN64\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib -O0 -fno-inline-functions -Xlinker /subsystem:console CMakeFiles/cmTC_bab84.dir/CMakeCCompilerABI.c.obj -o cmTC_bab84.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:cmTC_bab84.lib -Xlinker /pdb:cmTC_bab84.pdb -Xlinker /version:0.0     && cd ."
lld-link: error: <root>: undefined symbol: mainCRTStartup


clang: error: linker command failed with exit code 1 (use -v to see invocation)


ninja: build stopped: subcommand failed.





Determining if the C compiler works failed with the following output:
Change Dir: C:/ws/progrmaming/o/windows-release/CMakeFiles/CMakeTmp

Run Build Command(s):C:/PROGRA~2/MICROS~2/2019/PROFES~1/Common7/IDE/COMMON~1/MICROS~1/CMake/Ninja/ninja.exe cmTC_84703 && [1/2] Building C object CMakeFiles/cmTC_84703.dir/testCCompiler.c.obj

[2/2] Linking C executable cmTC_84703.exe

FAILED: cmTC_84703.exe 

cmd.exe /C "cd . && C:\ws\progrmaming\Tools\Compilers\llvm-12.0.1\WIN64\bin\clang.exe -fuse-ld=lld-link -nostartfiles -nostdlib -O0 -fno-inline-functions -Xlinker /subsystem:console CMakeFiles/cmTC_84703.dir/testCCompiler.c.obj -o cmTC_84703.exe -Xlinker /MANIFEST:EMBED -Xlinker /implib:cmTC_84703.lib -Xlinker /pdb:cmTC_84703.pdb -Xlinker /version:0.0   -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 -loldnames  && cd ."

lld-link: error: <root>: undefined symbol: mainCRTStartup


clang: error: linker command failed with exit code 1 (use -v to see invocation)


ninja: build stopped: subcommand failed.

Happens if you set it like this, or in a toolchain file.

How are you running CMake? From a command line, or from within an IDE? If the former, how did you set up the environment in that shell?

Running CMake from commandline (plain cmd), with Visual Studio’s vcvars64.bat environment on AMD64.
CMake version 3.22.3, Ninja version 1.10.2

It is difficult to know what’s happening in your case. You’ve got a number of very unusual things going on in that CMakePresets.json file, which also mean others can’t reproduce your problem. It seems like you’ve embedded copies of CMake and LLVM binaries in your source tree. That’s very atypical and means you’re at the mercy of whatever those binaries are built/configured to provide. I’ll assume the cmakeExecutable can be removed and we can just use a standard CMake installation. The full paths to the clang executables in CMAKE_CXX_COMPILER and CMAKE_C_COMPILER are more problematic. We don’t know what those compiler binaries will do by default, and the architecture value is essentially just an advisory note for IDEs because the external strategy is specified. In other words, what you’re seeing is whatever the clang binaries you’ve pointed at will build by default.

Its just my company’s way of providing compilers/tools for a project, and it’s a bit submodules-similar setup where the compiler and CMake are both submodules. That way you can have project specific versions of tools as well. Got any other recommendation for how to provide each developer with these things on a closed network?

But the Clang binaries are Clang’s own 12.0.1 pre-compiled for Windows binaries. If you want I could try this again with these tools installed and removed from the CMakePresets.

And by default it is compiling for x64, it’s just when those values are set to “” it will compile for x32.

There are two things you should confirm:

  • If you invoke the clang binaries directly, what sort of target do they build by default? 64-bit or 32-bit? By this I mean invoking them outside of anything to do with CMake, so just running directly at a command line to compile some test file.
  • If you don’t explicitly set CMAKE_CXX_FLAGS_DEBUG to anything, what does that variable contain by default? About the only way I can see explicitly setting this to an empty string making a difference is if for some reason it contains a setting that changes the target platform (which would be both weird and wrong).