From b44edbedc5bbcf27f27000329ddbd4dd5864f3cb Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Mon, 9 Oct 2023 01:17:36 -0400 Subject: [PATCH 1/5] stduuid: use std::span only when available --- recipes/stduuid/all/conanfile.py | 63 ++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py index 0ca3e6b2dcb08..f55f1352f8bca 100644 --- a/recipes/stduuid/all/conanfile.py +++ b/recipes/stduuid/all/conanfile.py @@ -1,7 +1,7 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration from conan.tools.build import check_min_cppstd -from conan.tools.files import copy, get +from conan.tools.files import copy, get, replace_in_file from conan.tools.layout import basic_layout from conan.tools.scm import Version import os @@ -18,12 +18,10 @@ class StduuidConan(ConanFile): homepage = "https://github.com/mariusbancila/stduuid" settings = "os", "arch", "compiler", "build_type" options = { + # True: Use std::span + # False: Use gsl::span "with_cxx20_span": [True, False], } - default_options = { - "with_cxx20_span": False, - } - no_copy_source = True @property def _min_cppstd(self): @@ -39,12 +37,50 @@ def _compilers_minimum_version(self): "Visual Studio": "15", } + @property + def _std_span_minimum_version(self): + # TODO double check these + return { + "apple-clang": "10", + "clang": "7", + "gcc": "10", + "msvc": "192", + "Visual Studio": "16", + } + + def _supports_std_span(self): + # Air on the side of caution, if we are not certain then we should return false. + + if self.settings.compiler.get_safe("cppstd"): + # This first check alone should almost always be correct on its own, as if you're on + # C++20, your compiler probably supports std::span. + try: + check_min_cppstd(self, "20", False) + except ConanInvalidConfiguration: + return False + else: + self.output.info("compiler.cppstd not set, assuming std::span not supported") + return False + + compiler_minimum_version = self._std_span_minimum_version.get(str(self.settings.compiler), False) + if not compiler_minimum_version: + self.output.info(f"Unsure if compiler '{self.settings.compiler}' supports std::span, assuming no.") + return False + if Version(self.settings.compiler.version) < compiler_minimum_version: + return False + + return True + + def config_options(self): + # By default, use std::span if we're certain the profile supports it. + self.options.with_cxx20_span = self._supports_std_span() + def layout(self): - basic_layout(self, src_folder="src") + basic_layout(self) def requirements(self): if not self.options.with_cxx20_span: - self.requires("ms-gsl/3.1.0", transitive_headers=True) + self.requires("ms-gsl/4.0.0", transitive_headers=True) if self.settings.os == "Linux" and Version(self.version) <= "1.0": self.requires("util-linux-libuuid/2.39", transitive_headers=True, transitive_libs=True) @@ -52,7 +88,7 @@ def package_id(self): self.info.clear() def validate(self): - if self.settings.compiler.get_safe("cppsd"): + 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) @@ -66,7 +102,14 @@ def source(self): destination=self.source_folder, strip_root=True) def build(self): - pass + uuid_h_file = os.path.join(self.build_folder, "..", "include", "uuid.h") + #replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if __cpp_lib_span") + if self.options.with_cxx20_span: + replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if 1") + replace_in_file(self, uuid_h_file, "#ifdef __cpp_lib_span", "#if 1") + else: + replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if 0") + replace_in_file(self, uuid_h_file, "#ifdef __cpp_lib_span", "#if 0") def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) @@ -75,5 +118,3 @@ def package(self): def package_info(self): self.cpp_info.bindirs = [] self.cpp_info.libdirs = [] - if not self.options.with_cxx20_span: - self.cpp_info.includedirs.append(os.path.join(self.dependencies["ms-gsl"].cpp_info.includedirs[0], "gsl")) From 96a0683f43882baf96089b2070b76ff775351a42 Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Tue, 10 Oct 2023 11:24:53 -0400 Subject: [PATCH 2/5] stduuid: only check for c++20 --- recipes/stduuid/all/conanfile.py | 26 +++----------------------- 1 file changed, 3 insertions(+), 23 deletions(-) diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py index f55f1352f8bca..60f9ca10c9bf4 100644 --- a/recipes/stduuid/all/conanfile.py +++ b/recipes/stduuid/all/conanfile.py @@ -37,23 +37,12 @@ def _compilers_minimum_version(self): "Visual Studio": "15", } - @property - def _std_span_minimum_version(self): - # TODO double check these - return { - "apple-clang": "10", - "clang": "7", - "gcc": "10", - "msvc": "192", - "Visual Studio": "16", - } - def _supports_std_span(self): # Air on the side of caution, if we are not certain then we should return false. + # std::span is a "small" enough feature that generally compilers will support + # it if C++20 is supported, so just check for the latter. if self.settings.compiler.get_safe("cppstd"): - # This first check alone should almost always be correct on its own, as if you're on - # C++20, your compiler probably supports std::span. try: check_min_cppstd(self, "20", False) except ConanInvalidConfiguration: @@ -62,13 +51,6 @@ def _supports_std_span(self): self.output.info("compiler.cppstd not set, assuming std::span not supported") return False - compiler_minimum_version = self._std_span_minimum_version.get(str(self.settings.compiler), False) - if not compiler_minimum_version: - self.output.info(f"Unsure if compiler '{self.settings.compiler}' supports std::span, assuming no.") - return False - if Version(self.settings.compiler.version) < compiler_minimum_version: - return False - return True def config_options(self): @@ -98,12 +80,10 @@ def validate(self): ) def source(self): - get(self, **self.conan_data["sources"][self.version], - destination=self.source_folder, strip_root=True) + get(self, **self.conan_data["sources"][self.version], strip_root=True) def build(self): uuid_h_file = os.path.join(self.build_folder, "..", "include", "uuid.h") - #replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if __cpp_lib_span") if self.options.with_cxx20_span: replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if 1") replace_in_file(self, uuid_h_file, "#ifdef __cpp_lib_span", "#if 1") From e4336b29e25ff14a9c03e4812790a7c0664acfa5 Mon Sep 17 00:00:00 2001 From: Luis Caro Campos <3535649+jcar87@users.noreply.github.com> Date: Tue, 10 Oct 2023 17:57:19 +0100 Subject: [PATCH 3/5] stduuid: fixes --- recipes/stduuid/all/conandata.yml | 9 ++++ recipes/stduuid/all/conanfile.py | 50 ++++++++----------- .../patches/1.2.2-handle-span-header.patch | 26 ++++++++++ .../patches/1.2.3-handle-span-header.patch | 29 +++++++++++ 4 files changed, 84 insertions(+), 30 deletions(-) create mode 100644 recipes/stduuid/all/patches/1.2.2-handle-span-header.patch create mode 100644 recipes/stduuid/all/patches/1.2.3-handle-span-header.patch diff --git a/recipes/stduuid/all/conandata.yml b/recipes/stduuid/all/conandata.yml index cb02ec2f29148..106008491388a 100644 --- a/recipes/stduuid/all/conandata.yml +++ b/recipes/stduuid/all/conandata.yml @@ -8,3 +8,12 @@ sources: "1.0": url: "https://github.com/mariusbancila/stduuid/archive/v1.0.tar.gz" sha256: "e96f2ac7c950c3c24d7e2e44a84236277b7774ee346dcc620edf400d9eda0a3c" +patches: + "1.2.2": + - patch_file: "patches/1.2.2-handle-span-header.patch" + patch_description: "Conditionally include span header based on compiler definition" + patch_type: "conan" + "1.2.3": + - patch_file: "patches/1.2.3-handle-span-header.patch" + patch_description: "Conditionally include span header based on compiler definition" + patch_type: "conan" diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py index 60f9ca10c9bf4..54735b09223c5 100644 --- a/recipes/stduuid/all/conanfile.py +++ b/recipes/stduuid/all/conanfile.py @@ -1,7 +1,7 @@ from conan import ConanFile from conan.errors import ConanInvalidConfiguration -from conan.tools.build import check_min_cppstd -from conan.tools.files import copy, get, replace_in_file +from conan.tools.build import check_min_cppstd, valid_min_cppstd +from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get from conan.tools.layout import basic_layout from conan.tools.scm import Version import os @@ -25,7 +25,7 @@ class StduuidConan(ConanFile): @property def _min_cppstd(self): - return "20" if self.options.with_cxx20_span else "17" + return "20" if self.options.get_safe("with_cxx20_span") else "17" @property def _compilers_minimum_version(self): @@ -36,32 +36,25 @@ def _compilers_minimum_version(self): "msvc": "191", "Visual Studio": "15", } - - def _supports_std_span(self): - # Air on the side of caution, if we are not certain then we should return false. - - # std::span is a "small" enough feature that generally compilers will support - # it if C++20 is supported, so just check for the latter. - if self.settings.compiler.get_safe("cppstd"): - try: - check_min_cppstd(self, "20", False) - except ConanInvalidConfiguration: - return False - else: - self.output.info("compiler.cppstd not set, assuming std::span not supported") - return False - - return True - def config_options(self): - # By default, use std::span if we're certain the profile supports it. - self.options.with_cxx20_span = self._supports_std_span() + def export_sources(self): + export_conandata_patches(self) def layout(self): basic_layout(self) + def config_options(self): + if Version(self.version) == "1.0": + # Version 1.0 unconditionally depends on gsl span + del self.options.with_cxx20_span + else: + # Conditionally set the default value of with_cxx20_span + # if cppstd is set and is 20 or greater + self.options.with_cxx20_span = (self.settings.compiler.get_safe("cppstd") + and valid_min_cppstd(self, 20)) + def requirements(self): - if not self.options.with_cxx20_span: + if not self.options.get_safe("with_cxx20_span") or Version(self.version) == "1.0": self.requires("ms-gsl/4.0.0", transitive_headers=True) if self.settings.os == "Linux" and Version(self.version) <= "1.0": self.requires("util-linux-libuuid/2.39", transitive_headers=True, transitive_libs=True) @@ -81,15 +74,10 @@ def validate(self): def source(self): get(self, **self.conan_data["sources"][self.version], strip_root=True) + apply_conandata_patches(self) def build(self): - uuid_h_file = os.path.join(self.build_folder, "..", "include", "uuid.h") - if self.options.with_cxx20_span: - replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if 1") - replace_in_file(self, uuid_h_file, "#ifdef __cpp_lib_span", "#if 1") - else: - replace_in_file(self, uuid_h_file, "#ifdef LIBUUID_CPP20_OR_GREATER", "#if 0") - replace_in_file(self, uuid_h_file, "#ifdef __cpp_lib_span", "#if 0") + pass def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) @@ -98,3 +86,5 @@ def package(self): def package_info(self): self.cpp_info.bindirs = [] self.cpp_info.libdirs = [] + if self.options.get_safe("with_cxx20_span"): + self.cpp_info.defines = ["LIBUUID_CPP20_OR_GREATER"] diff --git a/recipes/stduuid/all/patches/1.2.2-handle-span-header.patch b/recipes/stduuid/all/patches/1.2.2-handle-span-header.patch new file mode 100644 index 0000000000000..840c78174c772 --- /dev/null +++ b/recipes/stduuid/all/patches/1.2.2-handle-span-header.patch @@ -0,0 +1,26 @@ +diff --git a/include/uuid.h b/include/uuid.h +index 600846f..5f00a49 100644 +--- a/include/uuid.h ++++ b/include/uuid.h +@@ -15,7 +15,11 @@ + #include + #include + #include +-#include ++#if defined(LIBUUID_CPP20_OR_GREATER) ++# include ++#else ++# include ++#endif + + #ifdef _WIN32 + +@@ -51,7 +55,7 @@ + + namespace uuids + { +-#ifdef __cpp_lib_span ++#if defined(LIBUUID_CPP20_OR_GREATER) + template + using span = std::span; + #else diff --git a/recipes/stduuid/all/patches/1.2.3-handle-span-header.patch b/recipes/stduuid/all/patches/1.2.3-handle-span-header.patch new file mode 100644 index 0000000000000..fae5f65b66c25 --- /dev/null +++ b/recipes/stduuid/all/patches/1.2.3-handle-span-header.patch @@ -0,0 +1,29 @@ +diff --git a/include/uuid.h b/include/uuid.h +index d48059d..4d14e4d 100644 +--- a/include/uuid.h ++++ b/include/uuid.h +@@ -17,15 +17,6 @@ + #include + #include + +-#ifdef __cplusplus +- +-# if (__cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) +-# define LIBUUID_CPP20_OR_GREATER +-# endif +- +-#endif +- +- + #ifdef LIBUUID_CPP20_OR_GREATER + #include + #else +@@ -66,7 +57,7 @@ + + namespace uuids + { +-#ifdef __cpp_lib_span ++#if defined(LIBUUID_CPP20_OR_GREATER) + template + using span = std::span; + #else From 6f743c61afc48424e66dd1b1927658ada61f1898 Mon Sep 17 00:00:00 2001 From: Luis Caro Campos <3535649+jcar87@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:09:20 +0100 Subject: [PATCH 4/5] Add src folder to layout --- recipes/stduuid/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py index 54735b09223c5..d9fed27c59802 100644 --- a/recipes/stduuid/all/conanfile.py +++ b/recipes/stduuid/all/conanfile.py @@ -41,7 +41,7 @@ def export_sources(self): export_conandata_patches(self) def layout(self): - basic_layout(self) + basic_layout(self, src_folder="src") def config_options(self): if Version(self.version) == "1.0": From cfb173e5292123d49cc904954db7f4917715ebe7 Mon Sep 17 00:00:00 2001 From: Luis Caro Campos <3535649+jcar87@users.noreply.github.com> Date: Tue, 10 Oct 2023 18:58:25 +0100 Subject: [PATCH 5/5] Fix for Conan 1.x --- recipes/stduuid/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py index d9fed27c59802..740dfa380f1ad 100644 --- a/recipes/stduuid/all/conanfile.py +++ b/recipes/stduuid/all/conanfile.py @@ -50,7 +50,7 @@ def config_options(self): else: # Conditionally set the default value of with_cxx20_span # if cppstd is set and is 20 or greater - self.options.with_cxx20_span = (self.settings.compiler.get_safe("cppstd") + self.options.with_cxx20_span = (self.settings.compiler.get_safe("cppstd", False) and valid_min_cppstd(self, 20)) def requirements(self):