Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Conan recipe support #2831

Merged
merged 7 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .conan/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ project(PackageTest CXX)
find_package(Catch2 CONFIG REQUIRED)

add_executable(test_package test_package.cpp)
target_link_libraries(test_package Catch2::Catch2WithMain)
target_link_libraries(test_package Catch2::Catch2WithMain)
horenmar marked this conversation as resolved.
Show resolved Hide resolved
target_compile_features(test_package PRIVATE cxx_std_14)
19 changes: 13 additions & 6 deletions .conan/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,27 @@
from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
from conan.tools.build import can_run
from conan.tools.files import save, load
import os


class TestPackageConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain", "CMakeDeps"
generators = "CMakeToolchain", "CMakeDeps", "VirtualRunEnv"
test_type = "explicit"
horenmar marked this conversation as resolved.
Show resolved Hide resolved

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

def layout(self):
cmake_layout(self)

def generate(self):
save(self, os.path.join(self.build_folder, "package_folder"),
horenmar marked this conversation as resolved.
Show resolved Hide resolved
self.dependencies[self.tested_reference_str].package_folder)
save(self, os.path.join(self.build_folder, "license"),
self.dependencies[self.tested_reference_str].license)

def build(self):
cmake = CMake(self)
cmake.configure()
Expand All @@ -26,8 +34,7 @@ def test(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'
package_folder = load(self, os.path.join(self.build_folder, "package_folder"))
license = load(self, os.path.join(self.build_folder, "license"))
assert os.path.isfile(os.path.join(package_folder, "licenses", "LICENSE.txt"))
assert license == 'BSL-1.0'
6 changes: 3 additions & 3 deletions .github/workflows/package-manager-builds.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ jobs:
strategy:
matrix:
conan_version:
- '1.62'
- '2.0'
- '1.63'
- '2.1'

include:
# Conan 1 has default profiles installed
- conan_version: '1.62'
- conan_version: '1.63'
profile_generate: 'false'

steps:
Expand Down
90 changes: 65 additions & 25 deletions conanfile.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
#!/usr/bin/env python
from conan import ConanFile, tools, __version__ as conan_version
from conan import ConanFile
from conan.tools.cmake import CMake, CMakeToolchain, CMakeDeps, cmake_layout
from conan.tools import files, scm
from conan.tools.files import copy, rmdir
from conan.tools.build import check_min_cppstd
from conan.tools.scm import Version
from conan.errors import ConanInvalidConfiguration
import os
import shutil
import re

required_conan_version = ">=1.53.0"
Expand All @@ -16,11 +18,31 @@ class CatchConan(ConanFile):
homepage = url
license = "BSL-1.0"
version = "latest"
settings = "os", "compiler", "build_type", "arch"

exports = "LICENSE.txt"
exports_sources = ("src/*", "CMakeLists.txt", "CMake/*", "extras/*")
options = {
"shared": [True, False],
"fPIC": [True, False],
}
default_options = {
"shared": False,
"fPIC": True,
}

@property
def _min_cppstd(self):
return "14"

@property
def _compilers_minimum_version(self):
return {
"gcc": "7",
"Visual Studio": "15",
"msvc": "191",
"clang": "5",
"apple-clang": "10",
}

settings = "os", "compiler", "build_type", "arch"

def set_version(self):
pattern = re.compile(r"\w*VERSION (\d+\.\d+\.\d+) # CML version placeholder, don't delete")
Expand All @@ -32,39 +54,57 @@ def set_version(self):

self.output.info(f'Using version: {self.version}')

def export(self):
copy(self, "LICENSE.txt", src=self.recipe_folder, dst=self.export_folder)

def export_sources(self):
copy(self, "CMakeLists.txt", src=self.recipe_folder, dst=self.export_sources_folder)
copy(self, "src/*", src=self.recipe_folder, dst=self.export_sources_folder)
copy(self, "extras/*", src=self.recipe_folder, dst=self.export_sources_folder)
copy(self, "CMake/*", src=self.recipe_folder, dst=self.export_sources_folder)

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

def configure(self):
if self.options.shared:
self.options.rm_safe("fPIC")

def layout(self):
cmake_layout(self)

def validate(self):
if self.settings.compiler.get_safe("cppstd"):
check_min_cppstd(self, self._min_cppstd)
# INFO: Conan 1.x does not specify cppstd by default, so we need to check the compiler version instead.
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 generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["BUILD_TESTING"] = False
horenmar marked this conversation as resolved.
Show resolved Hide resolved
tc.cache_variables["CATCH_INSTALL_DOCS"] = False
tc.cache_variables["CATCH_INSTALL_EXTRAS"] = True
tc.generate()

deps = CMakeDeps(self)
deps.generate()

def _configure_cmake(self):
cmake = CMake(self)

# 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):
cmake = self._configure_cmake()
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
cmake = self._configure_cmake()
copy(self, "LICENSE.txt", src=str(self.recipe_folder), dst=os.path.join(self.package_folder, "licenses"))
cmake = CMake(self)
cmake.install()

os.mkdir(f'{self.package_folder}/licenses/')
shutil.copy2(f'{self.recipe_folder}/LICENSE.txt', f'{self.package_folder}/licenses/')
rmdir(self, os.path.join(self.package_folder, "share"))
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
copy(self, "*.cmake", src=os.path.join(self.export_sources_folder, "extras"),
dst=os.path.join(self.package_folder, "lib", "cmake", "Catch2"))

def package_info(self):
lib_suffix = "d" if self.settings.build_type == "Debug" else ""
Expand All @@ -84,4 +124,4 @@ def package_info(self):
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"]
self.cpp_info.components["catch2main"].requires = ["catch2base"]
Loading