Skip to content

Commit

Permalink
(#13794) catch2 (2.x.x): support conan v2
Browse files Browse the repository at this point in the history
* catch2 (2.x.x): support conan v2, based on work by SpaceIm that was done for 3.x.x

* Some minor tweaks

* Linter fixes

* Update recipes/catch2/2.x.x/conanfile.py

Co-authored-by: Uilian Ries <uilianries@gmail.com>

* Fixed CATCH_CONFIG_PREFIX_ALL behaviour

* Don't quote default_reporter - 3.x.x already changed

* Fix for conan 1.52

* Fixup error message

* Remove unused file

* Removed lines - not needed as no package CMakeLists.txt supplied anymore

* Update recipes/catch2/2.x.x/conanfile.py

Co-authored-by: Uilian Ries <uilianries@gmail.com>

* Fixes for linter

* v2 fixes

* Revert "v2 fixes"

This reverts commit 332eb40.

* Update recipes/catch2/2.x.x/conanfile.py

Co-authored-by: Chris Mc <prince.chrismc@gmail.com>

* v2 fixes

* Fixup todos filename for test_package

* Update recipes/catch2/2.x.x/conanfile.py

Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com>

Co-authored-by: Uilian Ries <uilianries@gmail.com>
Co-authored-by: Christopher McArthur <christopherm@jfrog.com>
Co-authored-by: Chris Mc <prince.chrismc@gmail.com>
Co-authored-by: SpaceIm <30052553+SpaceIm@users.noreply.github.com>
  • Loading branch information
5 people authored Dec 2, 2022
1 parent 002eaf2 commit 8c1c300
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 107 deletions.
16 changes: 0 additions & 16 deletions recipes/catch2/2.x.x/CMakeLists.txt

This file was deleted.

129 changes: 62 additions & 67 deletions recipes/catch2/2.x.x/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
import functools
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout
from conan.tools.files import copy, get, rmdir
from conan.tools.scm import Version
import os

required_conan_version = ">=1.43.0"
required_conan_version = ">=1.53.0"


class Catch2Conan(ConanFile):
Expand All @@ -20,7 +22,7 @@ class Catch2Conan(ConanFile):
"with_main": [True, False],
"with_benchmark": [True, False],
"with_prefix": [True, False],
"default_reporter": "ANY",
"default_reporter": [None, "ANY"],
}
default_options = {
"fPIC": True,
Expand All @@ -30,109 +32,102 @@ class Catch2Conan(ConanFile):
"default_reporter": None,
}

exports_sources = "CMakeLists.txt"
generators = "cmake"

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

@property
def _default_reporter_str(self):
return '"{}"'.format(str(self.options.default_reporter).strip('"'))
return str(self.options.default_reporter).strip('"')

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if not self.options.with_main:
del self.options.fPIC
del self.options.with_benchmark
self.options.rm_safe("fPIC")
self.options.rm_safe("with_benchmark")

def package_id(self):
if not self.options.with_main:
self.info.header_only()
self.info.clear()

def layout(self):
cmake_layout(self, src_folder="src")

def validate(self):
if tools.Version(self.version) < "2.13.1" and self.settings.arch == "armv8":
raise ConanInvalidConfiguration("ARMv8 is supported by 2.13.1+ only! give up!")
if self.options.with_main and tools.Version(self.version) < "2.13.4":
raise ConanInvalidConfiguration("Option with_main not supported with versions < 2.13.4")
if Version(self.version) < "2.13.1" and self.settings.arch == "armv8":
raise ConanInvalidConfiguration("ARMv8 is not supported by versions < 2.13.1+")
if self.info.options.get_safe("with_main") and Version(self.version) < "2.13.4":
raise ConanInvalidConfiguration("Option with_main not supported by versions < 2.13.4")

def source(self):
tools.get(**self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder)

