Как сделать мои цели cmake для тестирования catch2 и выполнения проекта более расширяемыми и разумными? - PullRequest
2 голосов
/ 03 мая 2019

После большой кропотливой работы и исследований мне удалось создать несколько целей cmake, чтобы отделить запуск моей программы от выполнения тестов в коде.Но мне не нравится то, что я сделал, потому что я вижу избыточность в CMakeList.txt файлах.

В настоящее время мне нужно добавить каждый новый исходный файл в обе цели, чтобы исходная цель могла быть построена с использованием этого файла.и цель тестирования может быть построена, так как им нужно проверить этот файл.Я не могу выбросить всю исходную цель в контрольную цель, потому что тогда контрольная цель будет содержать два основных файла.

Моя единственная идея, как исправить избыточность, - поместить все файлы в исходную цель.без файла main.cpp в какую-то группу, а затем присоедините эту группу к обеим целям.Таким образом, исходная цель содержит только файл main.cpp и группу исходных файлов, а цель тестирования содержит все свои тесты и группу исходных файлов.Таким образом, файловая группа в основном будет перекрывать две цели.Я просто не знаю, как это сделать.

Исследования

Вот другие вопросы о переполнении стека, которые я обнаружил, которые помогли мне добраться туда, где я нахожусь:

Код

Вот мой тестовый проект, созданный мной для экспериментов с catch2 и cmake, который в настоящее время работает для обеих целей сборки "tests" и "catch2Test":

/catch2Test      // <-- project folder
  |---- /include
  |       |---- /catch2
  |               |---- catch.hpp
  |---- /src
  |       |---- /myMath
  |       |       |---- factorial.cpp
  |       |       |---- factorial.h
  |       |---- main.cpp
  |       |---- CMakeLists.txt
  |---- /test
  |       |---- test_main.cpp
  |       |---- test_factorial.cpp
  |       |---- CMakeLists.txt
  |---- CMakeLists.txt

/include/catch2/catch.hpp - это файл заголовка библиотеки для catch2

/src/myMath/, содержащий файл заголовка и файл кода для факториальной реализации, такой же, как в учебнике catch2 .Отсюда и реализация факториальных тестов.

/src/main.cpp - это простой основной файл, который содержит factorial.h для выполнения факториальной математики, а затем печатает его в cout.

Вотявный код для оставшихся файлов, которые действительно имеют значение:

/test/test_main.cpp

#define CATCH_CONFIG_MAIN
#include "../include/catch2/catch.hpp"

/test/test_factorial.cpp

#include "../include/catch2/catch.hpp"
#include "../src/myMath/factorial.h"

TEST_CASE("Factorials are computed", "[factorial]")
{
    REQUIRE(factorial(0) == 1);
    REQUIRE(factorial(1) == 1);
    REQUIRE(factorial(2) == 2);
    REQUIRE(factorial(3) == 6);
    REQUIRE(factorial(10) == 3628800);
}

/CmakeLists.txt

cmake_minimum_required(VERSION 3.13)

set(CMAKE_CXX_STANDARD 14)

add_subdirectory(src)
add_subdirectory(test)

/test/CMakeLists.txt

add_executable(tests
        ../src/myMath/factorial.cpp ../src/myMath/factorial.h

        ../include/catch2/catch.hpp

        test_main.cpp
        test_factorial.cpp
)

/src/CMakeLists.txt

add_executable(catch2Test
        main.cpp
        myMath/factorial.cpp myMath/factorial.h
)

Запуск

Когда я запускаю цель catch2Test, я получаю желаемые результаты:

Hello, World!
Factorial 0! = 1
Factorial 1! = 1
Factorial 2! = 2
Factorial 3! = 6
Factorial 6! = 720
Factorial 10! = 3628800

Process finished with exit code 0

И когда я запускаю тестовую цель, я также получаю желаемые результаты:

===============================================================================
All tests passed (5 assertions in 1 test case)


Process finished with exit code 0

Все это работает, мне просто не нравится мое текущее решение.

Как мне сделать мои цели более легко расширяемыми?

Кроме того, дополнительный вопрос: Каков более подходящий способ включить библиотеку заголовков?Я предполагаю, что не должно быть в add_executable(), как я сделал в /test/CMakeLists.txt как ../include/catch2/catch.hpp ...

1 Ответ

1 голос
/ 03 мая 2019

Я думаю, что нашел ответ на свой вопрос в списке связанных вопросов на боковой панели: структура проекта cmake с юнит-тестами

Используя add_library, я могу создать списокфайлы с новым целевым именем, которые не обязательно содержат основной файл.Вот как я изменил мой подкаталог CMakeList.txt файлов:

src/CMakeList.txt

add_library(src
        myMath/factorial.cpp myMath/factorial.h
)

add_executable(catch2Test main.cpp)

target_link_libraries(catch2Test src)

test/CMakeList.txt

add_executable(tests
        ../include/catch2/catch.hpp

        test_main.cpp
        test_factorial.cpp
)

target_link_libraries(tests src)

Теперь все мои исходные файлы, которые яadd перейдите в библиотеку src и обе мои цели ссылаются на нее, используя target_link_libraries([target] src).

Теперь я пытаюсь выяснить, могу ли я использовать target_link_libraries для присоединения библиотеки catch2 к цели тестов.

Редактировать: Я думаю, что нашел свой ответ на мой второй вопрос здесь: ' cmake os x fail, нет конкретных членов архива ' и здесь: 'Как создать библиотеку cmake only header, которая зависит от внешних заголовочных файлов '.

Я попытался создать библиотеку из одного заголовочного файла, и cmake явно не распознает заголовочные файлы.Теперь у меня есть CMakeLists.txt в моей папке /include, которая выглядит следующим образом:

add_library(catch2 INTERFACE)
target_sources(catch2 INTERFACE catch2/catch.hpp)

Я добавил папку /include в список добавленных подкаталогов в моем основном файле CMakeLists.txt.

Кроме того, моя цель тестов теперь связывает библиотеку catch2 с помощью target_link_libraries(tests catch2), что, на мой взгляд, гораздо приятнее, чем помещение ссылки на перегруженную директорию в список исполняемых файлов для цели тестов.

...