如果更改了 CMAKE_RUNTIME_OUTPUT_DIRECTORY,CMake 找不到测试

Posted

技术标签:

【中文标题】如果更改了 CMAKE_RUNTIME_OUTPUT_DIRECTORY,CMake 找不到测试【英文标题】:CMake cannot find test if CMAKE_RUNTIME_OUTPUT_DIRECTORY is changed 【发布时间】:2014-01-28 00:42:12 【问题描述】:

我正在使用 CMake 构建我的项目,并且我正在尝试为每个模块创建一堆测试套件。显然,如果我修改变量 CMAKE_RUNTIME_OUTPUT_DIRECTORY 然后 ctest 找不到要运行的测试并失败。

我做了一个最小的例子来展示我在说什么,我在 Lubuntu 13.10 上使用 CMake 2.8.11.2 运行它。如果有人能告诉我这是否是一个错误和/或如何解决它,我将不胜感激。谢谢。

文件 CMakeLists.txt:

cmake_minimum_required (VERSION 2.6)
project (Test)

# Put all tests in the test directory, where the sources also are
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY $PROJECT_SOURCE_DIR/test)

enable_testing()

add_subdirectory ($PROJECT_SOURCE_DIR/test)

文件测试/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)

add_executable(ttest main.cpp)
add_test(ttest ttest)

文件测试/main.cpp:

int main() 
    return 0;

在新文件夹build 中构建后,可执行文件在文件夹test 中正确创建。从构建运行 make test 会产生以下输出:

Running tests...
Test project /home/svalorzen/Tests/cmake/build
    Start 1: ttest
Could not find executable ttest
Looked in the following places:
ttest
ttest
Release/ttest
Release/ttest
Debug/ttest
Debug/ttest
MinSizeRel/ttest
MinSizeRel/ttest
RelWithDebInfo/ttest
RelWithDebInfo/ttest
Deployment/ttest
Deployment/ttest
Development/ttest
Development/ttest
Unable to find executable: ttest
1/1 Test #1: ttest ............................***Not Run   0.00 sec

0% tests passed, 1 tests failed out of 1

Total Test time (real) =   0.00 sec

The following tests FAILED:
      1 - ttest (Not Run)
Errors while running CTest
make: *** [test] Error 8

【问题讨论】:

如果使用ctest 运行,您可以指定命令行选项来告诉CTest 在不同的位置查找测试:ctest --test-dir /path/to/tests。请注意,您必须使用 CMake 3.20 或更高版本才能获得此 CLI 功能。 【参考方案1】:

编辑:

实际上我在add_test 的文档中遗漏了一些内容:

如果 COMMAND 指定一个可执行目标(由 add_executable 创建),它将自动替换为构建时创建的可执行文件的位置

所以使用ttest 而不是$<TARGET_FILE:ttest> 应该可以工作。


我遇到了同样的问题,但我真的不知道这是否是一个错误。

我为此找到的解决方案是在命令中提供测试可执行文件的路径(带有目标 ttest):

在测试/CMakeLists.txt 中:

add_test(ttest test/ttest)

最终,您希望将路径存储在一个变量中,以便编写类似$test_dir/ttest 的内容。

如果你想要更健壮的东西,最好使用长的 add_test 命令和生成器表达式:

add_test(NAME ttest COMMAND $<TARGET_FILE:ttest>)

生成表达式$&lt;TARGET_FILE:ttest&gt;会扩展为可执行目标的输出文件(这里是ttest),所以你确定目录没有问题。 cmake documentation中引用了其他表达式。

如果你有很多测试要声明,它可能会有点冗长,所以我使用如下宏:

macro (create_test target)
  add_test (NAME $target COMMAND $<TARGET_FILE:$target>)
endmacro (create_test)

#[some code]

#test definition
create_test(ttest)

假设测试名称与可执行文件名称相同。

我找不到任何其他可行的解决方案。可以使用add_test 设置工作目录,这显然会使 ctest 找到可执行文件,但测试随后会因“BAD_COMMAND”错误而崩溃。

我是 cmake 新手,所以可能有其他解决方案。

【讨论】:

我还有一个问题,即我的测试需要文件夹中的一些数据并且没有被发现,因为工作目录仍然错误。如果有人正在阅读此内容,您可以在 COMMAND 子句之前使用 WORKING_DIRECTORY $CMAKE_RUNTIME_OUTPUT_DIRECTORY 修复此问题。 可执行文件的完整路径对我不起作用,例如/home/.../bin/mytest.似乎将 add_test 参数附加到 $PROJECT_SOURCE_DIR 例如对于 add_test(_mytest bin/mytest),路径变为 $PROJECT_SOURCE_DIR/bin/mytest 。 三年后你能回答this followup吗? 非常重要的是不要在 TARGET_FILE 后面加空格:【参考方案2】:

使用命令:

add_test(NAME ttest COMMAND $<TARGET_FILE:ttest>)

在使用TARGET_FILE 时必须写NAMECOMMAND(或者至少它对我不起作用。使用cmake --help-command add_test 了解更多信息。

【讨论】:

【参考方案3】:

如果您的测试命令包含参数并且您将它们与可执行文件名称一起引用,您也会遇到这个问题。

所以如果你有这样的事情:

    add_test(NAME "name" COMMAND "testExe arg1 arg2 arg3")

改为这样做:

    add_test(NAME "name" COMMAND "testExe" "arg1" "arg2" "arg3")

否则 CMake 将尝试查找包含空格的测试可执行文件名称。

【讨论】:

【参考方案4】:

清楚地使用 NAME 和 COMMAND 为我解决了问题

add_test(NAME ttest COMMAND ttest)

【讨论】:

以上是关于如果更改了 CMAKE_RUNTIME_OUTPUT_DIRECTORY,CMake 找不到测试的主要内容,如果未能解决你的问题,请参考以下文章

如果头文件被更改然后恢复,如何停止/欺骗cmake不重建?

如果在 LUA 中更改了对象的属性,如何使函数执行?

如果在运行时更改存储过程会发生啥?

如果我在安装过程中更改了 MySQL 的默认端口号(3306),会不会有啥问题?

访问 - 如果字段更改,则自动更改表中的字段

如果使用 useEffect 更改了另一个过滤器,则重置为第一页