@functools.lru_cache(1)
def _configure_cmake(self):
cmake = CMake(self)
cmake.definitions["BUILD_TESTING"] = "OFF"
cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF"
cmake.definitions["CATCH_INSTALL_HELPERS"] = "ON"
cmake.definitions["CATCH_BUILD_STATIC_LIBRARY"] = self.options.with_main
cmake.definitions["enable_benchmark"] = self.options.get_safe("with_benchmark", False)
cmake.definitions["CATCH_CONFIG_PREFIX_ALL"] = self.options.with_prefix
get(self, **self.conan_data["sources"][self.version], destination=self.source_folder, strip_root=True)

def generate(self):
tc = CMakeToolchain(self)
tc.variables["BUILD_TESTING"] = False
tc.cache_variables["CATCH_INSTALL_DOCS"] = False # these are cmake options, so use cache_variables
tc.cache_variables["CATCH_INSTALL_HELPERS"] = "ON" # these are cmake options, so use cache_variables
tc.cache_variables["CATCH_BUILD_STATIC_LIBRARY"] = str(self.options.with_main) # these are cmake options, so use cache_variables (str() is required for conan 1.52)
if self.options.with_prefix:
tc.preprocessor_definitions["CATCH_CONFIG_PREFIX_ALL"] = 1
if self.options.get_safe("with_benchmark", False):
tc.preprocessor_definitions["CATCH_CONFIG_ENABLE_BENCHMARKING"] = 1
if self.options.default_reporter:
cmake.definitions["CATCH_CONFIG_DEFAULT_REPORTER"] = self._default_reporter_str

cmake.configure(build_folder=self._build_subfolder)
return cmake
tc.variables["CATCH_CONFIG_DEFAULT_REPORTER"] = self._default_reporter_str
tc.generate()

def build(self):
# Catch2 does skip install if included as subproject:
# https://github.com/catchorg/Catch2/blob/79a5cd795c387e2da58c13e9dcbfd9ea7a2cfb30/CMakeLists.txt#L100-L102
main_cml = os.path.join(self._source_subfolder, "CMakeLists.txt")
tools.replace_in_file(main_cml, "if (NOT_SUBPROJECT)", "if (TRUE)")
cmake = CMake(self)
cmake.configure()
if self.options.with_main:
cmake = self._configure_cmake()
cmake.build()

