2010-08-07 32 views
17

Tôi đã có một dự án CMake chứa mã và một vài tệp dữ liệu (hình ảnh chính xác).Làm thế nào để xử lý tốt nhất các tệp dữ liệu với CMake?

cấu trúc thư mục của tôi là như thế này:

  • src
  • dữ liệu

src chứa mã nguồn, dữ liệu các tập tin dữ liệu. CMake đề xuất trong số các bản dựng nguồn, vì vậy khi tôi gọi tạo, tôi có chương trình thực thi, nhưng không có tệp dữ liệu, do đó tôi không thể thực thi chương trình.

Tất nhiên, make install sẽ sao chép các file dữ liệu của tôi đến vị trí cần thiết và làm cho nó hoạt động, do đó tôi phát triển như này ngay bây giờ:

  1. cmake -DCMAKE_INSTALL_DIR = quận
  2. <edit source code>
  3. hãy cài đặt
  4. dist/myprogram.exe

Không sao nếu tôi làm việc với dòng lệnh và trình soạn thảo, nhưng gần đây tôi đã quyết định chuyển sang Eclipse CDT. Tạo một dự án Eclipse từ CMake hoạt động tốt, nhưng việc thực hiện thủ công mục tiêu cài đặt từ Eclipse không phải là quá tốt đẹp.

Làm cách nào để mọi người giải quyết vấn đề này? Chương trình của bạn có một số thuật toán thông minh để thử và tìm thư mục dữ liệu của nó ngay cả khi nó không phải là nơi nhị phân? Hay bạn không sử dụng hết các bản dựng nguồn?

Trả lời

16

configure_file nên giải quyết vấn đề đó.

Tôi có một tập tin CMakeLists.txt trong thư mục dữ liệu của tôi, trong đó có những điều sau đây:

configure_file(data_file ${CMAKE_CURRENT_BINARY_DIR}/data_file COPYONLY) 

này sẽ copy một file nào đó vào thư mục build khi cmake được gọi, vì vậy nó có sẵn trong cùng một vị trí thậm chí trong số các bản dựng nguồn.

configure_file không hỗ trợ thư mục tuy nhiên trong khi lệnh file làm:

file(COPY assets DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) 
+3

tôi phải làm điều đó cho mỗi tập tin riêng – Arne

+2

tôi sử dụng file '(tài sản COPY ĐIỂM ĐẾN $ {CMAKE_CURRENT_BINARY_DIR})' – WarmWaffles

11

Và nếu sao chép các tập tin mất quá nhiều thời gian (họ là những hình ảnh ...), bạn có thể làm cho nó thậm chí còn tốt hơn bằng cách tạo ra một " tùy chỉnh "data_header.h với configure_file chứa đường dẫn đến dữ liệu vẫn còn trong thư mục nguồn của bạn.

Đây là những gì tôi làm: Tôi có một tập tin "global_build_config.h.in" trong mã nguồn của tôi, chứa những điều sau đây:

const char* const global_testdatapath = "@[email protected]"; 

và sau đó sử dụng configure_file trong CMake:

# Assume CMake knows a variable Test_Data_Path, it will be filled in automatically 
# in the generated config/Global_Build_Config.h 
configure_file(Global_Build_Config.h.in ${CMAKE_BINARY_DIR}/config/Global_Build_Config.h) 
# The config directory should be added as a include-searchpath 
include_directories(${CMAKE_BINARY_DIR}/config/) 

Sau đó tôi có thể #include "Global_Build_Config.h" trong tệp cpp của tôi và tham chiếu đến đường dẫn cố định.

+0

bạn nên biết rằng điều này làm cho bao bì của dự án phức tạp hơn nhiều, bởi vì đối với một gói phần mềm xây dựng cmake phải được thực hiện một lần nữa chưa kể đến mã lệnh mở rộng bạn phải viết. – Arne

2

Câu hỏi của bạn là một chút cũ, nhưng trong trường hợp bạn vẫn quan tâm (hoặc người khác), tôi có một kịch bản tương tự như nơi tôi sao chép TestData cho một mục tiêu đơn vị kiểm tra:

add_custom_command(TARGET ${UTEST_EXE_NAME} 
    POST_BUILD 
    COMMAND ${CMAKE_COMMAND} -E echo "Copying unit test data.." 
    COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_HOME_DIRECTORY}/utest/testdata ${CMAKE_BINARY_DIR} 
    ) 

Vì vậy, các ý tưởng chính là sử dụng một mục tiêu sau khi xây dựng, và nó được thực thi sau mỗi lần xây dựng. Đối với tôi, nó không có nhiều dữ liệu, và hệ thống tập tin lưu trữ nó, vì vậy tôi không cảm thấy quá trình sao chép cả. Bạn có thể tăng cường điều này bằng cách sao chép với copy_if_different. Trong trường hợp đó, tuy nhiên, bạn phải tạo một danh sách các tập tin hình ảnh của bạn và viết một vòng lặp, bởi vì lệnh là dựa trên tập tin. Với lệnh GLOB, điều này không khó thực hiện nếu bạn cần.

Các vấn đề liên quan