Repository: conan-io/conan-center-index

Issue:
[request] botan/2.19.3 - Upgrade conanfile to 2.x format
### Package Name/Version

botan/2.19.3

### Changelog

.

### Context about the new update

The recipe for botan v2.19.3 already exists, however we use it at work and since moving to 2.x is underway, we may soon have the need for an updated recipe.
I am available to perform the operation.
[package] botan/2.19.3 Unknown -fPIC flag
### Description

Build botan with MSVC. I am using Visual Studio 2017 x64 toolchain. The build log warns about an unknown `-fPIC`.

```
cl   /EHs /GR /D_WIN32_WINNT=0x0600 /MD /bigobj   /O2 /Oi -fPIC -DBOTAN_IS_BEING_BUILT /W4 /wd4250 /wd4251 /wd4275 /wd4127  /Ibuild\include /Ibuild\include\external /nologo /c botan_all.cpp /Fobuild\obj\lib\botan_all.obj
cl : Command line warning D9002 : ignoring unknown option '-fPIC'
```

### Package and Environment Details

* Package Name/Version: **botan/2.19.3**
* Operating System+version: **Windows 10**
* Compiler+version: **MSVC 19.16.27048**
* Conan version: **conan 1.54.0**
* Python version: **Python 3.10.8**


### Conan profile

[settings]
arch=x86_64
arch_build=x86_64
build_type=MinSizeRel
compiler=Visual Studio
compiler.runtime=MD
compiler.toolset=v141
compiler.version=15
os=Windows
os_build=Windows
[options]
[build_requires]
[env]

### Steps to reproduce

Just `conan install` on a conanfile.py containing botan

### Logs

<details><summary>Click to expand log</summary>

