ccmakeninja

Is there a way to use ninja to build and have cmake out put a sln file as well for vs19?


I would like to use ninja to build and cmake to output a sln file so we can use the debug features in vs19.


Solution

  • Just open the CMake project in Visual Studio directly.

    Well, this works for simple cmake-based C/C++ projects. But it assumes you don't specify any cmake options, i.e. -DOPTION_A=VALUE_A, etc. When there's some options to specify during cmake configure, edit CMake cache via GUI (e.g. CMake-GUI, Visual Studio) is a bad idea. It's time wasting.

    What this question asks, is more like this:

    cmake -S . -B build -DOPTION_A=VALUE_A -DOPTION_B=VALUE_B -G "Ninja Multi-Config" -DCMAKE_TOOLCHAIN_FILE=D:/work/WindowsToolchain/Windows.MSVC.toolchain.cmake
    

    And it generates to build directory, at least those files:

    build
      -- CMakeFiles/
      -- Debug/
      -- Release/
      -- RelWithDebInfo/
      -- build.ninja
      -- build-Debug.ninja
      -- build-Release.ninja
      -- build-RelWithDebInfo.ninja
      -- cmake_install.cmake
      -- CMakeCache.txt
      -- test.sln
      -- test.vcxproj
    

    To do so, one might use this simple CMakeLists.txt:

    cmake_minimum_required(VERSION 3.25)
    project(test)
    add_executable(test test.cpp)
    
    if(GEN_SLN)
      configure_file(test.sln.in ${CMAKE_BINARY_DIR}/test.sln @ONLY)
      configure_file(test.vcxproj ${CMAKE_BINARY_DIR}/test.vcxproj @ONLY)
    endif()
    

    And also have ninja.exe, vswhere.exe installed. Then the aforementioned cmake configure step generates what we expected, among which the CMAKE_TOOLCHAIN_FILE is part of https://github.com/MarkSchofield/WindowsToolchain .

    And in the template file test.vcxprojc.in, invoke cmake for configure, build and clean task:

    <Target Name="Configure">
      <Message Text="Configure: mode=$(Configuration), arch=$(Platform)" />
      <Exec Command="cmake -S . -B build" ConsoleToMsbuild="true" WorkingDirectory=".." />
    </Target>
    
    <Target Name="Build">
      <Message Text="Build" />
      <CallTarget Targets="Configure" />
      <Exec Command="cmake --build build --config $(Configuration)" ConsoleToMsBuild="true" WorkingDirectory=".." />
    </Target>
    
    <Target Name="Clean>
      <Message Text="Clean" />
      <Exec Command="cmake --build build --target clean --config $(Configuration)" ConsoleToMsBuild="true" WorkingDirectory=".." />
    </Target>
    

    NOTE: this is just a very naive demo, but far better that directly using Visual Studio to open a directory that contains a CMakeLists.txt.