使用CMake GLOB_递归查找目录
我有以下目录结构:使用CMake GLOB_递归查找目录,cmake,glob,Cmake,Glob,我有以下目录结构: . ├── CMakeLists.txt └── deps ├── eigen │ └── include │ ├── Eigen │ └── eigen.h └── osg ├── include │ └── Osg └── lib └── libosg.so 我正在尝试获取部署软件所不需要的最大数量的文件,即库。 我试图创建一个
.
├── CMakeLists.txt
└── deps
├── eigen
│ └── include
│ ├── Eigen
│ └── eigen.h
└── osg
├── include
│ └── Osg
└── lib
└── libosg.so
我正在尝试获取部署软件所不需要的最大数量的文件,即库。
我试图创建一个与*.h
文件和include
目录匹配的全局表达式:
file(GLOB_RECURSE
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/*/include
${CMAKE_SOURCE_DIR}/deps/*/*.h)
message(STATUS "Files are ${FOUND_FILES}")
但是,由于某种原因,变量FOUND\u FILES
包含deps/osg/lib
。关于GLOB\u RECURSE
函数,我不了解什么
- deps/eigen/include
- deps/eigen/include/eigen.h
- deps/osg/include
- deps/osg/lib
- deps/eigen/include
- deps/osg/include
- deps/osg/lib
使用
GLOB\u RECURSE
筛选目录时,CMake似乎会删除globbing表达式的最后一个组件。这就是为什么CMake不进一步过滤示例中的include
目录的原因。这可能是目录的CMakeGLOB_RECURSE
实现中的错误,也可能是CMake中的疏忽
编辑:解决方案1(不起作用):
您可以改为使用全局模式本身模拟递归。改为使用CMake的GLOB
,并在globbing模式中使用***
,以匹配在deps/
和/include
之间有一个或多个字符的任何内容:
file(GLOB
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/**/include
${CMAKE_BINARY_DIR}/deps/**/*.h)
)
message(STATUS "Files are ${FOUND_FILES}")
解决方案2(丑):
您可以手动添加CMake的目录级别,以搜索include
文件夹:
file(GLOB
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/*/include
${CMAKE_SOURCE_DIR}/deps/*/*/include
...
)
但是,这不是一个可扩展的解决方案。当使用
GLOB\u RECURSE
筛选目录时,CMake似乎会删除globbing表达式的最后一个组件。这就是为什么CMake不进一步过滤示例中的include
目录的原因。这可能是目录的CMakeGLOB_RECURSE
实现中的错误,也可能是CMake中的疏忽
编辑:解决方案1(不起作用):
您可以改为使用全局模式本身模拟递归。改为使用CMake的GLOB
,并在globbing模式中使用***
,以匹配在deps/
和/include
之间有一个或多个字符的任何内容:
file(GLOB
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/**/include
${CMAKE_BINARY_DIR}/deps/**/*.h)
)
message(STATUS "Files are ${FOUND_FILES}")
解决方案2(丑):
您可以手动添加CMake的目录级别,以搜索include
文件夹:
file(GLOB
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/*/include
${CMAKE_SOURCE_DIR}/deps/*/*/include
...
)
但是,这不是一个非常可扩展的解决方案。我认为这可能是一个解决方案:
file(GLOB_RECURSE
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/*/include
)
list(FILTER FOUND_FILES INCLUDE REGEX "^${CMAKE_SOURCE_DIR}/deps/.*/include$")
file(GLOB_RECURSE
tmp
${CMAKE_BINARY_DIR}/deps/*/*.h
)
list(APPEND FOUND_FILES ${tmp})
当
GLOB\u RECURSE
与LIST\u目录true
一起使用时,如果表达式的*
不在路径的最后一个条目上,我猜这是一个错误。一旦包含匹配项的目录在中匹配,下一个目录将无条件地递归添加到输出中。因此,一旦${CMAKE\u SOURCE\u DIR}/deps/*
目录中有一个include
目录或文件,所有从${CMAKE\u SOURCE\u DIR}/deps/
递归而来的目录都被添加到输出中。文件不会被添加,因为它们是根据regex进行检查的。我认为这可能是一个解决方法:
file(GLOB_RECURSE
FOUND_FILES
LIST_DIRECTORIES true
${CMAKE_SOURCE_DIR}/deps/*/include
)
list(FILTER FOUND_FILES INCLUDE REGEX "^${CMAKE_SOURCE_DIR}/deps/.*/include$")
file(GLOB_RECURSE
tmp
${CMAKE_BINARY_DIR}/deps/*/*.h
)
list(APPEND FOUND_FILES ${tmp})
当
GLOB\u RECURSE
与LIST\u目录true
一起使用时,如果表达式的*
不在路径的最后一个条目上,我猜这是一个错误。一旦包含匹配项的目录在中匹配,下一个目录将无条件地递归添加到输出中。因此,一旦${CMAKE\u SOURCE\u DIR}/deps/*
目录中有一个include
目录或文件,所有从${CMAKE\u SOURCE\u DIR}/deps/
递归而来的目录都被添加到输出中。不会添加文件,因为它们会根据您请求的regex进行检查。。从文档中:默认情况下,GLOB_RECURSE忽略结果列表中的目录-将list_directories设置为true会将目录添加到结果列表中。是的,但osg/lib中的任何内容都不匹配全局表达式good point。我一定错过了,抱歉吵闹。是的,deps/*.h
确实足够了。我可以用simplemkdir-p./source/deps/osg/{include,lib}./source/deps/eigen/include
和文件(全局递归找到的文件列表目录真${CMAKE\u当前的列表目录目录}/source deps/*/include)foreach(我在找到的文件列表中)消息(状态“${i}”)endforeach()
cmake脚本..:/你在请求它。从文档中:默认情况下,GLOB_RECURSE忽略结果列表中的目录-将list_directories设置为true会将目录添加到结果列表中。是的,但osg/lib中的任何内容都不匹配全局表达式good point。我一定错过了,抱歉吵闹。是的,deps/*.h
确实足够了。我可以用simplemkdir-p./source/deps/osg/{include,lib}./source/deps/eigen/include
和文件(全局递归找到的文件列表目录真${CMAKE\u当前的列表目录目录}/source deps/*/include)foreach(我在找到的文件列表中)消息(状态“${i}”)endforeach()
cmake脚本..:/不幸的是,CMake似乎不支持***
全局模式,因此不匹配*。h
和包括目录和deps下的两个目录。“与全局递归使用的全局模式似乎匹配星号(*
)后的任何目录在模式中,并且不会进一步过滤include
目录”-在搜索目录时,无论是否包含星号,CMake似乎只会删除全局表达式的最后一个路径组件。例如,此全局表达式${CMAKE\u SOURCE\u DIR}/deps/NonExistentFile
将“匹配”到${CMAKE\u SOURCE\u DIR}/deps/
下的所有目录,但不匹配到任何文件。这的确是一个有趣的行为。@Hugal31你是对的;CMake似乎不支持**
全局模式。我在回复中添加了一个潜在的解决方法,但它不是很好移植。几乎可以肯定有一个更强大的解决方案(可能是使用GLOB
收集目录列表,然后使用regex将其过滤到以/include
结尾的目录列表)!我修改了文件