Issue
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 for the MainProject
folder in the MainProject
folder:
And here's what I'd like to achieve:
See how there is no MainProject
filter in the MainProject
project.
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.
Solution
I got some help over on the CMake forum:
I put CMakeLists.txt in sub-folders and got this in the end:
CMakeLists.txt in the root directory:
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_subdirectory(MainProject)
add_subdirectory(TestMainProject)
CMakeLists.txt in the MainProject
folder:
add_executable(${main_project_name} ${main_project_files})
source_group(TREE "${main_project_path}/" FILES ${main_project_files})
CMakeLists.txt in the TestMainProject
folder:
cmake_minimum_required(VERSION 3.10)
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})
source_group(TREE "${main_project_path}/" PREFIX "${main_project_name}" FILES ${main_project_files})
source_group(TREE "${test_main_project_path}/" PREFIX "${test_main_project_name}" FILES ${test_main_project_files})
Now it generates the correct filters, just as I wanted:
Answered By - KulaGGin Answer Checked By - Mary Flores (WPSolving Volunteer)