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

libunifex: migrate to Conan v2 #18265

Merged
merged 10 commits into from
Feb 26, 2024
7 changes: 0 additions & 7 deletions recipes/libunifex/all/CMakeLists.txt

This file was deleted.

6 changes: 3 additions & 3 deletions recipes/libunifex/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sources:
"cci.20220430":
url: "https://github.com/facebookexperimental/libunifex/archive/c359fd8e7d97d91359cf4a6c1dbef99b0b1767b6.tar.gz"
sha256: "c306891967fa4cc1a22f3401581d35ceea41eb1dbdac3e6157ecf3defaa4b15d"
"0.4.0":
url: "https://github.com/facebookexperimental/libunifex/archive/refs/tags/v0.4.0.tar.gz"
sha256: "d5ce3b616e166da31e6b4284764a1feeba52aade868bcbffa94cfd86b402716e"
153 changes: 93 additions & 60 deletions recipes/libunifex/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,110 +1,143 @@
from conans import ConanFile, CMake, tools
from conans.errors import ConanInvalidConfiguration
import functools
import os

required_conan_version = ">=1.43.0"
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.build import check_min_cppstd, valid_min_cppstd
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import copy, get, rmdir, replace_in_file, export_conandata_patches, apply_conandata_patches
from conan.tools.microsoft import is_msvc

required_conan_version = ">=1.52.0"


class LibunifexConan(ConanFile):
name = "libunifex"
description = "A prototype implementation of the C++ sender/receiver async programming model"
license = ("Apache-2.0", "LLVM-exception")
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/facebookexperimental/libunifex"
description = "A prototype implementation of the C++ sender/receiver async programming model"
topics = ("async", "cpp")

package_type = "static-library"
settings = "os", "arch", "compiler", "build_type"

generators = "cmake", "cmake_find_package_multi"
no_copy_source = True
exports_sources = ["CMakeLists.txt"]
options = {
"fPIC": [True, False],
"with_liburing": [True, False],
}
default_options = {
"fPIC": True,
"with_liburing": False, # Enabled by default in the project, but incompatible with the Linux version used in C3I
}

@property
def _source_subfolder(self):
return "source_subfolder"
def _minimum_standard(self):
if is_msvc(self):
# Otherwise a forward declaration `extern const _schedule::_fn schedule;`
# conflicts with the implementation `inline constexpr _schedule::_fn schedule {};`
# https://github.com/facebookexperimental/libunifex/issues/591
return 20
return 17

@property
def _compilers_minimum_version(self):
return {
"gcc": "9",
"Visual Studio": "16",
"clang": "10",
"apple-clang": "11",
"Visual Studio": "17",
"msvc": "193",
}

@property
def _minimum_standard(self):
return "17"
def export_sources(self):
export_conandata_patches(self)

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

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

# FIXME: Add support for liburing
# def requirements(self):
# TODO: Make an option to opt-out of liburing for old kernel versions
# if self.settings.os == "Linux":
# self.requires("liburing/2.1")
def requirements(self):
if self.options.get_safe("with_liburing"):
self.requires("liburing/2.4", transitive_headers=True, transitive_libs=True)

def validate(self):
if self.settings.compiler.get_safe("cppstd"):
tools.check_min_cppstd(
self, self._minimum_standard)
check_min_cppstd(self, self._minimum_standard)

def lazy_lt_semver(v1, v2):
lv1 = [int(v) for v in v1.split(".")]
lv2 = [int(v) for v in v2.split(".")]
min_length = min(len(lv1), len(lv2))
return lv1[:min_length] < lv2[:min_length]

minimum_version = self._compilers_minimum_version.get(
str(self.settings.compiler), False)
if not minimum_version:
self.output.warn(
"{0} {1} requires C++{2}. Your compiler is unknown. Assuming it supports C++{2}."
.format(self.name, self.version, self._minimum_standard))
elif lazy_lt_semver(str(self.settings.compiler.version), minimum_version):
return all(int(p1) < int(p2) for p1, p2 in zip(str(v1).split("."), str(v2).split(".")))

minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and lazy_lt_semver(self.settings.compiler.version, minimum_version):
raise ConanInvalidConfiguration(
"{} {} requires C++{}, which your compiler does not support."
.format(self.name, self.version, self._minimum_standard))
f"{self.ref} requires C++{self._minimum_standard}, which your compiler does not support."
)

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

