Как сделать команду для cmake чтобы копировать dll-ки к екзешнику?

set(MINGW_DLL_DIR "C:/msys64/mingw64/bin")
set(BIN_DIR, "/build/bin")
add_custom_command(TARGET r21
    POST_BUILD
    COMMAND bash -c [[for dll in "$$(ldd ./build/bin/r21.exe | grep  'mingw' | cut -f 1 -d '=' )"; do cp  C:/msys64/mingw64/bin/$$dll ./build/bin/$$dll; done]]
    COMMENT "Coping necessary DLLs"
)

ругается:

C:\Windows\system32\cmd.exe /C "cd . && C:\msys64\mingw64\bin\c++.exe -mwindows CMakeFiles/r21.dir/main.cpp.obj CMakeFiles/r21.dir/resources.c.obj -o bin\r21.exe .. -luuid -lcomdlg32 -ladvapi32 && C:\Windows\system32\cmd.exe /C "cd /D E:\VBStore\common\r21-multiplatform\r21\gtk\build && bash -c for dll in "$(ldd ./build/bin/r21.exe | grep 'mingw' | cut -f 1 -d '=' )"; do cp C:/msys64/mingw64/bin/$dll ./build/bin/$dll; done"" cut: '); do cp C:/msys64/mingw64/bin/$dll ./build/bin/$dll; done': No such file or directory dll: -c: line 1: syntax error near unexpected token newline' dll: -c: line 1: for' ninja: build stopped: subcommand failed.

Если такой вариант:

set(MINGW_DLL_DIR "C:/msys64/mingw64/bin")
set(BIN_DIR, "/build/bin")
add_custom_command(TARGET r21
    POST_BUILD
    COMMAND bash -c ${PROJECT_SOURCE_DIR}/load_dlls.sh
    COMMENT "Coping necessary DLLs"
)

скриптина:

for dll in "$(ldd ./build/bin/r21.exe | grep  'mingw' | cut -d '=' -f 1)"; do cp  C:/msys64/mingw64/bin/$dll ./build/bin/$dll; done

ругается:

ldd: ./build/bin/r21.exe: No such file or directory cp: -r not specified; omitting directory 'C:/msys64/mingw64/bin/'


Ответы (2 шт):

Автор решения: Ingvar

Возможно поможет такое (пример из моего проекта):

if (UNIX AND NOT APPLE)
#-- копируем файл иконки в папку сборки (требуется исключительно для Linux!)
    #-- чтобы можно было устанвить иконку приложения
    add_custom_command(
            TARGET progr  POST_BUILD
            COMMAND ${CMAKE_COMMAND} -E copy
                    ${CMAKE_CURRENT_SOURCE_DIR}/src/XXX.ico
                    ${CMAKE_BINARY_DIR}/${PlatformDir}/XXX.ico)
    
endif()
→ Ссылка
Автор решения: maestro

Команду для поиска и копирования зависимостей можно вынести в отдельный файл. Так легче будет разобраться с преобразованиями символов, это легче для восприятия и отладки.

Вот пример CMakeLists.txt, который запускает внешний скрипт после компиляции основного исполняемого файла.

cmake_minimum_required(VERSION 3.13)
project(cmake-copylibs)

# Основной исполняемый файл
add_executable(r21
    main.cpp
)

find_program(BASH_PATH "bash")

# Добавляем цель для сборки. Она будет выполнена при каждой сборке после r21.
add_custom_target(copy_libs ALL
# Запускается команда bash copy_libs r21.exe <current_source_dir> "mingw"
# где mingw - маска для поиска файлов
    COMMAND ${BASH_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/copy_libs $<TARGET_FILE:r21> ${CMAKE_CURRENT_BINARY_DIR} "mingw"
    DEPENDS r21
    SOURCES copy_libs
)

Скрипт copy_libs для поиска и копирования зависимостей:

#! /bin/bash

executable=$1
bindir=$2
search_mask=$3

for dll_path in $(ldd $executable | grep "$search_mask" | awk -F '=> ' '{print $2}' | awk '{print $1}'); do
  cp $dll_path ${bindir}/
done

Когда будете создавать файл скрипта, не забывайте, что в bash окончания строк должны быть LF.

→ Ссылка