```
botan/2.19.3: Copying sources to build folder
botan/2.19.3: Building your package in C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\build\e7993c7f0c660b49f544baf0c45805ef3bdd797d
botan/2.19.3: Generator txt created conanbuildinfo.txt
botan/2.19.3: Aggregating env generators
botan/2.19.3: Calling build()
   INFO: ./configure.py invoked with options "--build-targets=static --distribution-info=Conan --without-documentation --cc-abi-flags=  --extra-cxxflags=-fPIC --cc=msvc --cpu=x86_64 --prefix=C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\package\e7993c7f0c660b49f544baf0c45805ef3bdd797d --os=windows --amalgamation --msvc-runtime=MD --without-pkg-config"
   INFO: Configuring to build Botan 2.19.3 (revision unknown)
   INFO: Running under 3.10.8 (tags/v3.10.8:aaaf517, Oct 11 2022, 16:50:30) [MSC v.1933 64 bit (AMD64)]
   INFO: Autodetected platform information: OS="Windows" machine="AMD64" proc="Intel64 Family 6 Model 158 Stepping 13, GenuineIntel"
   INFO: Auto-detected compiler version 19.16
   INFO: Auto-detected compiler arch x86_64
   INFO: Target is msvc:19.16-windows-x86_64
   INFO: Assuming target x86_64 is little endian
   INFO: Skipping (dependency failure): asio certstor_sqlite3 sessions_sqlite3
   INFO: Skipping (incompatible CPU): aes_armv8 aes_power8 sha1_armv8 sha2_32_armv8 sm4_armv8
   INFO: Skipping (incompatible OS): certstor_system_macos commoncrypto dev_random fd_unix getentropy proc_walk
   INFO: Skipping (incompatible compiler): argon2_ssse3 serpent_avx2 sha2_32_bmi2 sha2_64_bmi2 sha3_bmi2
   INFO: Skipping (no enabled compression schemes): compression
   INFO: Skipping (requires external dependency): boost bzip2 lzma sqlite3 tpm zlib
   INFO: Loading modules: adler32 aead aes aes_ni aes_vperm aont argon2 aria asn1 auto_rng base base32 base58 base64 bcrypt bcrypt_pbkdf bigint blake2 block blowfish camellia cascade cast128 cast256 cbc cbc_mac ccm cecpq1 certstor_flatfile certstor_sql certstor_system certstor_system_windows cfb chacha chacha20poly1305 chacha_avx2 chacha_rng chacha_simd32 checksum cmac comb4p cpuid crc24 crc32 cryptobox ctr curve25519 des dh dl_algo dl_group dlies dsa dyn_load eax ec_group ecc_key ecdh ecdsa ecgdsa ecies eckcdsa ed25519 elgamal eme_oaep eme_pkcs1 eme_raw emsa1 emsa_pkcs1 emsa_pssr emsa_raw emsa_x931 entropy ffi filters fpe_fe1 gcm ghash ghash_cpu ghash_vperm gmac gost_28147 gost_3410 gost_3411 hash hash_id hex hkdf hmac hmac_drbg hotp http_util idea idea_sse2 iso9796 kasumi kdf kdf1 kdf1_iso18033 kdf2 keccak keypair lion locking_allocator mac mce mceies md4 md5 mdx_hash mem_pool mgf1 misty1 mode_pad modes mp newhope nist_keywrap noekeon noekeon_simd numbertheory ocb ofb par_hash passhash9 pbes2 pbkdf pbkdf1 pbkdf2 pem pgp_s2k pk_pad pkcs11 poly1305 poly_dbl prf_tls prf_x942 processor_rng psk_db pubkey rc4 rdrand_rng rdseed rfc3394 rfc6979 rmd160 rng roughtime rsa salsa20 scrypt seed serpent serpent_simd sessions_sql sha1 sha1_sse2 sha1_x86 sha2_32 sha2_32_x86 sha2_64 sha3 shacal2 shacal2_avx2 shacal2_simd shacal2_x86 shake shake_cipher simd simd_avx2 siphash siv skein sm2 sm3 sm4 socket sodium sp800_108 sp800_56a sp800_56c srp6 stateful_rng stream streebog system_rng thread_utils threefish_512 threefish_512_avx2 tiger tls tls_10 tls_cbc tss twofish utils uuid whirlpool win32_stats x509 x919_mac xmss xtea xts zfec zfec_sse2 zfec_vperm
   INFO: Using hardlink to link files into build dir (use --link-method to change)
   INFO: Writing amalgamation header to botan_all.h
   INFO: Writing amalgamation source to botan_all.cpp
   INFO: Botan 2.19.3 (revision unknown) (unreleased undated) build setup is complete
Conan:vcvars already set 

Microsoft (R) Program Maintenance Utility Version 14.16.27048.0
Copyright (C) Microsoft Corporation.  All rights reserved.

	cl   /EHs /GR /D_WIN32_WINNT=0x0600 /MD /bigobj   /O2 /Oi -fPIC -DBOTAN_IS_BEING_BUILT /W4 /wd4250 /wd4251 /wd4275 /wd4127  /Ibuild\include /Ibuild\include\external /nologo /c botan_all.cpp /Fobuild\obj\lib\botan_all.obj
cl : Command line warning D9002 : ignoring unknown option '-fPIC'
botan_all.cpp
botan_all.cpp(100497): warning C4101: 'ex': unreferenced local variable
	lib /nologo /OUT:./botan.lib build\obj\lib\botan_all.obj
botan/2.19.3: Package 'e7993c7f0c660b49f544baf0c45805ef3bdd797d' built
botan/2.19.3: Build folder C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\build\e7993c7f0c660b49f544baf0c45805ef3bdd797d
botan/2.19.3: Generated conaninfo.txt
botan/2.19.3: Generated conanbuildinfo.txt
botan/2.19.3: Generating the package
botan/2.19.3: Package folder C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\package\e7993c7f0c660b49f544baf0c45805ef3bdd797d
botan/2.19.3: Calling package()
Conan:vcvars already set 

Microsoft (R) Program Maintenance Utility Version 14.16.27048.0
Copyright (C) Microsoft Corporation.  All rights reserved.

	"C:\Python\Python310\python.exe" "src/scripts/install.py" --prefix="C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\package\e7993c7f0c660b49f544baf0c45805ef3bdd797d" --build-dir="build" --bindir="C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\package\e7993c7f0c660b49f544baf0c45805ef3bdd797d\bin" --libdir="C:\Source\conan-pkgs\.conan\data\botan\2.19.3\_\_\package\e7993c7f0c660b49f544baf0c45805ef3bdd797d\lib" --docdir="docs" --includedir="include"
   INFO: Botan 2.19.3 installation complete
botan/2.19.3 package(): Packaged 308 '.h' files
botan/2.19.3 package(): Packaged 1 '.lib' file: botan.lib
botan/2.19.3 package(): Packaged 1 '.txt' file: license.txt
botan/2.19.3: Package 'e7993c7f0c660b49f544baf0c45805ef3bdd797d' created
botan/2.19.3: Created package revision 5241133ec1aef36217537ff75224b4a6
```