def generate(self):
tc = CMakeToolchain(self)
tc.variables["BUILD_TESTING"] = False
tc.variables["UNIFEX_BUILD_EXAMPLES"] = False
tc.variables["UNIFEX_NO_LIBURING"] = not self.options.get_safe("with_liburing", False)
if not valid_min_cppstd(self, self._minimum_standard):
tc.variables["CMAKE_CXX_STANDARD"] = self._minimum_standard
tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW"
tc.generate()
deps = CMakeDeps(self)
deps.set_property("liburing", "cmake_file_name", "LIBURING")
deps.generate()

@functools.lru_cache(1)
def _configure_cmake(self):
def build(self):
self._patch_sources()
cmake = CMake(self)
cmake.definitions["BUILD_TESTING"] = "OFF"
cmake.configure()
return cmake

def build(self):
cmake = self._configure_cmake()
cmake.build()

def _patch_sources(self):
apply_conandata_patches(self)
# Ensure liburing from the system is not used and that uuper-case variables are generated
required = "REQUIRED" if self.settings.os == "Linux" else ""
replace_in_file(self, os.path.join(self.source_folder, "cmake", "unifex_flags.cmake"),
"find_package(LibUring COMPONENTS)",
f"find_package(LIBURING {required} CONFIG NO_DEFAULT_PATH PATHS ${{CMAKE_PREFIX_PATH}})")
replace_in_file(self, os.path.join(self.source_folder, "cmake", "unifex_env.cmake"), "-Werror", "")
replace_in_file(self, os.path.join(self.source_folder, "cmake", "unifex_env.cmake"), "/WX", "")
# Allow cppstd to be overridden
replace_in_file(self, os.path.join(self.source_folder, "source", "CMakeLists.txt"),
"target_compile_features(unifex PUBLIC cxx_std_17)", "")

def package(self):
self.copy("LICENSE.txt", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
copy(self, "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, "lib", "pkgconfig"))
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))

def package_info(self):
self.cpp_info.bindirs = []
self.cpp_info.libdirs = []

self.cpp_info.set_property("cmake_file_name", "unifex")
self.cpp_info.set_property("cmake_target_name", "unifex::unifex")
self.cpp_info.set_property("pkg_config_name", "unifex")

self.cpp_info.components["unifex"].libs = ["unifex"]
self.cpp_info.components["unifex"].set_property("cmake_target_name", "unifex::unifex")
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["unifex"].system_libs = ["pthread"]
if self.options.get_safe("with_liburing"):
self.cpp_info.components["unifex"].requires.append("liburing::liburing")

# TODO: to remove in conan v2 once cmake_find_package_* generators removed
self.cpp_info.filenames["cmake_find_package"] = "unifex"
self.cpp_info.filenames["cmake_find_package_multi"] = "unifex"
self.cpp_info.names["cmake_find_package"] = "unifex"
self.cpp_info.names["cmake_find_package_multi"] = "unifex"
self.cpp_info.names["pkg_config"] = "unifex"
self.cpp_info.components["unifex"].names["cmake_find_package"] = "unifex"
self.cpp_info.components["unifex"].names["cmake_find_package_multi"] = "unifex"
self.cpp_info.components["unifex"].set_property(
"cmake_target_name", "unifex::unifex")
self.cpp_info.components["unifex"].libs = ["unifex"]

if self.settings.os == "Linux":
self.cpp_info.components["unifex"].system_libs = ["pthread"]
# self.cpp_info.components["unifex"].requires.append(
# "liburing::liburing")
13 changes: 7 additions & 6 deletions recipes/libunifex/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
cmake_minimum_required(VERSION 3.1)
project(test_package)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup(TARGETS)
cmake_minimum_required(VERSION 3.15)
project(test_package LANGUAGES CXX)

find_package(unifex REQUIRED CONFIG)

add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} PRIVATE unifex::unifex)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17)
if(MSVC)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20)
else()
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 17)
endif()
19 changes: 14 additions & 5 deletions recipes/libunifex/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
from conans import ConanFile, CMake, tools
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake
import os


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

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

def layout(self):
cmake_layout(self)

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindir, "test_package")
self.run(bin_path, env="conanrun")
8 changes: 8 additions & 0 deletions recipes/libunifex/all/test_v1_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.15)
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/)
17 changes: 17 additions & 0 deletions recipes/libunifex/all/test_v1_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
4 changes: 2 additions & 2 deletions recipes/libunifex/config.yml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
versions:
"cci.20220430":
folder: "all"
"0.4.0":
folder: all