Solution to quickly reproduce the problem:
I have this file structure:
My Solution(dir)
+-- CMakeLists.txt
+-- MainProject(dir)
+-- File1.cpp
+-- File1.h
+-- File2.cpp
+-- File2.h
+-- Subdirectory(dir)
+-- File1.cpp
+-- File1.h
+-- File2.cpp
+-- File2.h
+-- TestMainProject(dir)
+-- TestFile1.cpp
+-- TestFile2.cpp
+-- Subdirectory(dir)
+-- TestFile1.cpp
+-- TestFile2.cpp
For the MainProject I’d like to include all files from the MainProject folder with filters following the folder structure.
For the TestMainProject I’d like to include all files from the MainProject folder with filters following the folder structure but also put all these files under the MainProject filter. Same for the TestMainProject directory: put all files under the TestMainProject filter and follow the folder structure.
So I wrote this code:
cmake_minimum_required(VERSION 3.10)
project("CMake Subdirectories Filters Example")
set(main_project_name "MainProject")
set(main_project_path "${PROJECT_SOURCE_DIR}/${main_project_name}")
file(GLOB_RECURSE main_project_files "${main_project_path}/*.h" "${main_project_path}/*.cpp")
add_executable(${main_project_name} ${main_project_files})
source_group(TREE "${main_project_path}/" FILES ${main_project_files})
function(group_source_files_into_filter_with_folder_structure files_list project_path filter_to_put_into)
foreach(file_path IN LISTS files_list)
get_filename_component(file_directory_path "${file_path}" DIRECTORY)
string(REPLACE ${project_path} ${filter_to_put_into} file_path_msvc_relative "${file_directory_path}")
string(REPLACE "/" "\\" source_path_msvc "${file_path_msvc_relative}")
source_group("${source_path_msvc}" FILES "${file_path}")
endforeach()
endfunction()
set(test_main_project_name "TestMainProject")
set(test_main_project_path "${PROJECT_SOURCE_DIR}/${test_main_project_name}")
file(GLOB_RECURSE test_main_project_files "${test_main_project_path}/*.h" "${test_main_project_path}/*.cpp")
add_executable(${test_main_project_name} ${main_project_files} ${test_main_project_files})
group_source_files_into_filter_with_folder_structure("${main_project_files}" "${main_project_path}" "${main_project_name}")
group_source_files_into_filter_with_folder_structure("${test_main_project_files}" "${test_main_project_path}" "${test_main_project_name}")
It does create filters as I want it to for the TestMainProject: it creates the additional TestMainProject filter for the TestMainProject folder and additional MainProject filter for the MainProject folder.
The problem is that it also creates additional MainProject filter in the MainProject project, which isn’t what I’d like it to do.
Here’s what I’d like to achieve:
See how there is no MainProject filter inside the MainProject project but inside the TestMainProject there are filters for MainProject and TestMainProject folders.
Is there a way to do what I would like to do? Feels like I hit a limit of CMake and there’s no way because, apparently, source_group is global and it creates the group for the files for all projects.
