cmake add_test () с другим runtime_output_directory [дубликат]

Ну, простыми словами:

Вы пытаетесь получить доступ к объекту, который не создан или в настоящее время не находится в памяти.

Итак, как это решить:

  1. Отладить и отпустить отладчик ... Он сразу приведет вас к переменной, которая сломана ... Теперь ваша задача - просто исправить это. Используя новое ключевое слово в соответствующем месте.
  2. Если это вызвано некоторыми командами базы данных, потому что объект отсутствует, все, что вам нужно сделать, это выполнить нулевую проверку и обработать его:
    if (i == null) {
        // Handle this
    }
    
  3. Самый сложный. если GC уже собрал объект ... Это обычно происходит, если вы пытаетесь найти объект, используя строки ... То есть, найдя его по имени объекта, может случиться, что GC, возможно, уже очистил его ... Это трудно найти и станет проблемой. Лучшим способом решения этой проблемы является выполнение нулевых проверок везде, где это необходимо в процессе разработки. Это сэкономит вам много времени.

Поиск по имени означает, что некоторые фреймворки позволяют использовать FIndObjects с помощью строк, а код может выглядеть так: FindObject («ObjectName»);

77
задан claf 9 April 2009 в 10:22
поделиться

7 ответов

Возможно, ошибка в CMake (ранее отслеживаемая здесь ), что это не работает из коробки. Обходной путь состоит в том, чтобы сделать следующее:

add_test(TestName ExeName)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
                  DEPENDS ExeName)

Затем вы можете запустить make check, и он скомпилирует и запустит тест. Если у вас несколько тестов, вам придется использовать DEPENDS exe1 exe2 exe3 ... в приведенной выше строке.

59
ответ дан Flow 24 August 2018 в 19:19
поделиться
  • 1
    отличный ответ, спасибо :) – claf 10 April 2009 в 09:01
  • 2
    поэтому я предполагаю, что «сделать тест» цель останется неиспользованной, поскольку вам кажется, что вам нужно выбрать другое имя цели в команде add_custom_target? – claf 10 April 2009 в 09:04
  • 3
    @rq - но как я могу это сделать с несколькими проектами (когда один CMakeLists.txt является подпроектом другого), поэтому каждый из них будет определять цель check, и они могут столкнуться – Artyom 1 June 2010 в 08:08
  • 4
    @Artyom - в этом случае вам, вероятно, лучше всего использовать эквивалент «make all test». Фактически, это то, что я делаю в любом случае. – richq 1 June 2010 в 08:28
  • 5
    На самом деле, некоторые считают это особенностью (а не ошибкой) cmake, которую вы можете запустить & quot; make test & quot; и просто запускать тесты, поскольку они без каких-либо повторных построений ... – DLRdave 2 December 2011 в 04:15

Все ответы хороши, но они подразумевают нарушение традиции для запуска теста командой make test. Я сделал этот трюк:

add_test(NAME <mytest>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND sh -c "make <mytarget>; $<TARGET_FILE:<mytarget>>")

Это означает, что тест состоит из построения (необязательно) и запуска исполняемой цели.

-4
ответ дан dyomas 24 August 2018 в 19:19
поделиться
  • 1
    Правило №1: Не используйте код оболочки в cmake :-) – Igor 4 September 2013 в 10:48
  • 2
    :-D Правило № 1: Не используйте систему без sh. Вы знаете такую ​​систему? – dyomas 19 February 2014 в 00:10
  • 3
    Да, Windows является одним из них. – David Faure 14 November 2015 в 12:12
  • 4
    Это также жестко привязано к make и теряет функцию CMake для генерации скриптов для других инструментов сборки. – poolie 10 January 2016 в 19:31

Все вышеприведенные ответы идеальны. Но на самом деле CMake использует CTest в качестве своих инструментов тестирования, поэтому стандартный метод (я думаю, что это) выполняет миссию:

enable_testing ()
add_test (TestName TestCommand)
add_test (TestName2 AnotherTestCommand)

Затем запустите cmake и создайте цели. После этого вы можете либо запустить make test, либо просто запустить

ctest

, вы получите результат. Это проверено в CMake 2.8.

Проверьте данные на: http://cmake.org/Wiki/CMake/Testing_With_CTest#Simple_Testing

-2
ответ дан holmescn 24 August 2018 в 19:19
поделиться
  • 1
    это правильный ответ! – jopasserat 24 December 2012 в 23:58
  • 2
    Downvoted, потому что иногда вы хотите только создать цели, необходимые для запуска тестов. – Dave Abrahams 24 February 2013 в 17:54
  • 3
    Этот ответ, похоже, неправильно понимает вопрос: OP уже делает то же самое, что и этот ответ рекомендует: Использование CTest, enable_testing(), add_test() и т. Д. Проблема в том, что он должен вручную выдать команду сборки до запуска тестов. Он хочет, чтобы цель make test автоматически создавала тестовые исполняемые файлы по мере необходимости. – bames53 10 October 2014 в 15:56

