Командная строка CMake copy
может обрабатывать несколько файлов, когда вы просто предоставляете список , поэтому это работает:
COMMAND ${CMAKE_COMMAND} -E copy ${library_files_debug} ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}
Это расширяется до списка файлов , разделенных пробелами, когда команда copy
в конечном итоге выполняется, что является ожидаемым синтаксисом.
cmake.exe -E copy mylib1.dll mylib2.dll /your/binary/dir/python/proj
Однако, когда заключено в выражение генератора, список будет не правильно интерпретироваться CMake. Хотя выражение генератора будет оценено правильно, список будет храниться как список файлов, разделенных точкой с запятой , что является неправильным синтаксисом:
cmake.exe -E copy "mylib1.dll;mylib2.dll" /your/binary/dir/python/proj
Это вызывает copy
Сбой команды.
Чтобы обойти эту проблему, вы можете l oop для каждого DLL-файла, который вы хотите скопировать, если их не слишком много. Что-то вроде этого может работать:
# Loop through the Debug files.
foreach(cur_file ${library_files_debug})
get_filename_component(file_name ${cur_file} NAME)
add_custom_target(copy_dlls_to_wheel_debug_${file_name} ALL
DEPENDS setup.py
COMMAND ${CMAKE_COMMAND} -E echo "DLL file: ${cur_file}"
COMMAND ${CMAKE_COMMAND} -E echo "Destination dir: ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}"
COMMAND ${CMAKE_COMMAND} -E copy $<$<CONFIG:Debug>:${cur_file}> ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}
)
endforeach()
# Loop through the Release files.
foreach(cur_file ${library_files_release})
get_filename_component(file_name ${cur_file} NAME)
add_custom_target(copy_dlls_to_wheel_release_${file_name} ALL
DEPENDS setup.py
COMMAND ${CMAKE_COMMAND} -E echo "DLL file: ${cur_file}"
COMMAND ${CMAKE_COMMAND} -E echo "Destination dir: ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}"
COMMAND ${CMAKE_COMMAND} -E copy $<$<CONFIG:Release>:${cur_file}> ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME}
)
endforeach()
Более быстрое решение может заключаться в том, чтобы связать ваши DLL, используя утилиту командной строки CMake tar
, скопировать их, а затем извлечь их, как предложено в this ответ. Команда CMake tar
, похоже, также не принимает списки, заключенные в выражения генератора, поэтому список файлов для объединения записывается в файл.
file(GLOB library_files_debug ${outputdirectory_root}/Debug/*.dll)
file(GLOB library_files_release ${outputdirectory_root}/Release/*.dll)
# Write the filenames (not full path) of the files to pack to file
set(debug_content "")
set(release_content "")
foreach(lib_file ${library_files_debug})
get_filename_component(file_name ${lib_file} NAME)
set(debug_content "${debug_content}${file_name}\n")
endforeach(lib_file ${library_files_debug})
foreach(lib_file ${library_files_release})
get_filename_component(file_name ${lib_file} NAME)
set(release_content "${release_content}${file_name}\n")
endforeach(lib_file ${library_files_release})
set(filenames_debug ${outputdirectory_root}/debug_files.txt)
set(filenames_release ${outputdirectory_root}/release_files.txt)
file(WRITE ${filenames_debug} ${debug_content})
file(WRITE ${filenames_release} ${release_content})
# Read either the list of debug or release files, and pack files
add_custom_command(
TARGET bdist PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E tar "cfj" ${outputdirectory_root}/temp.tar --files-from="$<IF:$<CONFIG:Debug>,${filenames_debug},${filenames_release}>"
WORKING_DIRECTORY ${outputdirectory_root}/$<CONFIG>)
# Unpack the files in the folder building the python wheel
add_custom_command(
TARGET bdist PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E rename ${outputdirectory_root}/temp.tar temp.tar
COMMAND ${CMAKE_COMMAND} -E tar "xfj" temp.tar
COMMAND ${CMAKE_COMMAND} -E remove temp.tar
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/python/${PROJECT_NAME})