我试图复制使用多个文件${CMAKE_COMMAND} -E copy <from> <to>
格式,但我不知道是否有一种方式来提供大量的文件复制到指定目录。 看来cmake的副本只允许一个文件同时被复制。 我真的不想使用copy命令多次时,我宁愿提供要复制的文件作为第一个参数列表。
我想最简单的方法是使用平台相关者“CP”命令。 虽然这肯定是不适合的便携性,我们的系统是保证在Linux上构建的。 一个简单的,独立于平台的解决方案将是更好的。
我试图复制使用多个文件${CMAKE_COMMAND} -E copy <from> <to>
格式,但我不知道是否有一种方式来提供大量的文件复制到指定目录。 看来cmake的副本只允许一个文件同时被复制。 我真的不想使用copy命令多次时,我宁愿提供要复制的文件作为第一个参数列表。
我想最简单的方法是使用平台相关者“CP”命令。 虽然这肯定是不适合的便携性,我们的系统是保证在Linux上构建的。 一个简单的,独立于平台的解决方案将是更好的。
复制多个文件可从CMake的3.5
cmake -E copy <file>... <destination>
“CMake的-E复制”的多个文件的支持
命令行工具模式
我有一个循环做到了
# create a list of files to copy
set( THIRD_PARTY_DLLS
C:/DLLFOLDER/my_dll_1.dll
C:/DLLFOLDER/my_dll_2.dll
)
# do the copying
foreach( file_i ${THIRD_PARTY_DLLS})
add_custom_command(
TARGET ${VIEWER_NAME}
POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy ${file_i} "C:/TargetDirectory"
)
endforeach( file_i )
一个相对简单的解决方法是使用${CMAKE_COMMAND} -E tar
捆绑的来源,将压缩包,并在目标目录中提取出来。
如果你的来源是分散在多个不同的目录,因为提取将保留原来的目录结构(不像使用这可能是更多的麻烦比它的价值cp
)。 如果所有的文件都在一个目录然而,你可以在短短2实现复制add_custom_command
电话。
假设你的源移动都在${CMAKE_SOURCE_DIR}/source_dir
,目的地是${CMAKE_SOURCE_DIR}/destination_dir
和您的文件名(不完整路径)都在名单${FileList}
。 你可以这样做:
add_custom_command(
TARGET MyExe POST_BUILD
COMMAND ${CMAKE_COMMAND} -E tar cfj ${CMAKE_BINARY_DIR}/temp.tar ${FileList}
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/source_dir)
add_custom_command(
TARGET MyExe POST_BUILD
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_BINARY_DIR}/temp.tar temp.tar
COMMAND ${CMAKE_COMMAND} -E tar xfj temp.tar ${FileList}
COMMAND ${CMAKE_COMMAND} -E remove temp.tar
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/destination_dir)
因为我有或多或少完全相同的问题,并没有像上面的解决方案,最终我这个走了过来。 这并不仅仅是复制文件,但我想我会后整个事情,因为它显示了该技术在与发电机表达式,使不同的文件和目录取决于构建变量相结合的灵活性。 我相信COMMAND_EXPAND_LISTS是这里的功能至关重要。 此功能不仅一些文件复制到一个新的目录,但随后运行在他们每个人的命令。 在这种情况下,它使用Microsoft signtool程序数字签名添加到每个文件。
cmake_minimum_required (VERSION 3.12)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
SET(ALL_3RD_PARTY_DLLS_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/file1.dll" "${CMAKE_CURRENT_SOURCE_DIR}/file2.dll")
SET(ALL_3RD_PARTY_DLLS_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/file3.dll" "${CMAKE_CURRENT_SOURCE_DIR}/file4.dll")
STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" ";${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Debug" ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG ${ALL_3RD_PARTY_DLLS_DEBUG})
LIST(REMOVE_AT ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG 0)
STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" ";${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/Release" ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE ${ALL_3RD_PARTY_DLLS_RELEASE})
LIST(REMOVE_AT ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE 0)
FILE(TO_NATIVE_PATH "C:\\Program\ Files\ (x86)\\Windows\ Kits\\10\\bin\\10.0.17763.0\\x86\\signtool.exe" SIGNTOOL_COMMAND)
add_custom_target(Copy3rdPartyDLLs ALL
COMMENT "Copying and signing 3rd Party DLLs"
VERBATIM
COMMAND_EXPAND_LISTS
COMMAND ${CMAKE_COMMAND} -E
make_directory "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/"
COMMAND ${CMAKE_COMMAND} -E
copy_if_different
"$<$<CONFIG:Release>:${ALL_3RD_PARTY_DLLS_RELEASE}>"
"$<$<CONFIG:Debug>:${ALL_3RD_PARTY_DLLS_DEBUG}>"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/"
COMMAND ${SIGNTOOL_COMMAND} sign
"$<$<CONFIG:Release>:${ALL_OUTPUT_3RD_PARTY_DLLS_RELEASE}>"
"$<$<CONFIG:Debug>:${ALL_OUTPUT_3RD_PARTY_DLLS_DEBUG}>"
)
我希望这样可以节省别人一天左右,它花了我摸不着头脑。