</details>



Discussion:
Feel free to do so if possible, we'd really appreciate it yes :)
Edit : Will update to Botan 3.0.0, 2.19.3 will be left untouched and 3.0.0 will be added instead, using 2.x format


Resolving patch:
diff --git a/recipes/botan/all/conanfile.py b/recipes/botan/all/conanfile.py
--- a/recipes/botan/all/conanfile.py
+++ b/recipes/botan/all/conanfile.py
@@ -1,9 +1,21 @@
-from conan.tools.microsoft import is_msvc, msvc_runtime_flag
-from conans import ConanFile, tools
-from conans.errors import ConanInvalidConfiguration
 import os
+import shutil
+import platform
 
-required_conan_version = ">=1.45.0"
+from conan import ConanFile
+from conan.errors import ConanInvalidConfiguration
+from conan.tools.apple import is_apple_os, fix_apple_shared_install_name, XCRun
+from conan.tools.build import build_jobs, check_min_cppstd
+from conan.tools.env import VirtualBuildEnv
+from conan.tools.files import apply_conandata_patches, chdir, copy, export_conandata_patches, get
+from conan.tools.gnu import AutotoolsToolchain
+from conan.tools.layout import basic_layout
+from conan.tools.microsoft import is_msvc, msvc_runtime_flag, VCVars, check_min_vs
+from conan.tools.microsoft import unix_path
+from conan.tools.scm import Version
+
+
+required_conan_version = ">=1.55"
 
 
 class BotanConan(ConanFile):
@@ -11,9 +23,10 @@ class BotanConan(ConanFile):
     url = "https://github.com/conan-io/conan-center-index"
     homepage = "https://github.com/randombit/botan"
     license = "BSD-2-Clause"
-    description = "Botan is a cryptography library written in C++11."
-    topics = ("cryptography", "crypto", "C++11", "tls")
+    description = "Botan is a cryptography library written in modern C++."
+    topics = ("cryptography", "crypto", "c++11", "c++20", "tls")
 
+    package_type = "library"
     settings = "os", "arch", "compiler", "build_type"
     options = {
         "shared": [True, False],
@@ -39,8 +52,9 @@ class BotanConan(ConanFile):
         "with_neon": [True, False],
         "with_armv8crypto": [True, False],
         "with_powercrypto": [True, False],
-        "enable_modules": "ANY",
-        "system_cert_bundle": "ANY",
+        "enable_modules": [None, "ANY"],
+        "disable_modules": [None, "ANY"],
+        "system_cert_bundle": [None, "ANY"],
         "module_policy": [None, "bsi", "modern", "nist"],
     }
     default_options = {
@@ -68,10 +82,13 @@ class BotanConan(ConanFile):
         "with_armv8crypto": True,
         "with_powercrypto": True,
         "enable_modules": None,
+        "disable_modules": None,
         "system_cert_bundle": None,
         "module_policy": None,
     }
 
+    _extra_cxxflags = None
+
     @property
     def _is_x86(self):
         return str(self.settings.arch) in ['x86', 'x86_64']
