From abf39ae94ea705318603a206f62823a0082dbfe1 Mon Sep 17 00:00:00 2001 From: Martin Delille Date: Sat, 22 Oct 2022 06:44:30 +0200 Subject: [PATCH] (#12956) [libcurl/xxx] Conan v2 migration * [libcurl/xxx] Conan v2 migration * Use VirtualRunEnv * Bump wolfssl and libnghttp2 * Fix linter issues * Use cmake_layout conditionaly * Add test_type and tested_reference_str * Fix test_package * Add basic_layout * Delete compiler in package_id * Fix basic_layout * Update cacert.pem sha256 * Use old syntax for bin path * Revert "Use old syntax for bin path" This reverts commit 3d5aec88c5994b58991613c6f5d873a352c5b5cd. * Use old syntax for test_v1_package bin path * Remove conans.tools.get_env * Use export_conandata_patches * Update recipes/libcurl/all/conanfile.py Co-authored-by: Uilian Ries * Use info.options/settings * Apply suggestions from code review Co-authored-by: Uilian Ries Co-authored-by: Jordan Williams * Fix indentation * Add pkgconf conditionnaly Co-authored-by: Uilian Ries * Fix if condition Co-authored-by: Uilian Ries Co-authored-by: Jordan Williams --- recipes/libcurl/all/CMakeLists.txt | 8 - recipes/libcurl/all/conandata.yml | 1 - recipes/libcurl/all/conanfile.py | 439 +++++++++--------- .../libcurl/all/test_package/CMakeLists.txt | 3 - recipes/libcurl/all/test_package/conanfile.py | 44 +- .../all/test_v1_package/CMakeLists.txt | 10 + .../libcurl/all/test_v1_package/conanfile.py | 43 ++ 7 files changed, 288 insertions(+), 260 deletions(-) delete mode 100644 recipes/libcurl/all/CMakeLists.txt create mode 100644 recipes/libcurl/all/test_v1_package/CMakeLists.txt create mode 100644 recipes/libcurl/all/test_v1_package/conanfile.py diff --git a/recipes/libcurl/all/CMakeLists.txt b/recipes/libcurl/all/CMakeLists.txt deleted file mode 100644 index 8658c4251a78c..0000000000000 --- a/recipes/libcurl/all/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.0) - -project(cmake_wrapper) - -include(conanbuildinfo.cmake) -conan_basic_setup() - -add_subdirectory("source_subfolder") diff --git a/recipes/libcurl/all/conandata.yml b/recipes/libcurl/all/conandata.yml index 40396d0b0972c..40bf395099661 100644 --- a/recipes/libcurl/all/conandata.yml +++ b/recipes/libcurl/all/conandata.yml @@ -29,4 +29,3 @@ sources: patches: "7.79.0": - patch_file: "patches/004-no-checksrc.patch" - base_path: "source_subfolder" diff --git a/recipes/libcurl/all/conanfile.py b/recipes/libcurl/all/conanfile.py index 5d90d94f7a857..5c732a75e757f 100644 --- a/recipes/libcurl/all/conanfile.py +++ b/recipes/libcurl/all/conanfile.py @@ -1,17 +1,19 @@ -import glob -import os -import re -import functools -from conans import ConanFile, AutoToolsBuildEnvironment, CMake, tools +from conan import ConanFile from conan.errors import ConanInvalidConfiguration -from conan.tools.microsoft import is_msvc +from conan.tools.apple import is_apple_os, fix_apple_shared_install_name from conan.tools.build import cross_building +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.env import VirtualBuildEnv, VirtualRunEnv +from conan.tools.files import apply_conandata_patches, copy, download, export_conandata_patches, get, load, replace_in_file, rm, rmdir, save +from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps, PkgConfigDeps +from conan.tools.layout import basic_layout +from conan.tools.microsoft import is_msvc, unix_path from conan.tools.scm import Version -from conan.tools.files import replace_in_file, rmdir, chdir, get, download, save, load, apply_conandata_patches -from conan.tools.apple import is_apple_os +import os +import re -required_conan_version = ">=1.51.3" +required_conan_version = ">=1.52.0" class LibcurlConan(ConanFile): @@ -112,28 +114,19 @@ class LibcurlConan(ConanFile): "with_ca_bundle": None, "with_ca_path": None, } - generators = "cmake", "cmake_find_package_multi", "pkg_config", "cmake_find_package" - - @property - def _source_subfolder(self): - return "source_subfolder" - - @property - def _build_subfolder(self): - return "build_subfolder" @property def _is_mingw(self): return self.settings.os == "Windows" and self.settings.compiler == "gcc" - @property - def _is_win_x_android(self): - return self.settings.os == "Android" and tools.os_info.is_windows - @property def _settings_build(self): return getattr(self, "settings_build", self.settings) + @property + def _is_win_x_android(self): + return self.settings.os == "Android" and self._settings_build.os == "Windows" + @property def _is_using_cmake_build(self): return is_msvc(self) or self._is_win_x_android @@ -148,10 +141,8 @@ def _has_metalink_option(self): return Version(self.version) < "7.78.0" and not self._is_using_cmake_build def export_sources(self): - self.copy("CMakeLists.txt") - self.copy("lib_Makefile_add.am") - for patch in self.conan_data.get("patches", {}).get(self.version, []): - self.copy(patch["patch_file"]) + copy(self, "lib_Makefile_add.am", self.recipe_folder, self.export_sources_folder) + export_conandata_patches(self) def config_options(self): if Version(self.version) < "7.10.4": @@ -181,9 +172,9 @@ def requirements(self): if self.options.with_ssl == "openssl": self.requires("openssl/1.1.1q") elif self.options.with_ssl == "wolfssl": - self.requires("wolfssl/5.3.0") + self.requires("wolfssl/5.4.0") if self.options.with_nghttp2: - self.requires("libnghttp2/1.47.0") + self.requires("libnghttp2/1.48.0") if self.options.with_libssh2: self.requires("libssh2/1.10.0") if self.options.with_zlib: @@ -195,15 +186,19 @@ def requirements(self): if self.options.with_c_ares: self.requires("c-ares/1.18.1") + def package_id(self): + del self.info.settings.compiler + def validate(self): - if self.options.with_ssl == "schannel" and self.settings.os != "Windows": + if self.info.options.with_ssl == "schannel" and self.info.settings.os != "Windows": raise ConanInvalidConfiguration("schannel only suppported on Windows.") - if self.options.with_ssl == "darwinssl" and not is_apple_os(self): + if self.info.options.with_ssl == "darwinssl" and not is_apple_os(self): raise ConanInvalidConfiguration("darwinssl only suppported on Apple like OS (Macos, iOS, watchOS or tvOS).") - if self.options.with_ssl == "wolfssl" and self._is_using_cmake_build and Version(self.version) < "7.70.0": + if self.info.options.with_ssl == "wolfssl" and self._is_using_cmake_build and Version(self.version) < "7.70.0": raise ConanInvalidConfiguration("Before 7.70.0, libcurl has no wolfssl support for Visual Studio or \"Windows to Android cross compilation\"") - if self.options.with_ssl == "openssl": - if self.options.with_ntlm and self.options["openssl"].no_des: + if self.info.options.with_ssl == "openssl": + openssl = self.dependencies["openssl"] + if self.info.options.with_ntlm and openssl.options.no_des: raise ConanInvalidConfiguration("option with_ntlm=True requires openssl:no_des=False") def build_requirements(self): @@ -212,14 +207,34 @@ def build_requirements(self): self.tool_requires("ninja/1.11.0") else: self.tool_requires("libtool/2.4.6") - self.tool_requires("pkgconf/1.7.4") - if self._settings_build.os == "Windows" and not tools.get_env("CONAN_BASH_PATH"): - self.tool_requires("msys2/cci.latest") + if not self.conf.get("tools.gnu:pkg_config", default=False, check_type=str): + self.tool_requires("pkgconf/1.7.4") + if self._settings_build.os == "Windows": + self.win_bash = True + if not self.conf.get("tools.microsoft.bash:path", default=False, check_type=str): + self.tool_requires("msys2/cci.latest") + + def layout(self): + if self._is_using_cmake_build: + cmake_layout(self, src_folder="src") + else: + basic_layout(self, src_folder="src") def source(self): get(self, **self.conan_data["sources"][self.version], - destination=self._source_subfolder, strip_root=True) - download(self, "https://curl.haxx.se/ca/cacert.pem", "cacert.pem", verify=True) + destination=self.source_folder, strip_root=True) + download(self, "https://curl.haxx.se/ca/cacert.pem", "cacert.pem", verify=True, sha256="2cff03f9efdaf52626bd1b451d700605dc1ea000c5da56bd0fc59f8f43071040") + + def generate(self): + if self._is_using_cmake_build: + self._generate_with_cmake() + else: + self._generate_with_autotools() + ms = VirtualBuildEnv(self) + ms.generate() + if not cross_building(self): + env = VirtualRunEnv(self) + env.generate(scope="build") # TODO: remove imports once rpath of shared libs of libcurl dependencies fixed on macOS def imports(self): @@ -231,14 +246,19 @@ def imports(self): # but does not work on OS X 10.11 with SIP) # 2. copying dylib's to the build directory (fortunately works on OS X) if self.settings.os == "Macos": - self.copy("*.dylib*", dst=self._source_subfolder, keep_path=False) + copy(self, "*.dylib*", src=self.build_folder, dst=self.source_folder, keep_path=False) def build(self): self._patch_sources() if self._is_using_cmake_build: - self._build_with_cmake() + cmake = CMake(self) + cmake.configure() + cmake.build() else: - self._build_with_autotools() + autotools = Autotools(self) + autotools.autoreconf() + autotools.configure() + autotools.make() def _patch_sources(self): apply_conandata_patches(self) @@ -248,7 +268,7 @@ def _patch_sources(self): def _patch_misc_files(self): if self.options.with_largemaxwritesize: - replace_in_file(self, os.path.join(self._source_subfolder, "include", "curl", "curl.h"), + replace_in_file(self, os.path.join(self.source_folder, "include", "curl", "curl.h"), "define CURL_MAX_WRITE_SIZE 16384", "define CURL_MAX_WRITE_SIZE 10485760") @@ -256,7 +276,7 @@ def _patch_misc_files(self): # for additional info, see this comment https://github.com/conan-io/conan-center-index/pull/1008#discussion_r386122685 if self.settings.compiler == "apple-clang" and self.settings.compiler.version == "9.1": if self.options.with_ssl == "darwinssl": - replace_in_file(self, os.path.join(self._source_subfolder, "lib", "vtls", "sectransp.c"), + replace_in_file(self, os.path.join(self.source_folder, "lib", "vtls", "sectransp.c"), "#define CURL_BUILD_MAC_10_13 MAC_OS_X_VERSION_MAX_ALLOWED >= 101300", "#define CURL_BUILD_MAC_10_13 0") @@ -267,25 +287,25 @@ def _patch_autotools(self): # Disable curl tool for these reasons: # - link errors if mingw shared or iOS/tvOS/watchOS # - it makes recipe consistent with CMake build where we don't build curl tool - top_makefile = os.path.join(self._source_subfolder, "Makefile.am") + top_makefile = os.path.join(self.source_folder, "Makefile.am") replace_in_file(self, top_makefile, "SUBDIRS = lib src", "SUBDIRS = lib") replace_in_file(self, top_makefile, "include src/Makefile.inc", "") if self._is_mingw: # patch for zlib naming in mingw if self.options.with_zlib: - configure_ac = os.path.join(self._source_subfolder, "configure.ac") + configure_ac = os.path.join(self.source_folder, "configure.ac") zlib_name = self.deps_cpp_info["zlib"].libs[0] replace_in_file(self, configure_ac, "AC_CHECK_LIB(z,", - "AC_CHECK_LIB({},".format(zlib_name)) + f"AC_CHECK_LIB({zlib_name}") replace_in_file(self, configure_ac, "-lz ", - "-l{} ".format(zlib_name)) + f"-l{zlib_name}") if self.options.shared: # patch for shared mingw build - lib_makefile = os.path.join(self._source_subfolder, "lib", "Makefile.am") + lib_makefile = os.path.join(self.source_folder, "lib", "Makefile.am") replace_in_file(self, lib_makefile, "noinst_LTLIBRARIES = libcurlu.la", "") @@ -304,10 +324,10 @@ def _patch_autotools(self): def _patch_cmake(self): if not self._is_using_cmake_build: return - cmakelists = os.path.join(self._source_subfolder, "CMakeLists.txt") + cmakelists = os.path.join(self.source_folder, "CMakeLists.txt") # Custom findZstd.cmake file relies on pkg-config file, make sure that it's consumed on all platforms if self._has_zstd_option: - replace_in_file(self, os.path.join(self._source_subfolder, "CMake", "FindZstd.cmake"), + replace_in_file(self, os.path.join(self.source_folder, "CMake", "FindZstd.cmake"), "if(UNIX)", "if(TRUE)") # TODO: check this patch, it's suspicious replace_in_file(self, cmakelists, @@ -344,111 +364,143 @@ def _patch_cmake(self): get_target_property(_lib "${_libname}" LOCATION)""", ) - def _get_configure_command_args(self): - yes_no = lambda v: "yes" if v else "no" - params = [ - "--with-libidn2={}".format(yes_no(self.options.with_libidn)), - "--with-librtmp={}".format(yes_no(self.options.with_librtmp)), - "--with-libpsl={}".format(yes_no(self.options.with_libpsl)), - "--with-schannel={}".format(yes_no(self.options.with_ssl == "schannel")), - "--with-secure-transport={}".format(yes_no(self.options.with_ssl == "darwinssl")), - "--with-brotli={}".format(yes_no(self.options.with_brotli)), - "--enable-shared={}".format(yes_no(self.options.shared)), - "--enable-static={}".format(yes_no(not self.options.shared)), - "--enable-dict={}".format(yes_no(self.options.with_dict)), - "--enable-file={}".format(yes_no(self.options.with_file)), - "--enable-ftp={}".format(yes_no(self.options.with_ftp)), - "--enable-gopher={}".format(yes_no(self.options.with_gopher)), - "--enable-http={}".format(yes_no(self.options.with_http)), - "--enable-imap={}".format(yes_no(self.options.with_imap)), - "--enable-ldap={}".format(yes_no(self.options.with_ldap)), - "--enable-mqtt={}".format(yes_no(self.options.with_mqtt)), - "--enable-pop3={}".format(yes_no(self.options.with_pop3)), - "--enable-rtsp={}".format(yes_no(self.options.with_rtsp)), - "--enable-smb={}".format(yes_no(self.options.with_smb)), - "--enable-smtp={}".format(yes_no(self.options.with_smtp)), - "--enable-telnet={}".format(yes_no(self.options.with_telnet)), - "--enable-tftp={}".format(yes_no(self.options.with_tftp)), - "--enable-debug={}".format(yes_no(self.settings.build_type == "Debug")), - "--enable-ares={}".format(yes_no(self.options.with_c_ares)), - "--enable-threaded-resolver={}".format(yes_no(self.options.with_threaded_resolver)), - "--enable-cookies={}".format(yes_no(self.options.with_cookies)), - "--enable-ipv6={}".format(yes_no(self.options.with_ipv6)), - "--enable-manual={}".format(yes_no(self.options.with_docs)), - "--enable-verbose={}".format(yes_no(self.options.with_verbose_debug)), - "--enable-symbol-hiding={}".format(yes_no(self.options.with_symbol_hiding)), - "--enable-unix-sockets={}".format(yes_no(self.options.with_unix_sockets)), - ] + def _yes_no(self, value): + return "yes" if value else "no" + + def _generate_with_autotools(self): + tc = AutotoolsToolchain(self) + tc.configure_args.extend([ + f"--with-libidn2={self._yes_no(self.options.with_libidn)}", + f"--with-librtmp={self._yes_no(self.options.with_librtmp)}", + f"--with-libpsl={self._yes_no(self.options.with_libpsl)}", + f"--with-schannel={self._yes_no(self.options.with_ssl == 'schannel')}", + f"--with-secure-transport={self._yes_no(self.options.with_ssl == 'darwinssl')}", + f"--with-brotli={self._yes_no(self.options.with_brotli)}", + f"--enable-shared={self._yes_no(self.options.shared)}", + f"--enable-static={self._yes_no(not self.options.shared)}", + f"--enable-dict={self._yes_no(self.options.with_dict)}", + f"--enable-file={self._yes_no(self.options.with_file)}", + f"--enable-ftp={self._yes_no(self.options.with_ftp)}", + f"--enable-gopher={self._yes_no(self.options.with_gopher)}", + f"--enable-http={self._yes_no(self.options.with_http)}", + f"--enable-imap={self._yes_no(self.options.with_imap)}", + f"--enable-ldap={self._yes_no(self.options.with_ldap)}", + f"--enable-mqtt={self._yes_no(self.options.with_mqtt)}", + f"--enable-pop3={self._yes_no(self.options.with_pop3)}", + f"--enable-rtsp={self._yes_no(self.options.with_rtsp)}", + f"--enable-smb={self._yes_no(self.options.with_smb)}", + f"--enable-smtp={self._yes_no(self.options.with_smtp)}", + f"--enable-telnet={self._yes_no(self.options.with_telnet)}", + f"--enable-tftp={self._yes_no(self.options.with_tftp)}", + f"--enable-debug={self._yes_no(self.settings.build_type == 'Debug')}", + f"--enable-ares={self._yes_no(self.options.with_c_ares)}", + f"--enable-threaded-resolver={self._yes_no(self.options.with_threaded_resolver)}", + f"--enable-cookies={self._yes_no(self.options.with_cookies)}", + f"--enable-ipv6={self._yes_no(self.options.with_ipv6)}", + f"--enable-manual={self._yes_no(self.options.with_docs)}", + f"--enable-verbose={self._yes_no(self.options.with_verbose_debug)}", + f"--enable-symbol-hiding={self._yes_no(self.options.with_symbol_hiding)}", + f"--enable-unix-sockets={self._yes_no(self.options.with_unix_sockets)}", + ]) if self.options.with_ssl == "openssl": - params.append("--with-ssl={}".format(tools.unix_path(self.deps_cpp_info["openssl"].rootpath))) + path = unix_path(self, self.deps_cpp_info["openssl"].rootpath) + tc.configure_args.append(f"--with-ssl={path}") else: - params.append("--without-ssl") + tc.configure_args.append("--without-ssl") if self.options.with_ssl == "wolfssl": - params.append("--with-wolfssl={}".format(tools.unix_path(self.deps_cpp_info["wolfssl"].rootpath))) + path = unix_path(self, self.deps_cpp_info["wolfssl"].rootpath) + tc.configure_args.append(f"--with-wolfssl={path}") else: - params.append("--without-wolfssl") + tc.configure_args.append("--without-wolfssl") if self.options.with_libssh2: - params.append("--with-libssh2={}".format(tools.unix_path(self.deps_cpp_info["libssh2"].rootpath))) + path = unix_path(self, self.deps_cpp_info["libssh2"].rootpath) + tc.configure_args.append(f"--with-libssh2={path}") else: - params.append("--without-libssh2") + tc.configure_args.append("--without-libssh2") if self.options.with_nghttp2: - params.append("--with-nghttp2={}".format(tools.unix_path(self.deps_cpp_info["libnghttp2"].rootpath))) + path = unix_path(self, self.deps_cpp_info["libnghttp2"].rootpath) + tc.configure_args.append(f"--with-nghttp2={path}") else: - params.append("--without-nghttp2") + tc.configure_args.append("--without-nghttp2") if self.options.with_zlib: - params.append("--with-zlib={}".format(tools.unix_path(self.deps_cpp_info["zlib"].rootpath))) + path = unix_path(self, self.deps_cpp_info["zlib"].rootpath) + tc.configure_args.append(f"--with-zlib={path}") else: - params.append("--without-zlib") + tc.configure_args.append("--without-zlib") if self._has_zstd_option: - params.append("--with-zstd={}".format(yes_no(self.options.with_zstd))) + tc.configure_args.append(f"--with-zstd={self._yes_no(self.options.with_zstd)}") if self._has_metalink_option: - params.append("--with-libmetalink={}".format(yes_no(self.options.with_libmetalink))) + tc.configure_args.append(f"--with-libmetalink={self._yes_no(self.options.with_libmetalink)}") if not self.options.with_proxy: - params.append("--disable-proxy") + tc.configure_args.append("--disable-proxy") if not self.options.with_rtsp: - params.append("--disable-rtsp") + tc.configure_args.append("--disable-rtsp") if not self.options.with_crypto_auth: - params.append("--disable-crypto-auth") # also disables NTLM in versions of curl prior to 7.78.0 + tc.configure_args.append("--disable-crypto-auth") # also disables NTLM in versions of curl prior to 7.78.0 # ntlm will default to enabled if any SSL options are enabled if not self.options.with_ntlm: if Version(self.version) <= "7.77.0": - params.append("--disable-crypto-auth") + tc.configure_args.append("--disable-crypto-auth") else: - params.append("--disable-ntlm") + tc.configure_args.append("--disable-ntlm") if not self.options.with_ntlm_wb: - params.append("--disable-ntlm-wb") + tc.configure_args.append("--disable-ntlm-wb") - if self.options.with_ca_bundle == False: - params.append("--without-ca-bundle") + if self.options.with_ca_bundle is False: + tc.configure_args.append("--without-ca-bundle") elif self.options.with_ca_bundle: - params.append("--with-ca-bundle=" + str(self.options.with_ca_bundle)) + tc.configure_args.append("--with-ca-bundle=" + str(self.options.with_ca_bundle)) - if self.options.with_ca_path == False: - params.append('--without-ca-path') + if self.options.with_ca_path is False: + tc.configure_args.append('--without-ca-path') elif self.options.with_ca_path: - params.append("--with-ca-path=" + str(self.options.with_ca_path)) + tc.configure_args.append("--with-ca-path=" + str(self.options.with_ca_path)) # Cross building flags if cross_building(self): if self.settings.os == "Linux" and "arm" in self.settings.arch: - params.append("--host=%s" % self._get_linux_arm_host()) + tc.configure_args.append(f"--host={self._get_linux_arm_host()}") elif self.settings.os == "iOS": - params.append("--enable-threaded-resolver") - params.append("--disable-verbose") + tc.configure_args.append("--enable-threaded-resolver") + tc.configure_args.append("--disable-verbose") elif self.settings.os == "Android": pass # this just works, conan is great! - return params + # tweaks for mingw + if self._is_mingw: + rcflags = "-O COFF" + if self.settings.arch == "x86": + rcflags += " --target=pe-i386" + else: + rcflags += " --target=pe-x86-64" + env = tc.environment() + env.define("RCFLAGS", rcflags) + + tc.extra_defines.append("_AMD64_") + + if self.settings.os != "Windows": + tc.fpic = self.options.get_safe("fPIC", True) + + + if cross_building(self) and is_apple_os(self): + tc.extra_defines.extend(['HAVE_SOCKET', 'HAVE_FCNTL_O_NONBLOCK']) + + tc.generate() + tc = PkgConfigDeps(self) + tc.generate() + tc = AutotoolsDeps(self) + tc.generate() + def _get_linux_arm_host(self): arch = None @@ -472,150 +524,89 @@ def _arm_version(self, arch): version = int(match.group(1)) return version - def _build_with_autotools(self): - with chdir(self, self._source_subfolder): - # autoreconf - self.run("{} -fiv".format(tools.get_env("AUTORECONF") or "autoreconf"), win_bash=tools.os_info.is_windows, run_environment=True) - - # fix generated autotools files to have relocatable binaries - if is_apple_os(self): - replace_in_file(self, "configure", "-install_name \\$rpath/", "-install_name @rpath/") - - self.run("chmod +x configure") - - # run configure with *LD_LIBRARY_PATH env vars it allows to pick up shared openssl - with tools.run_environment(self): - autotools, autotools_vars = self._configure_autotools() - autotools.make(vars=autotools_vars) - - def _configure_autotools_vars(self): - autotools_vars = {} - # tweaks for mingw - if self._is_mingw: - autotools_vars["RCFLAGS"] = "-O COFF" - if self.settings.arch == "x86": - autotools_vars["RCFLAGS"] += " --target=pe-i386" - else: - autotools_vars["RCFLAGS"] += " --target=pe-x86-64" - return autotools_vars - - @functools.lru_cache(1) - def _configure_autotools(self): - autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows) - - if self.settings.os != "Windows": - autotools.fpic = self.options.get_safe("fPIC", True) - - autotools_vars = self._configure_autotools_vars() - - # tweaks for mingw - if self._is_mingw: - autotools.defines.append("_AMD64_") - - if cross_building(self) and is_apple_os(self): - autotools.defines.extend(['HAVE_SOCKET', 'HAVE_FCNTL_O_NONBLOCK']) - - configure_args = self._get_configure_command_args() - - if self.settings.os == "iOS" and self.settings.arch == "x86_64": - # please do not autodetect --build for the iOS simulator, thanks! - autotools.configure(vars=autotools_vars, args=configure_args, build=False) - else: - autotools.configure(vars=autotools_vars, args=configure_args) - - return autotools, autotools_vars - - @functools.lru_cache(1) - def _configure_cmake(self): + def _generate_with_cmake(self): if self._is_win_x_android: - cmake = CMake(self, generator="Ninja") + tc = CMakeToolchain(self, generator="Ninja") else: - cmake = CMake(self) - cmake.definitions["BUILD_TESTING"] = False - cmake.definitions["BUILD_CURL_EXE"] = False - cmake.definitions["CURL_DISABLE_LDAP"] = not self.options.with_ldap - cmake.definitions["BUILD_SHARED_LIBS"] = self.options.shared - cmake.definitions["CURL_STATICLIB"] = not self.options.shared - cmake.definitions["CMAKE_DEBUG_POSTFIX"] = "" + tc = CMakeToolchain(self) + tc.variables["BUILD_TESTING"] = False + tc.variables["BUILD_CURL_EXE"] = False + tc.variables["CURL_DISABLE_LDAP"] = not self.options.with_ldap + tc.variables["BUILD_SHARED_LIBS"] = self.options.shared + tc.variables["CURL_STATICLIB"] = not self.options.shared + tc.variables["CMAKE_DEBUG_POSTFIX"] = "" if Version(self.version) >= "7.81.0": - cmake.definitions["CURL_USE_SCHANNEL"] = self.options.with_ssl == "schannel" + tc.variables["CURL_USE_SCHANNEL"] = self.options.with_ssl == "schannel" elif Version(self.version) >= "7.72.0": - cmake.definitions["CMAKE_USE_SCHANNEL"] = self.options.with_ssl == "schannel" + tc.variables["CMAKE_USE_SCHANNEL"] = self.options.with_ssl == "schannel" else: - cmake.definitions["CMAKE_USE_WINSSL"] = self.options.with_ssl == "schannel" + tc.variables["CMAKE_USE_WINSSL"] = self.options.with_ssl == "schannel" if Version(self.version) >= "7.81.0": - cmake.definitions["CURL_USE_OPENSSL"] = self.options.with_ssl == "openssl" + tc.variables["CURL_USE_OPENSSL"] = self.options.with_ssl == "openssl" else: - cmake.definitions["CMAKE_USE_OPENSSL"] = self.options.with_ssl == "openssl" + tc.variables["CMAKE_USE_OPENSSL"] = self.options.with_ssl == "openssl" if Version(self.version) >= "7.81.0": - cmake.definitions["CURL_USE_WOLFSSL"] = self.options.with_ssl == "wolfssl" + tc.variables["CURL_USE_WOLFSSL"] = self.options.with_ssl == "wolfssl" elif Version(self.version) >= "7.70.0": - cmake.definitions["CMAKE_USE_WOLFSSL"] = self.options.with_ssl == "wolfssl" - cmake.definitions["USE_NGHTTP2"] = self.options.with_nghttp2 - cmake.definitions["CURL_ZLIB"] = self.options.with_zlib - cmake.definitions["CURL_BROTLI"] = self.options.with_brotli + tc.variables["CMAKE_USE_WOLFSSL"] = self.options.with_ssl == "wolfssl" + tc.variables["USE_NGHTTP2"] = self.options.with_nghttp2 + tc.variables["CURL_ZLIB"] = self.options.with_zlib + tc.variables["CURL_BROTLI"] = self.options.with_brotli if self._has_zstd_option: - cmake.definitions["CURL_ZSTD"] = self.options.with_zstd + tc.variables["CURL_ZSTD"] = self.options.with_zstd if Version(self.version) >= "7.81.0": - cmake.definitions["CURL_USE_LIBSSH2"] = self.options.with_libssh2 + tc.variables["CURL_USE_LIBSSH2"] = self.options.with_libssh2 else: - cmake.definitions["CMAKE_USE_LIBSSH2"] = self.options.with_libssh2 - cmake.definitions["ENABLE_ARES"] = self.options.with_c_ares + tc.variables["CMAKE_USE_LIBSSH2"] = self.options.with_libssh2 + tc.variables["ENABLE_ARES"] = self.options.with_c_ares if not self.options.with_c_ares: - cmake.definitions["ENABLE_THREADED_RESOLVER"] = self.options.with_threaded_resolver - cmake.definitions["CURL_DISABLE_PROXY"] = not self.options.with_proxy - cmake.definitions["USE_LIBRTMP"] = self.options.with_librtmp + tc.variables["ENABLE_THREADED_RESOLVER"] = self.options.with_threaded_resolver + tc.variables["CURL_DISABLE_PROXY"] = not self.options.with_proxy + tc.variables["USE_LIBRTMP"] = self.options.with_librtmp if Version(self.version) >= "7.75.0": - cmake.definitions["USE_LIBIDN2"] = self.options.with_libidn - cmake.definitions["CURL_DISABLE_RTSP"] = not self.options.with_rtsp - cmake.definitions["CURL_DISABLE_CRYPTO_AUTH"] = not self.options.with_crypto_auth - cmake.definitions["CURL_DISABLE_VERBOSE_STRINGS"] = not self.options.with_verbose_strings + tc.variables["USE_LIBIDN2"] = self.options.with_libidn + tc.variables["CURL_DISABLE_RTSP"] = not self.options.with_rtsp + tc.variables["CURL_DISABLE_CRYPTO_AUTH"] = not self.options.with_crypto_auth + tc.variables["CURL_DISABLE_VERBOSE_STRINGS"] = not self.options.with_verbose_strings # Also disables NTLM_WB if set to false if not self.options.with_ntlm: if Version(self.version) <= "7.77.0": - cmake.definitions["CURL_DISABLE_CRYPTO_AUTH"] = True + tc.variables["CURL_DISABLE_CRYPTO_AUTH"] = True else: - cmake.definitions["CURL_DISABLE_NTLM"] = True - cmake.definitions["NTLM_WB_ENABLED"] = self.options.with_ntlm_wb + tc.variables["CURL_DISABLE_NTLM"] = True + tc.variables["NTLM_WB_ENABLED"] = self.options.with_ntlm_wb - if self.options.with_ca_bundle == False: - cmake.definitions['CURL_CA_BUNDLE'] = 'none' + if self.options.with_ca_bundle is False: + tc.variables['CURL_CA_BUNDLE'] = 'none' elif self.options.with_ca_bundle: - cmake.definitions['CURL_CA_BUNDLE'] = self.options.with_ca_bundle + tc.variables['CURL_CA_BUNDLE'] = self.options.with_ca_bundle - if self.options.with_ca_path == False: - cmake.definitions['CURL_CA_PATH'] = 'none' + if self.options.with_ca_path is False: + tc.variables['CURL_CA_PATH'] = 'none' elif self.options.with_ca_path: - cmake.definitions['CURL_CA_PATH'] = self.options.with_ca_path - - cmake.configure(build_folder=self._build_subfolder) - return cmake + tc.variables['CURL_CA_PATH'] = self.options.with_ca_path - def _build_with_cmake(self): - cmake = self._configure_cmake() - cmake.build() + tc.generate() def package(self): - self.copy("COPYING", dst="licenses", src=self._source_subfolder) - self.copy("cacert.pem", dst="res") + copy(self, "COPYING", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder) + copy(self, pattern="cacert.pem", src=self.build_folder, dst="res") if self._is_using_cmake_build: - cmake = self._configure_cmake() + cmake = CMake(self) cmake.install() rmdir(self, os.path.join(self.package_folder, "lib", "cmake")) else: - with tools.run_environment(self): - with chdir(self, self._source_subfolder): - autotools, autotools_vars = self._configure_autotools() - autotools.install(vars=autotools_vars) + autotools = Autotools(self) + autotools.install() + fix_apple_shared_install_name(self) rmdir(self, os.path.join(self.package_folder, "share")) - for la_file in glob.glob(os.path.join(self.package_folder, "lib", "*.la")): - os.remove(la_file) + rm(self, "*.la", os.path.join(self.package_folder, "lib")) if self._is_mingw and self.options.shared: # Handle only mingw libs - self.copy(pattern="*.dll", dst="bin", keep_path=False) - self.copy(pattern="*.dll.a", dst="lib", keep_path=False) - self.copy(pattern="*.lib", dst="lib", keep_path=False) + copy(self, pattern="*.dll", src=self.build_folder, dst="bin", keep_path=False) + copy(self, pattern="*.dll.a", src=self.build_folder, dst="lib", keep_path=False) + copy(self, pattern="*.lib", src=self.build_folder, dst="lib", keep_path=False) rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) def package_info(self): diff --git a/recipes/libcurl/all/test_package/CMakeLists.txt b/recipes/libcurl/all/test_package/CMakeLists.txt index c1a339c384346..a36a89aea9b2b 100644 --- a/recipes/libcurl/all/test_package/CMakeLists.txt +++ b/recipes/libcurl/all/test_package/CMakeLists.txt @@ -1,9 +1,6 @@ cmake_minimum_required(VERSION 3.1) project(test_package C) -include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) -conan_basic_setup(TARGETS) - find_package(CURL REQUIRED) add_executable(${PROJECT_NAME} test_package.c) diff --git a/recipes/libcurl/all/test_package/conanfile.py b/recipes/libcurl/all/test_package/conanfile.py index 6221e377a7254..b0f5c0aed58a5 100644 --- a/recipes/libcurl/all/test_package/conanfile.py +++ b/recipes/libcurl/all/test_package/conanfile.py @@ -1,22 +1,21 @@ -from conans import ConanFile, CMake -from conan.tools.build import cross_building +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake import os import subprocess import re class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package" - - def build_requirements(self): - if self.settings.os == "Macos" and self.settings.arch == "armv8": - # Workaround for CMake bug with error message: - # Attempting to use @rpath without CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG being - # set. This could be because you are using a Mac OS X version less than 10.5 - # or because CMake's platform configuration is corrupt. - # FIXME: Remove once CMake on macOS/M1 CI runners is upgraded. - self.build_requires("cmake/3.22.0") + settings = "os", "arch", "compiler", "build_type" + 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) @@ -25,14 +24,11 @@ def build(self): @property def _test_executable(self): - if self.settings.os == "Windows": - return os.path.join("bin", "test_package.exe") - else: - return os.path.join("bin", "test_package") + return os.path.join(self.cpp.build.bindirs[0], "test_package") def test(self): - if not cross_building(self): - self.run(self._test_executable, run_environment=True) + if can_run(self): + self.run(self._test_executable, env="conanrun") else: # We will dump information for the generated executable if self.settings.os in ["Android", "iOS"]: @@ -42,15 +38,15 @@ def test(self): output = subprocess.check_output(["file", self._test_executable]).decode() if self.settings.os == "Macos" and self.settings.arch == "armv8": - assert "Mach-O 64-bit executable arm64" in output, "Not found in output: {}".format(output) + assert "Mach-O 64-bit executable arm64" in output, f"Not found in output: {output}" elif self.settings.os == "Linux": if self.settings.arch == "armv8_32": - assert re.search(r"Machine:\s+ARM", output), "Not found in output: {}".format(output) + assert re.search(r"Machine:\s+ARM", output), f"Not found in output: {output}" elif "armv8" in self.settings.arch: - assert re.search(r"Machine:\s+AArch64", output), "Not found in output: {}".format(output) + assert re.search(r"Machine:\s+AArch64", output), f"Not found in output: {output}" elif "arm" in self.settings.arch: - assert re.search(r"Machine:\s+ARM", output), "Not found in output: {}".format(output) + assert re.search(r"Machine:\s+ARM", output), f"Not found in output: {output}" elif self.settings.os == "Windows": # FIXME: It satisfies not only MinGW - assert re.search(r"PE32.*executable.*Windows", output), "Not found in output: {}".format(output) + assert re.search(r"PE32.*executable.*Windows", output), f"Not found in output: {output}" diff --git a/recipes/libcurl/all/test_v1_package/CMakeLists.txt b/recipes/libcurl/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..87b6e499b5d8e --- /dev/null +++ b/recipes/libcurl/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package C) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +find_package(CURL REQUIRED) + +add_executable(${PROJECT_NAME} ../test_package/test_package.c) +target_link_libraries(${PROJECT_NAME} CURL::libcurl) diff --git a/recipes/libcurl/all/test_v1_package/conanfile.py b/recipes/libcurl/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..7ebb558a2d5e3 --- /dev/null +++ b/recipes/libcurl/all/test_v1_package/conanfile.py @@ -0,0 +1,43 @@ +from conans import ConanFile, CMake, tools +import os +import subprocess +import re + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake", "cmake_find_package" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + @property + def _test_executable(self): + return os.path.join("bin", "test_package") + + def test(self): + if not tools.cross_building(self): + self.run(self._test_executable, run_environment=True) + else: + # We will dump information for the generated executable + if self.settings.os in ["Android", "iOS"]: + # FIXME: Check output for these hosts + return + + output = subprocess.check_output(["file", self._test_executable]).decode() + + if self.settings.os == "Macos" and self.settings.arch == "armv8": + assert "Mach-O 64-bit executable arm64" in output, f"Not found in output: {output}" + + elif self.settings.os == "Linux": + if self.settings.arch == "armv8_32": + assert re.search(r"Machine:\s+ARM", output), f"Not found in output: {output}" + elif "armv8" in self.settings.arch: + assert re.search(r"Machine:\s+AArch64", output), f"Not found in output: {output}" + elif "arm" in self.settings.arch: + assert re.search(r"Machine:\s+ARM", output), f"Not found in output: {output}" + + elif self.settings.os == "Windows": # FIXME: It satisfies not only MinGW + assert re.search(r"PE32.*executable.*Windows", output), f"Not found in output: {output}"