如何使用公共路径在列表中添加所有文件名?

时间:2010-12-03 14:20:11

标签: cmake

如何自动在列表中添加公共路径前缀的所有文件名?例如,在CMakeLists.txt中有一个文件列表:

SET(SRC_FILES foo1.cpp foo2.cpp)

我想得到一个与此相当的列表:

${CMAKE_CURRENT_SOURCE_DIR}/foo1.cpp ${CMAKE_CURRENT_SOURCE_DIR}/foo2.cpp

我需要在PARENT_SCOPE上下文中使用文件名,例如

SET(FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${SRC_FILES} PARENT_SCOPE)

所以,另一个目录中的CMakeFiles.txt仍然可以找到这些文件。

从本质上讲,我期待这样的事情(伪代码):

SET(FILES_TO_TRANSLATE PREPEND_ALL_NAMES(${CMAKE_CURRENT_SOURCE_DIR} ${SRC_FILES}) PARENT_SCOPE)

这是否容易实现,或者我是否必须使用“foreach”循环来创建新的文件列表?

6 个答案:

答案 0 :(得分:26)

以下功能可能就是您想要的。

FUNCTION(PREPEND var prefix)
   SET(listVar "")
   FOREACH(f ${ARGN})
      LIST(APPEND listVar "${prefix}/${f}")
   ENDFOREACH(f)
   SET(${var} "${listVar}" PARENT_SCOPE)
ENDFUNCTION(PREPEND)

要使用它,

PREPEND(FILES_TO_TRANSLATE ${CMAKE_CURRENT_SOURCE_DIR} ${SRC_FILES})

答案 1 :(得分:15)

CMake 3.12添加了列表转换器-这些转换器之一是PREPEND。因此,以下内容可以内联用于在列表中添加所有条目:

list(TRANSFORM FILES_TO_TRANSLATE PREPEND ${CMAKE_CURRENT_SOURCE_DIR})

...其中FILES_TO_TRANSLATE是列表的变量名。

更多信息可以在CMake documentation中找到。

答案 2 :(得分:12)

string(REGEX REPLACE "([^;]+)" "ANYPREFIX/\\1.cpp" outputlist "${inputlist}")

将ANYPREFIX替换为任何前缀,将“.cpp”替换为您需要的任何后缀。

答案 3 :(得分:1)

您需要使用foreach循环。但是,如果您在项目的多个部分中使用它,则可能需要创建函数或宏。

答案 4 :(得分:0)

作为对陈鼎一答案的改进,如果您仍然需要像我一样支持3.12之前的CMake,则可以使用以下代码:

function(list_transform_prepend var prefix)
    set(temp "")
    foreach(f ${${var}})
        list(APPEND temp "${prefix}${f}")
    endforeach()
    set(${var} "${temp}" PARENT_SCOPE)
endfunction()

此解决方案的优点是,该接口更接近于CMake 3.12 list(TRANSFORM ...),并且更改是就地完成的。

像这样使用

list_transform_prepend(FILES_TO_TRANSLATE "${CMAKE_CURRENT_SOURCE_DIR}/")

答案 5 :(得分:-1)

我假设你想要一个绝对文件名,因为你在$ {CMAKE_CURRENT_SOURCE_DIR}之前。如果您使用FILE(GLOB <VAR> <PATTER>),则所有文件都将具有绝对路径:

file(GLOB_RECURSE SOURCE_FILES src/*.cpp)

请参阅comments CMake in documentation,了解为何不使用GLOB添加源文件。