@@ -84,14 +101,8 @@ def _is_ppc(self):
     def _is_arm(self):
         return 'arm' in str(self.settings.arch)
 
-    @property
-    def _source_subfolder(self):
-        # Required to build at least 2.12.1
-        return "sources"
-
     def export_sources(self):
-        for patch in self.conan_data.get("patches", {}).get(self.version, []):
-            self.copy(patch["patch_file"])
+        export_conandata_patches(self)
 
     def config_options(self):
         if self.settings.os == 'Windows':
@@ -117,84 +128,149 @@ def config_options(self):
 
         # --single-amalgamation option is no longer available
         # See also https://github.com/randombit/botan/pull/2246
-        if tools.Version(self.version) >= '2.14.0':
+        if Version(self.version) >= '2.14.0':
             del self.options.single_amalgamation
 
+        # Support for the OpenSSL provider was removed in 2.19.2
+        if Version(self.version) >= '2.19.2':
+            del self.options.with_openssl
+
     def configure(self):
         if self.options.shared:
-            del self.options.fPIC
+            self.options.rm_safe("fPIC")
 
     def requirements(self):
         if self.options.with_bzip2:
             self.requires("bzip2/1.0.8")
-        if self.options.with_openssl:
-            self.requires("openssl/1.1.1o")
+        if self.options.get_safe('with_openssl', False):
+            self.requires("openssl/[>=1.1 <3]")
         if self.options.with_zlib:
-            self.requires("zlib/1.2.12")
+            self.requires("zlib/[>=1.2.11 <2]")
         if self.options.with_sqlite3:
             self.requires("sqlite3/3.38.5")
         if self.options.with_boost:
-            self.requires("boost/1.79.0")
+            self.requires("boost/1.83.0")
 
     @property
     def _required_boost_components(self):
         return ['coroutine', 'system']
 
+    @property
+    def _min_cppstd(self):
+        # From the same links as below
+        return 11 if Version(self.version) < "3.0.0" else 20
+
+    @property
+    def _compilers_minimum_version(self):
+        if Version(self.version).major < 3:
+            # From https://github.com/randombit/botan/blob/2.19.3/doc/support.rst
+            return {
+                "gcc": "4.8",
+                "clang": "3.5",
+                "Visual Studio": "14",
+                "msvc": "190",
+            }
+        else:
+            # From https://github.com/randombit/botan/blob/master/doc/support.rst
+            return {
+                "gcc":  "11.2",
+                "clang": "14",
+                "apple-clang": "14",
+                "Visual Studio": "17",
+                "msvc": "193",
+            }
+
     def validate(self):
         if self.options.with_boost:
-            miss_boost_required_comp = any(getattr(self.options['boost'], 'without_{}'.format(boost_comp), True) for boost_comp in self._required_boost_components)
-            if self.options['boost'].header_only or self.options['boost'].shared or self.options['boost'].magic_autolink or miss_boost_required_comp:
-                raise ConanInvalidConfiguration('{0} requires non-header-only static boost, without magic_autolink, and with these components: {1}'.format(self.name, ', '.join(self._required_boost_components)))
+            boost_opts = self.dependencies['boost'].options
+            miss_boost_required_comp = any(getattr(boost_opts, 'without_{}'.format(boost_comp), True) for boost_comp in self._required_boost_components)
+            if boost_opts.header_only or boost_opts.shared or boost_opts.magic_autolink or miss_boost_required_comp:
+                raise ConanInvalidConfiguration(
+                    f"{self.name} requires non-header-only static boost, "
+                    f"without magic_autolink, and with these components: {', '.join(self._required_boost_components)}")
+        if self.settings.get_safe("compiler.cppstd"):
+            check_min_cppstd(self, self._min_cppstd)
 
         compiler = self.settings.compiler
-        version = tools.Version(self.settings.compiler.version)
+        compiler_name = str(compiler)
+        compiler_version = Version(compiler.version)
 
-        if compiler == 'Visual Studio' and version < '14':
-            raise ConanInvalidConfiguration("Botan doesn't support MSVC < 14")
+        check_min_vs(self, self._compilers_minimum_version["msvc"])
+        if not is_msvc(self):
+            minimum_version = self._compilers_minimum_version.get(compiler_name, 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 does not support."
+                )
+            if not minimum_version:
+                self.output.warning(f"{self.name} recipe lacks information about the {compiler_name} compiler support.")
 
-        elif compiler == 'gcc' and version >= '5' and compiler.libcxx != 'libstdc++11':
+        if self.settings.compiler == 'gcc' and compiler_version >= "5" and self.settings.compiler.libcxx != 'libstdc++11':
             raise ConanInvalidConfiguration(
                 'Using Botan with GCC >= 5 on Linux requires "compiler.libcxx=libstdc++11"')
 
-        elif compiler == 'clang' and compiler.libcxx not in ['libstdc++11', 'libc++']:
+        if self.settings.compiler == 'clang' and self.settings.compiler.libcxx not in ['libstdc++11', 'libc++']:
             raise ConanInvalidConfiguration(
                 'Using Botan with Clang on Linux requires either "compiler.libcxx=libstdc++11" ' \
                 'or "compiler.libcxx=libc++"')
 
         # Some older compilers cannot handle the amalgamated build anymore
         # See also https://github.com/randombit/botan/issues/2328
-        if tools.Version(self.version) >= '2.14.0' and self.options.amalgamation:
-            if (compiler == 'apple-clang' and version < '10') or \
-               (compiler == 'gcc' and version < '8') or \
-               (compiler == 'clang' and version < '7'):
+        if Version(self.version) >= '2.14.0' and self.options.amalgamation:
+            if (self.settings.compiler == 'apple-clang' and compiler_version < '10') or \
+               (self.settings.compiler == 'gcc' and compiler_version < '8') or \
+               (self.settings.compiler == 'clang' and compiler_version < '7'):
                 raise ConanInvalidConfiguration(
-                    'botan amalgamation is not supported for {}/{}'.format(compiler, version))
+                    f"botan amalgamation is not supported for {compiler}/{compiler_version}")
 
         if self.options.get_safe("single_amalgamation", False) and not self.options.amalgamation:
             raise ConanInvalidConfiguration("botan:single_amalgamation=True requires botan:amalgamation=True")
 
+    def layout(self):
+        basic_layout(self, src_folder="src")
+
     def source(self):
-        tools.get(**self.conan_data['sources'][self.version], strip_root=True, destination=self._source_subfolder)
+        get(self, **self.conan_data["sources"][self.version], strip_root=True)
+
+    @property
+    def _cxxflags(self):
+        global_cxxflags = " ".join(self.conf.get("tools.build:cxxflags", default=[], check_type=list))
+        env_cxxflags = VirtualBuildEnv(self).vars().get("CXXFLAGS", default="")
+        cxxflags = f"{env_cxxflags} {global_cxxflags}".strip()
+        return cxxflags if len(cxxflags) > 1 else None
+
+    def generate(self):
+        if is_msvc(self):
+            ms = VCVars(self)
+            ms.generate()
+
+        # This is to work around botan's configure script that *replaces* its
+        # standard (platform dependent) flags in presence of an environment
+        # variable ${CXXFLAGS}. Most notably, this would build botan with
+        # disabled compiler optimizations.
+        self._extra_cxxflags = self._cxxflags
+        self.buildenv.unset('CXXFLAGS')
+        VirtualBuildEnv(self).generate()
 
     def build(self):
-        for patch in self.conan_data.get('patches', {}).get(self.version, []):
-            tools.patch(**patch)
-        with tools.chdir(self._source_subfolder):
+        apply_conandata_patches(self)
+        with chdir(self, self.source_folder):
             self.run(self._configure_cmd)
             self.run(self._make_cmd)
 
     def package(self):
-        self.copy(pattern='license.txt', dst='licenses', src=self._source_subfolder)
-        with tools.chdir(self._source_subfolder):
+        copy(self, "license.txt", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
+        with chdir(self, self.source_folder):
+            # Note: this will fail to properly consider the package_folder if a "conan build" followed by a "conan export-pkg" is executed
             self.run(self._make_install_cmd)
+        fix_apple_shared_install_name(self)
 
     def package_info(self):
-        major_version = tools.Version(self.version).major
+        major_version = Version(self.version).major
         self.cpp_info.set_property("pkg_config_name", f"botan-{major_version}")
-        self.cpp_info.names["pkg_config"] = f"botan-{major_version}"
-        self.cpp_info.libs = ["botan" if is_msvc(self) else f"botan-{major_version}"]
+        self.cpp_info.libs = ["botan" if is_msvc(self) and major_version < 3 else f"botan-{major_version}"]
         if self.settings.os == 'Linux':
-            self.cpp_info.system_libs.extend(['dl', 'rt', 'pthread'])
+            self.cpp_info.system_libs.extend(['dl', 'rt', 'pthread', 'm'])
         if self.settings.os == 'Macos':
             self.cpp_info.frameworks = ['Security', 'CoreFoundation']
         if self.settings.os == 'Windows':
@@ -220,10 +296,10 @@ def _botan_os(self):
     def _dependency_build_flags(self, dependency):
         # Since botan has a custom build system, we need to specifically inject
         # these build parameters so that it picks up the correct dependencies.
-        dep_cpp_info = self.deps_cpp_info[dependency]
+        dep_cpp_info = self.dependencies[dependency].cpp_info
         return \
-            ['--with-external-includedir={}'.format(include_path) for include_path in dep_cpp_info.include_paths] + \
-            ['--with-external-libdir={}'.format(lib_path) for lib_path in dep_cpp_info.lib_paths] + \
+            ['--with-external-includedir={}'.format(include_path) for include_path in dep_cpp_info.includedirs] + \
+            ['--with-external-libdir={}'.format(lib_path) for lib_path in dep_cpp_info.libdirs] + \
             ['--define-build-macro={}'.format(define) for define in dep_cpp_info.defines]
 
     @property
@@ -256,34 +332,27 @@ def _configure_cmd(self):
             elif self.settings.arch in ['x86_64']:
                 botan_abi_flags.append('-arch x86_64')
 
-        if self.options.get_safe('fPIC', True):
+        if self.options.get_safe('fPIC', True) and not is_msvc(self):
             botan_extra_cxx_flags.append('-fPIC')
 
-        if tools.is_apple_os(self.settings.os):
+        if is_apple_os(self):
             if self.settings.get_safe('os.version'):
                 # Required, see https://github.com/conan-io/conan-center-index/pull/3456
-                macos_min_version = tools.apple_deployment_target_flag(self.settings.os,
-                                                                       self.settings.get_safe('os.version'),
-                                                                       self.settings.get_safe('os.sdk'),
-                                                                       self.settings.get_safe('os.subsystem'),
-                                                                       self.settings.get_safe('arch'))
+                macos_min_version = macos_min_version = AutotoolsToolchain(self).apple_min_version_flag
                 botan_extra_cxx_flags.append(macos_min_version)
-            macos_sdk_path = '-isysroot {}'.format(tools.XCRun(self.settings).sdk_path)
+            macos_sdk_path = '-isysroot {}'.format(XCRun(self).sdk_path)
             botan_extra_cxx_flags.append(macos_sdk_path)
 
-        # This is to work around botan's configure script that *replaces* its
-        # standard (platform dependent) flags in presence of an environment
-        # variable ${CXXFLAGS}. Most notably, this would build botan with
-        # disabled compiler optimizations.
-        environment_cxxflags = tools.get_env('CXXFLAGS')
-        if environment_cxxflags:
-            del os.environ['CXXFLAGS']
-            botan_extra_cxx_flags.append(environment_cxxflags)
+        if self._extra_cxxflags:
+            botan_extra_cxx_flags.append(self._extra_cxxflags)
 
         if self.options.enable_modules:
             build_flags.append('--minimized-build')
             build_flags.append('--enable-modules={}'.format(self.options.enable_modules))
 
+        if self.options.disable_modules:
+            build_flags.append('--disable-modules={}'.format(self.options.disable_modules))
+
         if self.options.amalgamation:
             build_flags.append('--amalgamation')
 
@@ -293,11 +362,14 @@ def _configure_cmd(self):
         if self.options.system_cert_bundle:
             build_flags.append('--system-cert-bundle={}'.format(self.options.system_cert_bundle))
 
+        if self.conf.get("tools.build:sysroot"):
+            build_flags.append(f'--with-sysroot-dir={self.conf.get("tools.build:sysroot")}')
+
         if self.options.with_bzip2:
             build_flags.append('--with-bzip2')
             build_flags.extend(self._dependency_build_flags('bzip2'))
 
-        if self.options.with_openssl:
+        if self.options.get_safe('with_openssl', False):
             build_flags.append('--with-openssl')
             build_flags.extend(self._dependency_build_flags('openssl'))
 
@@ -375,11 +447,17 @@ def _configure_cmd(self):
         if is_msvc(self):
             build_flags.append(f"--msvc-runtime={msvc_runtime_flag(self)}")
 
+        if self._is_glibc_older_than_2_25_on_linux and Version(self.version) >= '3.0':
+            # INFO: Botan 3.0+ requires glibc >= 2.25. Disable features to make it backward compatible
+            # FIXME: CCI Docker images are running Ubuntu 16.04. Remove it after supporting later version.
+            self.output.warning("Disabling usage of getentropy(), getrandom(), and explicit_bzero() due to old glibc version")
+            build_flags.append('--without-os-features=getentropy,getrandom,explicit_bzero')
+
         build_flags.append('--without-pkg-config')
 
         call_python = 'python' if self.settings.os == 'Windows' else ''
 
-        prefix = tools.unix_path(self.package_folder) if self._is_mingw_windows else self.package_folder
+        prefix = unix_path(self, self.package_folder) if self._is_mingw_windows else self.package_folder
 
         botan_abi = ' '.join(botan_abi_flags) if botan_abi_flags else ' '
         botan_cxx_extras = ' '.join(botan_extra_cxx_flags) if botan_extra_cxx_flags else ' '
@@ -413,27 +491,23 @@ def _make_cmd(self):
 
     @property
     def _make_program(self):
-        return tools.get_env('CONAN_MAKE_PROGRAM', tools.which('make') or tools.which('mingw32-make'))
+        return self.conf.get("tools.gnu:make_program", os.getenv('CONAN_MAKE_PROGRAM', shutil.which('make') or shutil.which('mingw32-make')))
 
     @property
     def _gnumake_cmd(self):
         make_ldflags = 'LDFLAGS=-lc++abi' if self._is_linux_clang_libcxx else ''
 
-        make_cmd = ('{ldflags}' ' {make}' ' -j{cpucount}').format(
-                        ldflags=make_ldflags, make=self._make_program, cpucount=tools.cpu_count())
+        make_cmd = f"{make_ldflags} {self._make_program} -j{build_jobs(self)}"
         return make_cmd
 
     @property
     def _nmake_cmd(self):
-        vcvars = tools.vcvars_command(self.settings)
-        make_cmd = vcvars + ' && nmake'
-        return make_cmd
+        return 'nmake'
 
     @property
     def _make_install_cmd(self):
         if is_msvc(self):
-            vcvars = tools.vcvars_command(self.settings)
-            make_install_cmd = vcvars + ' && nmake install'
+            make_install_cmd = '{make} install'.format(make=self._nmake_cmd)
         else:
             make_install_cmd = '{make} install'.format(make=self._make_program)
         return make_install_cmd
@@ -445,3 +519,19 @@ def _is_linux_clang_libcxx(self):
             self.settings.compiler == 'clang' and
             self.settings.compiler.libcxx == 'libc++'
         )
