2014-02-09 82 views
2

我有下面這段腳本在我的CMake文件:CMake:每次make後都可以運行CONFIGURE_FILE嗎?

CONFIGURE_FILE(
    ${CMAKE_CURRENT_SOURCE_DIR}/version.hpp.cmake 
    ${CMAKE_CURRENT_SOURCE_DIR}/version.hpp 
) 

但它只是執行cmake,不make後運行。是否可以在每次製作後創建version.hpp文件?

這裏是version.hpp.cmake內容:

#ifndef _VERSION_HPP_ 
#define _VERSION_HPP_ 

#define MAJOR_VERSION "${MAJOR}" 
#define MINOR_VERSION "${MINOR}" 
#define PATCH_VERSION "${PATCH}" 
#define RELEASE_VERSION "${RELEASE}" 

#endif //_VERSION_HPP_ 

MAJORMINORPATCHRELEASE變量已經在CMakeLists.txt文件中定義。

P.S. This post顯然與我的問題有關,但我無法掌握它。

+0

'version.hpp.cmake'裏面有什麼?如果你在'CMakeLists.txt'中指定了版本宏,那麼調用'make'會導致檢查'CMakeLists.txt'是否被改變,並且它會自動調用'cmake'。 – yegorich

+0

@yegorich更新了問題。 – Meysam

+0

@yegorich如果'CMakeLists.txt'文件已更改,則當前調用'cmake'。但是如果'version.hpp'不存在(出於某種原因),它將如何被創建? – Meysam

回答

1

一個possibity是從Python中產生version.hpp和使用ADD_CUSTOM_TARGET

... find python ... 
ADD_CUSTOM_TARGET(gen_version ALL ${PYTHON_EXECUTABLE} gen_version.py) 
SET_SOURCE_FILES_PROPERTIES(version.hpp PROPERTIES GENERATED 1) 
... link gen_version to your library/executable ... 
+0

謝謝。 'gen_version.py'的內容是什麼?你能否給出更詳細的答案? – Meysam

+0

@Meysam這真的是非常基本的Python,閱讀教程http://docs.python.org/2/tutorial/和使用datetime http://docs.python.org/2/library/datetime.html – Peter

4

的問題是,configure_file應該在配置時運行,也就是說當你運行cmake,而不是編譯時間,這當你運行make。沒有簡單的解決方法。

問題是由configure_file寫的信息依賴於來自CMake構建環境的變量。無需再次運行CMake就可以檢測到這些變量的變化。如果您將該信息映射到其他位置,則可以使用自定義命令將其提取併爲您執行代碼生成,建議使用Peter's answer

post from the CMake mailing list that you linked在您的答案中建議的方法基於兩階段CMake運行:外部CMake項目(僅運行一次)爲構建內部CMake項目添加了一個自定義構建步驟(然後運行每make)執行configure_file。其基本思想與Peter的答案相同,只不過是使用CMake腳本生成文件的Python腳本。

我個人的建議:對於一個簡單的問題,作爲一個版本頭文件,我不會打擾這種複雜的方法。簡單地將文件生成到你的BINARY_DIR(而不是你的項目目錄,就像你現在做的那樣!你想保留從同一個源代碼執行幾個外部源代碼的能力),並假定它將在那裏進行編譯。如果用戶有足夠的勇氣去處理生成的文件,那麼他們可以自行重新運行CMake。

3

所以我不小心偶然發現了這一點,我知道它可能太晚了,但調用配置是可能的,正是我如何做到這一點與mercurial版本。

這個把戲需要很多不同的工具,而且我沒有時間來制定一個好的答案atm,但提出問題,我會在有空的時候填寫它。

工具1:調用的exec_program提取修訂信息(這是善變很容易)

exec_program(hg ${PROJECT_SOURCE_DIR} ARGS "id" "-i" OUTPUT_VARIABLE OUTPUT_VARIABLE ${PROJECT_NAME}_HG_HASH_CODE) 

我可能做一些更復雜的比你所關心的在這裏,但基本位hg這您將使用您正在使用的任何版本控制進行替換,${PROJECT_SOURCE_DIR}您將設置爲執行所需的任何目錄,並填寫自定義參數。

我把所有版本提取到一個宏(ReadProjectRevisionStatus())。

下一步是創建一個完全不同的CMake文件,該文件調用ReadProjectRevisionStatus(),然後調用CONFIGURE_FILE。這個文件會假定當你進入它時,所有正確的值都被設置。就我而言,我將這個文件的位置存儲到$ {CONFIG_FILE_LOC}中。

最後一步是添加一個將調用此腳本的自定義目標。例如:

ADD_CUSTOM_TARGET(${PROJECT_NAME}_HG_VERSION_CONFIG 
    COMMAND ${CMAKE_COMMAND} 
    ARGS -DPROJECT_SOURCE_DIR=${PROJECT_SOURCE_DIR} 
    -DPROJECT_BINARY_DIR=${PROJECT_BINARY_DIR} 
    -DPROJECT_NAME=${PROJECT_NAME} 
    -DCMAKE_MODULE_PATH=${CMAKE_MODULE_PATH} 
    "-D${PROJECT_NAME}_HG_CONFIG_FILE_IN=\"${${PROJECT_NAME}_HG_CONFIG_FILE_IN}\"" 
    "-D${PROJECT_NAME}_HG_CONFIG_FILE_OUT=\"${${PROJECT_NAME}_HG_CONFIG_FILE_OUT}\"" 
    ${ARGN} 
    -P ${CONFIG_FILE_LOC}) 

一個這樣做的漂亮的地方是自定義的目標呼叫也被稱爲的CMake構建系統之外,我已經上了幾個項目的完成,這是bash通話類似於:

cmake -D PROJECT_SOURCE_DIR=$sourcedir -DPROJECT_BINARY_DIR=$sourcedir -DPROJECT_NAME=uControl -DCMAKE_MODULE_PATH=$sourcedir -DuControl_HG_CONFIG_FILE_IN=$sourcedir/tsi_software_version.h.in -DuControl_HG_CONFIG_FILE_OUT=$sourcedir/tsi_software_version.h -P $sourcedir/ConfigureHGVersion.cmake 
+0

謝謝期待你的答覆。我仍然在等待這個問題的正確答案。如果有任何不清楚的地方,我會查看你的答案,並會提出進一步的問題。我希望我能使它工作。 – Meysam

+0

'$ {Files}'的價值是什麼? – Meysam

+0

'CONFIGURE_FILE'僅在其輸入文件已更改時執行。你在哪裏更新輸入文件? – Meysam

相關問題