diff --git a/recipes/snitch/all/conandata.yml b/recipes/snitch/all/conandata.yml new file mode 100644 index 0000000000000..c99303582e711 --- /dev/null +++ b/recipes/snitch/all/conandata.yml @@ -0,0 +1,7 @@ +sources: + "1.2.3": + url: "https://github.com/snitch-org/snitch/archive/refs/tags/v1.2.3.zip" + sha256: "f2649e716b612f3dbb5f109b7250be80e2d7e43c7827034a270bd1ca91eafb12" + "1.2.2": + url: "https://github.com/snitch-org/snitch/archive/refs/tags/v1.2.2.zip" + sha256: "01eefb4a5368974cbfc14fbae93a5ccdd1f9d7f63d102784f914083b79d264a0" diff --git a/recipes/snitch/all/conanfile.py b/recipes/snitch/all/conanfile.py new file mode 100644 index 0000000000000..a4bcbd5587b10 --- /dev/null +++ b/recipes/snitch/all/conanfile.py @@ -0,0 +1,199 @@ +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration +from conan.tools.build import check_min_cppstd +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.53.0" + + +class SnitchConan(ConanFile): + name = "snitch" + description = "Lightweight C++20 testing framework" + topics = ("snitch", "unit-test") + license = "BSL-1.0" + homepage = "https://github.com/snitch-org/snitch" + url = "https://github.com/conan-io/conan-center-index" + package_type = "library" + settings = "os", "arch", "compiler", "build_type" + options = { + "shared": [True, False], + "fPIC": [True, False], + "header_only": [True, False], + "with_main": [True, False], + "with_exceptions": [True, False], + "with_timings": [True, False], + "with_shorthand_macros": [True, False], + "with_default_color": [True, False], + "with_success_decompose": [True, False], + "with_reporters": [None, "ANY"], + "max_test_cases": ["ANY"], # integer + "max_nested_sections": ["ANY"], # integer + "max_expr_length": ["ANY"], # integer + "max_message_length": ["ANY"], # integer + "max_test_name_length": ["ANY"], # integer + "max_tag_length": ["ANY"], # integer + "max_captures": ["ANY"], # integer + "max_capture_length": ["ANY"], # integer + "max_unique_tags": ["ANY"], # integer + "max_command_line_args": ["ANY"], # integer + "max_registered_reporters": ["ANY"], # integer + "max_path_length": ["ANY"] # integer + } + default_options = { + "shared": False, + "fPIC": True, + "header_only": False, + "with_main": True, + "with_exceptions": True, + "with_timings": True, + "with_shorthand_macros": True, + "with_default_color": True, + "with_success_decompose": False, + "with_reporters": "all", + "max_test_cases": 5000, + "max_nested_sections": 8, + "max_expr_length": 1024, + "max_message_length": 1024, + "max_test_name_length": 1024, + "max_tag_length": 256, + "max_captures": 8, + "max_capture_length": 256, + "max_unique_tags": 1024, + "max_command_line_args": 1024, + "max_registered_reporters": 8, + "max_path_length": 1024 + } + + @property + def _min_cppstd(self): + return "20" + + @property + def _compilers_minimum_version(self): + return { + "gcc": "10", + "Visual Studio": "17", + "msvc": "193", + "clang": "10", + "apple-clang": "10", + } + + @property + def _available_reporters(self): + return ["xml", "teamcity"] + + def config_options(self): + if self.settings.os == "Windows": + # Position-independent code is irrelevant on Windows; this is UNIX only. + del self.options.fPIC + + def configure(self): + if self.options.shared or self.options.header_only: + # Position-independent code is only relevant for static builds. + self.options.rm_safe("fPIC") + + if self.options.header_only: + # Shared vs static is irrelevant in header-only mode, so should be removed. + del self.options.shared + + def package_id(self): + if self.info.options.header_only: + # In header-only mode, the OS, architecture, and compiler don't matter. + # However do not clear options; they influence the content of the header file. + self.info.settings.clear() + + def layout(self): + cmake_layout(self, src_folder="src") + + def validate(self): + if self.settings.compiler.get_safe("cppstd"): + check_min_cppstd(self, self._min_cppstd) + minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False) + if minimum_version and Version(self.settings.compiler.version) < minimum_version: + raise ConanInvalidConfiguration( + f"{self.ref} requires C++{self._min_cppstd}, which your compiler doesn't support") + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def generate(self): + tc = CMakeToolchain(self) + + # Basic configuration + tc.cache_variables["SNITCH_DO_TEST"] = False + tc.cache_variables["SNITCH_UNITY_BUILD"] = True + + # Library format + tc.cache_variables["SNITCH_HEADER_ONLY"] = self.options.header_only + + # Feature toggles + tc.cache_variables["SNITCH_DEFINE_MAIN"] = self.options.with_main + tc.cache_variables["SNITCH_WITH_EXCEPTIONS"] = self.options.with_exceptions + tc.cache_variables["SNITCH_WITH_TIMINGS"] = self.options.with_timings + tc.cache_variables["SNITCH_WITH_SHORTHAND_MACROS"] = self.options.with_shorthand_macros + tc.cache_variables["SNITCH_DEFAULT_WITH_COLOR"] = self.options.with_default_color + tc.cache_variables["SNITCH_DECOMPOSE_SUCCESSFUL_ASSERTIONS"] = self.options.with_success_decompose + + for reporter in str(self.options.with_reporters).split(','): + reporter = reporter.strip() + if reporter == "all": + tc.cache_variables["SNITCH_WITH_ALL_REPORTERS"] = True + break + elif reporter in self._available_reporters: + tc.cache_variables["SNITCH_WITH_ALL_REPORTERS"] = False + tc.cache_variables[f"SNITCH_WITH_{reporter.upper()}_REPORTER"] = True + else: + raise ConanInvalidConfiguration(f"unknown reporter '{reporter}'") + + # Configurable limits + tc.cache_variables["SNITCH_MAX_TEST_CASES"] = str(self.options.max_test_cases) + tc.cache_variables["SNITCH_MAX_NESTED_SECTIONS"] = str(self.options.max_nested_sections) + tc.cache_variables["SNITCH_MAX_EXPR_LENGTH"] = str(self.options.max_expr_length) + tc.cache_variables["SNITCH_MAX_MESSAGE_LENGTH"] = str(self.options.max_message_length) + tc.cache_variables["SNITCH_MAX_TEST_NAME_LENGTH"] = str(self.options.max_test_name_length) + tc.cache_variables["SNITCH_MAX_TAG_LENGTH"] = str(self.options.max_tag_length) + tc.cache_variables["SNITCH_MAX_CAPTURES"] = str(self.options.max_captures) + tc.cache_variables["SNITCH_MAX_CAPTURE_LENGTH"] = str(self.options.max_capture_length) + tc.cache_variables["SNITCH_MAX_UNIQUE_TAGS"] = str(self.options.max_unique_tags) + tc.cache_variables["SNITCH_MAX_COMMAND_LINE_ARGS"] = str(self.options.max_command_line_args) + tc.cache_variables["SNITCH_MAX_REGISTERED_REPORTERS"] = str(self.options.max_registered_reporters) + tc.cache_variables["SNITCH_MAX_PATH_LENGTH"] = str(self.options.max_path_length) + + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) + cmake = CMake(self) + cmake.install() + rmdir(self, os.path.join(self.package_folder, "lib", "cmake")) + + def package_info(self): + target = "snitch-header-only" if self.options.header_only else "snitch" + + self.cpp_info.set_property("cmake_file_name", "snitch") + self.cpp_info.set_property("cmake_target_name", f"snitch::{target}") + self.cpp_info.set_property("pkg_config_name", "snitch") + + if self.options.header_only: + self.cpp_info.components["_snitch"].bindirs = [] + self.cpp_info.components["_snitch"].libdirs = [] + else: + self.cpp_info.components["_snitch"].libs = ['snitch'] + if self.settings.os in ["Linux", "FreeBSD"]: + self.cpp_info.system_libs.append("m") + + # TODO: to remove in conan v2 once legacy generators removed + self.cpp_info.names["cmake_find_package"] = "snitch" + self.cpp_info.names["cmake_find_package_multi"] = "snitch" + self.cpp_info.names["pkg_config"] = "snitch" + self.cpp_info.components["_snitch"].names["cmake_find_package"] = target + self.cpp_info.components["_snitch"].names["cmake_find_package_multi"] = target + self.cpp_info.components["_snitch"].set_property("cmake_target_name", f"snitch::{target}") diff --git a/recipes/snitch/all/test_package/100-standalone.cpp b/recipes/snitch/all/test_package/100-standalone.cpp new file mode 100644 index 0000000000000..a3fbd51a23a25 --- /dev/null +++ b/recipes/snitch/all/test_package/100-standalone.cpp @@ -0,0 +1,11 @@ +#if defined(HEADER_ONLY) +# define SNITCH_IMPLEMENTATION +# include +#else +# include +# include +#endif + +SNITCH_TEST_CASE("compiles and runs") { + SNITCH_REQUIRE(true == !false); +} diff --git a/recipes/snitch/all/test_package/200-standalone-with-shorthand.cpp b/recipes/snitch/all/test_package/200-standalone-with-shorthand.cpp new file mode 100644 index 0000000000000..bfdc6f47fe273 --- /dev/null +++ b/recipes/snitch/all/test_package/200-standalone-with-shorthand.cpp @@ -0,0 +1,11 @@ +#if defined(HEADER_ONLY) +# define SNITCH_IMPLEMENTATION +# include +#else +# include +# include +#endif + +TEST_CASE("compiles and runs") { + REQUIRE(true == !false); +} diff --git a/recipes/snitch/all/test_package/CMakeLists.txt b/recipes/snitch/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..19d7688a6e4c0 --- /dev/null +++ b/recipes/snitch/all/test_package/CMakeLists.txt @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 3.8) +project(test_package LANGUAGES CXX) + +find_package(snitch REQUIRED CONFIG) + +if (WITH_SHORTHAND) + add_executable(standalone 200-standalone-with-shorthand.cpp) +else() + add_executable(standalone 100-standalone.cpp) +endif() + +if (HEADER_ONLY) + target_compile_definitions(standalone PRIVATE HEADER_ONLY) + target_link_libraries(standalone PRIVATE snitch::snitch-header-only) +else() + target_link_libraries(standalone PRIVATE snitch::snitch) +endif() + +target_compile_features(standalone PRIVATE cxx_std_20) diff --git a/recipes/snitch/all/test_package/conanfile.py b/recipes/snitch/all/test_package/conanfile.py new file mode 100644 index 0000000000000..21081577ec035 --- /dev/null +++ b/recipes/snitch/all/test_package/conanfile.py @@ -0,0 +1,31 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "VirtualRunEnv" + test_type = "explicit" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) + + def generate(self): + tc = CMakeToolchain(self) + tc.variables["WITH_SHORTHAND"] = self.dependencies[self.tested_reference_str].options.with_shorthand_macros + tc.variables["HEADER_ONLY"] = self.dependencies[self.tested_reference_str].options.header_only + tc.generate() + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if can_run(self): + self.run(os.path.join(self.cpp.build.bindirs[0], "standalone"), env="conanrun") diff --git a/recipes/snitch/all/test_v1_package/CMakeLists.txt b/recipes/snitch/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..0d20897301b68 --- /dev/null +++ b/recipes/snitch/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package + ${CMAKE_CURRENT_BINARY_DIR}/test_package) diff --git a/recipes/snitch/all/test_v1_package/conanfile.py b/recipes/snitch/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..c8d1d20a4e7d2 --- /dev/null +++ b/recipes/snitch/all/test_v1_package/conanfile.py @@ -0,0 +1,18 @@ +from conans import ConanFile, CMake, tools +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "cmake", "cmake_find_package_multi" + + def build(self): + cmake = CMake(self) + cmake.definitions["WITH_SHORTHAND"] = self.options["snitch"].with_shorthand_macros + cmake.definitions["HEADER_ONLY"] = self.options["snitch"].header_only + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self): + self.run(os.path.join("bin", "standalone"), run_environment=True) diff --git a/recipes/snitch/config.yml b/recipes/snitch/config.yml new file mode 100644 index 0000000000000..6d9f399765e2d --- /dev/null +++ b/recipes/snitch/config.yml @@ -0,0 +1,5 @@ +versions: + "1.2.3": + folder: all + "1.2.2": + folder: all