[cmake] Use source_group TREE on source_group_by_folder#2019
[cmake] Use source_group TREE on source_group_by_folder#2019CastagnaIT merged 1 commit intoxbmc:Piersfrom
Conversation
from cmake 4.3 source_group command supports generator expressions that is the cause of failure
ReviewMust Fix — The gen-expr skip relies on Correct fix: filter before the loop, drop list(FILTER files EXCLUDE REGEX "^\\$<")Medium — Loop structure unnecessary for
list(FILTER files EXCLUDE REGEX "^\\$<")
if(files)
source_group(TREE "${relative_dir}" FILES ${files})
endif() |
| endif() | ||
| foreach(file ${files}) | ||
| if(file MATCHES "^\\$<") | ||
| list(POP_FRONT files) |
There was a problem hiding this comment.
list(POP_FRONT files) only works because $< (ASCII 36) sorts before letters, putting gen-exprs at the front of the sorted list. It's fragile — any filename starting with a char < ASCII 36 (!, #, %, etc.) would sort first, and POP_FRONT would then remove a legitimate source file instead.
Filter gen-exprs from files before the loop and drop this line entirely:
| list(POP_FRONT files) | |
| continue() |
Add before the foreach:
list(FILTER files EXCLUDE REGEX "^\\$<")continue() alone is sufficient since the gen-expr is never appended to files when we skip the rest of the loop body.
|
i will not apply suggested code changes to keep consistency with main xbmc project |
Kodiai Review SummaryWhat ChangedThis PR updates the CMake Reviewed: core logic Strengths
ObservationsImpact[MAJOR] Helpers.cmake (31): Incorrect list manipulation during iteration [MAJOR] Helpers.cmake (42, 50): Non-standard usage pattern for source_group TREE Suggestions
Verdict🔴 Address before merging -- 2 blocking issue(s) found Review Details
|
| endif() | ||
| foreach(file ${files}) | ||
| if(file MATCHES "^\\$<") | ||
| list(POP_FRONT files) |
There was a problem hiding this comment.
[MAJOR] Incorrect list manipulation during iteration.
The list(POP_FRONT files) command modifies the files variable while the foreach(file ${files}) loop is iterating over it. While foreach iterates over a snapshot (so this doesn't break the iteration), this line is problematic because:
- It has no effect on which files are processed (the loop continues with all files)
- The
filesvariable is reused as an accumulator later in the loop (line 44 clears it, line 46 appends to it) - If a generator expression appears after the first directory group is processed, this would pop from the accumulator instead of the original list, corrupting the results
- The
continue()statement alone is sufficient to skip the generator expression
| list(POP_FRONT files) | |
| if(file MATCHES "^\\$<") | |
| continue() | |
| endif() |
| if(NOT dir STREQUAL "${last_dir}") | ||
| if(files) | ||
| source_group("${last_dir}" FILES ${files}) | ||
| source_group(TREE "${relative_dir}" FILES ${files}) |
There was a problem hiding this comment.
[MAJOR] Non-standard usage pattern for source_group(TREE ...).
The source_group(TREE <root> FILES ...) command is designed to be called once with all source files to automatically create the complete folder hierarchy. The current implementation calls it multiple times with directory-grouped subsets (triggered by the if(NOT dir STREQUAL "${last_dir}") condition at line 40).
While multiple calls may work, this approach is:
- Unconventional and more complex than necessary
- Inconsistent with CMake documentation examples
- Potentially fragile if CMake's behavior changes
Standard pattern:
# Filter generator expressions
set(filtered_files "")
foreach(file ${files})
if(NOT file MATCHES "^\\$<")
list(APPEND filtered_files "${file}")
endif()
endforeach()
# Create hierarchy in one call
if(filtered_files)
source_group(TREE "${relative_dir}" FILES ${filtered_files})
endif()This would eliminate the entire directory-grouping loop (lines 29-48) since TREE handles the hierarchy automatically.
Description
Motivation and context
from VS2026 with recent cmake versions (more likely from 4.3+) the folder hierarchy on solution tree view is broken and show a full list of files without folders
How has this been tested?
Screenshots (if appropriate):
Types of change
Checklist: