2011-06-16 42 views
8

我想添加一個測試目標,它依賴於正在成功構建的整個項目,而不需要重新指定所有庫或可執行文件的依賴關係。CMake add_custom_target取決於正在構建的整個項目

我會化妝的寫:

all: foo bar 

foo: ... 
bar: ... 

test: all 
    test.sh 

test.sh隱式使用foo和酒吧,並希望他們是最新的。

這就是我期望在cmake中指定的方式。

add_library(foo ...) 
add_executable(bar ...) 

add_custom_target(test test.sh 
       DEPENDS all 
) 

但是這不起作用,因爲沒有所有的目標。

有沒有辦法指定它?還是有一個變量擴展到我想要構建的所有目標?

回答

9

從版本2.8開始,CMake不提供包含所有目標列表的變量。您可以做的最好的方法是使用調用內置命令的自定義宏來覆蓋內置命令add_libraryadd_executable,並跟蹤變量中的所有已定義目標。

甚至可以爲自定義宏使用相同的名稱。這樣您就不必對現有的所有add_libraryadd_executable調用進行更改。原來的內置命令用下劃線前綴,如果你忽略其中任何一個:

set (_allTargets "") 

macro(add_library _target) 
    _add_library (${_target} ${ARGN}) 
    list (APPEND _allTargets ${_target}) 
endmacro() 

macro(add_executable _target) 
    _add_executable (${_target} ${ARGN}) 
    list (APPEND _allTargets ${_target}) 
endmacro() 

add_library(liba STATIC liba.cpp) 
add_executable(main liba main.cpp) 

add_custom_target(test "${CMAKE_CURRENT_SOURCE_DIR}/test.sh") 

add_dependencies(test ${_allTargets}) 

還要注意的是,你不能添加一個目標依賴於一個自定義的目標與DEPENDS選項。 DEPENDS只能引用在同一目錄下使用add_custom_command(...)生成的現有文件或文件。要添加目標依賴項,請改用add_dependencies命令。

0

您可以使用CTEST:

include(CTest) 
if (BUILD_TESTING) 
    add_test(MyTestName test.sh param1 param2) 
endif(BUILD_TESTING) 

的CMake會生成Makefile文件與新的目標測試,還看到:Documentation for add_test command

但你需要編譯你的項目,在運行測試之前:

make 
make test 

此外,您還可以使用目標實驗每晚,或連續。這些目標將編譯項目並運行所有測試,但它們也會嘗試提交測試結果(您可以使用CTestConfig.cmake進行配置)。

+0

感謝。我嘗試過使用CTest,並不喜歡它,因爲它沒有添加依賴項並且會輸出結果。如果我沒有現有的測試基礎架構,這可能更合適。 – 2011-06-27 10:30:24

4

我沒有足夠的聲譽在沙克拉回答評論...

一個問題,我與解決方案看到的是,如果你使用任何子目錄中的更改,您做的變量_allTargets裏面的子目錄將不會傳播到父範圍。

挖掘更多,list(append ...)不能在這種情況下使用:

到SET命令類似,LIST命令在當前範圍內創建新的變量 值,即使列表本身實際上是定義 一個父範圍。爲了向上傳播這些操作的結果,使用SET與PARENT_SCOPE,SET與CACHE INTERNAL,或某些其他價值傳播手段。

http://www.cmake.org/cmake/help/v2.8.11/cmake.html#command:set

如果PARENT_SCOPE存在時,該變量將在當前範圍以上的範圍 進行設置。 每個新的目錄或函數創建一個 新的範圍。該命令將把變量的值設置爲 父目錄或調用函數(以適用於 的情況爲準)。

(注意,我自己:宏不是函數)使用PARENT_SCOPE時

我沒有看到一個通用的解決方案(如獨立使用add_subdirectory)。但是,這裏似乎有一個使用CACHE INTERNAL的解決方案。

從報價:http://www.cmake.org/pipermail/cmake/2007-November/018109.html

# A macro for passing lists between different directories 
# through an internal cache variable. 
MACRO (APPEND_INTERNAL_LIST LIST_NAME VALUE) 

    # If the list in not in the cache, create it. 
    IF (${LIST_NAME}) 
     SET (${LIST_NAME} "${${LIST_NAME}};${VALUE}" CACHE INTERNAL "Internal 
variable") 
    ELSE (${LIST_NAME}) 
     SET (${LIST_NAME} "${VALUE}" CACHE INTERNAL "Internal variable") 
    ENDIF (${LIST_NAME}) 

ENDMACRO (APPEND_INTERNAL_LIST) 

# A macro for passing lists between different directories 
# through an internal cache variable. 
# This function empties the variable (usually because of older runs) 
MACRO (INITIALIZE_INTERNAL_LIST LIST_NAME) 
    SET (${LIST_NAME} "" CACHE INTERNAL "Internal variable") 
ENDMACRO (INITIALIZE_INTERNAL_LIST)