CMake를 사용하여 DLL 파일을 실행 파일과 동일한 폴더에 복사하는 방법은 무엇입니까?


98

SVN에서 소스의 Visual Studio 파일을 생성하기 위해 CMake를 사용합니다. 이제 내 도구는 일부 DLL 파일이 실행 파일과 동일한 폴더에 있어야합니다. DLL 파일은 소스와 함께 폴더에 있습니다.

어떻게 변경할 수 있습니다 내 CMakeLists.txt생성 된 비주얼 스튜디오 프로젝트 중 이미 출시 / 디버그 폴더에 특정 DLL 파일이되거나 편집에 복사 것 같은?

답변:


122

나는 add_custom_command이것을 cmake -E copy_if_different.... 전체 정보 실행

cmake --help-command add_custom_command
cmake -E


따라서 귀하의 경우에는 다음과 같은 디렉토리 구조가 있습니다.

/CMakeLists.txt
/src
/libs/test.dll

명령이 적용되는 CMake 대상이 MyTest이면 CMakeLists.txt에 다음을 추가 할 수 있습니다.

add_custom_command(TARGET MyTest POST_BUILD        # Adds a post-build event to MyTest
    COMMAND ${CMAKE_COMMAND} -E copy_if_different  # which executes "cmake - E copy_if_different..."
        "${PROJECT_SOURCE_DIR}/libs/test.dll"      # <--this is in-file
        $<TARGET_FILE_DIR:MyTest>)                 # <--this is out-file path


/libs/디렉토리 의 전체 내용 만 복사하려면 cmake -E copy_directory다음을 사용하십시오 .

add_custom_command(TARGET MyTest POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
        "${PROJECT_SOURCE_DIR}/libs"
        $<TARGET_FILE_DIR:MyTest>)


구성 (예 : 릴리스, 디버그)에 따라 다른 dll을 복사해야하는 경우 해당 구성으로 명명 된 하위 디렉토리에 /libs/Release, 및 /libs/Debug. 그런 다음 다음과 같이 구성 유형을 add_custom_command호출 의 dll 경로에 삽입해야합니다 .

add_custom_command(TARGET MyTest POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_directory
        "${PROJECT_SOURCE_DIR}/libs/$<CONFIGURATION>"
        $<TARGET_FILE_DIR:MyTest>)

3
미래에 다른 사람에게 도움이 될 경우에 대비하여 내 경우에 효과가 있었던 것에 대한 빠른 메모 : 기본 실행 파일이 선택적으로 연결되는 정적 라이브러리 프로젝트가 있으며 해당 라이브러리를 추가하면 DLL을 복사해야합니다. 따라서 해당 라이브러리의 CMakeLists.txt 파일 ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/$<CONFIG>에서 대상 대상으로 사용 했습니다. 그렇지 않으면 쓸모없는 라이브러리 빌드 경로에 복사합니다.
AberrantWolf

install()바이너리를 조합하는 것이 cmake 지시문 의 목표가 아닙니까? 아니면 cmake LIBRARY물건? 나는 툴체인을 정말로 모른다.
Sandburg

1
$<TARGET_FILE_DIR:MyTest>-뭐야? 정보를 인쇄하는 방법, 정확히 의미
ilw aug

명령을 통합 할 때 놓친 것이 아니라면이 방법은 IMPORTED_LIBRARIES. 아무것도 빌드되지 않은 상태에서 빌드 후 명령을 실행할 수 없다고 불평합니다.
Tzalumen

2
내 cmake를 테스트하고 제작할 때 : IMPORTED라이브러리를 사용하고 있고 DLL을 재배치해야하는 경우 변형 명령을 사용해야합니다. 당신이 추가 한 경우 IMPORTED로 라이브러리를 MyImportedLib사용할 것 COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:MyImportedLib> $<TARGET_FILE_DIR:MyTest>참고 여러 포스트 빌드 명령을 실행하는 것을 당신은 그들 모두가 하나의 사용자 지정 명령 예에 바인드해야합니다add_custom_command(TARGET MyTest POST_BUILD COMMAND #your first command# COMMAND #Your second command#)
Tzalumen

24

이 줄을 최상위 CMakeLists.txt 파일에 넣었습니다. CMake로 컴파일 된 모든 라이브러리와 실행 파일은 빌드 디렉터리의 최상위 수준에 배치되므로 실행 파일이 라이브러리를 찾을 수 있고 모든 것을 쉽게 실행할 수 있습니다.

set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})

이것은 프로젝트의 소스 디렉토리에서 미리 컴파일 된 바이너리를 복사하는 OP 문제를 해결하지 못합니다.


7

내 프로그램의 Windows 빌드를 만들려고 할 때 오늘이 문제가 발생했습니다. 그리고이 모든 답변이 저를 만족시키지 못했기 때문에 저는 스스로 조사를했습니다. 세 가지 주요 문제가 있습니다.

  • 디버그 빌드를 라이브러리의 디버그 버전과 연결하고 릴리스 빌드를 라이브러리의 릴리스 빌드와 각각 연결하고 싶었습니다.

  • 또한 올바른 버전의 DLL 파일 (Debug / Release)을 출력 디렉토리에 복사하고 싶었습니다.

  • 복잡하고 깨지기 쉬운 스크립트를 작성하지 않고이 모든 것을 달성하고 싶었습니다.

github에서 일부 CMake 매뉴얼과 일부 다중 플랫폼 프로젝트를 탐색 한 후이 솔루션을 찾았습니다.

