CMake не может найти тест, если CMAKE_RUNTIME_OUTPUT_DIRECTORY изменен

Я создаю свой проект с помощью CMake, и я пытаюсь создать набор тестовых наборов для каждого модуля. По-видимому, если я изменяю переменную CMAKE_RUNTIME_OUTPUT_DIRECTORY, то ctest не может найти тест для запуска и сбоя.

Я сделал минимальный пример, чтобы продемонстрировать, о чем я говорю, и я запускаю его с помощью CMake 2.8.11.2 на Lubuntu 13.10. Я был бы признателен, если бы кто-нибудь мог сказать мне, является ли это ошибкой и/или как ее обойти. Спасибо.

файл 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)

файл test/CMakeLists.txt:

cmake_minimum_required(VERSION 2.6)

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

file test/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

Ответ 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>)

Выражение генерации $<TARGET_FILE:ttest> будет расширяться до выходного файла исполняемой цели (ttest здесь), поэтому вы уверены, что в каталоге нет проблем. В документации cmake есть другое выражение, на которое ссылается.

Он может получить немного подробностей, если у вас много тестов для объявления, поэтому я использую макрос вроде:

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, поэтому может быть и другое решение.

Ответ 2

Использовать команду:

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

Запись NAME и COMMAND является обязательной при использовании TARGET_FILE (или, по крайней мере, она не работает для меня в противном случае. Используйте 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 попытается найти тестовое исполняемое имя с пробелами в нем.