如何自动在列表中添加公共路径前缀的所有文件名?例如,在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”循环来创建新的文件列表?
答案 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添加源文件。