Kartashuvit
Kartashuvit

Reputation: 103

CMake project structure with Visual Studio

I've been at this for hours and I'm so lost. This is what my project structure looks like, very basic.

Project
    - CMakeLists.txt
    - src
        - main.cpp
        - class.cpp
        - anotherClass.cpp
    - include
        - class.h
        - anotherClass.h

My CMakeLists.txt looks like this:

cmake_minimum_required(VERSION 3.22.1)

project(Project)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})

file(GLOB_RECURSE HEADERS "include/*.h")
file(GLOB SOURCES "src/*.cpp")

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
    
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})

target_link_directories(${PROJECT_NAME} PRIVATE include)

target_link_libraries(${PROJECT_NAME} ${SDL2_LIBRARIES})

When I build a Visual Studio project in the "Filter View" or whatever it's called, all headers are shown under "Header files" and all source files are shown under "Source files". That's fine, but the problem is that my actual folder structure is nonexistent. All source and header files are bunched up together and it doesn't look nice. How do I make the build have the project structure above?

Upvotes: 0

Views: 1923

Answers (1)

fabian
fabian

Reputation: 82461

Note: I assume by "Filter View" you mean "Solution Explorer".

The USE_FOLDERS property just determines, if the targets should be grouped into folders in the Visual Studio solution explorer, and even if you activate it, you'll still need to use the CMAKE_FOLDER variable or the FOLDER target property to specify the folder for targets.

If you want the source files to shown in a directory structure, you need to use the source_group command to accomplish this.

source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR}
    FILES ${HEADERS} ${SOURCES}
)

Setting the USE_FOLDERS property is not needed for this to work.


Unrelated note:

target_link_directories(${PROJECT_NAME} PRIVATE include)

Is just wrong in this case, even though it does not break anything here: target_link_directories is used to specify directories where the linker looks for libraries and there are no library files in the include directory; furthermore I'd try to avoid specifying link directories, if possible.


include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

It's imho preferrable to specify this kind of information on a per-target basis:

target_include_directories(${PROJECT_NAME} PRIVATE include)

Upvotes: 1

Related Questions