+
+    @property
+    def _is_glibc_older_than_2_25_on_linux(self):
+        # FIXME: glibc below 2.25 lacks support for certain syscalls that botan assumes
+        # to be present. Once CCI updated their CI images and provides a newer
+        # glibc, we can (and should) remove this workaround.
+        #
+        # https://github.com/conan-io/conan-center-index/pull/18079#issuecomment-1919206949
+        # https://github.com/conan-io/conan-center-index/pull/18079#issuecomment-1919486839
+
+        libver = platform.libc_ver()
+        return (
+            self.settings.os == 'Linux' and
+            libver[0] == 'glibc' and
+            Version(libver[1]) < '2.25'
+        )


Test patch:
diff --git a/recipes/botan/all/test_package/CMakeLists.txt b/recipes/botan/all/test_package/CMakeLists.txt
--- a/recipes/botan/all/test_package/CMakeLists.txt
+++ b/recipes/botan/all/test_package/CMakeLists.txt
@@ -1,11 +1,13 @@
-cmake_minimum_required(VERSION 3.1)
-project(test_package)
+cmake_minimum_required(VERSION 3.15)
 
-include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
-conan_basic_setup(TARGETS)
+project(test_package CXX)
 
 find_package(botan REQUIRED CONFIG)
 
 add_executable(${PROJECT_NAME} test_package.cpp)
 target_link_libraries(${PROJECT_NAME} botan::botan)