На самом деле есть способ использовать make test. Вам нужно определить сборку тестового исполняемого файла как один из тестов, а затем добавить зависимости между тестами. То есть:

ADD_TEST(ctest_build_test_code
         "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_code)
ADD_TEST(ctest_run_test_code test_code)
SET_TESTS_PROPERTIES(ctest_run_test_code
                     PROPERTIES DEPENDS ctest_build_test_code)
43
ответ дан pynexj 24 August 2018 в 19:19
поделиться
  • 1
    Это единственный, который масштабируется и не заставляет вас создавать «делать все», цели только для того, чтобы запустить тест. Возможный недостаток: детали ошибок сборки в двоичных файлах отображаются только в сгенерированном файле LastTest.log, а не на stdout / stderr – Dave Abrahams 24 February 2013 в 17:56
  • 2
    Хороший ответ! Однако вы должны добавить конфигурацию в цель сборки. В противном случае запуск тестов во всех конфигурациях невозможно. add_test (NAME & quot; $ {ARGV0} _BUILD "COMMAND & quot; $ {CMAKE_COMMAND}" --build $ {CMAKE_BINARY_DIR} --target $ {target} "- config & quot; $ & lt; CONFIG & gt;") – Daniel 26 March 2017 в 20:13
  • 3
    Это забивает тестового репортера кучей фальшивых тестов. – Barry 17 October 2017 в 17:19

Сохраните головную боль:

make all test

Работает из коробки для меня и будет создавать зависимости перед запуском теста. Учитывая, насколько это просто, это почти делает функциональность make test удобной, поскольку она дает вам возможность запускать последние компиляционные тесты, даже если ваш код поврежден.

4
ответ дан quant 24 August 2018 в 19:19
поделиться
  • 1
    Не работает с CDash. Вы должны позвонить make all & amp; & amp; ctest, а затем здание не является частью загруженного тестирования. Поэтому ошибки сборки или ошибки не отображаются. – usr1234567 24 April 2015 в 06:43
  • 2
    Также не работает, если вы хотите параллельную сборку, так как они будут работать параллельно: вам нужно make -j4 all && make test. И это также flaky, используя инструмент создания не-Make. – poolie 10 January 2016 в 18:58

Если вы пытаетесь эмулировать make check, вы можете найти эту запись в вики полезно:

http://www.cmake.org/Wiki/CMakeEmulateMakeCheck

Я только что проверил, что это делает то, что он говорит с успехом (CMake 2.8.10).

5
ответ дан Samuel 24 August 2018 в 19:19
поделиться
  • 1
    Это приведет к созданию всех исполняемых файлов при запуске make check. Для тестов с доминирующим временем компиляции это делает ctest -R бесполезным. – usr1234567 24 April 2015 в 06:50

Я использую вариант ответа richq. На верхнем уровне CMakeLists.txt я добавляю пользовательскую цель build_and_test для создания и запуска всех тестов:

find_package(GTest)
if (GTEST_FOUND)
    enable_testing()
    add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} -V)
    add_subdirectory(test)
endif()

В различных файлах подпроектов CMakeLists.txt в разделе test/ , Я добавляю каждый тестовый исполняемый файл как зависимость от build_and_test:

include_directories(${CMAKE_SOURCE_DIR}/src/proj1)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(proj1_test proj1_test.cpp)
target_link_libraries(proj1_test ${GTEST_BOTH_LIBRARIES} pthread)
add_test(proj1_test proj1_test)
add_dependencies(build_and_test proj1_test)

При таком подходе мне просто нужно make build_and_test вместо make test (или make all test), и он имеет преимущество только в создании тестового кода (и его зависимостей). Жаль, я не могу использовать целевое имя test. В моем случае это не так уж плохо, потому что у меня есть сценарий верхнего уровня, который выполняет отладочную и выпускную сборку (и кросс-скомпилированные) сборки, вызывая cmake, а затем make, и он переводит test в build_and_test.

Очевидно, что материал GTest не требуется. Я просто использовал / как Google Test и хотел поделиться полным примером использования его с CMake / CTest. IMHO, этот подход также имеет преимущество, позволяя мне использовать ctest -V, который показывает результат тестирования Google во время тестов:

1: Running main() from gtest_main.cc
1: [==========] Running 1 test from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 1 test from proj1
1: [ RUN      ] proj1.dummy
1: [       OK ] proj1.dummy (0 ms)
1: [----------] 1 test from proj1 (1 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 1 test from 1 test case ran. (1 ms total)
1: [  PASSED  ] 1 test.
1/2 Test #1: proj1_test .......................   Passed    0.03 sec
11
ответ дан Trevor Robinson 24 August 2018 в 19:19
поделиться
  • 1
    В этом примере есть ли способ сделать make-тест, чтобы сделать что-то ctest -V вместо ctest? Результат ctest выглядит очень неполным и просто говорит, что есть один тест. – Rajiv 22 October 2013 в 06:53
Другие вопросы по тегам:

Похожие вопросы: