Repository: conan-io/conan-center-index

Issue:
[package] openssl/1.1.1*: Lacks support for Conan 2.0
### Description

OpenSLL 1.1.1* fails to build with Conan 2.0

### Package and Environment Details

Package Name/Version: openssl/1.1.1s
Operating System+version: Debian 10.3
Compiler+version: GCC 8
Conan version: conan 2.0.0.0beta4
Python version: Python 3.7.3

### Conan profile


Profile host:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=8
os=Linux

Profile build:
[settings]
arch=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=gnu14
compiler.libcxx=libstdc++11
compiler.version=8
os=Linux

### Steps to reproduce

conan-2.0 create . --version 1.1.1s

### Logs

<details><summary>Click to expand log</summary>

```
conan-2.0 create . --version 1.1.1s -pr:b tools.jinja -pr:h tools.jinja
Exporting the recipe
ERROR: Error loading conanfile at '/tmp/tmp.8Oz3wKaCCB/openssl/conanfile.py': Unable to load conanfile in /tmp/tmp.8Oz3wKaCCB/openssl/conanfile.py
  File "<frozen importlib._bootstrap_external>", line 728, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/tmp/tmp.8Oz3wKaCCB/openssl/conanfile.py", line 6, in <module>
    from conans import AutoToolsBuildEnvironment, tools
ImportError: cannot import name 'AutoToolsBuildEnvironment' from 'conans' (/mathworks/devel/sandbox/marc/conan-2.0/conan-io/conans/__init__.py)
```

</details>



Discussion:
I have proposed fixes for these issues that I will submit as pull request.

Resolving patch:
diff --git a/recipes/openssl/1.x.x/conanfile.py b/recipes/openssl/1.x.x/conanfile.py
--- a/recipes/openssl/1.x.x/conanfile.py
+++ b/recipes/openssl/1.x.x/conanfile.py
@@ -1,22 +1,27 @@
-from conan import ConanFile
-from conan.errors import ConanInvalidConfiguration
+from conan import ConanFile, conan_version
+from conan.tools.env import Environment
 from conan.tools.build import cross_building
-from conan.tools.files import rename, get, rmdir
-from conan.tools.microsoft import is_msvc, msvc_runtime_flag
-from conans import AutoToolsBuildEnvironment, tools
+from conan.tools.layout import basic_layout
+from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps
+from conan.tools.microsoft import is_msvc, msvc_runtime_flag, unix_path
+from conan.tools.apple import is_apple_os, XCRun
+from conan.tools.scm import Version
+from conan.errors import ConanInvalidConfiguration
+from conan.tools.files import chdir, copy, rename, rmdir, load, save, get, apply_conandata_patches, export_conandata_patches, replace_in_file
 from contextlib import contextmanager
 from functools import total_ordering
 import fnmatch
+import json
 import os
 import textwrap
 
-required_conan_version = ">=1.47.0"
-
+required_conan_version = ">=1.53.0"
 
 @total_ordering
 class OpenSSLVersion(object):
-    def __init__(self, version_str):
+    def __init__(self, version):
         self._pre = ""
+        version_str = str(version)
 
         tokens = version_str.split("-")
         if len(tokens) > 1:
@@ -59,7 +64,7 @@ def compare(self, other):
             other = OpenSSLVersion(other)
         if self.as_list == other.as_list:
             return 0
-        elif self.as_list < other.as_list:
+        if self.as_list < other.as_list:
             return -1
         else:
             return 1
@@ -67,6 +72,7 @@ def compare(self, other):
 
 class OpenSSLConan(ConanFile):
     name = "openssl"
+    package_type = "library"
     url = "https://github.com/conan-io/conan-center-index"
     homepage = "https://github.com/openssl/openssl"
     license = "OpenSSL"
@@ -136,19 +142,13 @@ class OpenSSLConan(ConanFile):
         "no_tls1": [True, False],
         "capieng_dialog": [True, False],
         "enable_capieng": [True, False],
-        "openssldir": "ANY",
+        "openssldir": ["ANY", None]
     }
     default_options = {key: False for key in options.keys()}
     default_options["fPIC"] = True
     default_options["no_md2"] = True
     default_options["openssldir"] = None
 
-    _env_build = None
-
-    @property
-    def _source_subfolder(self):
-        return "source_subfolder"
-
     @property
     def _is_clangcl(self):
         return self.settings.compiler == "clang" and self.settings.os == "Windows"
@@ -169,15 +169,8 @@ def _settings_build(self):
     def _full_version(self):
         return OpenSSLVersion(self.version)
 
-    @property
-    def _win_bash(self):
-        return self._settings_build.os == "Windows" and \
-               not self._use_nmake and \
-               (self._is_mingw or cross_building(self, skip_x64_x86=True))
-
     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._full_version >= "1.1.0":
@@ -223,15 +216,12 @@ def config_options(self):
 
     def configure(self):
         if self.options.shared:
-            del self.options.fPIC
-        del self.settings.compiler.libcxx
-        del self.settings.compiler.cppstd
-
-    def layout(self):
-        pass
+            self.options.rm_safe("fPIC")
+        self.settings.rm_safe("compiler.libcxx")
+        self.settings.rm_safe("compiler.cppstd")
 
     def requirements(self):
-        if self._full_version < "1.1.0" and self.options.get_safe("no_zlib") == False:
+        if self._full_version < "1.1.0" and not self.options.get_safe("no_zlib"):
             self.requires("zlib/1.2.12")
 
     def validate(self):
@@ -241,17 +231,54 @@ def validate(self):
 
     def build_requirements(self):
         if self._settings_build.os == "Windows":
-            if not self._win_bash:
-                self.build_requires("strawberryperl/5.30.0.1")
-            if not self.options.no_asm and not tools.which("nasm"):
-                self.build_requires("nasm/2.15.05")
-        if self._win_bash and not tools.get_env("CONAN_BASH_PATH"):
+            if not self.win_bash:
+                self.tool_requires("strawberryperl/5.30.0.1")
+            if not self.options.no_asm:
+                self.tool_requires("nasm/2.15.05")
+        if self.win_bash and not os.getenv("CONAN_BASH_PATH") and not self._use_nmake:
             self.build_requires("msys2/cci.latest")
 
+    def layout(self):
+        basic_layout(self, src_folder="src")
+
     def source(self):
         get(self, **self.conan_data["sources"][self.version],
-            destination=self._source_subfolder, strip_root=True)
-
+            destination=self.source_folder, strip_root=True)
+
+    def generate(self):
+        tc = AutotoolsToolchain(self)
+        # workaround for random error: size too large (archive member extends past the end of the file)
+        # /Library/Developer/CommandLineTools/usr/bin/ar: internal ranlib command failed
+        if self.settings.os == "Macos" and self._full_version < "1.1.0":
+            tc.make_args = ["-j1"]
+        # 1.1.0 era Makefiles don't do well with parallel installs
+        if not self._use_nmake and self._full_version >= "1.1.0" and self._full_version < "1.1.1":
+            tc.make_args = ["-j1"]
+        if self.settings.os == "Macos" and not cross_building(self):
+            tc.extra_cflags = [f"-isysroot {XCRun(self).sdk_path}"]
+            tc.extra_cxxflags = [f"-isysroot {XCRun(self).sdk_path}"]
+            tc.extra_ldflags = [f"-isysroot {XCRun(self).sdk_path}"]
+        env = tc.environment()
+        env.define("PERL", self._perl)
+        tc.generate(env)
+        gen_info = {}
+        gen_info["CFLAGS"] = tc.cflags 
+        gen_info["CXXFLAGS"] = tc.cxxflags
+        gen_info["DEFINES"] = tc.defines
+        gen_info["LDFLAGS"] = tc.ldflags
+        # Support for self.dependencies in build() method is currently restricted to `generate()` and `validate()`
+        # See https://github.com/conan-io/conan/issues/12411 for more details 
+        if self._full_version < "1.1.0" and not self.options.get_safe("no_zlib"):
+            zlib_cpp_info = self.dependencies["zlib"].cpp_info
+            gen_info["zlib_include_path"] = zlib_cpp_info.includedirs[0]
+            if self.settings.os == "Windows":
+                gen_info["zlib_lib_path"] = f"{zlib_cpp_info.libdirs[0]}/{zlib_cpp_info.libs[0]}.lib"
+            else:
+                gen_info["zlib_lib_path"] = zlib_cpp_info.libdirs[0]  # Just path, linux will find the right file
+        save(self, "gen_info.conf", json.dumps(gen_info))
+        tc = AutotoolsDeps(self)
+        tc.generate()
+          
     @property
     def _target_prefix(self):
         if self._full_version < "1.1.0" and self.settings.build_type == "Debug":
@@ -283,7 +310,7 @@ def _perlasm_scheme(self):
                     "armv8_32": "ios64",
                     "armv8.3": "ios64",
                     "armv7k": "ios32"}.get(the_arch, None)
-        elif the_os == "Android":
+        if the_os == "Android":
             return {"armv7": "void",
                     "armv8": "linux64",
                     "mips": "o32",
@@ -447,14 +474,14 @@ def _tool(self, env_name, apple_name):
         if env_name in os.environ:
             return os.environ[env_name]
         if self.settings.compiler == "apple-clang":
-            return getattr(tools.XCRun(self.settings), apple_name)
+            return getattr(XCRun(self), apple_name)
         return None
 
     def _patch_configure(self):
         # since _patch_makefile_org will replace binutils variables
         # use a more restricted regular expresion to prevent that Configure script trying to do it again
-        configure = os.path.join(self._source_subfolder, "Configure")
-        tools.replace_in_file(configure, r"s/^AR=\s*ar/AR= $ar/;", r"s/^AR=\s*ar\b/AR= $ar/;")
+        configure = os.path.join(self.source_folder, "Configure")
+        replace_in_file(self, configure, r"s/^AR=\s*ar/AR= $ar/;", r"s/^AR=\s*ar\b/AR= $ar/;",encoding="latin_1")
 
     def _adjust_path(self, path):
         return path.replace("\\", "/") if self._settings_build.os == "Windows" else path
@@ -462,43 +489,36 @@ def _adjust_path(self, path):
     def _patch_makefile_org(self):
         # https://wiki.openssl.org/index.php/Compilation_and_Installation#Modifying_Build_Settings
         # its often easier to modify Configure and Makefile.org rather than trying to add targets to the configure scripts
-        makefile_org = os.path.join(self._source_subfolder, "Makefile.org")
-        env_build = self._get_env_build()
-        with tools.environment_append(env_build.vars):
-            if not "CROSS_COMPILE" in os.environ:
-                cc = os.environ.get("CC", "cc")
-                tools.replace_in_file(makefile_org, "CC= cc\n", "CC= %s %s\n" % (self._adjust_path(cc), os.environ["CFLAGS"]))
-                if "AR" in os.environ:
-                    tools.replace_in_file(makefile_org, "AR=ar $(ARFLAGS) r\n", "AR=%s $(ARFLAGS) r\n" % self._adjust_path(os.environ["AR"]))
-                if "RANLIB" in os.environ:
-                    tools.replace_in_file(makefile_org, "RANLIB= ranlib\n", "RANLIB= %s\n" % self._adjust_path(os.environ["RANLIB"]))
-                rc = os.environ.get("WINDRES", os.environ.get("RC"))
-                if rc:
-                    tools.replace_in_file(makefile_org, "RC= windres\n", "RC= %s\n" % self._adjust_path(rc))
-                if "NM" in os.environ:
-                    tools.replace_in_file(makefile_org, "NM= nm\n", "NM= %s\n" % self._adjust_path(os.environ["NM"]))
-                if "AS" in os.environ:
-                    tools.replace_in_file(makefile_org, "AS=$(CC) -c\n", "AS=%s\n" % self._adjust_path(os.environ["AS"]))
-
-    def _get_env_build(self):
-        if not self._env_build:
-            self._env_build = AutoToolsBuildEnvironment(self)
-        return self._env_build
+        makefile_org = os.path.join(self.source_folder, "Makefile.org")
+        if not "CROSS_COMPILE" in os.environ:
+            cc = os.environ.get("CC", "cc")
+            gen_info = json.loads(load(self, os.path.join(self.generators_folder, "gen_info.conf")))
+            replace_in_file(self, makefile_org, "CC= cc\n", "CC= %s %s\n" % (self._adjust_path(cc), gen_info["CFLAGS"]))
+            if "AR" in os.environ:
+                replace_in_file(self, makefile_org, "AR=ar $(ARFLAGS) r\n", "AR=%s $(ARFLAGS) r\n" % self._adjust_path(os.environ["AR"]))
+            if "RANLIB" in os.environ:
+                replace_in_file(self, makefile_org, "RANLIB= ranlib\n", "RANLIB= %s\n" % self._adjust_path(os.environ["RANLIB"]))
+            rc = os.environ.get("WINDRES", os.environ.get("RC"))
+            if rc:
+                replace_in_file(self, makefile_org, "RC= windres\n", "RC= %s\n" % self._adjust_path(rc))
+            if "NM" in os.environ:
+                replace_in_file(self, makefile_org, "NM= nm\n", "NM= %s\n" % self._adjust_path(os.environ["NM"]))
+            if "AS" in os.environ:
+                replace_in_file(self, makefile_org, "AS=$(CC) -c\n", "AS=%s\n" % self._adjust_path(os.environ["AS"]))
 
     def _get_default_openssl_dir(self):
         if self.settings.os == "Linux" and self._full_version >= "1.1.0":
             return "/etc/ssl"
-        return os.path.join(self.package_folder, "res")
+        return "res"
 
     @property
     def _configure_args(self):
         openssldir = self.options.openssldir or self._get_default_openssl_dir()
-        prefix = tools.unix_path(self.package_folder) if self._win_bash else self.package_folder
-        openssldir = tools.unix_path(openssldir) if self._win_bash else openssldir
+        openssldir = unix_path(self, openssldir) if self.win_bash else openssldir
         args = [
           '"%s"' % (self._target if self._full_version >= "1.1.0" else self._ancestor_target),
           "shared" if self.options.shared else "no-shared",
-                "--prefix=\"%s\"" % prefix,
+                "--prefix=/",
                 "--openssldir=\"%s\"" % openssldir,
           "no-unit-test",
           "no-threads" if self.options.no_threads else "threads"
@@ -510,6 +530,9 @@ def _configure_args(self):
         if self._full_version >= "1.1.0":
             args.append("--debug" if self.settings.build_type == "Debug" else "--release")
 
+        if self.settings.os == "Linux" and self.settings.arch == "x86_64":
+            args.append("--libdir=lib") # See https://github.com/openssl/openssl/blob/master/INSTALL.md#libdir
+
         if self.settings.os in ["tvOS", "watchOS"]:
             args.append(" -DNO_FORK") # fork is not available on tvOS and watchOS
         if self.settings.os == "Android":
@@ -535,27 +558,33 @@ def _configure_args(self):
             if self.options.get_safe("no_zlib"):
                 args.append("no-zlib")
             else:
-                zlib_info = self.deps_cpp_info["zlib"]
-                include_path = zlib_info.include_paths[0]
-                if self.settings.os == "Windows":
-                    lib_path = "%s/%s.lib" % (zlib_info.lib_paths[0], zlib_info.libs[0])
-                else:
-                    lib_path = zlib_info.lib_paths[0]  # Just path, linux will find the right file
+                gen_info = json.loads(load(self, os.path.join(self.generators_folder, "gen_info.conf")))
+                include_path = gen_info["zlib_include_path"]
+                lib_path     = gen_info["zlib_lib_path"]
                 # clang-cl doesn't like backslashes in #define CFLAGS (builldinf.h -> cversion.c)
                 include_path = self._adjust_path(include_path)
-                lib_path = self._adjust_path(lib_path)
+                lib_path     = self._adjust_path(lib_path)
 
-                if self.options["zlib"].shared:
-                    args.append("zlib-dynamic")
+                if Version(conan_version).major <2 :
+                    if self.options["zlib"].shared:
+                        args.append("zlib-dynamic")
+                    else:
+                        args.append("zlib")
                 else:
-                    args.append("zlib")
+                    if self.dependencies["zlib"].options.shared:
+                        args.append("zlib-dynamic")
+                    else:
+                        args.append("zlib")
 
                 args.extend(['--with-zlib-include="%s"' % include_path,
                              '--with-zlib-lib="%s"' % lib_path])
 
-
-        for option_name in self.options.values.fields:
-            activated = getattr(self.options, option_name)
+        if Version(conan_version).major < 2:
+            possible_values = self.options.values.fields
+        else:
+            possible_values = self.options.possible_values
+        for option_name in possible_values:
+            activated = self.options.get_safe(option_name)
             if activated and option_name not in ["fPIC", "openssldir", "capieng_dialog", "enable_capieng", "no_md2"]:
                 self.output.info("activated option: %s" % option_name)
                 args.append(option_name.replace("_", "-"))
@@ -581,11 +610,12 @@ def _create_targets(self):
     }},
 );
 """
+        gen_info = json.loads(load(self, os.path.join(self.generators_folder, "gen_info.conf")))
+        self.output.info(f"gen_info = {gen_info}")
         cflags = []
         cxxflags = []
-        env_build = self._get_env_build()
-        cflags.extend(env_build.vars_dict["CFLAGS"])
-        cxxflags.extend(env_build.vars_dict["CXXFLAGS"])
+        cflags.extend(gen_info["CFLAGS"])
+        cxxflags.extend(gen_info["CXXFLAGS"])
 
         cc = self._tool("CC", "cc")
         cxx = self._tool("CXX", "cxx")
@@ -599,13 +629,11 @@ def _create_targets(self):
         cc = 'cc => "%s",' % cc if cc else ""
         cxx = 'cxx => "%s",' % cxx if cxx else ""
         ar = 'ar => "%s",' % ar if ar else ""
-        defines = " ".join(env_build.defines)
-        defines = 'defines => add("%s"),' % defines if defines else ""
+        defines = ", ".join(f'"{d}"' for d in gen_info["DEFINES"])
+        defines = 'defines => add([%s]),' % defines if defines else ""
         ranlib = 'ranlib => "%s",' % ranlib if ranlib else ""
         targets = "my %targets" if self._full_version >= "1.1.1" else "%targets"
-        includes = ", ".join(['"%s"' % include for include in env_build.include_paths])
-        if self.settings.os == "Windows":
-            includes = includes.replace('\\', '/') # OpenSSL doesn't like backslashes
+        includes = ""
 
         if self._asm_target:
             ancestor = '[ "%s", asm("%s") ]' % (self._ancestor_target, self._asm_target)
@@ -616,7 +644,7 @@ def _create_targets(self):
         shared_target = ''
         if self.settings.os == 'Neutrino':
             if self.options.shared:
-                shared_extension = 'shared_extension => ".so.\$(SHLIB_VERSION_NUMBER)",'
+                shared_extension = r'shared_extension => ".so.\$(SHLIB_VERSION_NUMBER)",'
                 shared_target = 'shared_target  => "gnu-shared",'
             if self.options.get_safe("fPIC", True):
                 shared_cflag='shared_cflag => "-fPIC",'
@@ -636,38 +664,20 @@ def _create_targets(self):
                                         shared_target=shared_target,
                                         shared_extension=shared_extension,
                                         shared_cflag=shared_cflag,
-                                        lflags=" ".join(env_build.link_flags))
+                                        lflags=" ".join(gen_info["LDFLAGS"]))
         self.output.info("using target: %s -> %s" % (self._target, self._ancestor_target))
         self.output.info(config)
 
-        tools.save(os.path.join(self._source_subfolder, "Configurations", "20-conan.conf"), config)
-
-    def _run_make(self, targets=None, makefile=None, parallel=True):
-        command = [self._make_program]
-        if makefile:
-            command.extend(["-f", makefile])
-        if targets:
-            command.extend(targets)
-        if not self._use_nmake:
-            # workaround for random error: size too large (archive member extends past the end of the file)
-            # /Library/Developer/CommandLineTools/usr/bin/ar: internal ranlib command failed
-            if self.settings.os == "Macos" and self._full_version < "1.1.0":
-                parallel = False
-
-            # Building in parallel for versions less than 1.0.2d causes errors
-            # See https://github.com/openssl/openssl/issues/298
-            if self._full_version < "1.0.2d":
-                parallel = False
-            command.append(("-j%s" % tools.cpu_count()) if parallel else "-j1")
-        self.run(" ".join(command), win_bash=self._win_bash)
+        save(self, os.path.join(self.source_folder, "Configurations", "20-conan.conf"), config)
 
     @property
     def _perl(self):
-        if self._settings_build.os == "Windows" and not self._win_bash:
+        if self._settings_build.os == "Windows" and not self.win_bash:
             # enforce strawberry perl, otherwise wrong perl could be used (from Git bash, MSYS, etc.)
-            if "strawberryperl" in self.deps_cpp_info.deps:
-                return os.path.join(self.deps_cpp_info["strawberryperl"].rootpath, "bin", "perl.exe")
-            elif hasattr(self, "user_info_build") and "strawberryperl" in self.user_info_build:
+            build_deps = (dependency.ref.name for require, dependency in self.dependencies.build.items())
+            if "strawberryperl" in build_deps:
+                return os.path.join(self.dependencies.build["strawberryperl"].package_folder, "bin", "perl.exe")
+            if hasattr(self, "user_info_build") and "strawberryperl" in self.user_info_build:
                 return self.user_info_build["strawberryperl"].perl
         return "perl"
 
@@ -675,62 +685,6 @@ def _perl(self):
     def _nmake_makefile(self):
         return r"ms\ntdll.mak" if self.options.shared else r"ms\nt.mak"
 
-    def _make(self):
-        with tools.chdir(self._source_subfolder):
-            # workaround for clang-cl not producing .pdb files
-            if self._is_clangcl:
-                tools.save("ossl_static.pdb", "")
-            args = " ".join(self._configure_args)
-            self.output.info(self._configure_args)
-
-            if self._use_nmake and self._full_version >= "1.1.0":
-                self._replace_runtime_in_file(os.path.join("Configurations", "10-main.conf"))
-
-            self.run('{perl} ./Configure {args}'.format(perl=self._perl, args=args), win_bash=self._win_bash)
-
-            self._patch_install_name()
-
-            if self._use_nmake and self._full_version < "1.1.0":
-                if not self.options.no_asm and self.settings.arch == "x86":
-                    self.run(r"ms\do_nasm")
-                else:
-                    self.run(r"ms\do_ms" if self.settings.arch == "x86" else r"ms\do_win64a")
-
-                self._replace_runtime_in_file(os.path.join("ms", "nt.mak"))
-                self._replace_runtime_in_file(os.path.join("ms", "ntdll.mak"))
-                if self.settings.arch == "x86":
-                    tools.replace_in_file(os.path.join("ms", "nt.mak"), "-WX", "")
-                    tools.replace_in_file(os.path.join("ms", "ntdll.mak"), "-WX", "")
-
-                self._run_make(makefile=self._nmake_makefile)
-            else:
-                self._run_make()
-
-    def _make_install(self):
-        with tools.chdir(self._source_subfolder):
-            # workaround for MinGW (https://github.com/openssl/openssl/issues/7653)
-            if not os.path.isdir(os.path.join(self.package_folder, "bin")):
-                os.makedirs(os.path.join(self.package_folder, "bin"))
-
-            if self._use_nmake and self._full_version < "1.1.0":
-                self._run_make(makefile=self._nmake_makefile, targets=["install"], parallel=False)
-            else:
-                self._run_make(targets=["install_sw"], parallel=False)
-
-    @property
-    def _cc(self):
-        if "CROSS_COMPILE" in os.environ:
-            return "gcc"
-        if "CC" in os.environ:
-            return os.environ["CC"]
-        if self.settings.compiler == "apple-clang":
-            return tools.XCRun(self.settings).find("clang")
-        elif self.settings.compiler == "clang":
-            return "clang"
-        elif self.settings.compiler == "gcc":
-            return "gcc"
-        return "cc"
-
     @contextmanager
     def _make_context(self):
         if self._use_nmake:
@@ -739,74 +693,123 @@ def _make_context(self):
             # break nmake (don't know about mingw make). So we fix them
             def sanitize_env_var(var):
                 return '"{}"'.format(var).replace('/', '\\') if '"' not in var else var
-            env = {key: sanitize_env_var(tools.get_env(key)) for key in ("CC", "RC") if tools.get_env(key)}
-            with tools.environment_append(env):
+            env = Environment()
+            for key in ("CC", "RC"):
+                if os.getenv(key):
+                    env.define(key, sanitize_env_var(os.getenv(key)))
+            with env.vars(self).apply():
                 yield
         else:
             yield
 
     def build(self):
-        for patch in self.conan_data.get("patches", {}).get(self.version, []):
-            tools.patch(**patch)
-        with tools.vcvars(self.settings) if self._use_nmake else tools.no_op():
-            env_vars = {"PERL": self._perl}
-            if self._full_version < "1.1.0":
-                cflags = " ".join(self._get_env_build().vars_dict["CFLAGS"])
-                env_vars["CC"] = "%s %s" % (self._cc, cflags)
-            if self.settings.compiler == "apple-clang":
-                xcrun = tools.XCRun(self.settings)
-                env_vars["CROSS_SDK"] = os.path.basename(xcrun.sdk_path)
-                env_vars["CROSS_TOP"] = os.path.dirname(os.path.dirname(xcrun.sdk_path))
-            with tools.environment_append(env_vars):
-                if self._full_version > "1.1.0":
-                    self._create_targets()
-                else:
-                    self._patch_configure()
-                    self._patch_makefile_org()
-                with self._make_context():
-                    self._make()
+        apply_conandata_patches(self)
+        autotools = Autotools(self)
+        if self._full_version >= "1.1.0":
+            self._create_targets()
+        else:
+            self._patch_configure()
+            self._patch_makefile_org()
+        with self._make_context():
+            with chdir(self, self.source_folder):
+                # workaround for clang-cl not producing .pdb files
+                if self._is_clangcl:
+                    save(self, "ossl_static.pdb", "")
+                args = " ".join(self._configure_args)
+                self.output.info(self._configure_args)
 
-    @property
-    def _make_program(self):
-        if self._use_nmake:
-            return "nmake"
-        make_program = tools.get_env("CONAN_MAKE_PROGRAM", tools.which("make") or tools.which('mingw32-make'))
-        make_program = tools.unix_path(make_program) if self._settings_build.os == "Windows" else make_program
-        if not make_program:
-            raise Exception('could not find "make" executable. please set "CONAN_MAKE_PROGRAM" environment variable')
-        return make_program
+                if self._use_nmake and self._full_version >= "1.1.0":
+                    self._replace_runtime_in_file(os.path.join("Configurations", "10-main.conf"))
 
+                self.run(f'{self._perl} ./Configure {args}')
+
+                self._patch_install_name()
+
+                if not self._use_nmake:
+                    autotools.make()
+                else:
+                    if self._full_version >= "1.1.0":
+                        self.run(f'nmake /F Makefile')
+                    else: # nmake 1.0.2 support
+                        # Note: 1.0.2 should not be used according to the OpenSSL Project
+                        #       See https://www.openssl.org/source/
+
+                        if not self.options.no_asm and self.settings.arch == "x86":
+                            self.run(r"ms\do_nasm")
+                        else:
+                            self.run(r"ms\do_ms" if self.settings.arch == "x86" else r"ms\do_win64a")
+
+                        self._replace_runtime_in_file(os.path.join("ms", "nt.mak"))
+                        self._replace_runtime_in_file(os.path.join("ms", "ntdll.mak"))
+                        if self.settings.arch == "x86":
+                            replace_in_file(self, os.path.join("ms", "nt.mak"), "-WX", "")
+                            replace_in_file(self, os.path.join("ms", "ntdll.mak"), "-WX", "")
+
+                        # NMAKE interprets trailing backslash as line continuation
+                        replace_in_file(self, self._nmake_makefile, 'INSTALLTOP=\\', 'INSTALLTOP=/')
+
+                        self.run(f'nmake /F {self._nmake_makefile}')
+  
     def _patch_install_name(self):
-        if tools.is_apple_os(self.settings.os) and self.options.shared:
+        if is_apple_os(self) and self.options.shared:
             old_str = '-install_name $(INSTALLTOP)/$(LIBDIR)/'
             new_str = '-install_name @rpath/'
-
             makefile = "Makefile" if self._full_version >= "1.1.1" else "Makefile.shared"
-            tools.replace_in_file(makefile, old_str, new_str, strict=self.in_local_cache)
+            replace_in_file(self, makefile, old_str, new_str, strict=self.in_local_cache)
+        if self._use_nmake:
+            # NMAKE interprets trailing backslash as line continuation
+            if self._full_version >= "1.1.0":
+                replace_in_file(self, "Makefile", 'INSTALLTOP_dir=\\', 'INSTALLTOP_dir=/')
 
     def _replace_runtime_in_file(self, filename):
         runtime = msvc_runtime_flag(self)
         for e in ["MDd", "MTd", "MD", "MT"]:
-            tools.replace_in_file(filename, "/{} ".format(e), "/{} ".format(runtime), strict=False)
-            tools.replace_in_file(filename, "/{}\"".format(e), "/{}\"".format(runtime), strict=False)
+            replace_in_file(self, filename, "/{} ".format(e), "/{} ".format(runtime), strict=False)
+            replace_in_file(self, filename, "/{}\"".format(e), "/{}\"".format(runtime), strict=False)
 
     def package(self):
-        self.copy(src=self._source_subfolder, pattern="*LICENSE", dst="licenses")
-        with tools.vcvars(self.settings) if self._use_nmake else tools.no_op():
-            self._make_install()
+        copy(self, "*LICENSE", self.source_folder, os.path.join(self.package_folder, "licenses"), keep_path=False)
+        autotools = Autotools(self)
+        args = []
+        if self._full_version >= "1.1.0":
+            target = "install_sw"
+            args.append(f"DESTDIR={self.package_folder}")
+        else: # 1.0.2 support
+            # Note: 1.0.2 should not be used according to the OpenSSL Project
+            #       See https://www.openssl.org/source/
+            if not self._use_nmake:
+                target = "install_sw"
+                args.append(f"INSTALL_PREFIX={self.package_folder}")
+            else:
+                target = "install"
+                args.append(f"INSTALLTOP={self.package_folder}")
+                openssldir = self.options.openssldir or self._get_default_openssl_dir()
+                args.append(f"OPENSSLDIR={os.path.join(self.package_folder, openssldir)}")
+
+        with chdir(self, self.source_folder):
+            if not self._use_nmake:
+                autotools.make(target=target, args=args)
+            else:
+                if self._full_version >= "1.1.0":
+                    self.run(f'nmake /F Makefile {target} {" ".join(args)}')
+                else: # nmake 1.0.2 support
+                    # Note: 1.0.2 should not be used according to the OpenSSL Project
+                    #       See https://www.openssl.org/source/
+                    self.run(f'nmake /F {self._nmake_makefile} {target} {" ".join(args)}')
+
         for root, _, files in os.walk(self.package_folder):
             for filename in files:
                 if fnmatch.fnmatch(filename, "*.pdb"):
                     os.unlink(os.path.join(self.package_folder, root, filename))
         if self._use_nmake:
             if self.settings.build_type == 'Debug' and self._full_version >= "1.1.0":
-                with tools.chdir(os.path.join(self.package_folder, 'lib')):
+                with chdir(self, os.path.join(self.package_folder, 'lib')):
                     rename(self, "libssl.lib", "libssld.lib")
                     rename(self, "libcrypto.lib", "libcryptod.lib")
         # Old OpenSSL version family has issues with permissions.
         # See https://github.com/conan-io/conan/issues/5831
         if self._full_version < "1.1.0" and self.options.shared and self.settings.os in ("Android", "FreeBSD", "Linux"):
-            with tools.chdir(os.path.join(self.package_folder, "lib")):
+            with chdir(self, os.path.join(self.package_folder, "lib")):
                 os.chmod("libssl.so.1.0.0", 0o755)
                 os.chmod("libcrypto.so.1.0.0", 0o755)
 
@@ -863,11 +866,11 @@ def _create_cmake_module_variables(self, module_file):
                 set(OPENSSL_VERSION ${OpenSSL_VERSION})
             endif()
         """ % {"config":str(self.settings.build_type).upper()})
-        tools.save(module_file, content)
+        save(self, module_file, content)
 
     @property
     def _module_file_rel_path(self):
-        return os.path.join("lib", "cmake", "conan-official-{}-variables.cmake".format(self.name))
+        return os.path.join("lib", "cmake", f"conan-official-{self.name}-variables.cmake")
 
     def package_info(self):
         self.cpp_info.set_property("cmake_find_mode", "both")


Test patch:
diff --git a/recipes/openssl/1.x.x/test_package/conanfile.py b/recipes/openssl/1.x.x/test_package/conanfile.py
--- a/recipes/openssl/1.x.x/test_package/conanfile.py
+++ b/recipes/openssl/1.x.x/test_package/conanfile.py
@@ -53,4 +53,3 @@ def test(self):
         if not self._skip_test and can_run(self):
             bin_path = os.path.join(self.cpp.build.bindirs[0], "digest")
             self.run(bin_path, env="conanrun")
-        assert os.path.exists(os.path.join(self.deps_cpp_info["openssl"].rootpath, "licenses", "LICENSE"))
diff --git a/recipes/openssl/1.x.x/test_package/digest.c b/recipes/openssl/1.x.x/test_package/digest.c
--- a/recipes/openssl/1.x.x/test_package/digest.c
+++ b/recipes/openssl/1.x.x/test_package/digest.c
@@ -7,7 +7,7 @@
 #include <openssl/crypto.h>
 #include <openssl/ssl.h>
 #if defined(WITH_ZLIB)
-#include <zlib.h>
+#include <openssl/comp.h>
 #endif
 
 #if defined(_MSC_VER) && _MSC_VER < 1900
@@ -98,7 +98,8 @@ int main()
 	printf("SSL library version: %s\n", OpenSSL_version(OPENSSL_VERSION));
 #endif
 #if defined(WITH_ZLIB)
-	printf("ZLIB version: %s\n", ZLIB_VERSION);
+	COMP_METHOD *zlib_comp = COMP_zlib();
+	printf("ZLIB compression method is named: %s\n", SSL_COMP_get_name(zlib_comp));
 #endif
 
 	return 0;