"IMPORTED"속성을 사용하여 라이브러리를 대상으로 선언하고 디버그를 참조하고 .lib 및 .dll 파일을 릴리스하십시오.

add_library(sdl2 SHARED IMPORTED GLOBAL)
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_RELEASE "${SDL_ROOT_PATH}/lib/SDL2.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_RELEASE "${SDL_ROOT_PATH}/bin/SDL2.dll")
set_property(TARGET sdl2 PROPERTY IMPORTED_IMPLIB_DEBUG "${SDL_ROOT_PATH}/lib/SDL2d.lib")
set_property(TARGET sdl2 PROPERTY IMPORTED_LOCATION_DEBUG "${SDL_ROOT_PATH}/bin/SDL2d.dll")

평소와 같이이 대상을 프로젝트와 연결

target_link_libraries(YourProg sdl2 ...)

이전 빌드 이후 어떻게 든 변경된 경우 dll 파일을 대상에 복사하는 사용자 지정 빌드 단계를 만듭니다.

add_custom_command ( TARGET YourProg POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy_if_different
    $<TARGET_FILE:sdl2> $<TARGET_FILE_DIR:YourProg>
)

5

수락 된 답변에 대한 부록, 별도의 답변으로 추가되어 코드 형식을 얻습니다.

동일한 프로젝트에서 dll을 빌드하는 경우 일반적으로 Release, Debug 등의 디렉토리에 있습니다. Visual Studio 환경 변수를 사용하여 올바르게 복사해야합니다. 예 :

"${PROJECT_BINARY_DIR}/your_library/\$\(Configuration\)/your_library.dll"

소스 및

"${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/your_library.dll"

목적지. 탈출에주의하십시오!

구성에 CMake CMAKE_BUILD_TYPE 변수를 사용할 수 없습니다. VS 프로젝트 생성 시간에 확인되고 항상 기본값이되므로 구성에 사용할 수 없습니다.


8
허용 대답의 마지막 부분은 사용하는 청소기 CMake 방식으로이 문제를 해결$<CONFIGURATION>
척 Claunch

4

find_library 명령을 사용할 수도 있습니다.

find_library(<some_var> NAMES <name_of_lib> PATHS "<path/to/lib>")

정의 된 EXECUTABLE_PATH를 사용하면 예를 들면 다음과 같습니다.

set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

실행 파일에 필요한 .dll 파일을 이동할 수 있습니다.

file(COPY ${<some_var>}
    DESTINATION ${EXECUTABLE_OUTPUT_PATH})

2

이것은 그들 중 하나에 유용합니다

SET(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
    ${PROJECT_SOURCE_DIR}/lib CACHE
    PATH "Directory where all the .lib files are dumped." FORCE)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY
    ${PROJECT_SOURCE_DIR}/bin CACHE
    PATH "Directory where .exe and .dll files are dumped." FORCE)

1

사용자 지정 대상추가 하고 실행 가능한 대상 중 하나에 종속되도록 해야 할 수 있습니다 .

위의 기능을 사용하여 파일을 복사하려면 다음을 사용하십시오.

COMMAND ${CMAKE_PROGRAM} -E copy_if_different ${CMAKE_BINARY_DIR}/path/to/file.dll ${CMAKE_BINARY_DIR}/where/to/put/file.dll`

0

저는 CMake 초보자이지만 여전히 경험을 공유하고 싶었습니다. 제 경우에는 모든 바이너리가 포함되도록 설치 후 사본이 필요했습니다. CMake 내에서 가져올 수있는 타사 바이너리의 경우 다음이 저에게 효과적입니다.

find_package( dependency REQUIRED )
if( MSVC ) 
    # If done properly and if the dependency has a correct config file, IMPORTED_LOCATION_RELEASE should be defined
    get_target_property( DEP_SHARED_LIB_PATH dependency IMPORTED_LOCATION_RELEASE )
    # Create a bin directory in the install folder
    add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory  ${CMAKE_INSTALL_PREFIX}/bin/)
    # Copy the shared lib file
    add_custom_command(TARGET BGS POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${DEP_SHARED_LIB_PATH} ${CMAKE_INSTALL_PREFIX}/bin/)
endif()

분명히 IMPORTED_LOCATION_RELEASE는 공유 라이브러리가 구축 / 설치된 방법에 따라 변형을 가질 수 있습니다. IMPORTED_LOCATION_DEBUG 일 수 있습니다.

그 부동산 이름을 얻는 더 좋은 방법이 있을지 모르겠습니다.


0

빌드 중 파일 이동 install

9 단계 에서 CMake 공식 자습서를 따르려고이 문제가 발생했습니다 . 이동하려는 파일의 위치입니다.

src
 |_build
    |_Debug
       - `MathFunctions.dll`

이것이 내가 원하는 파일 위치입니다.

src
 |_build
    |_install
         |_bin
             - `MathFunctions.dll`

이 DLL은 공유 라이브러리로 생성 된 이후, 모든 나는이 라인을 포함하는 것이었다 않았다 CMakeLists.txt하위 디렉토리 라이브러리에 대한 소스 코드를 포함src/Mathfunctions/CMakeLists.txt

install(FILES ${PROJECT_BINARY_DIR}/$<CONFIG>/MathFunctions.dll
DESTINATION bin)

귀하의 답변 덕분에 나는 이것에 대해 생각할 수있었습니다. 한 줄이면 괜찮다고 생각합니다. $<CONFIG>에는 두 가지 값 이 있을 수 있습니다. Debug 또는 Release 프로젝트가 빌드 된 방법에 따라 원래 질문이 필요합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.