From 62d4aecb8c9c30b04188d6846e3ad072eee790ba Mon Sep 17 00:00:00 2001 From: Devon Adair Date: Sat, 17 Feb 2024 10:42:44 -0500 Subject: [PATCH] Conan v2 (#2805) * Removed Conan1 build.py file using conan package tools that are no longer supported * Working conan 1 and 2 build with the test package. updated the test_package to be updated to conan 2 and fixed missing cmake. Still need to check that the license file is packaged up and that the packages look identical before the changes * Removing debug prints and the license check that isn't working yet * Working license file copied over as it was before * Migrated the properties of cpp_info to conan 2. Keeping conan 1 support by checking the version of conan https://docs.conan.io/1/migrating_to_2.0/properties.html * Revert "Removed Conan1 build.py file using conan package tools that are no longer supported" This reverts commit a606d1dfe6e118199be8a371403717e3e42ad5da. * Need to add a set_version to parse the version from CMakeLists.txt Adding a package build yaml to ensure conan keeps building on 1 and 2 * Setting lowercase catch2 for pkg_config and cmake_target_name * Fixing the namespace for conan file cmake_target_name --- .conan/test_package/CMakeLists.txt | 15 +-- .conan/test_package/conanfile.py | 25 +++-- .github/workflows/package-manager-builds.yaml | 31 ++++++ .gitignore | 1 + conanfile.py | 100 +++++++++++++----- 5 files changed, 127 insertions(+), 45 deletions(-) create mode 100644 .github/workflows/package-manager-builds.yaml mode change 100644 => 100755 conanfile.py diff --git a/.conan/test_package/CMakeLists.txt b/.conan/test_package/CMakeLists.txt index 6ee069c0..ff9496ad 100644 --- a/.conan/test_package/CMakeLists.txt +++ b/.conan/test_package/CMakeLists.txt @@ -1,12 +1,7 @@ -cmake_minimum_required(VERSION 3.2.0) -project(test_package CXX) +cmake_minimum_required(VERSION 3.15) +project(PackageTest CXX) -include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") -conan_basic_setup() +find_package(Catch2 CONFIG REQUIRED) -find_package(Catch2 REQUIRED CONFIG) - -add_executable(${PROJECT_NAME} test_package.cpp) - -target_link_libraries(${PROJECT_NAME} Catch2::Catch2WithMain) -set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14) +add_executable(test_package test_package.cpp) +target_link_libraries(test_package Catch2::Catch2WithMain) \ No newline at end of file diff --git a/.conan/test_package/conanfile.py b/.conan/test_package/conanfile.py index 069ace61..88f3d137 100644 --- a/.conan/test_package/conanfile.py +++ b/.conan/test_package/conanfile.py @@ -1,12 +1,20 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -from conans import ConanFile, CMake +from conan import ConanFile +from conan.tools.cmake import CMake, cmake_layout +from conan.tools.build import can_run import os class TestPackageConan(ConanFile): settings = "os", "compiler", "build_type", "arch" - generators = "cmake_find_package_multi", "cmake" + generators = "CMakeToolchain", "CMakeDeps" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) @@ -14,7 +22,12 @@ class TestPackageConan(ConanFile): cmake.build() def test(self): - assert os.path.isfile(os.path.join( - self.deps_cpp_info["catch2"].rootpath, "licenses", "LICENSE.txt")) - bin_path = os.path.join("bin", "test_package") - self.run("%s -s" % bin_path, run_environment=True) + if can_run(self): + cmd = os.path.join(self.cpp.build.bindir, "test_package") + self.run(cmd, env="conanrun") + + # If we are on conan 2 we can check the license info is populated + if hasattr(self, 'dependencies'): + catch2 = self.dependencies["catch2"] + assert os.path.exists(f'{catch2.package_folder}/licenses/LICENSE.txt') + assert catch2.license == 'BSL-1.0' diff --git a/.github/workflows/package-manager-builds.yaml b/.github/workflows/package-manager-builds.yaml new file mode 100644 index 00000000..cb55b753 --- /dev/null +++ b/.github/workflows/package-manager-builds.yaml @@ -0,0 +1,31 @@ +name: Package Manager Builds + +on: [push, pull_request] + +jobs: + conan_builds: + name: Conan ${{matrix.conan_version}} + runs-on: ubuntu-20.04 + strategy: + matrix: + conan_version: + - '1.62' + - '2.0' + + include: + # Conan 1 has default profiles installed + - conan_version: '1.62' + profile_generate: 'false' + + steps: + - uses: actions/checkout@v4 + + - name: Install conan + run: pip install conan==${{matrix.conan_version}} + + - name: Setup conan profiles + if: matrix.profile_generate != 'false' + run: conan profile detect + + - name: Run conan package create + run: conan create . -tf .conan/test_package diff --git a/.gitignore b/.gitignore index 27f6bc0b..4ed76b0b 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ Build cmake-build-* benchmark-dir .conan/test_package/build +.conan/test_package/CMakeUserPresets.json bazel-* build-fuzzers debug-build diff --git a/conanfile.py b/conanfile.py old mode 100644 new mode 100755 index 7aa27ef5..2edb475b --- a/conanfile.py +++ b/conanfile.py @@ -1,5 +1,11 @@ #!/usr/bin/env python -from conans import ConanFile, CMake, tools +from conan import ConanFile, tools, __version__ as conan_version +from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout +from conan.tools import files, scm +import os +import shutil +import re + class CatchConan(ConanFile): name = "catch2" @@ -8,53 +14,89 @@ class CatchConan(ConanFile): url = "https://github.com/catchorg/Catch2" homepage = url license = "BSL-1.0" + version = "latest" exports = "LICENSE.txt" exports_sources = ("src/*", "CMakeLists.txt", "CMake/*", "extras/*") settings = "os", "compiler", "build_type", "arch" - generators = "cmake" + def set_version(self): + pattern = re.compile(r"\w*VERSION (\d+\.\d+\.\d+) # CML version placeholder, don't delete") + with open("CMakeLists.txt") as file: + for line in file: + result = pattern.search(line) + if result: + self.version = result.group(1) + + self.output.info(f'Using version: {self.version}') + + def layout(self): + cmake_layout(self) + + def generate(self): + tc = CMakeToolchain(self) + tc.generate() + + deps = CMakeDeps(self) + deps.generate() def _configure_cmake(self): cmake = CMake(self) - cmake.definitions["BUILD_TESTING"] = "OFF" - cmake.definitions["CATCH_INSTALL_DOCS"] = "OFF" - cmake.definitions["CATCH_INSTALL_EXTRAS"] = "ON" - cmake.configure(build_folder="build") + + # These are option variables. The toolchain in conan 2 doesn't appear to + # set these correctly so you have to do it in the configure variables. + cmake.configure(variables= { + "BUILD_TESTING": "OFF", + "CATCH_INSTALL_DOCS": "OFF", + "CATCH_INSTALL_EXTRAS": "ON", + } + ) return cmake def build(self): - # We need this workaround until the toolchains feature - # to inject stuff like MD/MT - line_to_replace = 'list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/CMake")' - tools.replace_in_file("CMakeLists.txt", line_to_replace, - '''{} -include("{}/conanbuildinfo.cmake") -conan_basic_setup()'''.format(line_to_replace, self.install_folder.replace("\\", "/"))) - cmake = self._configure_cmake() cmake.build() def package(self): - self.copy(pattern="LICENSE.txt", dst="licenses") cmake = self._configure_cmake() cmake.install() + os.mkdir(f'{self.package_folder}/licenses/') + shutil.copy2(f'{self.recipe_folder}/LICENSE.txt', f'{self.package_folder}/licenses/') + def package_info(self): lib_suffix = "d" if self.settings.build_type == "Debug" else "" - self.cpp_info.names["cmake_find_package"] = "Catch2" - self.cpp_info.names["cmake_find_package_multi"] = "Catch2" - # Catch2 - self.cpp_info.components["catch2base"].names["cmake_find_package"] = "Catch2" - self.cpp_info.components["catch2base"].names["cmake_find_package_multi"] = "Catch2" - self.cpp_info.components["catch2base"].names["pkg_config"] = "Catch2" - self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix] - self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2") - # Catch2WithMain - self.cpp_info.components["catch2main"].names["cmake_find_package"] = "Catch2WithMain" - self.cpp_info.components["catch2main"].names["cmake_find_package_multi"] = "Catch2WithMain" - self.cpp_info.components["catch2main"].names["pkg_config"] = "Catch2WithMain" - self.cpp_info.components["catch2main"].libs = ["Catch2Main" + lib_suffix] - self.cpp_info.components["catch2main"].requires = ["catch2base"] + if conan_version < scm.Version("2.0.0"): + self.cpp_info.names["cmake_find_package"] = "Catch2" + self.cpp_info.names["cmake_find_package_multi"] = "Catch2" + # Catch2 + self.cpp_info.components["catch2base"].names["cmake_find_package"] = "Catch2" + self.cpp_info.components["catch2base"].names["cmake_find_package_multi"] = "Catch2" + self.cpp_info.components["catch2base"].names["pkg_config"] = "catch2" + self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix] + self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2") + # Catch2WithMain + self.cpp_info.components["catch2main"].names["cmake_find_package"] = "Catch2WithMain" + self.cpp_info.components["catch2main"].names["cmake_find_package_multi"] = "Catch2WithMain" + self.cpp_info.components["catch2main"].names["pkg_config"] = "Catch2WithMain" + self.cpp_info.components["catch2main"].libs = ["Catch2Main" + lib_suffix] + self.cpp_info.components["catch2main"].requires = ["catch2base"] + else: + self.cpp_info.set_property("cmake_file_name", "Catch2") + self.cpp_info.set_property("cmake_target_name", "Catch2::Catch2WithMain") + self.cpp_info.set_property("pkg_config_name", "catch2-with-main") + + # Catch2 + self.cpp_info.components["catch2base"].set_property("cmake_file_name", "Catch2::Catch2") + self.cpp_info.components["catch2base"].set_property("pkg_config_name", "catch2") + self.cpp_info.components["catch2base"].libs = ["Catch2" + lib_suffix] + self.cpp_info.components["catch2base"].builddirs.append("lib/cmake/Catch2") + + # Catch2WithMain + self.cpp_info.components["catch2main"].set_property("cmake_file_name", "Catch2::Catch2WithMain") + self.cpp_info.components["catch2main"].set_property("cmake_target_name", "Catch2::Catch2WithMain") + self.cpp_info.components["catch2main"].set_property("pkg_config_name", "catch2-with-main") + self.cpp_info.components["catch2main"].libs = ["Catch2Main" + lib_suffix] + self.cpp_info.components["catch2main"].requires = ["catch2base"] \ No newline at end of file