CMake를 사용하여 소스 디렉터리에서 바이너리 디렉터리로 파일 복사


100

CLion에서 간단한 프로젝트를 만들려고합니다. CMake (저는 여기에 새로 왔어요)를 사용하여 프로젝트 (또는 일종의)를 빌드하기 위해 Makefile을 생성합니다.

내 코드를 실행할 때마다 프로젝트가 아닌 파일 (일종의 리소스 파일)을 바이너리 디렉토리로 전송하기 만하면됩니다.

해당 파일에는 테스트 데이터가 포함되어 있으며 응용 프로그램에서이를 열어 읽습니다. 이를 위해 여러 가지 방법을 시도했습니다.

  • 통하다 file(COPY ...

    file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
            DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/input.txt
    

    좋아 보이지만 한 번만 작동하고 다음 실행 후 파일을 다시 복사하지 않습니다.

  • 통하다 add_custom_command

    • OUTPUT 버전

      add_custom_command(
              OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
              COMMAND ${CMAKE_COMMAND} -E copy
                      ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                      ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
      
    • TARGET 버전

      add_custom_target(foo)
      add_custom_command(
              TARGET foo
              COMMAND ${CMAKE_COMMAND} copy
                      ${CMAKE_CURRENT_BINARY_DIR}/test/input.txt
                      ${CMAKE_SOURCE_DIR})
      

    하지만 그 누구도 작동하지 않습니다.

내가 뭘 잘못하고 있죠?

답변:


127

다음 옵션 과 함께 configure_file 사용을 고려할 수 있습니다 COPYONLY.

configure_file(<input> <output> COPYONLY)

file(COPY ...)입력과 출력간에 파일 수준 종속성을 생성하는 것과 달리 다음과 같습니다.

입력 파일이 수정되면 빌드 시스템이 CMake를 다시 실행하여 파일을 재구성하고 빌드 시스템을 다시 생성합니다.


12
참고하시기 바랍니다 configure_file당신이 파일의 목록을 만들 수 GLOB를 사용하는 경우에도 하위 디렉토리와 작업에가는되지 않습니다.
Tarantula

63

두 옵션 모두 유효하며 빌드의 두 가지 다른 단계를 대상으로합니다.

  1. file(COPY ...구성 단계와이 단계에서만 파일을 복사합니다. cmake 구성을 변경하지 않고 프로젝트를 다시 빌드하면이 명령이 실행되지 않습니다.
  2. add_custom_command 각 빌드 단계에서 파일을 복사하려는 경우 선호되는 선택입니다.

작업에 적합한 버전은 다음과 같습니다.

add_custom_command(
        TARGET foo POST_BUILD
        COMMAND ${CMAKE_COMMAND} -E copy
                ${CMAKE_SOURCE_DIR}/test/input.txt
                ${CMAKE_CURRENT_BINARY_DIR}/input.txt)

당신이 선택할 수 있습니다 PRE_BUILD, PRE_LINK, POST_BUILD 가장 당신의 문서를 읽어 add_custom_command을

첫 번째 버전을 사용하는 방법에 대한 예는 여기에서 찾을 수 있습니다. CMake add_custom_command를 사용하여 다른 대상에 대한 소스 생성


1
CMAKE_SOURCE_DIR 또는 CMAKE_CURRENT_SOURCE_DIR입니까?
Syaiful Nizam Yahya

1
@SyaifulNizamYahya CMAKE_CURRENT_SOURCE_DIRtest/input.txt파일이 현재 CMakeLists.txt파일에 상대적인 경우 사용 합니다. root에 상대적인 CMakeLists.txt경우 CMAKE_SOURCE_DIR.
Mark Ingram

16

시도한 첫 번째 옵션이 두 가지 이유로 작동하지 않습니다.

첫째, 괄호를 닫는 것을 잊었습니다.

둘째, DESTINATION파일 이름이 아니라 디렉토리 여야합니다. 괄호를 닫았다 고 가정하면 파일은 input.txt.

작동하려면 다음으로 변경하십시오.

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
     DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

4

TARGET_FILE_DIR파일을 .exe 파일과 동일한 폴더에 복사하려는 경우 제안 합니다.

$ 주 파일 (.exe, .so.1.2, .a)의 디렉토리.

add_custom_command(
  TARGET ${PROJECT_NAME} POST_BUILD
  COMMAND ${CMAKE_COMMAND} -E copy 
    ${CMAKE_CURRENT_SOURCE_DIR}/input.txt 
    $<TARGET_FILE_DIR:${PROJECT_NAME}>)

VS에서이 cmake 스크립트는 디버그 또는 릴리스에 관계없이 input.txt를 최종 exe와 동일한 파일에 복사합니다.


3

이것은 내가 일부 리소스 파일을 복사하는 데 사용한 것입니다. 복사 파일은 오류를 무시하는 빈 대상입니다.

 add_custom_target(copy-files ALL
    COMMAND ${CMAKE_COMMAND} -E copy_directory
    ${CMAKE_BINARY_DIR}/SOURCEDIRECTORY
    ${CMAKE_BINARY_DIR}/DESTINATIONDIRECTORY
    )

또한 add_dependencies(MainTarget copy-files)MainTarget을 빌드 할 때 자동으로 실행되도록 추가 합니다
Herrgott

이것은 실제로 소스의 현재 버전이 항상 대상 포스트 빌드에 있음을 보장하기 때문에 최선의 답변 (+ Herrgott의 의견)처럼 보입니다. 작은 복사 작업의 경우 잘 작동합니다. 감사합니다. add_dependencies(MainTarget copy-files)루트 CMakeLists.txt파일을 넣으면 프로젝트 전체에서 사용할 수 있습니다.
satnhak

1

currant 디렉토리에서 바이너리 (빌드 폴더) 폴더로 폴더를 복사하려는 경우

file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/yourFolder/ DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/yourFolder/)

그러면 syntexe는 다음과 같습니다.

file(COPY pathSource DESTINATION pathDistination)

0

제안 된 configure_file이 아마도 가장 쉬운 솔루션 일 것입니다. 그러나 빌드 디렉토리에서 파일을 수동으로 삭제 한 경우에는 복사 명령을 다시 실행하지 않습니다. 이 경우를 처리하기 위해 다음이 효과적입니다.

add_custom_target(copy-test-makefile ALL DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/input.txt)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.txt
                                                    ${CMAKE_CURRENT_BINARY_DIR}/input.txt
                   DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/input.txt)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.