2013-08-31 114 views
1

我的CMakeLists.txt:不能產生的CMake命令

cmake_minimum_required(VERSION 2.6) 
project(main) 

SET(MAIN main) 
SET(MAIN_OUT "${CMAKE_CURRENT_BINARY_DIR}/out.txt") 
add_executable(${MAIN} main.cpp) 

# command is unknown 
add_custom_command(OUTPUT ${MAIN_OUT} 
    POST_BUILD 
    COMMAND ./${MAIN} > ${MAIN_OUT} 
    DEPENDS ${MAIN} 
) 

編譯後,我只是希望能夠輸入

make out.txt 

然而,cmake的,似乎不知道這個目標( 「無規則」)。在構建目錄中,調用

grep out.txt -r * 

找不到包含out.txt的文件。我怎樣才能讓我的目標被調用?我知道這可能以前曾問過,但我還沒有找到它。

回答

2

如果您希望能夠輸入「make out.txt」,您可能需要add_custom_target而不是add_custom_command。這會創建一個可以構建的目標,並在構建中執行指定的命令。

與其將這個目標誤稱爲「out.txt」,而不是將目標設爲文本文件,我會推薦一些更像「RunMain」或「GetOutputOfMain」的東西。

如果您可以指定最新版本的CMake作爲最低版本,則可以在add_custom_target調用的命令部分中使用「生成器表達式」。 add_custom_target沒有記錄,但您可以在add_custom_command的文檔中閱讀有關生成器表達式的信息。我不確定爲了讓生成器表達式可用,應該設置哪些最低版本的CMake。

所以,你的CMakeLists.txt可改爲類似:

cmake_minimum_required(VERSION 2.8.10) 
project(Test) 

add_executable(MyExe main.cpp) 

set(MainOut "${CMAKE_CURRENT_BINARY_DIR}/out.txt") 
add_custom_target(RunMain $<TARGET_FILE:MyExe> > ${MainOut} 
        COMMENT "Running MyExe with output redirected to ${MainOut}") 

# Ensure MyExe is built before trying to build the custom target 
add_dependencies(RunMain MyExe) 

然後就去做make RunMain產生out.txt。

如果你不想指定如此高的最低版本,您可以使用過時的LOCATION目標屬性,而不是:

get_target_property(MyExeLocation MyExe LOCATION) 
add_custom_target(
    RunMain ${MyExeLocation} > ${MainOut} 
    COMMENT "Running ${MyExeLocation} with output redirected to ${MainOut}") 
+0

謝謝,這似乎工作。僅僅爲了興趣:如果我想讓RunMain只在二進制文件生成後執行一次,我需要做什麼? (假設編譯後二進制總是產生相同的輸出) – Johannes

+0

我不知道我在追隨。 RunMain只有在你想構建它時才能被執行(即構建)。它不是'ALL'目標的一部分,所以它不會自動生成。如果你想讓事情自動化,你可以使用'add_custom_command'的原始方法將該命令作爲後期構建事件。這樣你就沒有單獨的目標;你不能「製造」它 - 你只需構建MyExe並在構建完成時運行該命令。這個命令就像'add_custom_command(TARGET MyExe POST_BUILD COMMAND $ > $ {MainOut} COMMENT「...」)'。 – Fraser

+0

同意,我們在這種情況下不需要單獨的目標。但是如果我真的想要一個單獨的,那可能嗎? – Johannes