# Generates CMakeUserPresets.json, pinning "cmakeExecutable" to the CMake that is # running this script - i.e. the one build.cmd itself uses. # # Why: both drivers share one binaryDir per configuration, so build.cmd and Visual # Studio write the same Ninja tree. Visual Studio otherwise uses its own bundled # CMake, and two CMake versions generating one tree emit different compile command # lines, which makes Ninja rebuild everything on every switch. See CLAUDE.md. # # Why generated rather than committed: Visual Studio resolves "cmakeExecutable" # against the current directory only - a bare "cmake" is not looked up on PATH - so # the value must be an absolute path, which is machine-specific and cannot live in # the committed CMakePresets.json. # # Run as: cmake -P cmake/write_user_presets.cmake cmake_minimum_required(VERSION 3.21) # Marks the file as ours, so a hand-written one is never clobbered. set(GENERATED_MARKER "local-cmake") set(TEMPLATE [==[ { "version": 2, "configurePresets": [ { "name": "local-cmake", "hidden": true, "cmakeExecutable": "@CMAKE_COMMAND@" }, { "name": "build-release-msvc-local", "inherits": [ "local-cmake", "build-release-msvc" ], "displayName": "Release (MSVC) [local CMake]", "description": "Select this in Visual Studio: same build tree as build.cmd, pinned to the same CMake. Generated by build.cmd - do not edit." }, { "name": "build-debug-msvc-local", "inherits": [ "local-cmake", "build-debug-msvc" ], "displayName": "Debug (MSVC) [local CMake]", "description": "Select this in Visual Studio: same build tree as build.cmd, pinned to the same CMake. Generated by build.cmd - do not edit." }, { "name": "build-release-clang-cl-local", "inherits": [ "local-cmake", "build-release-clang-cl" ], "displayName": "Release (Clang) [local CMake]", "description": "Select this in Visual Studio: same build tree as build.cmd, pinned to the same CMake. Generated by build.cmd - do not edit." }, { "name": "build-debug-clang-cl-local", "inherits": [ "local-cmake", "build-debug-clang-cl" ], "displayName": "Debug (Clang) [local CMake]", "description": "Select this in Visual Studio: same build tree as build.cmd, pinned to the same CMake. Generated by build.cmd - do not edit." } ], "buildPresets": [ { "name": "release-msvc-local", "configurePreset": "build-release-msvc-local", "displayName": "Release (MSVC) [local CMake]" }, { "name": "debug-msvc-local", "configurePreset": "build-debug-msvc-local", "displayName": "Debug (MSVC) [local CMake]" }, { "name": "release-clang-cl-local", "configurePreset": "build-release-clang-cl-local", "displayName": "Release (Clang) [local CMake]" }, { "name": "debug-clang-cl-local", "configurePreset": "build-debug-clang-cl-local", "displayName": "Debug (Clang) [local CMake]" } ] } ]==]) string(CONFIGURE "${TEMPLATE}" CONTENT @ONLY) get_filename_component(OUTPUT_FILE "${CMAKE_CURRENT_LIST_DIR}/../CMakeUserPresets.json" ABSOLUTE) if(EXISTS "${OUTPUT_FILE}") file(READ "${OUTPUT_FILE}" EXISTING) # Unchanged: leave the timestamp alone, or Visual Studio reloads the presets # after every command-line build. if(EXISTING STREQUAL CONTENT) return() endif() string(FIND "${EXISTING}" "\"${GENERATED_MARKER}\"" MARKER_POS) if(MARKER_POS EQUAL -1) message(WARNING "CMakeUserPresets.json was not generated by build.cmd - leaving it untouched.\n" "Delete it to let build.cmd manage it, or add \"cmakeExecutable\": \"${CMAKE_COMMAND}\" to it yourself." ) return() endif() endif() file(WRITE "${OUTPUT_FILE}" "${CONTENT}") message(STATUS "Wrote CMakeUserPresets.json (cmakeExecutable: ${CMAKE_COMMAND})")