2011-12-08 29 views
13

Trong CMake, tôi có một thư mục chứa danh mục Gettext được xác định trước, tại thời điểm xây dựng mà tôi sao chép vào một thư mục và sau đó sửa đổi chúng. Nhưng vấn đề là mỗi khi tôi chạy các mục tiêu nó sẽ sao chép các tập tin được xác định trước trên bản sao địa phương (có lẽ là sửa đổi). Có cách nào để sao chép nếu tệp khác với trạng thái trước đó, nếu không thì hãy để nó một mình? Tôi cũng nghĩ rằng một cách để làm điều này sẽ là sao chép chúng qua thời gian thế hệ CMake, nhưng tôi cảm thấy hơi mệt mỏi khi làm điều đó vì mọi người có thể xóa các thư mục và sửa chữa mọi thứ. Ngoài ra tôi không biết làm thế nào để thực hiện lệnh trong thời gian thế hệ, chỉ ở thời gian xây dựng.Bản sao CMake nếu tệp gốc đã thay đổi

Trả lời

5

Được rồi, tôi đã cố gắng khắc phục điều này một lúc nhưng quên mất câu trả lời này. Xin lỗi tất cả những người đã bỏ qua điều này và không có câu trả lời!

# ----- Copy and merge across the po files that come with the source. 

message("Copying and updating stock translations...") 

file(GLOB poFiles "${stockDir}/*.po") 

foreach(file ${poFiles}) 
    # Get the language name, like en_US or zh_CN from the name of the po file, so 
    # 'en_US.po' or 'zh_CN.po' become 'en_US' or 'zh_CN.po' 
    get_filename_component(langName ${file} NAME_WE) 

    set(newFile "${langDir}/${langName}.po") 

    if(NOT EXISTS ${newFile}) 
    execute_process(COMMAND ${MSGMERGE_EXECUTABLE} 
     "--output-file" ${newFile} ${file} ${potFile} 
     OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret) 

    if(ret) # Have to do this hack as msgmerge prints to stderr. 
     message(SEND_ERROR "${error}") 
    endif() 

    message(" '${langName}' copied.") 
    elseif(${file} IS_NEWER_THAN ${newFile}) 
    execute_process(COMMAND ${MSGMERGE_EXECUTABLE} 
     "--update" ${newFile} ${file} 
     OUTPUT_QUIET ERROR_VARIABLE error RESULT_VARIABLE ret) 

    if(ret) # Have to do this hack as msgmerge prints to stderr. 
     message(SEND_ERROR "${error}") 
    endif() 

    message(" '${langName}' merged.") 
    endif() 
endforeach() 

stockDir là thư mục chứa các tệp po được lưu trữ không có nghĩa là người dùng chỉnh sửa (trừ khi cam kết với repo). langDir nằm trong thư mục xây dựng dưới 'lang'. Nó đi qua, và một trong hai bản sao hoặc cập nhật nó dựa trên tuổi của các tập tin.

+0

Ví dụ tuyệt vời !! – gone

20

Tôi tin rằng bạn sẽ có thể sử dụng lệnh tùy chỉnh tùy thuộc vào tệp. Một cái gì đó như:

add_custom_command(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/output.file 
    COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/input.file ${CMAKE_CURRENT_BINARY_DIR}/output.file 
    MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/input.file) 

Hãy cho tôi biết nếu điều đó không làm điều đó. Nó có thể giúp cung cấp mã CMake mà bạn hiện đang sử dụng.

Bạn cũng có thể thử "$ {CMAKE_COMMAND} -E copy_if_different"; nó không rõ ràng với tôi cho dù điều này sẽ khác nhau cho các phụ thuộc của lệnh, nhưng tôi chắc chắn có thể thiếu một cái gì đó, hoặc nó có thể khác nhau nếu bạn không sử dụng "làm" đầu ra.


Trong trường hợp bạn muốn thử làm các bản sao ở "thời gian thế hệ" (khi bạn chạy cmake), bạn có thể sử dụng lệnh này (tôi nghĩ cú pháp của tôi là đúng nhưng tôi đã không kiểm tra nó):

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

Sử dụng INSTALL thay vì COPY cho hành vi hơi khác.

Nếu bạn cần chạy một quá trình tùy ý vào thời gian tạo, hãy thử lệnh execute_process.

Tất nhiên để biết chi tiết, xem the CMake documentation.

+1

"cp" là unix cụ thể, nhưng tôi sẽ cung cấp cho nó một shot. – Jookia

+1

Thay vì sử dụng "cp", bạn có thể chỉ cần sử dụng "$ {CMAKE_COMMAND} -E copy" - chạy "cmake -E" mà không có bất kỳ đối số nào khác để xem danh sách các lệnh giống như công cụ đa nền tảng cmake -E có thể chạy. Thậm chí còn có một "copy_if_different" ... Sử dụng một lệnh tùy chỉnh như thế này là giải pháp hoàn hảo, và câu trả lời tôi cũng đã đưa ra. – DLRdave

+0

Ồ vâng, tôi đã sử dụng ít nhất một lần trước đây nhưng hoàn toàn quên mất nó. Cảm ơn con trỏ. –

7

Một tùy chọn khác là sử dụng configure_file với đối số COPYONLY.

configure_file(input_file output_file COPYONLY) 

Điều này sẽ không thực hiện bất kỳ thay thế biến nào và sẽ sao chép "input_file" khi bạn chạy make. Nhưng nó kích hoạt một cmake chạy và điều này có thể là không mong muốn vì thời gian tiêu thụ.

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