Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
CMake根据正在构建的整个项目添加自定义目标_Cmake - Fatal编程技术网

CMake根据正在构建的整个项目添加自定义目标

CMake根据正在构建的整个项目添加自定义目标,cmake,Cmake,我想添加一个依赖于成功构建的整个项目的测试目标,而不需要重新指定对所有库或可执行文件的依赖关系 我将在make中这样写: all: foo bar foo: ... bar: ... test: all test.sh sh隐式使用foo和bar,并希望它们是最新的 这就是我希望在cmake中指定的方式 add_library(foo ...) add_executable(bar ...) add_custom_target(test test.sh

我想添加一个依赖于成功构建的整个项目的测试目标,而不需要重新指定对所有库或可执行文件的依赖关系

我将在make中这样写:

all: foo bar

foo: ...
bar: ...

test: all
    test.sh
sh隐式使用foo和bar,并希望它们是最新的

这就是我希望在cmake中指定的方式

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

add_custom_target(test test.sh
              DEPENDS all
)
但是,这不起作用,因为没有“全部”目标


有没有办法具体说明这一点?或者是否有一个变量扩展到我试图构建的所有目标?

从2.8版开始,CMake没有提供一个包含所有目标列表的变量。您所能做的最好是使用调用内置宏并跟踪变量中所有已定义目标的自定义宏来覆盖内置命令
add_library
add_executable

您甚至可以对自定义宏使用相同的名称。这样,您就不必对所有现有的
add_库
add_可执行文件
调用进行更改。如果覆盖了以下任何一个内置命令,则原始内置命令将以下划线作为前缀:

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})
还要注意,不能使用
dependens
选项将目标依赖项添加到自定义目标<代码>依赖项只能引用同一目录中的现有文件或使用
添加自定义命令(…)
生成的文件。要添加目标依赖项,请改用
add_dependencies
命令。

您可以使用CTest:

include(CTest)
if (BUILD_TESTING)
    add_test(MyTestName test.sh param1 param2)
endif(BUILD_TESTING)
Cmake将生成带有新目标测试的Makefile,另请参见:

但在运行测试之前,您需要编译项目:

make
make test

此外,您还可以使用targetExperimentalNightlyContinuous。这些目标将编译项目并运行所有测试,但他们也会尝试提交测试结果(您可以使用CTestConfig.cmake对其进行配置)。

我没有足够的声誉来评论Sakra答案

我看到该解决方案的一个问题是,如果使用任何子目录,那么对子目录内的变量_allTargets所做的更改将不会传播到父范围

挖掘更多,在这种情况下不能使用:

与SET命令类似,LIST命令创建新变量 当前范围中的值,即使列表本身实际上是 在父作用域中定义。传播这些结果 向上操作,使用具有父\u作用域的集合,使用缓存进行集合 内部,或其他价值传播方式

:

如果存在父范围,则变量将在范围中设置 超出当前范围每个新目录或函数都会创建一个 新范围。此命令将变量的值设置为 父目录或调用函数(以适用于 手边的箱子)

(请注意:宏不是函数)

在使用PARENT_作用域时,我看不到通用的解决方案(例如,独立于使用add_子目录)。然而,这里似乎有一个使用内部缓存的解决方案

引述自:


谢谢我试着使用CTest,但不喜欢它,因为它没有添加依赖项并吃掉输出。如果我没有现有的测试基础设施,这可能更合适。
# 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)