catchorg / Catch2

A modern, C++-native, test framework for unit-tests, TDD and BDD - using C++14, C++17 and later (C++11 support is in v2.x branch, and C++03 on the Catch1.x branch)
https://discord.gg/4CWS9zD
Boost Software License 1.0
18.79k stars 3.06k forks source link

Catch2::Catch2Main CMake target in v3 preview seems to create lots of work for users #1852

Open claremacrae opened 4 years ago

claremacrae commented 4 years ago

Describe the bug

I think that lots of Catch2 v2 users are going to have to make lots of repetitive edits to their CMakeLists.txt files....

I have a dozens of projects that use use Catch2 and ApprovalTests...

Their CMake target_link_libraries used to look like this:

target_link_libraries(${PROJECT_NAME} PRIVATE ApprovalTests::ApprovalTests Catch2::Catch2)

These all use CATCH_CONFIG_MAIN, or occasionally CATCH_CONFIG_RUNNER...

I'm guessing that the vast majority of Catch2 users will use CATCH_CONFIG_MAIN.

In order to work with the Catch2 v3 preview release, I have had to change all of them to this:

target_link_libraries(${PROJECT_NAME} PRIVATE ApprovalTests::ApprovalTests Catch2::Catch2)
if (TARGET Catch2::Catch2Main)
    # link Catch2::Catch2Main only if it exists (so probably catch2 v3)
    target_link_libraries(${PROJECT_NAME} PRIVATE Catch2::Catch2Main)
endif()

Am I right in assuming that every project that uses CATCH_CONFIG_MAIN will have to add Catch2::Catch2Main in v3 - and that if they wish to support v2 and v3 for a period, they will need the if block above as well?

Expected behavior

That v3 should ideally use the same CMake as v2...

Idea

Is it possible to make the CMake target that includes the main() be Catch2::Catch2 - and to have the library one be something like Catch2::Catch2WithoutMain?

claremacrae commented 4 years ago

It's actually slightly more work than I suggested above:

Previously this worked:

target_link_libraries(${PROJECT_NAME} Catch2::Catch2)

Adding the if() block to the above line gives:

CMake Error at catch2_pure_demo/CMakeLists.txt:17 (target_link_libraries):
  The plain signature for target_link_libraries has already been used with
  the target "catch2_pure_demo".  All uses of target_link_libraries with a
  target must be either all-keyword or all-plain.

  The uses of the plain signature are here:

   * catch2_pure_demo/CMakeLists.txt:14 (target_link_libraries)

So this change is also required:

-target_link_libraries(${PROJECT_NAME} Catch2::Catch2)
+target_link_libraries(${PROJECT_NAME} PRIVATE Catch2::Catch2)
Karsteski commented 4 years ago

This change is going to add a lot of headache to people's projects... CMake is a pain to use as it is :(