In any subdirectory of my project it shall be possible to create anywhere a directory called 'hide' and put some code files (.c, .cpp, .h, ...) inside. CMake shall ignore those files. How can I achieve this? Any proposals for a simple approach? Searched the net but could not find a solution.
What I tried:
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
file(GLOB_RECURSE REMOVE_SOURCES
"*/hide/*"
"${PROJECT_SOURCE_DIR}/CMakeFiles/*"
"*main.c")
file(GLOB_RECURSE REMOVE_SOURCES "*/hide/*")
list(REMOVE_ITEM SOURCE_FILES ${REMOVE_SOURCES})
The 2rd line works fine if the directory path is known (as for the 'CMakeFiles' directory) or if the file is known (as for the 'main.c' file). But it does not work if there are two '*' for a string. I can not find a simple solution for a directory which is located somewhere.
Then I tried with REGEX.
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
string(REGEX REPLACE ";.*/hide/.*;" ";" FOO ${SOURCE_FILES})
Because the source file list is separated by semicolon, the line above shall remove the string from one semicolon to the next in case it contained the string 'hide'. The expression seems to have a problem with the semicolon. Having any semicolon makes the command to find nothing.
I tried with some foreach loops, but could not achieve to get a list of all my 'hide'-directories.
One of the ways, I suppose, would be just like this:
set (EXCLUDE_DIR "/hide/")
file (GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
foreach (TMP_PATH ${SOURCE_FILES})
string (FIND ${TMP_PATH} ${EXCLUDE_DIR} EXCLUDE_DIR_FOUND)
if (NOT ${EXCLUDE_DIR_FOUND} EQUAL -1)
list (REMOVE_ITEM SOURCE_FILES ${TMP_PATH})
endif ()
endforeach(TMP_PATH)
Simply searching for /hide/
substring in strings from the list. If the substring found --- remove whole string from the list.
Beware, this might be only solution for Linux. And might not work on older versions of CMake (<2.8.5, according to this).
In mentioned case You can do something like:
# try to replace substring with empty string, compare to original:
string (REPLACE ${EXCLUDE_DIR} "" REPLACED_PATH ${TMP_PATH})
string (COMPARE EQUAL ${TMP_PATH} ${REPLACED_PATH} EXCLUDE_DIR_FOUND)
NOTE: GLOB_RECURSE
is considered to be root of all evil.
NOTE2: another thing to be aware of - CMake bug in matching empty variable to string.
NOTE3: took into account gg99's comment
Found a solution that works for me. Added a function to make it easy to exclude another directory.
# Function: EXCLUDE_FILES_FROM_DIR_IN_LIST
# Description: Exclude all files from a list under a specific directory.
# Param _InFileList: Input and returned List
# Param _excludeDirName: Name of the directory, which shall be ignored.
# Param _verbose: Print the names of the files handled
FUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST _InFileList _excludeDirName _verbose)
foreach (ITR ${_InFileList})
if ("${_verbose}")
message(STATUS "ITR=${ITR}")
endif ("${_verbose}")
if ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)") # Check if the item matches the directory name in _excludeDirName
message(STATUS "Remove Item from List:${ITR}")
list (REMOVE_ITEM _InFileList ${ITR}) # Remove the item from the list
endif ("${ITR}" MATCHES "(.*)${_excludeDirName}(.*)")
endforeach(ITR)
set(SOURCE_FILES ${_InFileList} PARENT_SCOPE) # Return the SOURCE_FILES variable to the calling parent
ENDFUNCTION (EXCLUDE_FILES_FROM_DIR_IN_LIST)
EXCLUDE_FILES_FROM_DIR_IN_LIST("${SOURCE_FILES}" "/hide/" FALSE)
Generalizing the function solution mentioned above you get something like:
# Remove strings matching given regular expression from a list.
# @param(in,out) aItems Reference of a list variable to filter.
# @param aRegEx Value of regular expression to match.
function (filter_items aItems aRegEx)
# For each item in our list
foreach (item ${${aItems}})
# Check if our items matches our regular expression
if ("${item}" MATCHES ${aRegEx})
# Remove current item from our list
list (REMOVE_ITEM ${aItems} ${item})
endif ("${item}" MATCHES ${aRegEx})
endforeach(item)
# Provide output parameter
set(${aItems} ${${aItems}} PARENT_SCOPE)
endfunction (filter_items)
You can then use it thus:
file(GLOB_RECURSE MyFunFiles "*.fun")
filter_items(MyFunFiles ".*NotCool.*")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With