-set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
+if(botan_VERSION_STRING VERSION_LESS "3.0.0")
+    target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
+else()
+    target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
+endif()
diff --git a/recipes/botan/all/test_package/conanfile.py b/recipes/botan/all/test_package/conanfile.py
--- a/recipes/botan/all/test_package/conanfile.py
+++ b/recipes/botan/all/test_package/conanfile.py
@@ -1,10 +1,25 @@
-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
+from conan.tools.microsoft import is_msvc, VCVars
 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 generate(self):
+        if is_msvc(self):
+            ms = VCVars(self)
+            ms.generate()
 
     def build(self):
         cmake = CMake(self)
@@ -12,6 +27,6 @@ def build(self):
         cmake.build()
 
     def test(self):
-        if not tools.cross_building(self, skip_x64_x86=True):
-            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.build_folder, self.cpp.build.bindirs[0], "test_package")
+            self.run(bin_path, env="conanrun")
diff --git a/recipes/botan/all/test_v1_package/CMakeLists.txt b/recipes/botan/all/test_v1_package/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/recipes/botan/all/test_v1_package/CMakeLists.txt
@@ -0,0 +1,15 @@
+cmake_minimum_required(VERSION 3.1)
+project(test_package)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup(TARGETS)
+
+find_package(botan REQUIRED CONFIG)
+
+add_executable(${PROJECT_NAME} test_package.cpp)
+target_link_libraries(${PROJECT_NAME} botan::botan)
+if(botan_VERSION_STRING VERSION_LESS "3.0.0")
+    target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
+else()
+    target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
+endif()
diff --git a/recipes/botan/all/test_v1_package/conanfile.py b/recipes/botan/all/test_v1_package/conanfile.py
new file mode 100644
--- /dev/null
+++ b/recipes/botan/all/test_v1_package/conanfile.py
@@ -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, skip_x64_x86=True):
+            bin_path = os.path.join("bin", "test_package")
+            self.run(bin_path, run_environment=True)
diff --git a/recipes/botan/all/test_v1_package/test_package.cpp b/recipes/botan/all/test_v1_package/test_package.cpp
new file mode 100644
--- /dev/null
+++ b/recipes/botan/all/test_v1_package/test_package.cpp
@@ -0,0 +1,7 @@
+#include <botan/hex.h>
+
+int main()
+{
+    std::vector<uint8_t> key = Botan::hex_decode("000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F");
+    return 0;
+}