Repository: conan-io/conan-center-index

Issue:
[package] stduuid: Under default config, breaks any time std::span is used
### Description

With a basic project that uses `stduuid` (I believe any version, though I only tested the latest), trying to use `std::span` breaks the build.

Cause: When the option `with_cxx20_span` is set to False (which is the default), the package appends ms-gsl's include folder in such a way that <span> resolves to ms-gsl's span, instead of std. Thus any use of std::span does not work, as it is never included.

Possible fix: can set the option to True as a temporary workaround, but ultimately this needs to be fixed in the package. Perhaps we can give 3 options instead:
1. Force use of std::span (requires changes to the source)
2. Force use of gsl::span (requires changes to the source)
3. Autodetect (based on C++ version, C++20 and up uses std, otherwise use gsl) (This should be the default, as it is how stduuid works normally)

(@jcar87 FYI, issue I described earlier)

### Package and Environment Details

* Package Name/Version: **stduuid/(probably) all**
* Operating System+version: **Windows 10 (probably others)**
* Compiler+version: **VS2019 + VS2022**
* Conan version: **conan 1.61.0, conan 2.0.13**
* Python version: **Python 3.9.6**


### Conan profile

(Visual Studio 2022 profile)
[settings]
os=Windows
os_build=Windows
arch=x86_64
arch_build=x86_64
compiler=Visual Studio
compiler.version=17
build_type=Release
[options]
[conf]
tools.cmake.cmaketoolchain:generator=Ninja
[build_requires]
[env]

### Steps to reproduce

```
# conanfile.txt
[requires]
stduuid/1.2.3

[generators]
CMakeDeps
CMakeToolchain

[layout]
cmake_layout
```
```cmake
# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)
project(spantest)
find_package(stduuid REQUIRED)

add_executable(test test.cpp)
target_compile_features(test PRIVATE cxx_std_20)
target_link_libraries(test PRIVATE stduuid::stduuid)
```
```c++
// test.cpp
#include <span>

int main() {
    std::span<int>{};
}
```
(any build method should reproduce)

### Logs

C:\Users\Alex\Documents\spantest>cmake --build --preset release
[1/2] Building CXX object CMakeFiles\test.dir\test.cpp.obj
FAILED: CMakeFiles/test.dir/test.cpp.obj
C:\PROGRA~1\MICROS~4\2022\COMMUN~1\VC\Tools\MSVC\1437~1.328\bin\Hostx86\x86\cl.exe  /nologo /TP  -external:IC:\Users\Alex\.conan\data\stduuid\1.2.3\_\_\package\5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9\include -external:IC:\Users\Alex\.conan\data\ms-gsl\3.1.0\_\_\package\5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9\include\gsl -external:IC:\Users\Alex\.conan\data\ms-gsl\3.1.0\_\_\package\5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9\include -external:W0 /DWIN32 /D_WINDOWS /GR /EHsc /O2 /Ob2 /DNDEBUG -std:c++20 -MD /showIncludes /FoCMakeFiles\test.dir\test.cpp.obj /FdCMakeFiles\test.dir\ /FS -c C:\Users\Alex\Documents\spantest\test.cpp
C:\Users\Alex\Documents\spantest\test.cpp(4): error C2039: 'span': is not a member of 'std'
C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.37.32822\include\iterator(21): note: see declaration of 'std'
C:\Users\Alex\Documents\spantest\test.cpp(4): error C2062: type 'int' unexpected
C:\Users\Alex\Documents\spantest\test.cpp(4): error C2143: syntax error: missing ';' before '{'
ninja: build stopped: subcommand failed


Discussion:

Resolving patch:
diff --git a/recipes/stduuid/all/conanfile.py b/recipes/stduuid/all/conanfile.py
--- 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.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
@@ -18,16 +18,14 @@ 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):
-        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):
@@ -38,13 +36,26 @@ def _compilers_minimum_version(self):
             "msvc": "191",
             "Visual Studio": "15",
         }
+    
+    def export_sources(self):
+        export_conandata_patches(self)
 
     def layout(self):
         basic_layout(self, src_folder="src")
 
+    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", False)
+                                            and valid_min_cppstd(self, 20))
+
     def requirements(self):
-        if not self.options.with_cxx20_span:
-            self.requires("ms-gsl/3.1.0", transitive_headers=True)
+        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)
 
@@ -52,7 +63,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)
@@ -62,8 +73,8 @@ 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)
+        apply_conandata_patches(self)
 
     def build(self):
         pass
@@ -75,5 +86,5 @@ 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"))
+        if self.options.get_safe("with_cxx20_span"):
+            self.cpp_info.defines = ["LIBUUID_CPP20_OR_GREATER"]


Test patch: