Set cache, build files and binary files directories for Visual Studio in CMake

Viewed 27

Current environment

I have the following file structure:

project_root/
__main.cpp        # app starting point
__CMakeLists.txt  # CMake build starting point
__include/        # header files
__src/            # source files
__lib/            # libraries/dependencies which are also CMake projects
__res/
__build/          # CMake cache, build files
__bin/            # compiled binaries

I've been working with VS Code for both Windows and Linux platforms, but I would like to try out Visual Studio environment.

So far, using CMake Tools extension worked pretty well placing build files in build/ and binaries in /bin with the following CMakeLists.txt:

cmake_minimum_required(VERSION 3.19 FATAL_ERROR)
project(OPENGL_TEMPLATE)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build")

# targets, libs and properties setup

The problem

Unfortunately, Visual Studio overrides these variables and creates some project_root/out/Debug/ directory, which does not fit my current directory tree.

There are two ways (to my knowledge) to run CMake project in Visual Studio, which I would like both to be compatible with my current directory tree:

  1. Generate VS solution with CMake from terminal or CMake GUI and open it;
  2. Open directory from File Explorer with "Open with Visual Studio"

So far, I have come up with this CMakeLists.txt:

cmake_minimum_required(VERSION 3.19 FATAL_ERROR)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/build")
set(CMAKE_BINARY_DIR "${CMAKE_SOURCE_DIR}/build")

project(PROJECT_NAME)

if(${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR})
    message(FATAL_ERROR "In-source builds are forbidden.")
endif()

add_executable(main)

set_target_properties(main PROPERTIES
    RUNTIME_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/bin"
    ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_SOURCE_DIR}/build"
    VS_STARTUP_PROJECT main
    FOLDER "App"
)

# other targets, libs and properties setup

And it works when generating .sln solution with CMake (but does not set the VS_STARTUP_PROJECT for some reason, but this is for another SO question), here build files go to build/ and binaries to bin/.

When using the second approach, VS still generates everything into out/Debug/, seemingly completely ignoring CMAKE_BINARY_DIR (which they claim corresponds to buildRoot VS configuration variable) and ARCHIVE_OUTPUT_DIRECTORY, RUNTIME_OUTPUT_DIRECTORY target properties.

The question (finally)

How can I setup CMake variables so that Visual Studio respects them (and does not override) using both approaches? Ideal situation would be to just open a clean project and be ready to configure, build and run, which means no additional tinkering in Visual Studio configuration files/settings. I am using Visual Studio 2022 Community 17.3.3.

0 Answers
Related