问题
After a change to make a CMake project have hierarchical folder management, source_group() no longer seems to be working correctly. CMake just dumps everything into the default filters.
I've tried various regexes to get the relative file path from the parent for every source file and even hard coding the source files in the parent CMakeLists.txt just to see if that was the issue. I've also tried regenerating the VS project a couple times after these changes.
Here's sample files for your viewing pleasure:
Parent CMakeLists.txt
cmake_minimum_required (VERSION 3.3)
set(SRCS)
add_subdirectory(PlatformDetection)
include_directories (.)
add_library(SystemAbstraction STATIC ${SRCS})
set_property(TARGET SystemAbstraction PROPERTY FOLDER "Engine")
set_target_properties(SystemAbstraction PROPERTIES LINKER_LANGUAGE CXX)
install (TARGETS SystemAbstraction
ARCHIVE DESTINATION lib)
Child CMakeLists.txt:
cmake_minimum_required (VERSION 3.3)
add_subdirectory(Compilers)
set(SRCS ${SRCS} PARENT_SCOPE)
and
cmake_minimum_required (VERSION 3.3)
set (COMPILER_DETECTION_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/CompilerDetection.h)
set (COMPILER_DETECTION_SRC ${CMAKE_CURRENT_SOURCE_DIR}/CompilerDetection.cpp)
source_group("Header Files\\Platform Detection\\Compilers" FILES ${COMPILER_DETECTION_HEADERS})
source_group("Source Files\\Platform Detection\\Compilers" FILES ${COMPILER_DETECTION_SRC})
set(SRCS ${SRCS} ${COMPILER_DETECTION_HEADERS} ${COMPILER_DETECTION_SRC} PARENT_SCOPE)
回答1:
This is a direct copy of @BlamKiwi 's answer but with an absolute path added to fix problems seen with relative only paths (and put into a macro) I would comment on his but i have no reputation.
MACRO(GROUP_SRC SRCS)
foreach(FILE ${SRCS})
#convert source file to absolute
get_filename_component(ABSOLUTE_PATH "${FILE}" ABSOLUTE)
# Get the directory of the absolute source file
get_filename_component(PARENT_DIR "${ABSOLUTE_PATH}" DIRECTORY)
# Remove common directory prefix to make the group
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" GROUP "${PARENT_DIR}")
# Make sure we are using windows slashes
string(REPLACE "/" "\\" GROUP "${GROUP}")
# Group into "Source Files" and "Header Files"
if ("${FILE}" MATCHES ".*\\.cpp")
set(GROUP "Source Files${GROUP}")
elseif("${FILE}" MATCHES ".*\\.h")
set(GROUP "Header Files${GROUP}")
endif()
source_group("${GROUP}" FILES "${FILE}")
endforeach()
ENDMACRO(GROUP_SRC)
回答2:
I fixed my problem by writing a foreach loop which iterates over the source files and groups them by their relative path and if they're header or source files. Then just run this as a macro in every place where you define a library/executable.
foreach(FILE ${SRCS})
# Get the directory of the source file
get_filename_component(PARENT_DIR "${FILE}" DIRECTORY)
# Remove common directory prefix to make the group
string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" GROUP "${PARENT_DIR}")
# Make sure we are using windows slashes
string(REPLACE "/" "\\" GROUP "${GROUP}")
# Group into "Source Files" and "Header Files"
if ("${FILE}" MATCHES ".*\\.cpp")
set(GROUP "Source Files${GROUP}")
elseif("${FILE}" MATCHES ".*\\.h")
set(GROUP "Header Files${GROUP}")
endif()
source_group("${GROUP}" FILES "${FILE}")
endforeach()
回答3:
I think you need to add set_property(GLOBAL PROPERTY USE_FOLDERS ON)
.
来源:https://stackoverflow.com/questions/31966135/cmake-source-group-not-working-correctly-with-hierarchical-project-setup