我想添加一个测试目标,该目标依赖于正在成功构建的整个项目,而无需重新指定所有库或可执行文件的依赖项。
我会在make中写这个:
all: foo bar
foo: ...
bar: ...
test: all
test.sh
test.sh隐式使用foo和bar,并希望它们是最新的。
我希望在cmake中指定它。
add_library(foo ...)
add_executable(bar ...)
add_custom_target(test test.sh
DEPENDS all
)
然而,这不起作用,因为没有所有目标。
有没有办法指定这个?或者是否有一个变量扩展到我想要构建的所有目标?
答案 0 :(得分:9)
从版本2.8开始,CMake不提供包含所有目标列表的变量。您可以做的最好的事情是使用调用内置宏的自定义宏覆盖内置命令add_library
和add_executable
,并跟踪变量中所有已定义的目标。
您甚至可以为自定义宏使用相同的名称。这样您就不必对所有现有的add_library
和add_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
命令。
答案 1 :(得分:4)
我没有足够的声誉评论Sakra的答案......
我在该解决方案中看到的一个问题是,如果使用任何子目录,则对子目录中的变量_allTargets所做的更改将不会传播到父作用域。
在这种情况下,不能再使用list(append ...):
与SET命令类似,LIST命令创建新变量 当前范围中的值,即使列表本身实际上也是如此 在父范围中定义。传播这些结果 操作向上,使用SET与PARENT_SCOPE,SET与CACHE 内部,或其他一些价值传播方式。
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)
答案 2 :(得分: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 对其进行配置。)