2012-03-08 16 views
5

Tôi muốn đổi tên tệp trình cài đặt mà CPack (v2.8.7) tạo để bao gồm số phiên bản thu được tại thời gian xây dựng từ hệ thống kiểm soát phiên bản. Nó xuất hiện điều này không thể được thực hiện bằng cách thiết lập các biến CPACK_ * vì điều đó xảy ra tại thời gian "cmake".Đổi tên đầu ra của CPack

Điều tôi muốn có thể làm là chạy "(n) tạo gói" và có tệp trình cài đặt được tạo mà không cần thêm lệnh nào. Hai cách tiếp cận có thể có mà tôi biết là thao tác các biến tên tệp CPack tại thời gian xây dựng và đổi tên đầu ra cuối cùng của CPack.

Nếu sử dụng "include (CPack)" trong tệp CMakeLists.txt thì có vẻ như CPack luôn chạy cuối cùng và bạn không thể có lệnh sau khi tạo. This mailing list message cho thấy rằng một mục tiêu tùy chỉnh có thể được viết để chạy CPack, nhưng tôi đã không thể tìm ra cách để làm điều đó mà không cần tạo đệ quy vô hạn.

Làm cách nào để thực hiện điều này?

Trả lời

5

Với một chút trợ giúp từ danh sách gửi thư của CMake, tôi đã tìm ra cách thực hiện, bằng cách sử dụng lật đổ.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8) 
project(myapp) 

add_executable(main main.cpp) 
install(TARGETS main DESTINATION .) 

add_custom_target(first ALL 
    # update the working copy 
    COMMAND ${Subversion_SVN_EXECUTABLE} update ${CMAKE_SOURCE_DIR} 

    # generate cpackoptions.cmake at build time so we get the 
    # most recent revision number 
    COMMAND ${CMAKE_COMMAND} 
    -DSOURCE_DIR=${CMAKE_SOURCE_DIR} 
    -DBINARY_DIR=${CMAKE_BINARY_DIR} 
    -Dproj_name=${CMAKE_PROJECT_NAME} 
    -P ${CMAKE_SOURCE_DIR}/create-cpackoptions.cmake 
    ) 

add_dependencies(main first) 

set(CPACK_PROJECT_CONFIG_FILE ${CMAKE_BINARY_DIR}/CPackOptions.cmake) 

include(CPack) 

tạo-cpackoptions.cmake

include(FindSubversion) 
Subversion_WC_INFO(${SOURCE_DIR} ${proj_name}) 

set(revision ${${proj_name}_WC_REVISION}) 

configure_file(${SOURCE_DIR}/CPackOptions.cmake.in 
    ${BINARY_DIR}/CPackOptions.cmake 
    @ONLY) 

cpackOptions.cmake.in

set(CPACK_PACKAGE_FILE_NAME "@[email protected]${CPACK_PACKAGE_VERSION}[email protected]@-${CPACK_SYSTEM_NAME}") 
+0

Bạn có thể tiến thêm một bước nữa và tạo ra 'CPackOptions.cmake.in' và' create-cpackoptions.cmake' từ CMakeFile.txt. Điều này có nghĩa là bạn không cần hai tệp trong cây nguồn của mình. Ví dụ: tập tin «tệp (WRITE $ {CMAKE_BINARY_DIR} /CPackOptions.cmake.in" (CPACK_PACKAGE_FILE_NAME \ "@ proj_name @ - \ $ {CPACK_PACKAGE_VERSION} r @ revision @ - \ $ {CPACK_SYSTEM_NAME} \") ")' –

4

Tại sao không trích xuất thông tin xây dựng từ VCS tại thời gian thực hiện? Sau đó, bạn có thể dễ dàng sửa đổi CPACK_PACKAGE_FILE_NAME để bao gồm số phiên bản của mình.

Đã thêm tiền thưởng: Khi thực hiện việc này tại thời gian CMake, bạn có thể, ví dụ: điền vào một tập tin "Readme.txt" với git-thông tin bằng cách sử dụng configure_file của CMake và thêm nó vào gói của bạn. Hoặc có thể sử dụng nó để điền vào một "config.h", được sử dụng trong các bản dựng của bạn.

Ví dụ: trong một dự án của riêng tôi, tôi có một đoạn mã CMake tìm Git và trích xuất băm thay đổi hiện tại từ kho lưu trữ mã nguồn. Nó có thể không phải là cách tốt nhất Git từ việc khai thác thông tin, nhưng nó làm việc cho tôi ...

# First try to find the git-executable 
find_program(Git_EXECUTABLE NAMES git git.cmd PATHS 
    ${Git_DIR} 
    ENV PATHS 
    $ENV{Git_DIR} 
) 
# Run "git log -n 1 --pretty="%h" for the current commit-hash 
execute_process(COMMAND ${Git_EXECUTABLE} "log" "-n" "1" "--pretty=\"%h\"" 
       WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 
       OUTPUT_VARIABLE Git_Commit_Hash 
       OUTPUT_STRIP_TRAILING_WHITESPACE 
       ) 
# and use a regex to strip quotes. 
string(REGEX REPLACE "^\"(.*)\"$" "\\1" Git_Commit_Hash ${Git_Commit_Hash}) 

Kết quả sẽ là một biến Git_Commit_Hash với giá trị băm 7-char, được sử dụng khi thiết lập CPack :

set(CPACK_PACKAGE_NAME "MyProject") 
message(STATUS " CPack options: " ${CPACK_PACKAGE_NAME}) 
message(STATUS " Preparing CPACK: ") 
message(STATUS "  and hash: ${Git_Commit_Hash}") 

set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${Git_Build_Version}_${CPACK_PACKAGE_VERSION}") 
+2

tôi thực sự cần nó được tại thời điểm xây dựng chứ không phải là thời gian cmake , nhưng cảm ơn câu trả lời của bạn. – glennr

+0

Tôi đã sợ bạn sẽ nói rằng ... các altenative sau đó là để chạy một lệnh tùy chỉnh tại thời gian xây dựng mà làm điều này cho bạn. –

+0

Nó không phải là đơn giản. Bạn không thể ghi đè CPACK_PACKAGE_FILE_NAME vào lúc xây dựng vì CPack đọc nó từ tệp cấu hình. Bạn phải đặt CPACK_PROJECT_CONFIG_FILE thành tệp được tạo lúc xây dựng. Đây là những gì mã trong câu trả lời của tôi. – glennr