def package(self):
self.copy(pattern="LICENSE.txt", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
copy(self, pattern="LICENSE.txt", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
cmake = CMake(self)
cmake.install()
tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
tools.rmdir(os.path.join(self.package_folder, "share"))
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rmdir(self, os.path.join(self.package_folder, "share"))
for cmake_file in ["ParseAndAddCatchTests.cmake", "Catch.cmake", "CatchAddTests.cmake"]:
self.copy(
copy(self,
cmake_file,
src=os.path.join(self._source_subfolder, "contrib"),
dst=os.path.join("lib", "cmake", "Catch2"),
src=os.path.join(self.source_folder, "contrib"),
dst=os.path.join(self.package_folder, "lib", "cmake", "Catch2"),
)

def package_info(self):
self.cpp_info.set_property("cmake_file_name", "Catch2")
self.cpp_info.set_property("cmake_target_name", "Catch2::Catch2{}".format("WithMain" if self.options.with_main else ""))
self.cpp_info.set_property("pkg_config_name", "catch2".format("-with-main" if self.options.with_main else ""))
self.cpp_info.names["cmake_find_package"] = "Catch2"
self.cpp_info.names["cmake_find_package_multi"] = "Catch2"
self.cpp_info.set_property("pkg_config_name", "catch2{}".format("-with-main" if self.options.with_main else ""))

defines = []
if self.options.get_safe("with_benchmark", False):
defines.append("CATCH_CONFIG_ENABLE_BENCHMARKING")
if self.options.with_prefix:
defines.append("CATCH_CONFIG_PREFIX_ALL")
if self.options.default_reporter:
defines.append(f"CATCH_CONFIG_DEFAULT_REPORTER={self._default_reporter_str}")

if self.options.with_main:
self.cpp_info.components["_catch2"].set_property("cmake_target_name", "Catch2::Catch2")
self.cpp_info.components["_catch2"].set_property("pkg_config_name", "catch2")
self.cpp_info.components["_catch2"].names["cmake_find_package"] = "Catch2"
self.cpp_info.components["_catch2"].names["cmake_find_package_multi"] = "Catch2"
self.cpp_info.components["_catch2"].defines = defines

self.cpp_info.components["catch2_with_main"].builddirs = [os.path.join("lib", "cmake", "Catch2")]
self.cpp_info.components["catch2_with_main"].builddirs.append(os.path.join("lib", "cmake", "Catch2"))
self.cpp_info.components["catch2_with_main"].libs = ["Catch2WithMain"]
self.cpp_info.components["catch2_with_main"].system_libs = ["log"] if self.settings.os == "Android" else []
self.cpp_info.components["catch2_with_main"].set_property("cmake_target_name", "Catch2::Catch2WithMain")
self.cpp_info.components["catch2_with_main"].set_property("pkg_config_name", "catch2-with-main")
self.cpp_info.components["catch2_with_main"].names["cmake_find_package"] = "Catch2WithMain"
self.cpp_info.components["catch2_with_main"].names["cmake_find_package_multi"] = "Catch2WithMain"
defines = self.cpp_info.components["catch2_with_main"].defines
self.cpp_info.components["catch2_with_main"].defines = defines
else:
self.cpp_info.builddirs = [os.path.join("lib", "cmake", "Catch2")]
self.cpp_info.system_libs = ["log"] if self.settings.os == "Android" else []
defines = self.cpp_info.defines
self.cpp_info.defines = defines

if self.options.get_safe("with_benchmark", False):
defines.append("CATCH_CONFIG_ENABLE_BENCHMARKING")
if self.options.with_prefix:
defines.append("CATCH_CONFIG_PREFIX_ALL")
if self.options.default_reporter:
defines.append("CATCH_CONFIG_DEFAULT_REPORTER={}".format(self._default_reporter_str))
# TODO: to remove in conan v2 once legacy generators removed
self.cpp_info.names["cmake_find_package"] = "Catch2"
self.cpp_info.names["cmake_find_package_multi"] = "Catch2"
if self.options.with_main:
self.cpp_info.components["_catch2"].names["cmake_find_package"] = "Catch2"
self.cpp_info.components["_catch2"].names["cmake_find_package_multi"] = "Catch2"
self.cpp_info.components["catch2_with_main"].names["cmake_find_package"] = "Catch2WithMain"
self.cpp_info.components["catch2_with_main"].names["cmake_find_package_multi"] = "Catch2WithMain"
17 changes: 8 additions & 9 deletions recipes/catch2/2.x.x/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
cmake_minimum_required(VERSION 3.5)
project(test_package)
cmake_minimum_required(VERSION 3.8)
project(test_package LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

find_package(Catch2 REQUIRED)
find_package(Catch2 REQUIRED CONFIG)

if(NOT WITH_PREFIX)
add_executable(test_package 000-CatchMain.cpp 100-Fix-Section.cpp)
target_link_libraries(test_package PRIVATE Catch2::Catch2)
target_compile_features(test_package PRIVATE cxx_std_11)

if(WITH_MAIN)
add_executable(standalone 200-standalone.cpp)
target_link_libraries(standalone PRIVATE Catch2::Catch2WithMain)
target_compile_features(standalone PRIVATE cxx_std_11)
if(WITH_BENCHMARK)
add_executable(benchmark 300-benchmark.cpp)
target_link_libraries(benchmark PRIVATE Catch2::Catch2WithMain)
target_compile_features(benchmark PRIVATE cxx_std_11)
endif()
endif()
else()
add_executable(test_package 000-CatchMain.cpp 400-with-prefix.cpp)
target_link_libraries(test_package PRIVATE Catch2::Catch2)
target_compile_features(test_package PRIVATE cxx_std_11)

if(WITH_MAIN)
add_executable(standalone 400-with-prefix.cpp)
target_link_libraries(standalone PRIVATE Catch2::Catch2WithMain)
target_compile_features(standalone PRIVATE cxx_std_11)
endif()
endif()
55 changes: 42 additions & 13 deletions recipes/catch2/2.x.x/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,53 @@
from conans import ConanFile, CMake, tools
from conans.tools import Version
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout
import os

import yaml

class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake", "cmake_find_package"
generators = "CMakeDeps", "VirtualRunEnv"
test_type = "explicit"

_tests_todo = []

@property
def _todos_filename(self):
return os.path.join(self.recipe_folder, self.folders.generators, "catch2_test_to_do.yml")

def requirements(self):
self.requires(self.tested_reference_str)

def generate(self):
tc = CMakeToolchain(self)
catch_opts = self.dependencies[self.tested_reference_str].options
tc.variables["WITH_PREFIX"] = catch_opts.with_prefix
tc.variables["WITH_MAIN"] = catch_opts.with_main
tc.variables["WITH_BENCHMARK"] = not catch_opts.with_prefix and catch_opts.with_main and catch_opts.with_benchmark
tc.generate()

# note: this is required as self.dependencies is not available in test()
self._tests_todo.append("test_package")
if catch_opts.with_main:
self._tests_todo.append("standalone")
if not catch_opts.with_prefix and catch_opts.with_main and catch_opts.with_benchmark:
self._tests_todo.append("benchmark")

with open(self._todos_filename, "w", encoding="utf-8") as file:
yaml.dump(self._tests_todo, file)

def layout(self):
cmake_layout(self)

def build(self):
cmake = CMake(self)
cmake.definitions["WITH_MAIN"] = self.options["catch2"].with_main
cmake.definitions["WITH_BENCHMARK"] = self.options["catch2"].with_main and self.options["catch2"].with_benchmark
cmake.definitions["WITH_PREFIX"] = self.options["catch2"].with_prefix
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self.settings):
self.run(os.path.join("bin", "test_package"), run_environment=True)
if self.options["catch2"].with_main:
self.run(os.path.join("bin", "standalone"), run_environment=True)
if self.options["catch2"].with_benchmark:
self.run(os.path.join("bin", "benchmark"), run_environment=True)
with open(self._todos_filename, "r", encoding="utf-8") as file:
self._tests_todo = yaml.safe_load(file)
if can_run(self):
for test_name in self._tests_todo:
self.run(os.path.join(self.cpp.build.bindirs[0], test_name), env="conanrun")
7 changes: 5 additions & 2 deletions recipes/catch2/3.x.x/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _compilers_minimum_version(self):

@property
def _default_reporter_str(self):
return '"{}"'.format(str(self.options.default_reporter).strip('"'))
return str(self.options.default_reporter).strip('"')

def export_sources(self):
export_conandata_patches(self)
Expand Down Expand Up @@ -146,11 +146,14 @@ def package_info(self):
self.cpp_info.components["catch2_with_main"].system_libs = ["log"] if self.settings.os == "Android" else []
self.cpp_info.components["catch2_with_main"].set_property("cmake_target_name", "Catch2::Catch2WithMain")
self.cpp_info.components["catch2_with_main"].set_property("pkg_config_name", "catch2-with-main")
defines = self.cpp_info.components["catch2_with_main"].defines
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["catch2_with_main"].system_libs.append("m")
defines = []
if self.options.with_prefix:
defines.append("CATCH_CONFIG_PREFIX_ALL")
if self.options.default_reporter:
defines.append(f"CATCH_CONFIG_DEFAULT_REPORTER={self._default_reporter_str}")
self.cpp_info.components["catch2_with_main"].defines = defines

# TODO: to remove in conan v2 once legacy generators removed
self.cpp_info.filenames["cmake_find_package"] = "Catch2"
Expand Down

0 comments on commit 8c1c300

Please sign in to comment.