在我的项目的任何子目录中,都可以创建一个名为“隐藏”的目录。并将一些代码文件(.c,.cpp,.h,...)放入其中。 CMake应忽略这些文件。我怎样才能做到这一点? 有关简单方法的任何建议吗?搜索网但无法找到解决方案。
我尝试了什么:
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})
如果目录路径已知(对于' CMakeFiles'目录)或者文件是已知的(对于' main.c'文件),第2行可以正常工作。但如果有两个' *'它就不起作用。一个字符串。我找不到位于某处的目录的简单解决方案。
然后我尝试了REGEX。
file(GLOB_RECURSE SOURCE_FILES "*.cpp" "*.c")
string(REGEX REPLACE ";.*/hide/.*;" ";" FOO ${SOURCE_FILES})
因为源文件列表以分号分隔,所以上面的行应该将字符串从一个分号移到下一个分号,以防它包含字符串' hide'。 表达式似乎与分号有问题。任何分号都会使命令找不到任何内容。
我尝试了一些foreach循环,但无法获得我所有隐藏的目录列表。
答案 0 :(得分:4)
我想,其中一种方式就是这样:
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)
只需从列表中搜索字符串中的/hide/
子字符串即可。如果找到子字符串---从列表中删除整个字符串。
请注意,这可能只是Linux的解决方案。并且可能不适用于旧版本的CMake(< 2.8.5,根据this)。
在上述案例中,您可以执行以下操作:
# 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)
注意: GLOB_RECURSE
被视为万恶之源。
注2:要注意的另一件事 - CMake bug in matching empty variable to string。
答案 1 :(得分:2)
找到适合我的解决方案。添加了一个功能,可以轻松排除另一个目录。
# 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)
答案 2 :(得分:0)
概括上面提到的功能解决方案,你会得到类似的东西:
# 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)
然后您可以使用它:
file(GLOB_RECURSE MyFunFiles "*.fun")
filter_items(MyFunFiles ".*NotCool.*")