如何在列表中的所有文件名前面添加公共路径?

发布于 2024-10-06 01:17:02 字数 621 浏览 0 评论 0原文

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

How can I prepend all filenames on the list with a common path prefix automatically? For instance having a list of files in CMakeLists.txt:

SET(SRC_FILES foo1.cpp foo2.cpp)

I'd like to get a list that is equivalent to this:

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

I need this to use filenames in a PARENT_SCOPE context, e.g.

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

so, that a CMakeFiles.txt in another directory can still find these files.

In essence, I'd expect something like this (pseudo-code):

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

Is this is easily doable, or do I have to user "foreach" loop to create new list of files?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

路还长,别太狂 2024-10-13 01:17:02

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

list(TRANSFORM FILES_TO_TRANSLATE PREPEND ${CMAKE_CURRENT_SOURCE_DIR})

...其中 FILES_TO_TRANSLATE 是以下变量的名称名单。

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

CMake 3.12 added list transformers - one of these transformers is PREPEND. Thus, the following can be used inline to prepend all entries in a list:

list(TRANSFORM FILES_TO_TRANSLATE PREPEND ${CMAKE_CURRENT_SOURCE_DIR})

...where FILES_TO_TRANSLATE is the variable name of the list.

More information can be found in the CMake documentation.

友谊不毕业 2024-10-13 01:17:02

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

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})

Following function may be what you want.

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

To use it,

PREPEND(FILES_TO_TRANSLATE ${CMAKE_CURRENT_SOURCE_DIR} ${SRC_FILES})
笑红尘 2024-10-13 01:17:02
string(REGEX REPLACE "([^;]+)" "ANYPREFIX/\\1.cpp" outputlist "${inputlist}")

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

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

Replace ANYPREFIX with any prefix and '.cpp' with any suffix you need.

国产ˉ祖宗 2024-10-13 01:17:02

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

You need to use a foreach loop. But if you use that in several parts of your project, you might want to create a function or a macro.

最佳男配角 2024-10-13 01:17:02

作为对 Ding-Yi Chen 答案的改进,如果您仍然需要像我一样支持 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}/")

As an improvement to Ding-Yi Chen's answer, if you still need to support pre-3.12 CMake as I do, you can use following code:

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

Advantage of this solution is, that interface is closer to one is CMake 3.12 list(TRANSFORM ...) and the change is done in-place.

Used like this

list_transform_prepend(FILES_TO_TRANSLATE "${CMAKE_CURRENT_SOURCE_DIR}/")
机场等船 2024-10-13 01:17:02

我假设您需要绝对文件名,因为您要在 ${CMAKE_CURRENT_SOURCE_DIR} 前面添加。如果您使用 FILE(GLOB ),所有文件都将具有绝对路径:

file(GLOB_RECURSE SOURCE_FILES src/*.cpp)

请参阅 在文档中注释 CMake 为什么不使用 GLOB 添加源文件。

I assume that you want an absolute filename as you are prepending ${CMAKE_CURRENT_SOURCE_DIR}. If you are using FILE(GLOB <VAR> <PATTER>), all the files will have an absolute path already:

file(GLOB_RECURSE SOURCE_FILES src/*.cpp)

See the comments CMake in documentation on why not to use GLOB to add source files.

还在原地等你 2024-10-13 01:17:02

OP 询问如何在列表中的所有项目前面加上字符串。依赖于 list(TRANSFORM FILES_TO_TRANSLATE PREPEND ${CMAKE_CURRENT_SOURCE_DIR}) 之类的答案错过了这里的要点,因为它们向列表添加新项目,而不是修改现有列表项目。

通过查看 CMake 文档,我发现以下内容正是我所需要的:

list(TRANSFORM <existing_cmake_var> PREPEND <token_to_prepend>)

修改现有变量。如果您想保持现有变量不变,但将新变量设置为新列表(其中现有列表项将全部以开头,您可以使用以下语法:

list(TRANSFORM <existing_cmake_var> PREPEND <token_to_prepend> OUTPUT_VARIABLE <output_var_name>

示例:在我的情况下,我想添加将令牌 CONFIG_ 添加到现有列表中的所有令牌,并设置一个新变量,而不是修改原始变量:

set(DOXYGEN_OPTION_PREFS LOGGING COMPUTE)
list(TRANSFORM DOXYGEN_OPTION_PREFS PREPEND CONFIG_ OUTPUT_VARIABLE doxygen_predefined_list)

现在,doxygen_predenfined_list 具有该值

CONFIG_LOGGING CONFIG_COMPUTE

(此选项是在 CMake 3.12 中添加的)
https://cmake.org/cmake/help/latest/command/list。 html

The OP has asked how to prepend all items in a list with a string. Answers relying on the likes of list(TRANSFORM FILES_TO_TRANSLATE PREPEND ${CMAKE_CURRENT_SOURCE_DIR}) miss the point here because they add new items to the list, rather than modifying existing list items.

From looking at the CMake documentation, I've found the following does exactly what I need:

list(TRANSFORM <existing_cmake_var> PREPEND <token_to_prepend>)

which modifies the existing variable. If you want to leave the existing variable unchanged but set a new variable to the new list (where existing list items will all be prepended with <token_to_prepend>, you can use this syntax instead:

list(TRANSFORM <existing_cmake_var> PREPEND <token_to_prepend> OUTPUT_VARIABLE <output_var_name>

Example: in my case, I wanted to add the token CONFIG_ to all the tokens in an existing list, and set a new variable, rather than modify the original:

set(DOXYGEN_OPTION_PREFS LOGGING COMPUTE)
list(TRANSFORM DOXYGEN_OPTION_PREFS PREPEND CONFIG_ OUTPUT_VARIABLE doxygen_predefined_list)

Now, doxygen_predenfined_list has the value

CONFIG_LOGGING CONFIG_COMPUTE

(This option was added in CMake 3.12)
https://cmake.org/cmake/help/latest/command/list.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文