From e4f04557d19ceac3aab678be8d0d7dd696d0f3a7 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 6 Feb 2024 10:03:48 +0100 Subject: [PATCH 01/39] Ported over recipe of Ahajha fork This is a quick and dirty way of testing if the PR made by @Ahajha for CPython 3.10.x, 3.11.x and 3.12.x can be be used by us in the future. Contribute to CURA-11079 Co-authored-by: Alex Trotta --- recipes/cpython/all/conandata.yml | 119 +-- recipes/cpython/all/conanfile.py | 824 +++++++++++------- .../all/patches/2.7.18-0001-msvc.patch | 278 ------ .../2.7.18-0004-disable-macos-tcltk.patch | 15 - .../all/patches/2.7/2.7.18-0001-msvc.patch | 93 ++ .../2.7.18-0002-add-support-msvc-14.patch | 0 .../2.7.18-0003-msvc-fix-static.patch | 0 .../all/patches/3.10.0-0001-msvc.patch | 416 --------- ...0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch | 15 - .../3.10.0-0005-disable-macos-tcltk.patch | 13 - .../3.10.4-0005-disable-macos-tcltk.patch | 13 - .../{ => 3.10}/3.10.0-0003-_ctypes-ffi.patch | 0 .../3.11/3.11.7-0001-_ctypes-ffi.patch | 37 + .../3.12/3.12.1-0001-_ctypes-ffi.patch | 37 + .../3.12/3.12.1-0002-remove-module-deps.patch | 50 ++ .../cpython/all/patches/3.7.9-0001-msvc.patch | 416 --------- ...9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch | 15 - .../3.7.9-0003-disable-macos-tcltk.patch | 15 - .../all/patches/3.7/3.7.9-0001-msvc.patch | 19 + .../all/patches/3.8.12-0001-msvc.patch | 431 --------- ...2-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch | 15 - .../3.8.12-0004-disable-macos-tcltk.patch | 13 - .../{ => 3.8}/3.8.12-0002-_ctypes-ffi.patch | 0 .../cpython/all/patches/3.9.7-0001-msvc.patch | 434 --------- ...7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch | 15 - .../3.9.7-0005-disable-macos-tcltk.patch | 13 - .../{ => 3.9}/3.9.7-0002-_msi-vcxproj.patch | 0 .../{ => 3.9}/3.9.7-0003-_ctypes-ffi.patch | 0 .../patches/3.x-0002-remove-module-deps.patch | 10 + .../cpython/all/test_package/CMakeLists.txt | 33 +- recipes/cpython/all/test_package/conanfile.py | 300 ++++--- .../all/test_package/py3/test_package.c | 1 - recipes/cpython/all/test_package/setup.py | 14 +- .../cpython/all/test_package/test_package.py | 47 +- .../all/test_v1_package/CMakeLists.txt | 100 +++ .../cpython/all/test_v1_package/conanfile.py | 212 +++++ .../all/test_v1_package/py2/test_module.c | 42 + .../all/test_v1_package/py2/test_package.c | 12 + .../all/test_v1_package/py3/test_module.c | 52 ++ .../all/test_v1_package/py3/test_package.c | 20 + recipes/cpython/all/test_v1_package/setup.py | 35 + recipes/cpython/config.yml | 6 +- 42 files changed, 1515 insertions(+), 2665 deletions(-) delete mode 100644 recipes/cpython/all/patches/2.7.18-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/2.7.18-0004-disable-macos-tcltk.patch create mode 100644 recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch rename recipes/cpython/all/patches/{ => 2.7}/2.7.18-0002-add-support-msvc-14.patch (100%) rename recipes/cpython/all/patches/{ => 2.7}/2.7.18-0003-msvc-fix-static.patch (100%) delete mode 100644 recipes/cpython/all/patches/3.10.0-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.10.0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch delete mode 100644 recipes/cpython/all/patches/3.10.0-0005-disable-macos-tcltk.patch delete mode 100644 recipes/cpython/all/patches/3.10.4-0005-disable-macos-tcltk.patch rename recipes/cpython/all/patches/{ => 3.10}/3.10.0-0003-_ctypes-ffi.patch (100%) create mode 100644 recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch create mode 100644 recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch create mode 100644 recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch delete mode 100644 recipes/cpython/all/patches/3.7.9-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.7.9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch delete mode 100644 recipes/cpython/all/patches/3.7.9-0003-disable-macos-tcltk.patch create mode 100644 recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.8.12-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.8.12-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch delete mode 100644 recipes/cpython/all/patches/3.8.12-0004-disable-macos-tcltk.patch rename recipes/cpython/all/patches/{ => 3.8}/3.8.12-0002-_ctypes-ffi.patch (100%) delete mode 100644 recipes/cpython/all/patches/3.9.7-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.9.7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch delete mode 100644 recipes/cpython/all/patches/3.9.7-0005-disable-macos-tcltk.patch rename recipes/cpython/all/patches/{ => 3.9}/3.9.7-0002-_msi-vcxproj.patch (100%) rename recipes/cpython/all/patches/{ => 3.9}/3.9.7-0003-_ctypes-ffi.patch (100%) create mode 100644 recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch create mode 100644 recipes/cpython/all/test_v1_package/CMakeLists.txt create mode 100644 recipes/cpython/all/test_v1_package/conanfile.py create mode 100644 recipes/cpython/all/test_v1_package/py2/test_module.c create mode 100644 recipes/cpython/all/test_v1_package/py2/test_package.c create mode 100644 recipes/cpython/all/test_v1_package/py3/test_module.c create mode 100644 recipes/cpython/all/test_v1_package/py3/test_package.c create mode 100644 recipes/cpython/all/test_v1_package/setup.py diff --git a/recipes/cpython/all/conandata.yml b/recipes/cpython/all/conandata.yml index 8d7da3f..8b2d6fb 100644 --- a/recipes/cpython/all/conandata.yml +++ b/recipes/cpython/all/conandata.yml @@ -1,86 +1,55 @@ sources: - "3.10.4": - url: "https://www.python.org/ftp/python/3.10.4/Python-3.10.4.tgz" - sha256: "f3bcc65b1d5f1dc78675c746c98fcee823c038168fc629c5935b044d0911ad28" - "3.10.0": - url: "https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tgz" - sha256: "c4e0cbad57c90690cb813fb4663ef670b4d0f587d8171e2c42bd4c9245bd2758" - "3.9.7": - url: "https://www.python.org/ftp/python/3.9.7/Python-3.9.7.tgz" - sha256: "a838d3f9360d157040142b715db34f0218e535333696a5569dc6f854604eb9d1" - "3.8.12": - url: "https://www.python.org/ftp/python/3.8.12/Python-3.8.12.tgz" - sha256: "316aa33f3b7707d041e73f246efedb297a70898c4b91f127f66dc8d80c596f1a" - "3.7.12": - url: "https://www.python.org/ftp/python/3.7.12/Python-3.7.12.tgz" - sha256: "33b4daaf831be19219659466d12645f87ecec6eb21d4d9f9711018a7b66cce46" + "3.12.1": + url: "https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz" + sha256: "d01ec6a33bc10009b09c17da95cc2759af5a580a7316b3a446eb4190e13f97b2" + "3.11.7": + url: "https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz" + sha256: "068c05f82262e57641bd93458dfa883128858f5f4997aad7a36fd25b13b29209" + "3.10.13": + url: "https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz" + sha256: "698ec55234c1363bd813b460ed53b0f108877c7a133d48bde9a50a1eb57b7e65" + "3.9.18": + url: "https://www.python.org/ftp/python/3.9.18/Python-3.9.18.tgz" + sha256: "504ce8cfd59addc04c22f590377c6be454ae7406cb1ebf6f5a350149225a9354" + "3.8.18": + url: "https://www.python.org/ftp/python/3.8.18/Python-3.8.18.tgz" + sha256: "7c5df68bab1be81a52dea0cc2e2705ea00553b67107a301188383d7b57320b16" + "3.7.17": + url: "https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tgz" + sha256: "fd50161bc2a04f4c22a0971ff0f3856d98b4bf294f89740a9f06b520aae63b49" "2.7.18": url: "https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz" sha256: "da3080e3b488f648a3d7a4560ddee895284c3380b11d6de75edb986526b9a814" patches: - "3.10.4": - - patch_file: "patches/3.10.0-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0002-_msi-vcxproj.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.10.0-0003-_ctypes-ffi.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.10.4-0005-disable-macos-tcltk.patch" - base_path: "source_subfolder" + "3.12.1": + - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" + - patch_file: "patches/3.12/3.12.1-0001-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - base_path: "source_subfolder" - "3.10.0": - - patch_file: "patches/3.10.0-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0002-_msi-vcxproj.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.10.0-0003-_ctypes-ffi.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.10.0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.10.0-0005-disable-macos-tcltk.patch" - base_path: "source_subfolder" + - patch_file: "patches/3.12/3.12.1-0002-remove-module-deps.patch" + "3.11.7": + - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" + - patch_file: "patches/3.11/3.11.7-0001-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - base_path: "source_subfolder" - "3.9.7": - - patch_file: "patches/3.9.7-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0002-_msi-vcxproj.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0003-_ctypes-ffi.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.9.7-0005-disable-macos-tcltk.patch" - base_path: "source_subfolder" + - patch_file: "patches/3.x-0002-remove-module-deps.patch" + "3.10.13": + - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" + - patch_file: "patches/3.10/3.10.0-0003-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - base_path: "source_subfolder" - "3.8.12": - - patch_file: "patches/3.8.12-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.8.12-0002-_ctypes-ffi.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.8.12-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.8.12-0004-disable-macos-tcltk.patch" - base_path: "source_subfolder" + - patch_file: "patches/3.x-0002-remove-module-deps.patch" + "3.9.18": + - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" + - patch_file: "patches/3.9/3.9.7-0003-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - base_path: "source_subfolder" - "3.7.12": - - patch_file: "patches/3.7.9-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.7.9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch" - base_path: "source_subfolder" - - patch_file: "patches/3.7.9-0003-disable-macos-tcltk.patch" - base_path: "source_subfolder" + - patch_file: "patches/3.x-0002-remove-module-deps.patch" + "3.8.18": + - patch_file: "patches/3.8/3.8.12-0002-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - base_path: "source_subfolder" + - patch_file: "patches/3.x-0002-remove-module-deps.patch" + "3.7.17": + - patch_file: "patches/3.7/3.7.9-0001-msvc.patch" + - patch_file: "patches/3.x-0001-relocatable-python-config.patch" + - patch_file: "patches/3.x-0002-remove-module-deps.patch" "2.7.18": - - patch_file: "patches/2.7.18-0001-msvc.patch" - base_path: "source_subfolder" - - patch_file: "patches/2.7.18-0002-add-support-msvc-14.patch" - base_path: "source_subfolder" - - patch_file: "patches/2.7.18-0003-msvc-fix-static.patch" - base_path: "source_subfolder" - - patch_file: "patches/2.7.18-0004-disable-macos-tcltk.patch" - base_path: "source_subfolder" + - patch_file: "patches/2.7/2.7.18-0001-msvc.patch" + - patch_file: "patches/2.7/2.7.18-0002-add-support-msvc-14.patch" + - patch_file: "patches/2.7/2.7.18-0003-msvc-fix-static.patch" diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index a0d341f..d2f5f24 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -1,21 +1,29 @@ -from conans import AutoToolsBuildEnvironment, ConanFile, MSBuild, tools -from conans.errors import ConanInvalidConfiguration -from io import StringIO import os import re import textwrap -required_conan_version = ">=1.33.0" +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration, ConanException +from conan.tools.apple import is_apple_os, fix_apple_shared_install_name +from conan.tools.env import VirtualRunEnv +from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, load, mkdir, replace_in_file, rm, rmdir, save, unzip +from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps, PkgConfigDeps +from conan.tools.layout import basic_layout +from conan.tools.microsoft import MSBuildDeps, MSBuildToolchain, MSBuild, is_msvc, is_msvc_static_runtime, msvc_runtime_flag, msvs_toolset +from conan.tools.scm import Version + +required_conan_version = ">=1.58.0" class CPythonConan(ConanFile): name = "cpython" + description = "Python is a programming language that lets you work quickly and integrate systems more effectively." + license = "Python-2.0" url = "https://github.com/conan-io/conan-center-index" homepage = "https://www.python.org" - description = "Python is a programming language that lets you work quickly and integrate systems more effectively." topics = ("python", "cpython", "language", "script") - license = ("Python-2.0",) - exports_sources = "patches/**" + + package_type = "library" settings = "os", "arch", "compiler", "build_type" options = { "shared": [True, False], @@ -64,44 +72,31 @@ class CPythonConan(ConanFile): "env_vars": True, } - _autotools = None - - @property - def _source_subfolder(self): - return "source_subfolder" - - @property - def _version_number_only(self): - return re.match(r"^([0-9.]+)", self.version).group(1) - - @property - def _version_tuple(self): - return tuple(self._version_number_only.split(".")) - @property def _supports_modules(self): - return self.settings.compiler != "Visual Studio" or self.options.shared + return not is_msvc(self) or self.options.shared @property def _version_suffix(self): - if self.settings.compiler == "Visual Studio": - joiner = "" - else: - joiner = "." - return joiner.join(self._version_tuple[:2]) + v = Version(self.version) + joiner = "" if is_msvc(self) else "." + return f"{v.major}{joiner}{v.minor}" @property def _is_py3(self): - return tools.Version(self._version_number_only).major == "3" + return Version(self.version).major == 3 @property def _is_py2(self): - return tools.Version(self._version_number_only).major == "2" + return Version(self.version).major == 2 + + def export_sources(self): + export_conandata_patches(self) def config_options(self): if self.settings.os == "Windows": del self.options.fPIC - if self.settings.compiler == "Visual Studio": + if is_msvc(self): del self.options.lto del self.options.docstrings del self.options.pymalloc @@ -116,223 +111,410 @@ def config_options(self): del self.options.with_bsddb del self.options.unicode - del self.settings.compiler.libcxx - del self.settings.compiler.cppstd + self.settings.compiler.rm_safe("libcxx") + self.settings.compiler.rm_safe("cppstd") def configure(self): if self.options.shared: - del self.options.fPIC + self.options.rm_safe("fPIC") if not self._supports_modules: - del self.options.with_bz2 - del self.options.with_sqlite3 - del self.options.with_tkinter + self.options.rm_safe("with_bz2") + self.options.rm_safe("with_sqlite3") + self.options.rm_safe("with_tkinter") - del self.options.with_bsddb - del self.options.with_lzma - if self.settings.compiler == "Visual Studio": - # The msbuild generator only works with Visual Studio - self.generators.append("MSBuildDeps") + self.options.rm_safe("with_bsddb") + self.options.rm_safe("with_lzma") - def validate(self): - if self.options.shared: - if self.settings.compiler == "Visual Studio" and "MT" in self.settings.compiler.runtime: - raise ConanInvalidConfiguration("cpython does not support MT(d) runtime when building a shared cpython library") - if self.settings.compiler == "Visual Studio": - if self.options.optimizations: - raise ConanInvalidConfiguration("This recipe does not support optimized MSVC cpython builds (yet)") - # FIXME: should probably throw when cross building - # FIXME: optimizations for Visual Studio, before building the final `build_type`: - # 1. build the MSVC PGInstrument build_type, - # 2. run the instrumented binaries, (PGInstrument should have created a `python.bat` file in the PCbuild folder) - # 3. build the MSVC PGUpdate build_type - if self.settings.build_type == "Debug" and "d" not in self.settings.compiler.runtime: - raise ConanInvalidConfiguration("Building debug cpython requires a debug runtime (Debug cpython requires _CrtReportMode symbol, which only debug runtimes define)") - if self._is_py2: - if self.settings.compiler.version >= tools.Version("14"): - self.output.warn("Visual Studio versions 14 and higher were never officially supported by the CPython developers") - if str(self.settings.arch) not in self._msvc_archs: - raise ConanInvalidConfiguration("Visual Studio does not support this architecture") + def layout(self): + basic_layout(self, src_folder="src") - if not self.options.shared and tools.Version(self._version_number_only) >= "3.10": - raise ConanInvalidConfiguration("Static msvc build disabled (>=3.10) due to \"AttributeError: module 'sys' has no attribute 'winver'\"") - - if self.options.get_safe("with_curses", False) and not self.options["ncurses"].with_widec: - raise ConanInvalidConfiguration("cpython requires ncurses with wide character support") - - def package_id(self): - del self.info.options.env_vars - - def source(self): - tools.get(**self.conan_data["sources"][self.version], - destination=self._source_subfolder, strip_root=True) + @property + def _use_vendored_libffi(self): + # cpython < 3.8 on MSVC uses an ancient libffi 2.00-beta + # (which is not available at cci, and is API/ABI incompatible with current 3.2+) + return Version(self.version) < "3.8" and is_msvc(self) @property def _with_libffi(self): - # cpython 3.7.x on MSVC uses an ancient libffi 2.00-beta (which is not available at cci, and is API/ABI incompatible with current 3.2+) - return self._supports_modules \ - and (self.settings.compiler != "Visual Studio" or tools.Version(self._version_number_only) >= "3.8") + return self._supports_modules and not self._use_vendored_libffi + + def build_requirements(self): + if Version(self.version) >= "3.11" and not is_msvc(self) and not self.conf.get("tools.gnu:pkg_config", check_type=str): + self.tool_requires("pkgconf/2.1.0") def requirements(self): - self.requires("zlib/1.2.11") + self.requires("zlib/[>=1.2.11 <2]") if self._supports_modules: - self.requires("openssl/1.1.1w") - self.requires("expat/2.4.1") + self.requires("openssl/[>=1.1 <4]") + self.requires("expat/2.5.0") if self._with_libffi: - self.requires("libffi/3.2.1") - if tools.Version(self._version_number_only) < "3.8": + self.requires("libffi/3.4.4") + if Version(self.version) < "3.8": self.requires("mpdecimal/2.4.2") - elif tools.Version(self._version_number_only) < "3.10": + elif Version(self.version) < "3.10" or is_apple_os(self): + # FIXME: mpdecimal > 2.5.0 on MacOS causes the _decimal module to not be importable self.requires("mpdecimal/2.5.0") else: - self.requires("mpdecimal/2.5.0") # FIXME: no 2.5.1 to troubleshoot apple + self.requires("mpdecimal/2.5.1") if self.settings.os != "Windows": - if not tools.is_apple_os(self.settings.os): + if not is_apple_os(self): self.requires("util-linux-libuuid/2.39.2") - self.requires("libxcrypt/4.4.25") + # If crypt.h is detected, it is included in the public headers. + self.requires("libxcrypt/4.4.36", transitive_headers=True, transitive_libs=True) if self.options.get_safe("with_bz2"): self.requires("bzip2/1.0.8") if self.options.get_safe("with_gdbm", False): - self.requires("gdbm/1.19") + self.requires("gdbm/1.23") if self.options.get_safe("with_nis", False): # TODO: Add nis when available. raise ConanInvalidConfiguration("nis is not available on CCI (yet)") if self.options.get_safe("with_sqlite3"): - self.requires("sqlite3/3.36.0") + self.requires("sqlite3/3.44.2") if self.options.get_safe("with_tkinter"): self.requires("tk/8.6.10") if self.options.get_safe("with_curses", False): - self.requires("ncurses/6.3") + # Used in a public header + # https://github.com/python/cpython/blob/v3.10.13/Include/py_curses.h#L34 + self.requires("ncurses/6.4", transitive_headers=True, transitive_libs=True) if self.options.get_safe("with_bsddb", False): self.requires("libdb/5.3.28") if self.options.get_safe("with_lzma", False): - self.requires("xz_utils/5.2.5") + self.requires("xz_utils/5.4.5") + + def package_id(self): + del self.info.options.env_vars + + def validate(self): + if self.options.shared: + if is_msvc_static_runtime(self): + raise ConanInvalidConfiguration( + "cpython does not support MT(d) runtime when building a shared cpython library" + ) + if is_msvc(self): + if self.options.optimizations: + raise ConanInvalidConfiguration( + "This recipe does not support optimized MSVC cpython builds (yet)" + ) + # FIXME: should probably throw when cross building + # FIXME: optimizations for Visual Studio, before building the final `build_type`: + # 1. build the MSVC PGInstrument build_type, + # 2. run the instrumented binaries, (PGInstrument should have created a `python.bat` file in the PCbuild folder) + # 3. build the MSVC PGUpdate build_type + if self.settings.build_type == "Debug" and "d" not in msvc_runtime_flag(self): + raise ConanInvalidConfiguration( + "Building debug cpython requires a debug runtime (Debug cpython requires _CrtReportMode" + " symbol, which only debug runtimes define)" + ) + if str(self.settings.arch) not in self._msvc_archs: + raise ConanInvalidConfiguration("Visual Studio does not support this architecture") + if not self.options.shared and Version(self.version) >= "3.10": + # Static CPython on Windows is only loosely supported, see https://github.com/python/cpython/issues/110234 + # 3.10 fails during the test, 3.11 fails during the build (missing symbol that seems to be DLL specific: PyWin_DLLhModule) + raise ConanInvalidConfiguration("Static msvc build disabled (>=3.10) due to \"AttributeError: module 'sys' has no attribute 'winver'\"") + + if self.options.get_safe("with_curses", False) and not self.dependencies["ncurses"].options.with_widec: + raise ConanInvalidConfiguration("cpython requires ncurses with wide character support") + + if self._supports_modules: + if Version(self.version) < "3.8.0": + if self.dependencies["mpdecimal"].ref.version >= Version("2.5.0"): + raise ConanInvalidConfiguration("cpython versions lesser then 3.8.0 require a mpdecimal lesser then 2.5.0") + elif Version(self.version) >= "3.9.0": + if self.dependencies["mpdecimal"].ref.version < Version("2.5.0"): + raise ConanInvalidConfiguration("cpython 3.9.0 (and newer) requires (at least) mpdecimal 2.5.0") - def _configure_autotools(self): - if self._autotools: - return self._autotools - self._autotools = AutoToolsBuildEnvironment(self, win_bash=tools.os_info.is_windows) - self._autotools.libs = [] + if is_apple_os(self) and self.settings.arch == "armv8" and Version(self.version) < "3.8.0": + raise ConanInvalidConfiguration("cpython 3.7 and older does not support Apple ARM CPUs") + + if self.settings.compiler == "gcc" and Version(self.settings.compiler.version).major == 9 and Version(self.version) == "3.12.1": + raise ConanInvalidConfiguration("FIXME: GCC 9 produces an internal compiler error locally, and a link error in CCI") + + def source(self): + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def _generate_autotools(self): + tc = AutotoolsToolchain(self, prefix=self.package_folder) yes_no = lambda v: "yes" if v else "no" - conf_args = [ - "--enable-shared={}".format(yes_no(self.options.shared)), + tc.configure_args += [ "--with-doc-strings={}".format(yes_no(self.options.docstrings)), "--with-pymalloc={}".format(yes_no(self.options.pymalloc)), "--with-system-expat", - "--with-system-ffi", "--enable-optimizations={}".format(yes_no(self.options.optimizations)), "--with-lto={}".format(yes_no(self.options.lto)), "--with-pydebug={}".format(yes_no(self.settings.build_type == "Debug")), + "--disable-test-modules", ] + if not self._use_vendored_libffi: + tc.configure_args += ["--with-system-ffi"] if self._is_py2: - conf_args.extend([ - "--enable-unicode={}".format(yes_no(self.options.unicode)), - ]) + tc.configure_args += ["--enable-unicode={}".format(yes_no(self.options.unicode))] if self._is_py3: - conf_args.extend([ + tc.configure_args += [ "--with-system-libmpdec", - "--with-openssl={}".format(self.deps_cpp_info["openssl"].rootpath), - "--enable-loadable-sqlite-extensions={}".format(yes_no(not self.options["sqlite3"].omit_load_extension)), - ]) - if self.settings.compiler == "intel": - conf_args.extend(["--with-icc"]) - if tools.get_env("CC") or self.settings.compiler != "gcc": - conf_args.append("--without-gcc") - if self.options.with_tkinter: + "--with-openssl={}".format(self.dependencies["openssl"].package_folder), + "--enable-loadable-sqlite-extensions={}".format( + yes_no(not self.dependencies["sqlite3"].options.omit_load_extension) + ), + ] + if self.settings.compiler == "intel-cc": + tc.configure_args.append("--with-icc") + if os.environ.get("CC") or self.settings.compiler != "gcc": + tc.configure_args.append("--without-gcc") + if self.options.with_tkinter and Version(self.version) < "3.11": tcltk_includes = [] tcltk_libs = [] # FIXME: collect using some conan util (https://github.com/conan-io/conan/issues/7656) for dep in ("tcl", "tk", "zlib"): - tcltk_includes += ["-I{}".format(d) for d in self.deps_cpp_info[dep].include_paths] - tcltk_libs += ["-l{}".format(lib) for lib in self.deps_cpp_info[dep].libs] - if self.settings.os == "Linux" and not self.options["tk"].shared: + cpp_info = self.dependencies[dep].cpp_info.aggregated_components() + tcltk_includes += [f"-I{d}" for d in cpp_info.includedirs] + tcltk_libs += [f"-L{lib}" for lib in cpp_info.libdirs] + tcltk_libs += [f"-l{lib}" for lib in cpp_info.libs] + if self.settings.os in ["Linux", "FreeBSD"] and not self.dependencies["tk"].options.shared: # FIXME: use info from xorg.components (x11, xscrnsaver) - tcltk_libs.extend(["-l{}".format(lib) for lib in ("X11", "Xss")]) - conf_args.extend([ + tcltk_libs.extend([f"-l{lib}" for lib in ("X11", "Xss")]) + tc.configure_args += [ "--with-tcltk-includes={}".format(" ".join(tcltk_includes)), "--with-tcltk-libs={}".format(" ".join(tcltk_libs)), - ]) - if self.settings.os in ("Linux", "FreeBSD"): - # Building _testembed fails due to missing pthread/rt symbols - self._autotools.link_flags.append("-lpthread") - - build = None - if tools.cross_building(self) and not tools.cross_building(self, skip_x64_x86=True): - # Building from x86_64 to x86 is not a "real" cross build, so set build == host - build = tools.get_gnu_triplet(str(self.settings.os), str(self.settings.arch), str(self.settings.compiler)) - self._autotools.configure(args=conf_args, configure_dir=self._source_subfolder, build=build) - return self._autotools + ] + if not is_apple_os(self): + tc.extra_ldflags.append('-Wl,--as-needed') + + tc.generate() + + deps = AutotoolsDeps(self) + deps.generate() + if Version(self.version) >= "3.11": + pkgdeps = PkgConfigDeps(self) + pkgdeps.generate() + + def generate(self): + VirtualRunEnv(self).generate(scope="build") + + if is_msvc(self): + # The msbuild generator only works with Visual Studio + deps = MSBuildDeps(self) + deps.generate() + # The toolchain.props is not injected yet, but it also generates VCVars + toolchain = MSBuildToolchain(self) + toolchain.properties["IncludeExternals"] = "true" + toolchain.generate() + else: + self._generate_autotools() + + def _msvc_project_path(self, name): + return os.path.join(self.source_folder, "PCBuild", f"{name}.vcxproj") + + def _regex_replace_in_file(self, filename, pattern, replacement): + content = load(self, filename) + content = re.sub(pattern, replacement, content) + save(self, filename, content) + + def _inject_conan_props_file(self, project_basename, dep_name, condition=True): + if condition: + search = '' if self._is_py3 else '' + replace_in_file(self, + self._msvc_project_path(project_basename), + search, + search + f'') + + def _patch_setup_py(self): + setup_py = os.path.join(self.source_folder, "setup.py") + if self._is_py3 and Version(self.version) < "3.10": + replace_in_file(self, setup_py, ":libmpdec.so.2", "mpdec") + + if self.options.get_safe("with_curses", False): + # FIXME: this will link to ALL libraries of ncurses. Only need to link to ncurses(w) (+ eventually tinfo) + ncurses_info = self.dependencies["ncurses"].cpp_info.aggregated_components() + replace_in_file(self, setup_py, + "curses_libs = ", + "curses_libs = {} #".format(repr(ncurses_info.libs + ncurses_info.system_libs))) + + if self._supports_modules: + openssl = self.dependencies["openssl"].cpp_info.aggregated_components() + zlib = self.dependencies["zlib"].cpp_info.aggregated_components() + if self._is_py2: + replace_in_file(self, setup_py, "'/usr/local/ssl/include',", f"{(openssl.includedirs + zlib.includedirs)[1:-2]}") + replace_in_file(self, setup_py, "'/usr/contrib/ssl/include/'", "") + replace_in_file(self, setup_py, "lib_dirs = []", f"lib_dirs = {openssl.libdirs + zlib.libdirs}") + replace_in_file(self, setup_py, "libraries = ['ssl', 'crypto'],", f"libraries = {openssl.libs + zlib.libs}, #") + elif Version(self.version) < "3.11": + replace_in_file(self, setup_py, + "openssl_includes = ", + f"openssl_includes = {openssl.includedirs + zlib.includedirs} #") + replace_in_file(self, setup_py, + "openssl_libdirs = ", + f"openssl_libdirs = {openssl.libdirs + zlib.libdirs} #") + replace_in_file(self, setup_py, + "openssl_libs = ", + f"openssl_libs = {openssl.libs + zlib.libs} #") + + if Version(self.version) < "3.8": + replace_in_file(self, setup_py, "self.detect_tkinter_darwin(inc_dirs, lib_dirs)", "False") + elif Version(self.version) < "3.11": + replace_in_file(self, setup_py, "if (MACOS and self.detect_tkinter_darwin())", "if (False)") + + def _patch_msvc_projects(self): + self._regex_replace_in_file(self._msvc_project_path("_bz2" if self._is_py3 else "bz2"), r'.*Include=\"\$\(bz2Dir\).*', "") + if self._with_libffi: + replace_in_file(self, self._msvc_project_path("_ctypes"), '', "") + if Version(self.version) < "3.11": + replace_in_file(self, self._msvc_project_path("_ctypes"), "FFI_BUILDING;", "") + + if self._is_py3: + replace_in_file(self, self._msvc_project_path("_hashlib"), '', "") + replace_in_file(self, self._msvc_project_path("_ssl"), '', "") + + # For mpdecimal, we need to remove all headers and all c files *except* the main module file, _decimal.c + self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\.*\.h.*', "") + self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\libmpdec\\.*\.c.*', "") + # There is also an assembly file with a complicated build step as part of the mpdecimal build + replace_in_file(self, self._msvc_project_path("_decimal"), "", "-->") + # Remove extra include directory + replace_in_file(self, self._msvc_project_path("_decimal"), "..\Modules\_decimal\libmpdec;", "") + + replace_in_file(self, self._msvc_project_path("_sqlite3"), + '', + '') + + if self._is_py3: + replace_in_file(self, self._msvc_project_path("_lzma"), "", "$(ConanPreprocessorDefinitions);") + replace_in_file(self, self._msvc_project_path("_lzma"), "$(OutDir)liblzma$(PyDebugExt).lib;", "") + replace_in_file(self, self._msvc_project_path("_lzma"), + '', + '') + + replace_in_file(self, self._msvc_project_path("pyexpat"), + "$(PySourcePath)Modules\expat;", + "") + replace_in_file(self, self._msvc_project_path("pyexpat"), ("HAVE_EXPAT_H;" if self._is_py3 and Version(self.version) < "3.11" else "") + "XML_STATIC;", "") + self._regex_replace_in_file(self._msvc_project_path("pyexpat"), r'.*Include=\"\.\.\\Modules\\expat\\.*" />', "") + + replace_in_file(self, self._msvc_project_path("_elementtree"), + "..\Modules\expat;", + "") + replace_in_file(self, self._msvc_project_path("_elementtree"), "XML_STATIC;", "") + self._regex_replace_in_file(self._msvc_project_path("_elementtree"), r'.*Include=\"\.\.\\Modules\\expat\\.*" />', "") + + if self._is_py3: + if Version(self.version) >= "3.9": + # deflate.c has warning 4244 disabled, need special patching else it breaks the regex below + # Add an extra space to avoid being picked up by the regex + replace_in_file(self, self._msvc_project_path("pythoncore"), + r'', + r'') + self._regex_replace_in_file(self._msvc_project_path("pythoncore"), r'.*Include=\"\$\(zlibDir\).*', "") + + replace_in_file(self, self._msvc_project_path("_tkinter"), "$(tcltkDir)include;", "") + replace_in_file(self, self._msvc_project_path("_tkinter"), "$(tcltkLib);", "") + if self._is_py3: + replace_in_file(self, self._msvc_project_path("_tkinter"), + "", + "") + self._regex_replace_in_file(self._msvc_project_path("_tkinter"), r'.*Include=\"\$\(tcltkdir\).*', "") + + if self._is_py3: + # Disable "ValidateUcrtbase" target + replace_in_file(self, self._msvc_project_path("python"), "$(Configuration) != 'PGInstrument'", "False") + + if Version(self.version) < "3.11": + replace_in_file(self, self._msvc_project_path("_freeze_importlib"), + "', + r'') + + self._inject_conan_props_file("_bz2" if self._is_py3 else "bz2", "bzip2", self.options.get_safe("with_bz2")) + self._inject_conan_props_file("_elementtree", "expat", self._supports_modules) + self._inject_conan_props_file("pyexpat", "expat", self._supports_modules) + self._inject_conan_props_file("_hashlib", "openssl", self._supports_modules) + self._inject_conan_props_file("_ssl", "openssl", self._supports_modules) + self._inject_conan_props_file("_sqlite3", "sqlite3", self.options.get_safe("with_sqlite3")) + self._inject_conan_props_file("_tkinter", "tk", self.options.get_safe("with_tkinter")) + self._inject_conan_props_file("pythoncore", "zlib") + self._inject_conan_props_file("python", "zlib") + self._inject_conan_props_file("pythonw", "zlib") + self._inject_conan_props_file("_ctypes", "libffi", self._with_libffi) + self._inject_conan_props_file("_decimal", "mpdecimal", self._is_py3 and self._supports_modules) + self._inject_conan_props_file("_lzma", "xz_utils", self.options.get_safe("with_lzma")) + self._inject_conan_props_file("_bsddb", "libdb", self.options.get_safe("with_bsddb")) def _patch_sources(self): - for patch in self.conan_data.get("patches",{}).get(self.version, []): - tools.patch(**patch) - if self._is_py3 and tools.Version(self._version_number_only) < "3.10": - tools.replace_in_file(os.path.join(self._source_subfolder, "setup.py"), - ":libmpdec.so.2", "mpdec") - if self.settings.compiler == "Visual Studio": + apply_conandata_patches(self) + # <=3.10 requires a lot of manual injection of dependencies through setup.py + # 3.12 removes setup.py completely, and uses pkgconfig dependencies + # 3.11 is an in awkward transition state where some dependencies use pkgconfig, and others use setup.py + if Version(self.version) < "3.12": + self._patch_setup_py() + if Version(self.version) >= "3.11": + replace_in_file(self, os.path.join(self.source_folder, "configure"), + 'OPENSSL_LIBS="-lssl -lcrypto"', + 'OPENSSL_LIBS="-lssl -lcrypto -lz"') + if is_msvc(self): runtime_library = { "MT": "MultiThreaded", "MTd": "MultiThreadedDebug", "MD": "MultiThreadedDLL", "MDd": "MultiThreadedDebugDLL", - }[str(self.settings.compiler.runtime)] + }[msvc_runtime_flag(self)] self.output.info("Patching runtime") - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pyproject.props"), - "MultiThreadedDLL", runtime_library) - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pyproject.props"), - "MultiThreadedDebugDLL", runtime_library) + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pyproject.props"), + "MultiThreadedDLL", runtime_library) + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pyproject.props"), + "MultiThreadedDebugDLL", runtime_library) # Remove vendored packages - tools.rmdir(os.path.join(self._source_subfolder, "Modules", "_decimal", "libmpdec")) - tools.rmdir(os.path.join(self._source_subfolder, "Modules", "expat")) + rmdir(self, os.path.join(self.source_folder, "Modules", "_decimal", "libmpdec")) + rmdir(self, os.path.join(self.source_folder, "Modules", "expat")) - if self.options.get_safe("with_curses", False): - # FIXME: this will link to ALL libraries of ncurses. Only need to link to ncurses(w) (+ eventually tinfo) - tools.replace_in_file(os.path.join(self._source_subfolder, "setup.py"), - "curses_libs = ", - "curses_libs = {} #".format(repr(self.deps_cpp_info["ncurses"].libs + self.deps_cpp_info["ncurses"].system_libs))) + if self._is_py3 and Version(self.version) < "3.12": + replace_in_file(self, os.path.join(self.source_folder, "Makefile.pre.in"), + "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)'", + "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)'") # Enable static MSVC cpython if not self.options.shared: - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pythoncore.vcxproj"), - "","Py_NO_BUILD_SHARED;") - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pythoncore.vcxproj"), - "Py_ENABLE_SHARED", "Py_NO_ENABLE_SHARED") - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pythoncore.vcxproj"), - "DynamicLibrary", "StaticLibrary") - - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "python.vcxproj"), - "", "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "python.vcxproj"), - "", "Py_NO_ENABLE_SHARED;") - - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pythonw.vcxproj"), - "", "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") - tools.replace_in_file(os.path.join(self._source_subfolder, "PCbuild", "pythonw.vcxproj"), - "", "Py_NO_ENABLE_SHARED;%(PreprocessorDefinitions)") - - def _upgrade_single_project_file(self, project_file): - """ - `devenv /upgrade ` will upgrade *ALL* projects referenced by the project. - By temporarily moving the solution project, only one project is upgraded - This is needed for static cpython or for disabled optional dependencies (e.g. tkinter=False) - Restore it afterwards because it is needed to build some targets. - """ - tools.rename(os.path.join(self._source_subfolder, "PCbuild", "pcbuild.sln"), - os.path.join(self._source_subfolder, "PCbuild", "pcbuild.sln.bak")) - tools.rename(os.path.join(self._source_subfolder, "PCbuild", "pcbuild.proj"), - os.path.join(self._source_subfolder, "PCbuild", "pcbuild.proj.bak")) - with tools.vcvars(self.settings): - self.run("devenv \"{}\" /upgrade".format(project_file), run_environment=True) - tools.rename(os.path.join(self._source_subfolder, "PCbuild", "pcbuild.sln.bak"), - os.path.join(self._source_subfolder, "PCbuild", "pcbuild.sln")) - tools.rename(os.path.join(self._source_subfolder, "PCbuild", "pcbuild.proj.bak"), - os.path.join(self._source_subfolder, "PCbuild", "pcbuild.proj")) + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), + "", + "Py_NO_BUILD_SHARED;") + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), + "Py_ENABLE_SHARED", + "Py_NO_ENABLE_SHARED") + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), + "DynamicLibrary", + "StaticLibrary") + + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "python.vcxproj"), + "", + "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "python.vcxproj"), + "", + "Py_NO_ENABLE_SHARED;") + + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythonw.vcxproj"), + "", + "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") + replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythonw.vcxproj"), + "", + "Py_NO_ENABLE_SHARED;%(PreprocessorDefinitions)") + + conantoolchain_props = os.path.join(self.generators_folder, MSBuildToolchain.filename) + replace_in_file( + self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), + '', + f'', + ) + + if is_msvc(self): + self._patch_msvc_projects() @property def _solution_projects(self): if self.options.shared: - solution_path = os.path.join(self._source_subfolder, "PCbuild", "pcbuild.sln") - projects = set(m.group(1) for m in re.finditer("\"([^\"]+)\\.vcxproj\"", open(solution_path).read())) + solution_path = os.path.join(self.source_folder, "PCbuild", "pcbuild.sln") + projects = set(m.group(1) for m in re.finditer('"([^"]+)\\.vcxproj"', open(solution_path).read())) def project_build(name): if os.path.basename(name) in self._msvc_discarded_projects: @@ -341,24 +523,20 @@ def project_build(name): return False return True - def sort_importance(key): - importance = ( - "pythoncore", # The python library MUST be built first. All modules and executables depend on it - "python", # Build the python executable next (for convenience, when debugging) - ) - try: - return importance.index(key) - except ValueError: - return len(importance) - - projects = sorted((p for p in projects if project_build(p)), key=sort_importance) + projects = list(filter(project_build, projects)) return projects else: - return "pythoncore", "python", "pythonw" + return ["pythoncore", "python", "pythonw"] @property def _msvc_discarded_projects(self): - discarded = {"python_uwp", "pythonw_uwp"} + discarded = { + "python_uwp", + "pythonw_uwp", + "_freeze_importlib", + "sqlite3", + "bdist_wininst", + } if not self.options.with_bz2: discarded.add("bz2") if not self.options.with_sqlite3: @@ -367,11 +545,21 @@ def _msvc_discarded_projects(self): discarded.add("_tkinter") if self._is_py2: # Python 2 Visual Studio projects NOT to build - discarded = discarded.union({"bdist_wininst", "libeay", "ssleay", "sqlite3", "tcl", "tk", "tix"}) + discarded = discarded.union({ + "libeay", + "ssleay", + "tcl", + "tk", + "tix", + }) if not self.options.with_bsddb: discarded.add("_bsddb") elif self._is_py3: - discarded = discarded.union({"bdist_wininst", "liblzma", "openssl", "sqlite3", "xxlimited"}) + discarded = discarded.union({ + "liblzma", + "openssl", + "xxlimited", + }) if not self.options.with_lzma: discarded.add("_lzma") return discarded @@ -382,7 +570,7 @@ def _msvc_archs(self): "x86": "Win32", "x86_64": "x64", } - if tools.Version(self._version_number_only) >= "3.8": + if Version(self.version) >= "3.8": archs.update({ "armv7": "ARM", "armv8_32": "ARM", @@ -392,39 +580,29 @@ def _msvc_archs(self): def _msvc_build(self): msbuild = MSBuild(self) - msbuild_properties = { - "IncludeExternals": "true", - } + msbuild.platform = self._msvc_archs[str(self.settings.arch)] + projects = self._solution_projects - self.output.info("Building {} Visual Studio projects: {}".format(len(projects), projects)) + self.output.info(f"Building {len(projects)} Visual Studio projects: {projects}") - with tools.no_op(): - for project_i, project in enumerate(projects, 1): - self.output.info("[{}/{}] Building project '{}'...".format(project_i, len(projects), project)) - project_file = os.path.join(self._source_subfolder, "PCbuild", project + ".vcxproj") - self._upgrade_single_project_file(project_file) - msbuild.build(project_file, upgrade_project=False, build_type="Debug" if self.settings.build_type == "Debug" else "Release", - platforms=self._msvc_archs, properties=msbuild_properties) + sln = os.path.join(self.source_folder, "PCbuild", "pcbuild.sln") + # FIXME: Solution files do not pick up the toolset automatically. + cmd = msbuild.command(sln, targets=projects) + self.run(f"{cmd} /p:PlatformToolset={msvs_toolset(self)}") def build(self): - # FIXME: these checks belong in validate, but the versions of dependencies are not available there yet - if self._supports_modules: - if tools.Version(self._version_number_only) < "3.8.0": - if tools.Version(self.deps_cpp_info["mpdecimal"].version) >= "2.5.0": - raise ConanInvalidConfiguration("cpython versions lesser then 3.8.0 require a mpdecimal lesser then 2.5.0") - elif tools.Version(self._version_number_only) >= "3.9.0": - if tools.Version(self.deps_cpp_info["mpdecimal"].version) < "2.5.0": - raise ConanInvalidConfiguration("cpython 3.9.0 (and newer) requires (at least) mpdecimal 2.5.0") - - if self._with_libffi: - if tools.Version(self.deps_cpp_info["libffi"].version) >= "3.3" and self.settings.compiler == "Visual Studio" and "d" in str(self.settings.compiler.runtime): - raise ConanInvalidConfiguration("libffi versions >= 3.3 cause 'read access violations' when using a debug runtime (MTd/MDd)") - self._patch_sources() - if self.settings.compiler == "Visual Studio": + if is_msvc(self): self._msvc_build() else: - autotools = self._configure_autotools() + autotools = Autotools(self) + # For debugging configure errors + try: + autotools.configure() + except ConanException: + with open(os.path.join(self.build_folder, "config.log"), 'r') as f: + self.output.info(f.read()) + raise autotools.make() @property @@ -433,59 +611,58 @@ def _msvc_artifacts_path(self): "x86_64": "amd64", "x86": "win32", } - if tools.Version(self._version_number_only) >= "3.8": + if Version(self.version) >= "3.8": build_subdir_lut.update({ "armv7": "arm32", "armv8_32": "arm32", "armv8": "arm64", }) - return os.path.join(self._source_subfolder, "PCbuild", build_subdir_lut[str(self.settings.arch)]) + return os.path.join(self.source_folder, "PCbuild", build_subdir_lut[str(self.settings.arch)]) @property def _msvc_install_subprefix(self): return "bin" def _copy_essential_dlls(self): - if self.settings.compiler == "Visual Studio": + if is_msvc(self): # Until MSVC builds support cross building, copy dll's of essential (shared) dependencies to python binary location. # These dll's are required when running the layout tool using the newly built python executable. dest_path = os.path.join(self.build_folder, self._msvc_artifacts_path) if self._with_libffi: - for bin_path in self.deps_cpp_info["libffi"].bin_paths: - self.copy("*.dll", src=bin_path, dst=dest_path) - for bin_path in self.deps_cpp_info["expat"].bin_paths: - self.copy("*.dll", src=bin_path, dst=dest_path) - for bin_path in self.deps_cpp_info["zlib"].bin_paths: - self.copy("*.dll", src=bin_path, dst=dest_path) + for bin_path in self.dependencies["libffi"].cpp_info.bindirs: + copy(self, "*.dll", src=bin_path, dst=dest_path) + for bin_path in self.dependencies["expat"].cpp_info.bindirs: + copy(self, "*.dll", src=bin_path, dst=dest_path) + for bin_path in self.dependencies["zlib"].cpp_info.bindirs: + copy(self, "*.dll", src=bin_path, dst=dest_path) def _msvc_package_layout(self): self._copy_essential_dlls() install_prefix = os.path.join(self.package_folder, self._msvc_install_subprefix) - tools.mkdir(install_prefix) + mkdir(self, install_prefix) build_path = self._msvc_artifacts_path infix = "_d" if self.settings.build_type == "Debug" else "" # FIXME: if cross building, use a build python executable here - python_built = os.path.join(build_path, "python{}.exe".format(infix)) + python_built = os.path.join(build_path, f"python{infix}.exe") layout_args = [ - os.path.join(self._source_subfolder, "PC", "layout", "main.py"), + os.path.join(self.source_folder, "PC", "layout", "main.py"), "-v", - "-s", self._source_subfolder, + "-s", self.source_folder, "-b", build_path, "--copy", install_prefix, "-p", "--include-pip", "--include-venv", "--include-dev", - "--include-stable", ] if self.options.with_tkinter: layout_args.append("--include-tcltk") if self.settings.build_type == "Debug": layout_args.append("-d") - python_args = " ".join("\"{}\"".format(a) for a in layout_args) - self.run("{} {}".format(python_built, python_args), run_environment=True) + python_args = " ".join(f'"{a}"' for a in layout_args) + self.run(f"{python_built} {python_args}") - tools.rmdir(os.path.join(self.package_folder, "bin", "tcl")) + rmdir(self, os.path.join(self.package_folder, "bin", "tcl")) for file in os.listdir(install_prefix): if re.match("vcruntime.*", file): @@ -499,45 +676,77 @@ def _msvc_package_layout(self): def _msvc_package_copy(self): build_path = self._msvc_artifacts_path infix = "_d" if self.settings.build_type == "Debug" else "" - self.copy("*.exe", src=build_path, dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) - self.copy("*.dll", src=build_path, dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) - self.copy("*.pyd", src=build_path, dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "DLLs")) - self.copy("python{}{}.lib".format(self._version_suffix, infix), src=build_path, dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "libs")) - self.copy("*", src=os.path.join(self._source_subfolder, "Include"), dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) - self.copy("pyconfig.h", src=os.path.join(self._source_subfolder, "PC"), dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) - self.copy("*.py", src=os.path.join(self._source_subfolder, "lib"), dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib")) - tools.rmdir(os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib", "test")) + copy(self, "*.exe", + src=build_path, + dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) + copy(self, "*.dll", + src=build_path, + dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) + copy(self, "*.pyd", + src=build_path, + dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "DLLs")) + copy(self, f"python{self._version_suffix}{infix}.lib", + src=build_path, + dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "libs")) + copy(self, "*", + src=os.path.join(self.source_folder, "Include"), + dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) + copy(self, "pyconfig.h", + src=os.path.join(self.source_folder, "PC"), + dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) + copy(self, "*.py", + src=os.path.join(self.source_folder, "lib"), + dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib")) + rmdir(self, os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib", "test")) packages = {} get_name_version = lambda fn: fn.split(".", 2)[:2] - whldir = os.path.join(self._source_subfolder, "Lib", "ensurepip", "_bundled") + whldir = os.path.join(self.source_folder, "Lib", "ensurepip", "_bundled") for fn in filter(lambda n: n.endswith(".whl"), os.listdir(whldir)): name, version = get_name_version(fn) add = True if name in packages: pname, pversion = get_name_version(packages[name]) - add = tools.Version(version) > tools.Version(pversion) + add = Version(version) > Version(pversion) if add: packages[name] = fn for fname in packages.values(): - tools.unzip(filename=os.path.join(whldir, fname), destination=os.path.join(self.package_folder, "bin", "Lib", "site-packages")) + unzip(self, filename=os.path.join(whldir, fname), + destination=os.path.join(self.package_folder, "bin", "Lib", "site-packages")) - self.run("{} -c \"import compileall; compileall.compile_dir('{}')\"".format(os.path.join(build_path, self._cpython_interpreter_name), os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib").replace("\\", "/")), - run_environment=True) + interpreter_path = os.path.join(build_path, self._cpython_interpreter_name) + lib_dir_path = os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib").replace("\\", "/") + self.run(f"{interpreter_path} -c \"import compileall; compileall.compile_dir('{lib_dir_path}')\"") def package(self): - self.copy("LICENSE", src=self._source_subfolder, dst="licenses") - if self.settings.compiler == "Visual Studio": + copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) + if is_msvc(self): if self._is_py2 or not self.options.shared: self._msvc_package_copy() else: self._msvc_package_layout() - tools.remove_files_by_mask(os.path.join(self.package_folder, "bin"), "vcruntime*") + rm(self, "vcruntime*", os.path.join(self.package_folder, "bin"), recursive=True) else: - autotools = self._configure_autotools() - autotools.install() - tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig")) - tools.rmdir(os.path.join(self.package_folder, "share")) + # FIXME: C3I sometimes has a `lib` folder in the package folder, only on MacOS. + # Shot in the dark attempt: If it fails, remove the entire package folder and try again + try: + autotools = Autotools(self) + # FIXME: Autotools.install() always adds DESTDIR, we don't want this argument. + # Use .make() directly instead + autotools.make(target="altinstall") + except: + if (os.path.isfile(os.path.join(self.package_folder, "lib"))): + # FIXME not sure where this file comes from + self.output.info(f"{os.path.join(self.package_folder, 'lib')} exists, but it shouldn't.") + rmdir(self, self.package_folder) + mkdir(self, self.package_folder) + + copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) + autotools = Autotools(self) + autotools.make(target="altinstall") + + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + rmdir(self, os.path.join(self.package_folder, "share")) # Rewrite shebangs of python scripts for filename in os.listdir(os.path.join(self.package_folder, "bin")): @@ -551,23 +760,23 @@ def package(self): if not(firstline.startswith(b"#!") and b"/python" in firstline and b"/bin/sh" not in firstline): continue text = fn.read() - self.output.info("Rewriting shebang of {}".format(filename)) + self.output.info(f"Rewriting shebang of {filename}") with open(filepath, "wb") as fn: - fn.write(textwrap.dedent("""\ + fn.write(textwrap.dedent(f"""\ #!/bin/sh ''':' __file__="$0" while [ -L "$__file__" ]; do __file__="$(dirname "$__file__")/$(readlink "$__file__")" done - exec "$(dirname "$__file__")/python{}" "$0" "$@" + exec "$(dirname "$__file__")/python{self._version_suffix}" "$0" "$@" ''' - """.format(self._version_suffix)).encode()) + """).encode()) fn.write(text) if not os.path.exists(self._cpython_symlink): - os.symlink("python{}".format(self._version_suffix), self._cpython_symlink) - self._fix_install_name() + os.symlink(f"python{self._version_suffix}", self._cpython_symlink) + fix_apple_shared_install_name(self) @property def _cpython_symlink(self): @@ -578,14 +787,12 @@ def _cpython_symlink(self): @property def _cpython_interpreter_name(self): - if self.settings.compiler == "Visual Studio": - suffix = "" - else: - suffix = self._version_suffix - python = "python{}".format(suffix) - if self.settings.compiler == "Visual Studio": + python = "python" + if is_msvc(self): if self.settings.build_type == "Debug": python += "_d" + else: + python += self._version_suffix if self.settings.os == "Windows": python += ".exe" return python @@ -600,34 +807,23 @@ def _abi_suffix(self): if self._is_py3: if self.settings.build_type == "Debug": res += "d" - if tools.Version(self._version_number_only) < "3.8": + if Version(self.version) < "3.8": if self.options.get_safe("pymalloc", False): res += "m" return res @property def _lib_name(self): - if self.settings.compiler == "Visual Studio": + if is_msvc(self): if self.settings.build_type == "Debug": lib_ext = "_d" else: lib_ext = "" else: - lib_ext = self._abi_suffix + (".dll.a" if self.options.shared and self.settings.os == "Windows" else "") - return "python{}{}".format(self._version_suffix, lib_ext) - - def _fix_install_name(self): - if tools.is_apple_os(self.settings.os) and self.options.shared: - buffer = StringIO() - python = os.path.join(self.package_folder, "bin", "python") - self.run('otool -L "%s"' % python, output=buffer) - lines = buffer.getvalue().strip().split('\n')[1:] - for line in lines: - library = line.split()[0] - if library.startswith(self.package_folder): - new = library.replace(self.package_folder, "@executable_path/..") - self.output.info("patching {}, replace {} with {}".format(python, library, new)) - self.run("install_name_tool -change {} {} {}".format(library, new, python)) + lib_ext = self._abi_suffix + ( + ".dll.a" if self.options.shared and self.settings.os == "Windows" else "" + ) + return f"python{self._version_suffix}{lib_ext}" def package_info(self): # FIXME: conan components Python::Interpreter component, need a target type @@ -635,40 +831,53 @@ def package_info(self): # self.cpp_info.names["cmake_find_package_multi"] = "Python" # FIXME: conan components need to generate multiple .pc files (python2, python-27) - py_version = tools.Version(self._version_number_only) + py_version = Version(self.version) # python component: "Build a C extension for Python" - if self.settings.compiler == "Visual Studio": + if is_msvc(self): self.cpp_info.components["python"].includedirs = [os.path.join(self._msvc_install_subprefix, "include")] libdir = os.path.join(self._msvc_install_subprefix, "libs") else: - self.cpp_info.components["python"].includedirs.append(os.path.join("include", "python{}{}".format(self._version_suffix, self._abi_suffix))) + self.cpp_info.components["python"].includedirs.append( + os.path.join("include", f"python{self._version_suffix}{self._abi_suffix}") + ) libdir = "lib" if self.options.shared: self.cpp_info.components["python"].defines.append("Py_ENABLE_SHARED") else: self.cpp_info.components["python"].defines.append("Py_NO_ENABLE_SHARED") - if self.settings.os == "Linux": + if self.settings.os in ["Linux", "FreeBSD"]: self.cpp_info.components["python"].system_libs.extend(["dl", "m", "pthread", "util"]) elif self.settings.os == "Windows": - self.cpp_info.components["python"].system_libs.extend(["pathcch", "shlwapi", "version", "ws2_32"]) + self.cpp_info.components["python"].system_libs.extend( + ["pathcch", "shlwapi", "version", "ws2_32"] + ) self.cpp_info.components["python"].requires = ["zlib::zlib"] if self.settings.os != "Windows": self.cpp_info.components["python"].requires.append("libxcrypt::libxcrypt") - self.cpp_info.components["python"].names["pkg_config"] = "python-{}.{}".format(py_version.major, py_version.minor) + self.cpp_info.components["python"].set_property( + "pkg_config_name", f"python-{py_version.major}.{py_version.minor}" + ) self.cpp_info.components["python"].libdirs = [] - self.cpp_info.components["_python_copy"].names["pkg_config"] = "python{}".format(py_version.major) + self.cpp_info.components["_python_copy"].set_property("pkg_config_name", f"python{py_version.major}") self.cpp_info.components["_python_copy"].requires = ["python"] + self.cpp_info.components["_python_copy"].includedirs = [] self.cpp_info.components["_python_copy"].libdirs = [] # embed component: "Embed Python into an application" self.cpp_info.components["embed"].libs = [self._lib_name] self.cpp_info.components["embed"].libdirs = [libdir] - self.cpp_info.components["embed"].names["pkg_config"] = "python-{}.{}-embed".format(py_version.major, py_version.minor) + self.cpp_info.components["embed"].includedirs = [] + self.cpp_info.components["embed"].set_property( + "pkg_config_name", f"python-{py_version.major}.{py_version.minor}-embed" + ) self.cpp_info.components["embed"].requires = ["python"] self.cpp_info.components["_embed_copy"].requires = ["embed"] - self.cpp_info.components["_embed_copy"].names["pkg_config"] = ["python{}-embed".format(py_version.major)] + self.cpp_info.components["_embed_copy"].includedirs = [] + self.cpp_info.components["_embed_copy"].set_property( + "pkg_config_name", f"python{py_version.major}-embed" + ) self.cpp_info.components["_embed_copy"].libdirs = [] if self._supports_modules: @@ -682,7 +891,7 @@ def package_info(self): if self._with_libffi: self.cpp_info.components["_hidden"].requires.append("libffi::libffi") if self.settings.os != "Windows": - if not tools.is_apple_os(self.settings.os): + if not is_apple_os(self): self.cpp_info.components["_hidden"].requires.append("util-linux-libuuid::util-linux-libuuid") self.cpp_info.components["_hidden"].requires.append("libxcrypt::libxcrypt") if self.options.with_bz2: @@ -699,34 +908,34 @@ def package_info(self): self.cpp_info.components["_hidden"].requires.append("xz_utils::xz_utils") if self.options.get_safe("with_tkinter"): self.cpp_info.components["_hidden"].requires.append("tk::tk") + self.cpp_info.components["_hidden"].includedirs = [] self.cpp_info.components["_hidden"].libdirs = [] if self.options.env_vars: bindir = os.path.join(self.package_folder, "bin") - self.output.info("Appending PATH environment variable: {}".format(bindir)) + self.output.info(f"Appending PATH environment variable: {bindir}") self.env_info.PATH.append(bindir) python = self._cpython_interpreter_path + self.conf_info.define("user.cpython:python", python) self.user_info.python = python if self.options.env_vars: - self.output.info("Setting PYTHON environment variable: {}".format(python)) self.env_info.PYTHON = python - if self.settings.compiler == "Visual Studio": + if is_msvc(self): pythonhome = os.path.join(self.package_folder, "bin") - elif tools.is_apple_os(self.settings.os): - pythonhome = self.package_folder else: - version = tools.Version(self._version_number_only) - pythonhome = os.path.join(self.package_folder, "lib", "python{}.{}".format(version.major, version.minor)) + pythonhome = self.package_folder + self.conf_info.define("user.cpython:pythonhome", pythonhome) self.user_info.pythonhome = pythonhome - pythonhome_required = self.settings.compiler == "Visual Studio" or tools.is_apple_os(self.settings.os) + pythonhome_required = is_msvc(self) or is_apple_os(self) + self.conf_info.define("user.cpython:module_requires_pythonhome", pythonhome_required) self.user_info.module_requires_pythonhome = pythonhome_required - if self.settings.compiler == "Visual Studio": + if is_msvc(self): if self.options.env_vars: - self.output.info("Setting PYTHONHOME environment variable: {}".format(pythonhome)) + self.output.info(f"Setting PYTHONHOME environment variable: {pythonhome}") self.env_info.PYTHONHOME = pythonhome if self._is_py2: @@ -734,6 +943,7 @@ def package_info(self): else: python_root = self.package_folder if self.options.env_vars: - self.output.info("Setting PYTHON_ROOT environment variable: {}".format(python_root)) + self.output.info(f"Setting PYTHON_ROOT environment variable: {python_root}") self.env_info.PYTHON_ROOT = python_root + self.conf_info.define("user.cpython:python_root", python_root) self.user_info.python_root = python_root diff --git a/recipes/cpython/all/patches/2.7.18-0001-msvc.patch b/recipes/cpython/all/patches/2.7.18-0001-msvc.patch deleted file mode 100644 index 2c10104..0000000 --- a/recipes/cpython/all/patches/2.7.18-0001-msvc.patch +++ /dev/null @@ -1,278 +0,0 @@ ---- PCbuild/_bsddb.vcxproj -+++ PCbuild/_bsddb.vcxproj -@@ -46,7 +46,7 @@ - NotSet - - -- -+ - - .pyd - -@@ -75,7 +75,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -64,7 +64,7 @@ - $(opensslIncludeDir);%(AdditionalIncludeDirectories) - - -- ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) -+ ws2_32.lib;%(AdditionalDependencies) - - - -@@ -75,14 +75,14 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_sqlite3.vcxproj -+++ PCbuild/_sqlite3.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -96,10 +96,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -64,7 +64,7 @@ - $(opensslIncludeDir);%(AdditionalIncludeDirectories) - - -- ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) -+ ws2_32.lib;crypt32.lib;%(AdditionalDependencies) - - - -@@ -75,14 +75,14 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - {86937f53-c189-40ef-8ce8-8759d8e7d480} - false ---- PCbuild/bz2.vcxproj -+++ PCbuild/bz2.vcxproj -@@ -47,7 +47,7 @@ - NotSet - - -- -+ - - .pyd - -@@ -72,13 +72,13 @@ - - - -- -+ - - - ---- PCbuild/_elementtree.vcxproj -+++ PCbuild/_elementtree.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -61,15 +61,15 @@ - - - -- ..\Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;%(PreprocessorDefinitions) - - - 0x1D100000 - - - -- -+ - - - -- -+ - - - ---- PCbuild/pyexpat.vcxproj -+++ PCbuild/pyexpat.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -58,19 +58,19 @@ - - - -- $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;%(PreprocessorDefinitions) - - - -- -- -+ - - - -- -+ - - - ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -61,11 +61,11 @@ - - - -- $(tcltkDir)include;%(AdditionalIncludeDirectories) -+ %(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) - - -- $(tcltkLib);%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -77,12 +77,12 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - diff --git a/recipes/cpython/all/patches/2.7.18-0004-disable-macos-tcltk.patch b/recipes/cpython/all/patches/2.7.18-0004-disable-macos-tcltk.patch deleted file mode 100644 index 5c61acd..0000000 --- a/recipes/cpython/all/patches/2.7.18-0004-disable-macos-tcltk.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- setup.py -+++ setup.py -@@ -1928,9 +1928,9 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (host_platform == 'darwin' and -- self.detect_tkinter_darwin(inc_dirs, lib_dirs)): -- return -+ #if (host_platform == 'darwin' and -+ # self.detect_tkinter_darwin(inc_dirs, lib_dirs)): -+ # return - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch b/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch new file mode 100644 index 0000000..3cb9b50 --- /dev/null +++ b/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch @@ -0,0 +1,93 @@ +--- PCbuild/_bsddb.vcxproj ++++ PCbuild/_bsddb.vcxproj +@@ -75,7 +75,7 @@ + + + +- ++ + + + +--- PCbuild/_hashlib.vcxproj ++++ PCbuild/_hashlib.vcxproj +@@ -64,7 +64,7 @@ + $(opensslIncludeDir);%(AdditionalIncludeDirectories) + + +- ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) ++ ws2_32.lib;%(AdditionalDependencies) + + + +@@ -75,14 +75,14 @@ + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + +- ++ + + + +--- PCbuild/_ssl.vcxproj ++++ PCbuild/_ssl.vcxproj +@@ -64,7 +64,7 @@ + $(opensslIncludeDir);%(AdditionalIncludeDirectories) + + +- ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) ++ ws2_32.lib;crypt32.lib;%(AdditionalDependencies) + + + +@@ -75,14 +75,14 @@ + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + +- ++ + + {86937f53-c189-40ef-8ce8-8759d8e7d480} + false +--- PCbuild/_tkinter.vcxproj ++++ PCbuild/_tkinter.vcxproj +@@ -77,12 +77,12 @@ + {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} + false + +- ++ + + + diff --git a/recipes/cpython/all/patches/2.7.18-0002-add-support-msvc-14.patch b/recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch similarity index 100% rename from recipes/cpython/all/patches/2.7.18-0002-add-support-msvc-14.patch rename to recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch diff --git a/recipes/cpython/all/patches/2.7.18-0003-msvc-fix-static.patch b/recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch similarity index 100% rename from recipes/cpython/all/patches/2.7.18-0003-msvc-fix-static.patch rename to recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch diff --git a/recipes/cpython/all/patches/3.10.0-0001-msvc.patch b/recipes/cpython/all/patches/3.10.0-0001-msvc.patch deleted file mode 100644 index e9b1faf..0000000 --- a/recipes/cpython/all/patches/3.10.0-0001-msvc.patch +++ /dev/null @@ -1,416 +0,0 @@ ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -58,2 +58,0 @@ --Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" --EndProject ---- PCbuild/python.vcxproj -+++ PCbuild/python.vcxproj -@@ -120,1 +120,1 @@ -- -+ ---- PCbuild/_freeze_importlib.vcxproj -+++ PCbuild/_freeze_importlib.vcxproj -@@ -151,1 +151,1 @@ -- -+ --> ---- PCbuild/_bz2.vcxproj -+++ PCbuild/_bz2.vcxproj -@@ -71,7 +71,7 @@ - bz2 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -101,17 +101,17 @@ - - - -- -+ - - -- -- -+ - - - ---- PCbuild/_ctypes.vcxproj -+++ PCbuild/_ctypes.vcxproj -@@ -71,7 +71,7 @@ - _ctypes - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -94,7 +94,7 @@ - - - -- FFI_BUILDING;%(PreprocessorDefinitions) -+ %(PreprocessorDefinitions) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) ---- PCbuild/_decimal.vcxproj -+++ PCbuild/_decimal.vcxproj -@@ -71,7 +71,7 @@ - _decimal - Win32Proj - -- -+ - - - DynamicLibrary -@@ -98,11 +98,11 @@ - CONFIG_32;ANSI;%(PreprocessorDefinitions) - CONFIG_64;ANSI;%(PreprocessorDefinitions) - CONFIG_64;MASM;%(PreprocessorDefinitions) -- ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) -+ ..\Modules\_decimal;%(AdditionalIncludeDirectories) - - - -- -+ - - - -- -+ - - -- -+ - - - ---- PCbuild/_lzma.vcxproj -+++ PCbuild/_lzma.vcxproj -@@ -71,7 +71,7 @@ - lzma - Win32Proj - -- -+ - - - DynamicLibrary -@@ -94,10 +94,10 @@ - - - $(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories) -- WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) -+ $(ConanPreprocessorDefinitions);WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - -- $(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -111,10 +111,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_sqlite3.vcxproj -+++ PCbuild/_sqlite3.vcxproj -@@ -74,1 +74,1 @@ -- -+ -@@ -129,4 +129,4 @@ -- -+ ---- PCbuild/pythoncore.vcxproj -+++ PCbuild/pythoncore.vcxproj -@@ -73,1 +73,1 @@ -- -+ -@@ -302,7 +302,7 @@ - - - -- -+ - - - -@@ -496,7 +496,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -71,7 +71,7 @@ - _hashlib - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -71,7 +71,7 @@ - _ssl - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -99,9 +99,9 @@ - - - -- -+ - - - ---- PCbuild/_elementtree.vcxproj -+++ PCbuild/_elementtree.vcxproj -@@ -71,7 +71,7 @@ - _elementtree - Win32Proj - -- -+ - - - DynamicLibrary -@@ -93,12 +93,12 @@ - - - -- ..\Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;%(PreprocessorDefinitions) - - - -- -+ - - - -- -+ - - - ---- PCbuild/pyexpat.vcxproj -+++ PCbuild/pyexpat.vcxproj -@@ -71,7 +71,7 @@ - {D06B6426-4762-44CC-8BAD-D79052507F2F} - pyexpat - -- -+ - - - DynamicLibrary -@@ -90,19 +90,19 @@ - - - -- $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;%(PreprocessorDefinitions) - - - -- -- -+ - - - -- -+ - - - ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -77,7 +77,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -93,12 +93,12 @@ - - - -- $(tcltkDir)include;%(AdditionalIncludeDirectories) -+ %(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) -- Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions) -+ - - -- $(tcltkLib);%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -108,10 +108,10 @@ - - - -- -+ - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -9,9 +9,6 @@ - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - EndProject diff --git a/recipes/cpython/all/patches/3.10.0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch b/recipes/cpython/all/patches/3.10.0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch deleted file mode 100644 index 0288bda..0000000 --- a/recipes/cpython/all/patches/3.10.0-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- Makefile.pre.in -+++ Makefile.pre.in -@@ -627,10 +627,10 @@ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ echo "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - diff --git a/recipes/cpython/all/patches/3.10.0-0005-disable-macos-tcltk.patch b/recipes/cpython/all/patches/3.10.0-0005-disable-macos-tcltk.patch deleted file mode 100644 index ec23890..0000000 --- a/recipes/cpython/all/patches/3.10.0-0005-disable-macos-tcltk.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- setup.py -+++ setup.py -@@ -2094,8 +2094,8 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (MACOS and self.detect_tkinter_darwin()): -- return True -+ #if (MACOS and self.detect_tkinter_darwin()): -+ # return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/3.10.4-0005-disable-macos-tcltk.patch b/recipes/cpython/all/patches/3.10.4-0005-disable-macos-tcltk.patch deleted file mode 100644 index b1a81aa..0000000 --- a/recipes/cpython/all/patches/3.10.4-0005-disable-macos-tcltk.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- setup.py -+++ setup.py -@@ -2109,8 +2109,8 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (MACOS and self.detect_tkinter_darwin()): -- return True -+ # if (MACOS and self.detect_tkinter_darwin()): -+ # return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/3.10.0-0003-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch similarity index 100% rename from recipes/cpython/all/patches/3.10.0-0003-_ctypes-ffi.patch rename to recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch diff --git a/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch new file mode 100644 index 0000000..65027b6 --- /dev/null +++ b/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch @@ -0,0 +1,37 @@ +diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c +index 9bdf1db856..799f99e809 100644 +--- a/Modules/_ctypes/cfield.c ++++ b/Modules/_ctypes/cfield.c +@@ -1473,7 +1473,11 @@ P_get(void *ptr, Py_ssize_t size) + return PyLong_FromVoidPtr(*(void **)ptr); + } + +-static struct fielddesc formattable[] = { ++#define FORMATTABLE_SIZE 30 ++static struct fielddesc formattable[FORMATTABLE_SIZE]; ++ ++static void formattable_init(void) { ++struct fielddesc my_formattable[] = { + { 's', s_set, s_get, NULL}, + { 'b', b_set, b_get, NULL}, + { 'B', B_set, B_get, NULL}, +@@ -1510,6 +1514,11 @@ static struct fielddesc formattable[] = { + { 'O', O_set, O_get, NULL}, + { 0, NULL, NULL, NULL}, + }; ++ size_t nb = 1; ++ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); ++ if (FORMATTABLE_SIZE < nb) abort(); ++ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); ++} + + /* + Ideas: Implement VARIANT in this table, using 'V' code. +@@ -1597,6 +1606,7 @@ _ctypes_get_fielddesc(const char *fmt) + + if (!initialized) { + initialized = 1; ++ formattable_init(); + _ctypes_init_fielddesc(); + } + diff --git a/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch new file mode 100644 index 0000000..06bb62c --- /dev/null +++ b/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch @@ -0,0 +1,37 @@ +diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c +index 128506a9ee..ee9ade67b8 100644 +--- a/Modules/_ctypes/cfield.c ++++ b/Modules/_ctypes/cfield.c +@@ -1448,7 +1448,11 @@ P_get(void *ptr, Py_ssize_t size) + return PyLong_FromVoidPtr(*(void **)ptr); + } + +-static struct fielddesc formattable[] = { ++#define FORMATTABLE_SIZE 30 ++static struct fielddesc formattable[FORMATTABLE_SIZE]; ++ ++static void formattable_init(void) { ++struct fielddesc my_formattable[] = { + { 's', s_set, s_get, NULL}, + { 'b', b_set, b_get, NULL}, + { 'B', B_set, B_get, NULL}, +@@ -1485,6 +1489,11 @@ static struct fielddesc formattable[] = { + { 'O', O_set, O_get, NULL}, + { 0, NULL, NULL, NULL}, + }; ++ size_t nb = 1; ++ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); ++ if (FORMATTABLE_SIZE < nb) abort(); ++ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); ++} + + /* + Ideas: Implement VARIANT in this table, using 'V' code. +@@ -1572,6 +1581,7 @@ _ctypes_get_fielddesc(const char *fmt) + + if (!initialized) { + initialized = 1; ++ formattable_init(); + _ctypes_init_fielddesc(); + } + diff --git a/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch b/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch new file mode 100644 index 0000000..1d9d31f --- /dev/null +++ b/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch @@ -0,0 +1,50 @@ +diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln +index bdddec60da..f6a30955bf 100644 +--- a/PCbuild/pcbuild.sln ++++ b/PCbuild/pcbuild.sln +@@ -9,45 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution + EndProjectSection + EndProject + Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" +- ProjectSection(ProjectDependencies) = postProject +- {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} +- {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} +- {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} +- {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} +- {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} +- {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} +- {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} +- {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} +- {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} +- {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} +- {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} +- {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8} +- {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} +- {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} +- {31FFC478-7B4A-43E8-9954-8D03E2187E9C} = {31FFC478-7B4A-43E8-9954-8D03E2187E9C} +- {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} +- {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} +- {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} +- {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} +- {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} +- {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44} +- {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} +- {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E} +- {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} +- {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} +- {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} +- {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} +- {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} +- {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} +- {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F} +- {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} +- {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} +- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} +- {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} +- {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} +- {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} +- {A840DDFB-ED50-484B-B527-B32E7CF90FD5} = {A840DDFB-ED50-484B-B527-B32E7CF90FD5} +- EndProjectSection + EndProject + Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" + ProjectSection(ProjectDependencies) = postProject diff --git a/recipes/cpython/all/patches/3.7.9-0001-msvc.patch b/recipes/cpython/all/patches/3.7.9-0001-msvc.patch deleted file mode 100644 index 29be01b..0000000 --- a/recipes/cpython/all/patches/3.7.9-0001-msvc.patch +++ /dev/null @@ -1,416 +0,0 @@ ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -58,2 +58,0 @@ --Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" --EndProject ---- PCbuild/python.vcxproj -+++ PCbuild/python.vcxproj -@@ -85,1 +85,1 @@ -- -+ ---- PCbuild/_freeze_importlib.vcxproj -+++ PCbuild/_freeze_importlib.vcxproj -@@ -110,1 +110,1 @@ -- -+ --> ---- PCbuild/_bz2.vcxproj -+++ PCbuild/_bz2.vcxproj -@@ -39,7 +39,7 @@ - bz2 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -69,17 +69,17 @@ - - - -- -+ - - -- -- -+ - - - ---- PCbuild/_decimal.vcxproj -+++ PCbuild/_decimal.vcxproj -@@ -39,7 +39,7 @@ - _decimal - Win32Proj - -- -+ - - - DynamicLibrary -@@ -64,11 +64,11 @@ - _CRT_SECURE_NO_WARNINGS;MASM;%(PreprocessorDefinitions) - CONFIG_32;PPRO;%(PreprocessorDefinitions) - CONFIG_64;%(PreprocessorDefinitions) -- ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) -+ ..\Modules\_decimal;%(AdditionalIncludeDirectories) - - - -- -+ - - - -- -+ - - -- -+ - - - ---- PCbuild/_elementtree.vcxproj -+++ PCbuild/_elementtree.vcxproj -@@ -39,7 +39,7 @@ - _elementtree - Win32Proj - -- -+ - - - DynamicLibrary -@@ -65,8 +65,8 @@ -- _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) -+ _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;%(PreprocessorDefinitions) - - - -- -+ - - - -- -+ - - - ---- PCbuild/_lzma.vcxproj -+++ PCbuild/_lzma.vcxproj -@@ -39,7 +39,7 @@ - lzma - Win32Proj - -- -+ - - - DynamicLibrary -@@ -62,10 +62,10 @@ - - - $(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories) -- WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) -+ $(ConanPreprocessorDefinitions);WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - -- $(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -79,10 +79,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_sqlite3.vcxproj -+++ PCbuild/_sqlite3.vcxproj -@@ -39,7 +39,7 @@ - _sqlite3 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -95,10 +95,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/openssl.vcxproj -+++ PCbuild/openssl.vcxproj -@@ -74,6 +74,6 @@ nmake - - - -- -+ - - - ---- PCbuild/pyexpat.vcxproj -+++ PCbuild/pyexpat.vcxproj -@@ -39,7 +39,7 @@ - {D06B6426-4762-44CC-8BAD-D79052507F2F} - pyexpat - -- -+ - - - DynamicLibrary -@@ -58,19 +58,19 @@ - - - -- $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) - - - -- -- -+ - - - -- -+ - - - ---- PCbuild/pythoncore.vcxproj -+++ PCbuild/pythoncore.vcxproj -@@ -38,7 +38,7 @@ - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - pythoncore - -- -+ - - - DynamicLibrary -@@ -215,7 +215,7 @@ - - - -- -+ - - - -@@ -409,7 +409,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -39,7 +39,7 @@ - _hashlib - Win32Proj - -- -+ - - - DynamicLibrary -@@ -54,7 +54,7 @@ - - - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -39,7 +39,7 @@ - _ssl - Win32Proj - -- -+ - - - DynamicLibrary -@@ -54,7 +54,7 @@ - - - -- -+ - - - -@@ -67,9 +67,9 @@ - - - -- -+ - - - ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -45,7 +45,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -61,12 +61,12 @@ - - - -- $(tcltkDir)include;%(AdditionalIncludeDirectories) -+ %(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) -- Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions) -+ - - -- $(tcltkLib);%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -76,10 +76,10 @@ - - - -- -+ - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -9,9 +9,6 @@ - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - EndProject diff --git a/recipes/cpython/all/patches/3.7.9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch b/recipes/cpython/all/patches/3.7.9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch deleted file mode 100644 index 92e44c8..0000000 --- a/recipes/cpython/all/patches/3.7.9-0002-setup.py-pass-CFLAGS-CPPFLAGS.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- Makefile.pre.in -+++ Makefile.pre.in -@@ -618,10 +618,10 @@ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ echo "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - diff --git a/recipes/cpython/all/patches/3.7.9-0003-disable-macos-tcltk.patch b/recipes/cpython/all/patches/3.7.9-0003-disable-macos-tcltk.patch deleted file mode 100644 index f5ffba2..0000000 --- a/recipes/cpython/all/patches/3.7.9-0003-disable-macos-tcltk.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- setup.py -+++ setup.py -@@ -1829,9 +1829,9 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (host_platform == 'darwin' and -- self.detect_tkinter_darwin(inc_dirs, lib_dirs)): -- return -+ #if (host_platform == 'darwin' and -+ # self.detect_tkinter_darwin(inc_dirs, lib_dirs)): -+ # return - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch b/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch new file mode 100644 index 0000000..be1387c --- /dev/null +++ b/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch @@ -0,0 +1,19 @@ +--- PCbuild/openssl.vcxproj ++++ PCbuild/openssl.vcxproj +@@ -74,6 +74,6 @@ nmake + + + +- ++ + + + diff --git a/recipes/cpython/all/patches/3.8.12-0001-msvc.patch b/recipes/cpython/all/patches/3.8.12-0001-msvc.patch deleted file mode 100644 index 4e39081..0000000 --- a/recipes/cpython/all/patches/3.8.12-0001-msvc.patch +++ /dev/null @@ -1,431 +0,0 @@ ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -60,2 +60,0 @@ --Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" --EndProject ---- PCbuild/python.vcxproj -+++ PCbuild/python.vcxproj -@@ -118,1 +118,1 @@ -- -+ ---- PCbuild/_freeze_importlib.vcxproj -+++ PCbuild/_freeze_importlib.vcxproj -@@ -149,1 +149,1 @@ -- -+ --> ---- PCbuild/_bz2.vcxproj -+++ PCbuild/_bz2.vcxproj -@@ -71,7 +71,7 @@ - bz2 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -101,17 +101,17 @@ - - - -- -+ - - -- -- -+ - - - ---- PCbuild/_ctypes.vcxproj -+++ PCbuild/_ctypes.vcxproj -@@ -71,7 +71,7 @@ - _ctypes - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -94,7 +94,7 @@ - - - -- FFI_BUILDING;%(PreprocessorDefinitions) -+ %(PreprocessorDefinitions) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) ---- PCbuild/_decimal.vcxproj -+++ PCbuild/_decimal.vcxproj -@@ -71,7 +71,7 @@ - _decimal - Win32Proj - -- -+ - - - DynamicLibrary -@@ -98,11 +98,11 @@ - CONFIG_32;ANSI;%(PreprocessorDefinitions) - CONFIG_64;ANSI;%(PreprocessorDefinitions) - CONFIG_64;%(PreprocessorDefinitions) -- ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) -+ ..\Modules\_decimal;%(AdditionalIncludeDirectories) - - - -- -+ - - - -- -+ - - -- -+ - - - ---- PCbuild/_lzma.vcxproj -+++ PCbuild/_lzma.vcxproj -@@ -71,7 +71,7 @@ - lzma - Win32Proj - -- -+ - - - DynamicLibrary -@@ -94,10 +94,10 @@ - - - $(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories) -- WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) -+ $(ConanPreprocessorDefinitions);WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - -- $(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -111,10 +111,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_sqlite3.vcxproj -+++ PCbuild/_sqlite3.vcxproj -@@ -71,7 +71,7 @@ - _sqlite3 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -127,10 +127,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/pythoncore.vcxproj -+++ PCbuild/pythoncore.vcxproj -@@ -70,7 +70,7 @@ - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - pythoncore - -- -+ - - - DynamicLibrary -@@ -272,7 +272,7 @@ - - - -- -+ - - - -@@ -468,7 +468,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -71,7 +71,7 @@ - _hashlib - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -71,7 +71,7 @@ - _ssl - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -99,9 +99,9 @@ - - - -- -+ - - - ---- PCbuild/_elementtree.vcxproj -+++ PCbuild/_elementtree.vcxproj -@@ -71,7 +71,7 @@ - _elementtree - Win32Proj - -- -+ - - - DynamicLibrary -@@ -93,12 +93,12 @@ - - - -- ..\Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;%(PreprocessorDefinitions) - - - -- -+ - - - -- -+ - - - ---- PCbuild/pyexpat.vcxproj -+++ PCbuild/pyexpat.vcxproj -@@ -71,7 +71,7 @@ - {D06B6426-4762-44CC-8BAD-D79052507F2F} - pyexpat - -- -+ - - - DynamicLibrary -@@ -91,18 +91,18 @@ - - - $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_STATIC;%(PreprocessorDefinitions) -+ _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;%(PreprocessorDefinitions) - - - -- -- -+ - - - -- -+ - - - ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -77,7 +77,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -93,12 +93,12 @@ - - - -- $(tcltkDir)include;%(AdditionalIncludeDirectories) -+ %(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) -- Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions) -+ - - -- $(tcltkLib);%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -108,10 +108,10 @@ - - - -- -+ - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -9,9 +9,6 @@ - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - EndProject diff --git a/recipes/cpython/all/patches/3.8.12-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch b/recipes/cpython/all/patches/3.8.12-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch deleted file mode 100644 index 21527d0..0000000 --- a/recipes/cpython/all/patches/3.8.12-0003-setup.py-pass-CFLAGS-CPPFLAGS.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- Makefile.pre.in -+++ Makefile.pre.in -@@ -606,10 +606,10 @@ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ echo "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - diff --git a/recipes/cpython/all/patches/3.8.12-0004-disable-macos-tcltk.patch b/recipes/cpython/all/patches/3.8.12-0004-disable-macos-tcltk.patch deleted file mode 100644 index 90af822..0000000 --- a/recipes/cpython/all/patches/3.8.12-0004-disable-macos-tcltk.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- setup.py -+++ setup.py -@@ -1838,8 +1838,8 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (MACOS and self.detect_tkinter_darwin()): -- return True -+ #if (MACOS and self.detect_tkinter_darwin()): -+ # return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/3.8.12-0002-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch similarity index 100% rename from recipes/cpython/all/patches/3.8.12-0002-_ctypes-ffi.patch rename to recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch diff --git a/recipes/cpython/all/patches/3.9.7-0001-msvc.patch b/recipes/cpython/all/patches/3.9.7-0001-msvc.patch deleted file mode 100644 index fac9247..0000000 --- a/recipes/cpython/all/patches/3.9.7-0001-msvc.patch +++ /dev/null @@ -1,434 +0,0 @@ ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -60,2 +60,0 @@ --Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sqlite3", "sqlite3.vcxproj", "{A1A295E5-463C-437F-81CA-1F32367685DA}" --EndProject ---- PCbuild/python.vcxproj -+++ PCbuild/python.vcxproj -@@ -118,1 +118,1 @@ -- -+ ---- PCbuild/_freeze_importlib.vcxproj -+++ PCbuild/_freeze_importlib.vcxproj -@@ -149,1 +149,1 @@ -- -+ --> ---- PCbuild/_bz2.vcxproj -+++ PCbuild/_bz2.vcxproj -@@ -71,7 +71,7 @@ - bz2 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -101,17 +101,17 @@ - - - -- -+ - - -- -- -+ - - - ---- PCbuild/_ctypes.vcxproj -+++ PCbuild/_ctypes.vcxproj -@@ -71,7 +71,7 @@ - _ctypes - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -94,7 +94,7 @@ - - - -- FFI_BUILDING;%(PreprocessorDefinitions) -+ %(PreprocessorDefinitions) - - - /EXPORT:DllGetClassObject,PRIVATE /EXPORT:DllCanUnloadNow,PRIVATE %(AdditionalOptions) ---- PCbuild/_decimal.vcxproj -+++ PCbuild/_decimal.vcxproj -@@ -71,7 +71,7 @@ - _decimal - Win32Proj - -- -+ - - - DynamicLibrary -@@ -98,11 +98,11 @@ - CONFIG_32;ANSI;%(PreprocessorDefinitions) - CONFIG_64;ANSI;%(PreprocessorDefinitions) - CONFIG_64;%(PreprocessorDefinitions) -- ..\Modules\_decimal;..\Modules\_decimal\libmpdec;%(AdditionalIncludeDirectories) -+ ..\Modules\_decimal;%(AdditionalIncludeDirectories) - - - -- -+ - - - -- -+ - - -- -+ - - - ---- PCbuild/_lzma.vcxproj -+++ PCbuild/_lzma.vcxproj -@@ -71,7 +71,7 @@ - lzma - Win32Proj - -- -+ - - - DynamicLibrary -@@ -94,10 +94,10 @@ - - - $(lzmaDir)src/liblzma/api;%(AdditionalIncludeDirectories) -- WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) -+ $(ConanPreprocessorDefinitions);WIN32;_FILE_OFFSET_BITS=64;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;LZMA_API_STATIC;%(PreprocessorDefinitions) - - -- $(OutDir)liblzma$(PyDebugExt).lib;%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -111,10 +111,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_sqlite3.vcxproj -+++ PCbuild/_sqlite3.vcxproj -@@ -71,7 +71,7 @@ - _sqlite3 - Win32Proj - -- -+ - - - DynamicLibrary -@@ -127,10 +127,10 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/pythoncore.vcxproj -+++ PCbuild/pythoncore.vcxproj -@@ -70,7 +70,7 @@ - {CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26} - pythoncore - -- -+ - - - DynamicLibrary -@@ -295,7 +295,7 @@ - - - -- -+ - - - -@@ -497,7 +497,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -71,7 +71,7 @@ - _hashlib - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -71,7 +71,7 @@ - _ssl - Win32Proj - -- -+ - - - DynamicLibrary -@@ -86,7 +86,7 @@ - - - -- -+ - - - -@@ -99,9 +99,9 @@ - - - -- -+ - - - ---- PCbuild/_elementtree.vcxproj -+++ PCbuild/_elementtree.vcxproj -@@ -71,7 +71,7 @@ - _elementtree - Win32Proj - -- -+ - - - DynamicLibrary -@@ -93,12 +93,12 @@ - - - -- ..\Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;USE_PYEXPAT_CAPI;%(PreprocessorDefinitions) - - - -- -+ - - - -- -+ - - - ---- PCbuild/pyexpat.vcxproj -+++ PCbuild/pyexpat.vcxproj -@@ -71,7 +71,7 @@ - {D06B6426-4762-44CC-8BAD-D79052507F2F} - pyexpat - -- -+ - - - DynamicLibrary -@@ -90,19 +90,19 @@ - - - -- $(PySourcePath)Modules\expat;%(AdditionalIncludeDirectories) -- _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;HAVE_EXPAT_H;XML_STATIC;%(PreprocessorDefinitions) -+ %(AdditionalIncludeDirectories) -+ _CRT_SECURE_NO_WARNINGS;PYEXPAT_EXPORTS;%(PreprocessorDefinitions) - - - -- -- -+ - - - -- -+ - - - ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -77,7 +77,7 @@ - DynamicLibrary - NotSet - -- -+ - - .pyd - -@@ -93,12 +93,12 @@ - - - -- $(tcltkDir)include;%(AdditionalIncludeDirectories) -+ %(AdditionalIncludeDirectories) - WITH_APPINIT;%(PreprocessorDefinitions) -- Py_TCLTK_DIR="$(tcltkDir.TrimEnd('\').Replace('\', '\\'))";%(PreprocessorDefinitions) -+ - - -- $(tcltkLib);%(AdditionalDependencies) -+ %(AdditionalDependencies) - - - -@@ -108,10 +108,10 @@ - - - -- -+ - - - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -9,9 +9,6 @@ - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - EndProject diff --git a/recipes/cpython/all/patches/3.9.7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch b/recipes/cpython/all/patches/3.9.7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch deleted file mode 100644 index 0bec735..0000000 --- a/recipes/cpython/all/patches/3.9.7-0004-setup.py-pass-CFLAGS-CPPFLAGS.patch +++ /dev/null @@ -1,15 +0,0 @@ ---- Makefile.pre.in -+++ Makefile.pre.in -@@ -630,10 +630,10 @@ - *\ -s*|s*) quiet="-q";; \ - *) quiet="";; \ - esac; \ -- echo "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ echo "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build"; \ -- $(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ -+ $(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)' \ - _TCLTK_INCLUDES='$(TCLTK_INCLUDES)' _TCLTK_LIBS='$(TCLTK_LIBS)' \ - $(PYTHON_FOR_BUILD) $(srcdir)/setup.py $$quiet build - diff --git a/recipes/cpython/all/patches/3.9.7-0005-disable-macos-tcltk.patch b/recipes/cpython/all/patches/3.9.7-0005-disable-macos-tcltk.patch deleted file mode 100644 index 68a4885..0000000 --- a/recipes/cpython/all/patches/3.9.7-0005-disable-macos-tcltk.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- setup.py -+++ setup.py -@@ -1986,8 +1986,8 @@ - # Rather than complicate the code below, detecting and building - # AquaTk is a separate method. Only one Tkinter will be built on - # Darwin - either AquaTk, if it is found, or X11 based Tk. -- if (MACOS and self.detect_tkinter_darwin()): -- return True -+ #if (MACOS and self.detect_tkinter_darwin()): -+ # return True - - # Assume we haven't found any of the libraries or include files - # The versions with dots are used on Unix, and the versions without diff --git a/recipes/cpython/all/patches/3.9.7-0002-_msi-vcxproj.patch b/recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch similarity index 100% rename from recipes/cpython/all/patches/3.9.7-0002-_msi-vcxproj.patch rename to recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch diff --git a/recipes/cpython/all/patches/3.9.7-0003-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch similarity index 100% rename from recipes/cpython/all/patches/3.9.7-0003-_ctypes-ffi.patch rename to recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch diff --git a/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch b/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch new file mode 100644 index 0000000..38a6425 --- /dev/null +++ b/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch @@ -0,0 +1,10 @@ +--- PCbuild/pcbuild.sln ++++ PCbuild/pcbuild.sln +@@ -9,7 +9,4 @@ + EndProjectSection + EndProject + Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" +- ProjectSection(ProjectDependencies) = postProject +- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} +- EndProjectSection + EndProject diff --git a/recipes/cpython/all/test_package/CMakeLists.txt b/recipes/cpython/all/test_package/CMakeLists.txt index 5253293..fe9f422 100644 --- a/recipes/cpython/all/test_package/CMakeLists.txt +++ b/recipes/cpython/all/test_package/CMakeLists.txt @@ -1,13 +1,18 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.15) project(test_package C) -include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") -conan_basic_setup() +find_package(cpython REQUIRED CONFIG) -set(CACHE PY_VERSION_MAJOR "" CACHE STRING "MAJOR version of python") -set(CACHE PY_VERSION_MAJOR_MINOR "" CACHE STRING "MAJOR.MINOR version of python") -set(CACHE PY_VERSION "" CACHE STRING "Required version of python") -set(CACHE PY_VERSION_SUFFIX "" CACHE STRING "Suffix of python") +# FIXME: We can't modify CMake's FindPython to link dependencies pulled by +# Conan, so here we just include them globally. This is mainly necessary for +# MacOS missing crypt.h, which is available at configure time (in the main recipe) +# but otherwise not at build time (in consumer packages). +link_libraries(cpython::python) + +set(PY_VERSION_MAJOR "" CACHE STRING "MAJOR version of python") +set(PY_VERSION_MAJOR_MINOR "" CACHE STRING "MAJOR.MINOR version of python") +set(PY_VERSION "" CACHE STRING "Required version of python") +set(PY_VERSION_SUFFIX "" CACHE STRING "Suffix of python") set(Python_ADDITIONAL_VERSIONS ${PY_VERSION}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR_MINOR}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR}${PY_VERSION_SUFFIX} ${PY_VERSION} ${PY_VERSION_MAJOR_MINOR} ${PY_VERSION_MAJOR}) message("Using Python_ADDITIONAL_VERSIONS: ${Python_ADDITIONAL_VERSIONS}") @@ -64,16 +69,14 @@ if(BUILD_MODULE) ) set_property(TARGET spam PROPERTY PREFIX "") if(MSVC) - if(CONAN_SETTINGS_BUILD_TYPE STREQUAL "Debug") - set(SUFFIX "_d.pyd") - else() - set(SUFFIX ".pyd") - endif() - set_property(TARGET spam PROPERTY SUFFIX "${SUFFIX}") + set_target_properties(spam PROPERTIES + DEBUG_POSTFIX "_d" + SUFFIX ".pyd" + ) endif() option(USE_FINDPYTHON_X "Use new-style FindPythonX module") - if(USE_FINDPYTHON_X AND NOT (CMAKE_VERSION VERSION_LESS "3.16")) + if(USE_FINDPYTHON_X AND NOT CMAKE_VERSION VERSION_LESS "3.16") # Require CMake 3.16 because this version introduces Python${PY_VERSION_MAJOR}_FIND_ABI find_package(Python${PY_VERSION_MAJOR} REQUIRED COMPONENTS Interpreter Development) message("Python${PY_VERSION_MAJOR}_EXECUTABLE: ${Python${PY_VERSION_MAJOR}_EXECUTABLE}") @@ -97,4 +100,4 @@ if(BUILD_MODULE) endif() add_executable(${PROJECT_NAME} "py${PY_VERSION_MAJOR}/test_package.c") -target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) +target_link_libraries(${PROJECT_NAME} PRIVATE cpython::embed) diff --git a/recipes/cpython/all/test_package/conanfile.py b/recipes/cpython/all/test_package/conanfile.py index bb22adc..f9fc84c 100644 --- a/recipes/cpython/all/test_package/conanfile.py +++ b/recipes/cpython/all/test_package/conanfile.py @@ -1,17 +1,17 @@ -from conans import AutoToolsBuildEnvironment, CMake, RunEnvironment -from conans import tools as legacy_tools -from conan import ConanFile +import os +from io import StringIO + +from conan import ConanFile, conan_version from conan.errors import ConanException +from conan.tools.apple import is_apple_os from conan.tools.build import can_run +from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout +from conan.tools.env import VirtualRunEnv +from conan.tools.gnu import AutotoolsDeps +from conan.tools.microsoft import is_msvc, VCVars from conan.tools.scm import Version -from conan.tools.apple import is_apple_os -from conan.tools.files import mkdir -from conan.tools.microsoft import is_msvc -from io import StringIO -import os -import re -import shutil +conan2 = conan_version.major >= 2 class CmakePython3Abi(object): def __init__(self, debug, pymalloc, unicode): @@ -25,11 +25,14 @@ def __init__(self, debug, pymalloc, unicode): @property def suffix(self): - return "{}{}{}".format( - "d" if self.debug else "", - "m" if self.pymalloc else "", - "u" if self.unicode else "", - ) + suffix = "" + if self.debug: + suffix += "d" + if self.pymalloc: + suffix += "m" + if self.unicode: + suffix += "u" + return suffix @property def cmake_arg(self): @@ -37,164 +40,209 @@ def cmake_arg(self): class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake" + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def build_requirements(self): + # The main recipe does not require CMake, but we test with it. + # The interesting problem that arises here is if you have CMake installed + # with your global pip, then it will fail to run in this test package. + # To avoid that, just add a requirement on CMake. + self.tool_requires("cmake/[>=3.15 <4]") + + def layout(self): + cmake_layout(self) + + @property + def _python(self): + if conan2: + return self.dependencies["cpython"].conf_info.get("user.cpython:python", check_type=str) + else: + return self.deps_user_info["cpython"].python + + @property + def _clean_py_version(self): + return str(self._py_version) @property def _py_version(self): - return re.match(r"^([0-9.]+)", self.deps_cpp_info["cpython"].version).group(1) + if conan2: + return Version(self.dependencies["cpython"].ref.version) + else: + return Version(self.deps_cpp_info["cpython"].version) + + @property + def _test_setuptools(self): + # TODO Should we still try to test this? + # https://github.com/python/cpython/pull/101039 + return can_run(self) and self._supports_modules and self._py_version < "3.12" @property def _pymalloc(self): - return bool("pymalloc" in self.options["cpython"] and self.options["cpython"].pymalloc) + if conan2: + return bool(self.dependencies["cpython"].options.get_safe("pymalloc", False)) + else: + return bool("pymalloc" in self.options["cpython"] and self.options["cpython"].pymalloc) @property def _cmake_abi(self): - if self._py_version < Version("3.8"): - return CmakePython3Abi( - debug=self.settings.build_type == "Debug", - pymalloc=self._pymalloc, - unicode=False, - ) + if self._py_version < "3.8": + return CmakePython3Abi(debug=self.settings.build_type == "Debug", pymalloc=self._pymalloc, unicode=False) else: - return CmakePython3Abi( - debug=self.settings.build_type == "Debug", - pymalloc=False, - unicode=False, - ) + return CmakePython3Abi(debug=self.settings.build_type == "Debug", pymalloc=False, unicode=False) @property def _cmake_try_FindPythonX(self): - if is_msvc(self) and self.settings.build_type == "Debug": - return False - return True + return not is_msvc(self) or self.settings.build_type != "Debug" @property def _supports_modules(self): - return not is_msvc(self) or self.options["cpython"].shared + if conan2: + return not is_msvc(self) or self.dependencies["cpython"].options.shared + else: + return not is_msvc(self) or self.options["cpython"].shared + + def generate(self): + tc = CMakeToolchain(self) + version = self._py_version + py_major = str(version.major) + tc.cache_variables["BUILD_MODULE"] = self._supports_modules + tc.cache_variables["PY_VERSION_MAJOR"] = py_major + tc.cache_variables["PY_VERSION_MAJOR_MINOR"] = f"{version.major}.{version.minor}" + tc.cache_variables["PY_FULL_VERSION"] = str(version) + tc.cache_variables["PY_VERSION"] = self._clean_py_version + tc.cache_variables["PY_VERSION_SUFFIX"] = self._cmake_abi.suffix + tc.cache_variables["PYTHON_EXECUTABLE"] = self._python + tc.cache_variables["USE_FINDPYTHON_X".format(py_major)] = self._cmake_try_FindPythonX + tc.cache_variables[f"Python{py_major}_EXECUTABLE"] = self._python + tc.cache_variables[f"Python{py_major}_ROOT_DIR"] = self.dependencies["cpython"].package_folder + tc.cache_variables[f"Python{py_major}_USE_STATIC_LIBS"] = not self.dependencies["cpython"].options.shared + tc.cache_variables[f"Python{py_major}_FIND_FRAMEWORK"] = "NEVER" + tc.cache_variables[f"Python{py_major}_FIND_REGISTRY"] = "NEVER" + tc.cache_variables[f"Python{py_major}_FIND_IMPLEMENTATIONS"] = "CPython" + tc.cache_variables[f"Python{py_major}_FIND_STRATEGY"] = "LOCATION" + if not is_msvc(self) and self._py_version < "3.8": + tc.cache_variables[f"Python{py_major}_FIND_ABI"] = self._cmake_abi.cmake_arg + tc.generate() - def build(self): - if can_run(self): - command = "{} --version".format(self.deps_user_info["cpython"].python) - buffer = StringIO() - self.run(command, output=buffer, ignore_errors=True, run_environment=True) - self.output.info("output: %s" % buffer.getvalue()) - self.run(command, run_environment=True) + try: + # CMakeToolchain might generate VCVars, but we need it + # unconditionally for the setuptools build. + VCVars(self).generate() + except ConanException: + pass + + # The build also needs access to the run environment to run the python executable + VirtualRunEnv(self).generate(scope="run") + VirtualRunEnv(self).generate(scope="build") + if self._test_setuptools: + # Just for the distutils build + AutotoolsDeps(self).generate(scope="build") + + def build(self): cmake = CMake(self) - py_major = self.deps_cpp_info["cpython"].version.split(".")[0] - cmake.definitions["BUILD_MODULE"] = self._supports_modules - cmake.definitions["PY_VERSION_MAJOR"] = py_major - cmake.definitions["PY_VERSION_MAJOR_MINOR"] = ".".join(self._py_version.split(".")[:2]) - cmake.definitions["PY_FULL_VERSION"] = self.deps_cpp_info["cpython"].version - cmake.definitions["PY_VERSION"] = self._py_version - cmake.definitions["PY_VERSION_SUFFIX"] = self._cmake_abi.suffix - cmake.definitions["PYTHON_EXECUTABLE"] = self.deps_user_info["cpython"].python - cmake.definitions["USE_FINDPYTHON_X".format(py_major)] = self._cmake_try_FindPythonX - cmake.definitions["Python{}_EXECUTABLE".format(py_major)] = self.deps_user_info["cpython"].python - cmake.definitions["Python{}_ROOT_DIR".format(py_major)] = self.deps_cpp_info["cpython"].rootpath - cmake.definitions["Python{}_USE_STATIC_LIBS".format(py_major)] = not self.options["cpython"].shared - cmake.definitions["Python{}_FIND_FRAMEWORK".format(py_major)] = "NEVER" - cmake.definitions["Python{}_FIND_REGISTRY".format(py_major)] = "NEVER" - cmake.definitions["Python{}_FIND_IMPLEMENTATIONS".format(py_major)] = "CPython" - cmake.definitions["Python{}_FIND_STRATEGY".format(py_major)] = "LOCATION" - - if is_msvc(self): - if Version(self._py_version) < Version("3.8"): - cmake.definitions["Python{}_FIND_ABI".format(py_major)] = self._cmake_abi.cmake_arg - - with legacy_tools.environment_append(RunEnvironment(self).vars): - cmake.configure() + cmake.configure() cmake.build() - if can_run(self): - if self._supports_modules: - with legacy_tools.vcvars(self.settings) if is_msvc(self) else legacy_tools.no_op(): - modsrcfolder = "py2" if Version(self.deps_cpp_info["cpython"].version).major < "3" else "py3" - mkdir(self, os.path.join(self.build_folder, modsrcfolder)) - for fn in os.listdir(os.path.join(self.source_folder, modsrcfolder)): - shutil.copy(os.path.join(self.source_folder, modsrcfolder, fn), os.path.join(self.build_folder, modsrcfolder, fn)) - shutil.copy(os.path.join(self.source_folder, "setup.py"), os.path.join(self.build_folder, "setup.py")) - env = { - "DISTUTILS_USE_SDK": "1", - "MSSdk": "1" - } - env.update(**AutoToolsBuildEnvironment(self).vars) - with legacy_tools.environment_append(env): - setup_args = [ - f"{self.source_folder}/setup.py", - # "conan", - # "--install-folder", self.build_folder, - "build", - "--build-base", self.build_folder, - "--build-platlib", os.path.join(self.build_folder, "lib_setuptools"), - ] - if self.settings.build_type == "Debug": - setup_args.append("--debug") - self.run("{} {}".format(self.deps_user_info["cpython"].python, " ".join("\"{}\"".format(a) for a in setup_args)), run_environment=True) + if self._test_setuptools: + os.environ["DISTUTILS_USE_SDK"] = "1" + os.environ["MSSdk"] = "1" + setup_args = [ + os.path.join(self.source_folder, "setup.py"), + "build", + "--build-base", self.build_folder, + "--build-platlib", os.path.join(self.build_folder, "lib_setuptools"), + ] + if self.settings.build_type == "Debug": + setup_args.append("--debug") + args = " ".join(f'"{a}"' for a in setup_args) + self.run(f"{self._python} {args}") def _test_module(self, module, should_work): - exception = None try: - self.run("{} {}/test_package.py -b {} -t {} ".format( - self.deps_user_info["cpython"].python, self.source_folder, self.build_folder, module), run_environment=True) - works = True - except ConanException as e: - works = False - exception = e - if should_work == works: - self.output.info("Result of test was expected.") - else: - if works: - raise ConanException("Module '{}' works, but should not have worked".format(module)) - else: - self.output.warn("Module '{}' does not work, but should have worked".format(module)) - raise exception + self.run(f"{self._python} {self.source_folder}/test_package.py -b {self.build_folder} -t {module}", env="conanrun") + except ConanException: + if should_work: + self.output.warning(f"Module '{module}' does not work, but should have worked") + raise + self.output.info("Module failed as expected") + return + if not should_work: + raise ConanException(f"Module '{module}' works, but should not have worked") + self.output.info("Module worked as expected") def _cpython_option(self, name): - try: - return getattr(self.options["cpython"], name, False) - except ConanException: - return False + if conan2: + return self.dependencies["cpython"].options.get_safe(name, False) + else: + try: + return getattr(self.options["cpython"], name, False) + except ConanException: + return False def test(self): if can_run(self): - self.run("{} -c \"print('hello world')\"".format(self.deps_user_info["cpython"].python), run_environment=True) + self.run(f"{self._python} --version", env="conanrun") + + self.run(f"{self._python} -c \"print('hello world')\"", env="conanrun") buffer = StringIO() - self.run("{} -c \"import sys; print('.'.join(str(s) for s in sys.version_info[:3]))\"".format(self.deps_user_info["cpython"].python), run_environment=True, output=buffer) + self.run(f"{self._python} -c \"import sys; print('.'.join(str(s) for s in sys.version_info[:3]))\"", buffer, env="conanrun") self.output.info(buffer.getvalue()) version_detected = buffer.getvalue().splitlines()[-1].strip() - if self._py_version != version_detected: - raise ConanException("python reported wrong version. Expected {exp}. Got {res}.".format(exp=self._py_version, res=version_detected)) + if self._clean_py_version != version_detected: + raise ConanException( + f"python reported wrong version. Expected {self._clean_py_version}. Got {version_detected}." + ) if self._supports_modules: self._test_module("gdbm", self._cpython_option("with_gdbm")) self._test_module("bz2", self._cpython_option("with_bz2")) - self._test_module("bsddb", self._cpython_option("with_bsddb")) + if self._py_version.major < 3: + self._test_module("bsddb", self._cpython_option("with_bsddb")) self._test_module("lzma", self._cpython_option("with_lzma")) self._test_module("tkinter", self._cpython_option("with_tkinter")) - with legacy_tools.environment_append({"TERM": "ansi"}): - self._test_module("curses", self._cpython_option("with_curses")) + os.environ["TERM"] = "ansi" + self._test_module("curses", self._cpython_option("with_curses")) self._test_module("expat", True) - self._test_module("sqlite3", True) + self._test_module("sqlite3", self._cpython_option("with_sqlite3")) self._test_module("decimal", True) self._test_module("ctypes", True) - - if is_apple_os(self) and not self.options["cpython"].shared: - self.output.info("Not testing the module, because these seem not to work on apple when cpython is built as a static library") + skip_ssl_test = is_msvc(self) and self._py_version < "3.8" and self._cpython_option("shared") + if not skip_ssl_test: + # Unsure cause of failure in this oddly specific combo, but these versions are EOL so not concerned with fixing. + self._test_module("ssl", True) + + if is_apple_os(self) and not self._cpython_option("shared"): + self.output.info( + "Not testing the module, because these seem not to work on apple when cpython is built as" + " a static library" + ) # FIXME: find out why cpython on apple does not allow to use modules linked against a static python else: if self._supports_modules: - with legacy_tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib")]}): - self.output.info("Testing module (spam) using cmake built module") - self._test_module("spam", True) + os.environ["PYTHONPATH"] = os.path.join(self.build_folder, self.cpp.build.libdirs[0]) + self.output.info("Testing module (spam) using cmake built module") + self._test_module("spam", True) - with legacy_tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib_setuptools")]}): + if self._test_setuptools: + os.environ["PYTHONPATH"] = os.path.join(self.build_folder, "lib_setuptools") self.output.info("Testing module (spam) using setup.py built module") self._test_module("spam", True) - # MSVC builds need PYTHONHOME set. - with legacy_tools.environment_append({"PYTHONHOME": self.deps_user_info["cpython"].pythonhome}) if self.deps_user_info["cpython"].module_requires_pythonhome == "True" else legacy_tools.no_op(): - self.run(os.path.join("bin", "test_package"), run_environment=True) + del os.environ["PYTHONPATH"] + + # MSVC builds need PYTHONHOME set. Linux and Mac don't require it to be set if tested after building, + # but if the package is relocated then it needs to be set. + if conan2: + os.environ["PYTHONHOME"] = self.dependencies["cpython"].conf_info.get("user.cpython:pythonhome", check_type=str) + else: + os.environ["PYTHONHOME"] = self.deps_user_info["cpython"].pythonhome + bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/cpython/all/test_package/py3/test_package.c b/recipes/cpython/all/test_package/py3/test_package.c index f5dfe41..cf1688e 100644 --- a/recipes/cpython/all/test_package/py3/test_package.c +++ b/recipes/cpython/all/test_package/py3/test_package.c @@ -9,7 +9,6 @@ main(int argc, char *argv[]) fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); exit(1); } - Py_SetProgramName(program); /* optional but recommended */ Py_Initialize(); PyRun_SimpleString("from time import time, ctime\n" "print('Today is', ctime(time()))\n"); diff --git a/recipes/cpython/all/test_package/setup.py b/recipes/cpython/all/test_package/setup.py index 0affa6d..0f28378 100644 --- a/recipes/cpython/all/test_package/setup.py +++ b/recipes/cpython/all/test_package/setup.py @@ -8,27 +8,29 @@ if os.path.isdir(directory): os.add_dll_directory(directory) -PY2 = (2, 0) <= sys.version_info < (3, 0) -PY3 = (3, 0) <= sys.version_info < (4, 0) +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 -use_2to3 = True if PY2: subdir = "py2" from distutils.core import setup, Extension + use_2to3 = True elif PY3: subdir = "py3" - from setuptools import setup, Extension, __version__ as setuptools_versions + from setuptools import setup, Extension, __version__ as setuptools_version import pkg_resources - use_2to3 = pkg_resources.parse_version(setuptools_versions) <= pkg_resources.parse_version("58.0.0") + # use_2to3 is deprecated in this version + use_2to3 = pkg_resources.parse_version(setuptools_version) < pkg_resources.parse_version("46.2.0") else: raise Exception +script_dir = os.path.dirname(os.path.realpath(__file__)) setup( name="test_package", version="1.0", use_2to3=use_2to3, ext_modules=[ - Extension("spam", [os.path.join(subdir, "test_module.c")]), + Extension("spam", [os.path.join(script_dir, subdir, "test_module.c")]), ], ) diff --git a/recipes/cpython/all/test_package/test_package.py b/recipes/cpython/all/test_package/test_package.py index f77d283..b682818 100644 --- a/recipes/cpython/all/test_package/test_package.py +++ b/recipes/cpython/all/test_package/test_package.py @@ -14,12 +14,13 @@ def add_test(fn): global ALL_TESTS - name = fn.__name__[fn.__name__.find("_")+1:] + name = fn.__name__[fn.__name__.find("_") + 1 :] def inner_fn(): print("testing {}".format(name)) sys.stdout.flush() fn() + ALL_TESTS[name] = inner_fn return fn @@ -30,13 +31,13 @@ def test_expat(): # 3 handler functions def start_element(name, attrs): - print('Start element:', name, attrs) + print("Start element:", name, attrs) def end_element(name): - print('End element:', name) + print("End element:", name) def char_data(data): - print('Character data:', repr(data)) + print("Character data:", repr(data)) p = xml.parsers.expat.ParserCreate() @@ -44,10 +45,13 @@ def char_data(data): p.EndElementHandler = end_element p.CharacterDataHandler = char_data - p.Parse(""" + p.Parse( + """ Text goes here More text - """, 1) + """, + 1, + ) @add_test @@ -85,10 +89,8 @@ def test_spam(): if "This is an example spam doc." not in spam.__doc__: raise Exception("spam.__doc__ does not contain the expected text") - cmd = { - "Windows": "dir", - }.get(platform.system(), "ls") - print("About to run spam.system(\"{}\")".format(cmd)) + cmd = {"Windows": "dir"}.get(platform.system(), "ls") + print('About to run spam.system("{}")'.format(cmd)) sys.stdout.flush() spam.system(cmd) @@ -133,6 +135,7 @@ def test_lzma(): @add_test def test_sqlite3(): import sqlite3 + conn = sqlite3.connect("sqlite3.db") c = conn.cursor() @@ -141,16 +144,16 @@ def test_sqlite3(): c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") conn.commit() - t = ('RHAT',) - c.execute('SELECT * FROM stocks WHERE symbol=?', t) + t = ("RHAT",) + c.execute("SELECT * FROM stocks WHERE symbol=?", t) # Larger example that inserts many records at a time purchases = [ - ('2006-03-28', 'BUY', 'IBM', 1000, 45.00), - ('2006-04-05', 'BUY', 'MSFT', 1000, 72.00), - ('2006-04-06', 'SELL', 'IBM', 500, 53.00), + ("2006-03-28", "BUY", "IBM", 1000, 45.00), + ("2006-04-05", "BUY", "MSFT", 1000, 72.00), + ("2006-04-06", "SELL", "IBM", 500, 53.00), ] - c.executemany('INSERT INTO stocks VALUES (?,?,?,?,?)', purchases) + c.executemany("INSERT INTO stocks VALUES (?,?,?,?,?)", purchases) conn.commit() conn.close() conn = sqlite3.connect("sqlite3.db") @@ -161,11 +164,13 @@ def test_sqlite3(): raise Exception("Need 4 stocks") print(data) conn.close() + # Remove the file so subsequent tests don't fail + os.remove("sqlite3.db") @add_test def test_decimal(): - if sys.version_info >= (3, ): + if sys.version_info >= (3,): # Check whether the _decimal package was built successfully import _decimal as decimal else: @@ -199,6 +204,14 @@ def test_tkinter(): print("tk version: {}".format(_tkinter.TK_VERSION)) +@add_test +def test_ssl(): + import ssl + + default_context = ssl.create_default_context() + print("default_context.options={}".format(default_context.options)) + + def main(): parser = argparse.ArgumentParser() parser.add_argument("-b", dest="build_folder", help="build_folder", required=True) diff --git a/recipes/cpython/all/test_v1_package/CMakeLists.txt b/recipes/cpython/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000..5253293 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,100 @@ +cmake_minimum_required(VERSION 3.1) +project(test_package C) + +include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") +conan_basic_setup() + +set(CACHE PY_VERSION_MAJOR "" CACHE STRING "MAJOR version of python") +set(CACHE PY_VERSION_MAJOR_MINOR "" CACHE STRING "MAJOR.MINOR version of python") +set(CACHE PY_VERSION "" CACHE STRING "Required version of python") +set(CACHE PY_VERSION_SUFFIX "" CACHE STRING "Suffix of python") + +set(Python_ADDITIONAL_VERSIONS ${PY_VERSION}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR_MINOR}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR}${PY_VERSION_SUFFIX} ${PY_VERSION} ${PY_VERSION_MAJOR_MINOR} ${PY_VERSION_MAJOR}) +message("Using Python_ADDITIONAL_VERSIONS: ${Python_ADDITIONAL_VERSIONS}") + +find_package(PythonInterp REQUIRED) +find_package(PythonLibs REQUIRED) + +string(FIND "${PYTHON_EXECUTABLE}" "${CONAN_CPYTHON_ROOT}" ROOT_SUBPOS) +if(ROOT_SUBPOS EQUAL -1) + message(FATAL_ERROR "found wrong python interpreter: ${PYTHON_EXECUTABLE}") +endif() + +message(STATUS "FindPythonInterp:") +message(STATUS "PYTHON_VERSION_STRING: ${PYTHON_VERSION_STRING}") +message(STATUS "PYTHON_VERSION_MAJOR: ${PYTHON_VERSION_MAJOR}") +message(STATUS "PYTHON_VERSION_MINOR: ${PYTHON_VERSION_MINOR}") +message(STATUS "PYTHON_VERSION_PATCH: ${PYTHON_VERSION_PATCH}") +message(STATUS "=============================================") +message(STATUS "FindPythonLibs:") +message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}") +message(STATUS "PYTHON_INCLUDE_PATH: ${PYTHON_INCLUDE_PATH} (deprecated)") +message(STATUS "PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}") +message(STATUS "PYTHON_DEBUG_LIBRARIES: ${PYTHON_DEBUG_LIBRARIES} (deprecated)") +message(STATUS "PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}") + +if(NOT PYTHON_VERSION_STRING AND NOT PYTHONLIBS_VERSION_STRING) + message(FATAL_ERROR "Version of python interpreter and libraries not found") +endif() + +if(PYTHON_VERSION_STRING) + if(NOT PYTHON_VERSION_STRING VERSION_EQUAL "${PY_VERSION}") + message("PYTHON_VERSION_STRING does not match PY_VERSION") + message(FATAL_ERROR "CMake detected wrong cpython version") + endif() +endif() + +if(PYTHONLIBS_VERSION_STRING) + if(NOT PYTHONLIBS_VERSION_STRING STREQUAL "${PY_FULL_VERSION}") + message("PYTHONLIBS_VERSION_STRING does not match PY_FULL_VERSION") + message(FATAL_ERROR "CMake detected wrong cpython version") + endif() +endif() + +option(BUILD_MODULE "Build python module") + +if(BUILD_MODULE) + add_library(spam MODULE "py${PY_VERSION_MAJOR}/test_module.c") + target_include_directories(spam + PRIVATE + ${PYTHON_INCLUDE_DIRS} + ) + target_link_libraries(spam PRIVATE + ${PYTHON_LIBRARIES} + ) + set_property(TARGET spam PROPERTY PREFIX "") + if(MSVC) + if(CONAN_SETTINGS_BUILD_TYPE STREQUAL "Debug") + set(SUFFIX "_d.pyd") + else() + set(SUFFIX ".pyd") + endif() + set_property(TARGET spam PROPERTY SUFFIX "${SUFFIX}") + endif() + + option(USE_FINDPYTHON_X "Use new-style FindPythonX module") + if(USE_FINDPYTHON_X AND NOT (CMAKE_VERSION VERSION_LESS "3.16")) + # Require CMake 3.16 because this version introduces Python${PY_VERSION_MAJOR}_FIND_ABI + find_package(Python${PY_VERSION_MAJOR} REQUIRED COMPONENTS Interpreter Development) + message("Python${PY_VERSION_MAJOR}_EXECUTABLE: ${Python${PY_VERSION_MAJOR}_EXECUTABLE}") + message("Python${PY_VERSION_MAJOR}_INTERPRETER_ID: ${Python${PY_VERSION_MAJOR}_INTERPRETER_ID}") + message("Python${PY_VERSION_MAJOR}_VERSION: ${Python${PY_VERSION_MAJOR}_VERSION}") + message("Python${PY_VERSION_MAJOR}_INCLUDE_DIRS: ${Python${PY_VERSION_MAJOR}_INCLUDE_DIRS}") + message("Python${PY_VERSION_MAJOR}_LIBRARIES: ${Python${PY_VERSION_MAJOR}_LIBRARIES}") + if(NOT Python${PY_VERSION_MAJOR}_VERSION STREQUAL "${PY_VERSION}") + message("Python_ADDITIONAL_VERSIONS does not match PY_VERSION") + message(FATAL_ERROR "CMake detected wrong cpython version") + endif() + + if(PY_VERSION_MAJOR STREQUAL "2") + python2_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") + elseif(PY_VERSION_MAJOR STREQUAL "3") + python3_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") + else() + message(FATAL_ERROR "Unknown PY_VERSION_MAJOR") + endif() + endif() +endif() + +add_executable(${PROJECT_NAME} "py${PY_VERSION_MAJOR}/test_package.c") +target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/cpython/all/test_v1_package/conanfile.py b/recipes/cpython/all/test_v1_package/conanfile.py new file mode 100644 index 0000000..eecbd54 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/conanfile.py @@ -0,0 +1,212 @@ +from conans import AutoToolsBuildEnvironment, ConanFile, CMake, tools, RunEnvironment +from conans.errors import ConanException +from conan.tools.env import VirtualRunEnv +from io import StringIO +import os +import re +import shutil + + +class CmakePython3Abi(object): + def __init__(self, debug, pymalloc, unicode): + self.debug, self.pymalloc, self.unicode = debug, pymalloc, unicode + + _cmake_lut = { + None: "ANY", + True: "ON", + False: "OFF", + } + + @property + def suffix(self): + return "{}{}{}".format( + "d" if self.debug else "", + "m" if self.pymalloc else "", + "u" if self.unicode else "", + ) + + @property + def cmake_arg(self): + return ";".join(self._cmake_lut[a] for a in (self.debug, self.pymalloc, self.unicode)) + + +class TestPackageConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake" + + @property + def _py_version(self): + return re.match(r"^([0-9.]+)", self.deps_cpp_info["cpython"].version).group(1) + + @property + def _test_setuptools(self): + # TODO Should we still try to test this? + # https://github.com/python/cpython/pull/101039 + return not tools.cross_building(self, skip_x64_x86=True) and self._supports_modules and self._py_version < tools.Version("3.12") + + @property + def _pymalloc(self): + return bool("pymalloc" in self.options["cpython"] and self.options["cpython"].pymalloc) + + @property + def _cmake_abi(self): + if self._py_version < tools.Version("3.8"): + return CmakePython3Abi( + debug=self.settings.build_type == "Debug", + pymalloc=self._pymalloc, + unicode=False, + ) + else: + return CmakePython3Abi( + debug=self.settings.build_type == "Debug", + pymalloc=False, + unicode=False, + ) + + @property + def _cmake_try_FindPythonX(self): + if self.settings.compiler == "Visual Studio" and self.settings.build_type == "Debug": + return False + return True + + @property + def _supports_modules(self): + return self.settings.compiler != "Visual Studio" or self.options["cpython"].shared + + def generate(self): + # The build also needs access to the run environment to run the python executable + VirtualRunEnv(self).generate(scope="run") + VirtualRunEnv(self).generate(scope="build") + + def build_requirements(self): + # The main recipe does not require CMake, but we test with it. + # The interesting problem that arises here is if you have CMake installed + # with your global pip, then it will fail to run in this test package. + # To avoid that, just add a requirement on CMake. + self.tool_requires("cmake/[>=3.15 <4]") + + def build(self): + if not tools.cross_building(self, skip_x64_x86=True): + command = "{} --version".format(self.deps_user_info["cpython"].python) + buffer = StringIO() + self.run(command, output=buffer, ignore_errors=True, run_environment=True) + self.output.info("output: %s" % buffer.getvalue()) + self.run(command, run_environment=True) + + cmake = CMake(self) + py_major = self.deps_cpp_info["cpython"].version.split(".")[0] + cmake.definitions["BUILD_MODULE"] = self._supports_modules + cmake.definitions["PY_VERSION_MAJOR"] = py_major + cmake.definitions["PY_VERSION_MAJOR_MINOR"] = ".".join(self._py_version.split(".")[:2]) + cmake.definitions["PY_FULL_VERSION"] = self.deps_cpp_info["cpython"].version + cmake.definitions["PY_VERSION"] = self._py_version + cmake.definitions["PY_VERSION_SUFFIX"] = self._cmake_abi.suffix + cmake.definitions["PYTHON_EXECUTABLE"] = self.deps_user_info["cpython"].python + cmake.definitions["USE_FINDPYTHON_X".format(py_major)] = self._cmake_try_FindPythonX + cmake.definitions["Python{}_EXECUTABLE".format(py_major)] = self.deps_user_info["cpython"].python + cmake.definitions["Python{}_ROOT_DIR".format(py_major)] = self.deps_cpp_info["cpython"].rootpath + cmake.definitions["Python{}_USE_STATIC_LIBS".format(py_major)] = not self.options["cpython"].shared + cmake.definitions["Python{}_FIND_FRAMEWORK".format(py_major)] = "NEVER" + cmake.definitions["Python{}_FIND_REGISTRY".format(py_major)] = "NEVER" + cmake.definitions["Python{}_FIND_IMPLEMENTATIONS".format(py_major)] = "CPython" + cmake.definitions["Python{}_FIND_STRATEGY".format(py_major)] = "LOCATION" + + if self.settings.compiler != "Visual Studio": + if tools.Version(self._py_version) < tools.Version("3.8"): + cmake.definitions["Python{}_FIND_ABI".format(py_major)] = self._cmake_abi.cmake_arg + + with tools.environment_append(RunEnvironment(self).vars): + cmake.configure() + cmake.build() + + if self._test_setuptools: + with tools.vcvars(self.settings) if self.settings.compiler == "Visual Studio" else tools.no_op(): + modsrcfolder = "py2" if tools.Version(self.deps_cpp_info["cpython"].version).major < "3" else "py3" + tools.mkdir(os.path.join(self.build_folder, modsrcfolder)) + for fn in os.listdir(os.path.join(self.source_folder, modsrcfolder)): + shutil.copy(os.path.join(self.source_folder, modsrcfolder, fn), os.path.join(self.build_folder, modsrcfolder, fn)) + shutil.copy(os.path.join(self.source_folder, "setup.py"), os.path.join(self.build_folder, "setup.py")) + env = { + "DISTUTILS_USE_SDK": "1", + "MSSdk": "1" + } + env.update(**AutoToolsBuildEnvironment(self).vars) + with tools.environment_append(env): + setup_args = [ + "{}/setup.py".format(self.source_folder), + # "conan", + # "--install-folder", self.build_folder, + "build", + "--build-base", self.build_folder, + "--build-platlib", os.path.join(self.build_folder, "lib_setuptools"), + ] + if self.settings.build_type == "Debug": + setup_args.append("--debug") + self.run("{} {}".format(self.deps_user_info["cpython"].python, " ".join("\"{}\"".format(a) for a in setup_args)), run_environment=True) + + def _test_module(self, module, should_work): + try: + self.run("{} {}/../test_package/test_package.py -b {} -t {} ".format( + self.deps_user_info["cpython"].python, self.source_folder, self.build_folder, module), run_environment=True) + works = True + except ConanException as e: + works = False + exception = e + if should_work == works: + self.output.info("Result of test was expected.") + else: + if works: + raise ConanException("Module '{}' works, but should not have worked".format(module)) + else: + self.output.warn("Module '{}' does not work, but should have worked".format(module)) + raise exception + + def _cpython_option(self, name): + try: + return getattr(self.options["cpython"], name, False) + except ConanException: + return False + + def test(self): + if not tools.cross_building(self, skip_x64_x86=True): + self.run("{} -c \"print('hello world')\"".format(self.deps_user_info["cpython"].python), run_environment=True) + + buffer = StringIO() + self.run("{} -c \"import sys; print('.'.join(str(s) for s in sys.version_info[:3]))\"".format(self.deps_user_info["cpython"].python), run_environment=True, output=buffer) + self.output.info(buffer.getvalue()) + version_detected = buffer.getvalue().splitlines()[-1].strip() + if self._py_version != version_detected: + raise ConanException("python reported wrong version. Expected {exp}. Got {res}.".format(exp=self._py_version, res=version_detected)) + + if self._supports_modules: + self._test_module("gdbm", self._cpython_option("with_gdbm")) + self._test_module("bz2", self._cpython_option("with_bz2")) + self._test_module("bsddb", self._cpython_option("with_bsddb")) + self._test_module("lzma", self._cpython_option("with_lzma")) + self._test_module("tkinter", self._cpython_option("with_tkinter")) + with tools.environment_append({"TERM": "ansi"}): + self._test_module("curses", self._cpython_option("with_curses")) + + self._test_module("expat", True) + self._test_module("sqlite3", True) + self._test_module("decimal", True) + self._test_module("ctypes", True) + + if tools.is_apple_os(self.settings.os) and not self.options["cpython"].shared: + self.output.info("Not testing the module, because these seem not to work on apple when cpython is built as a static library") + # FIXME: find out why cpython on apple does not allow to use modules linked against a static python + else: + if self._supports_modules: + with tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib")]}): + self.output.info("Testing module (spam) using cmake built module") + self._test_module("spam", True) + + if self._test_setuptools: + with tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib_setuptools")]}): + self.output.info("Testing module (spam) using setup.py built module") + self._test_module("spam", True) + + # MSVC builds need PYTHONHOME set. Linux and Mac don't require it to be set if tested after building, + # but if the package is relocated then it needs to be set. + with tools.environment_append({"PYTHONHOME": self.deps_user_info["cpython"].pythonhome}): + self.run(os.path.join("bin", "test_package"), run_environment=True) diff --git a/recipes/cpython/all/test_v1_package/py2/test_module.c b/recipes/cpython/all/test_v1_package/py2/test_module.c new file mode 100644 index 0000000..9c5af39 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/py2/test_module.c @@ -0,0 +1,42 @@ +#include + +#include + +static PyObject *SpamError; + +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + if (sts < 0) { + PyErr_SetString(SpamError, "System command failed"); + return NULL; + } + return PyLong_FromLong(sts); +} + +const char spam_doc[] = "This is an example spam doc."; + +static PyMethodDef SpamMethods[] = { + {"system", spam_system, METH_VARARGS, "Execute a shell command."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +PyMODINIT_FUNC +initspam(void) +{ + PyObject *m; + + m = Py_InitModule("spam", SpamMethods); + if (m == NULL) + return; + PyModule_AddStringConstant(m, "__doc__", spam_doc); + SpamError = PyErr_NewException("spam.error", NULL, NULL); + Py_INCREF(SpamError); + PyModule_AddObject(m, "error", SpamError); +} diff --git a/recipes/cpython/all/test_v1_package/py2/test_package.c b/recipes/cpython/all/test_v1_package/py2/test_package.c new file mode 100644 index 0000000..5e5d839 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/py2/test_package.c @@ -0,0 +1,12 @@ +#include + +int +main(int argc, char *argv[]) +{ + Py_SetProgramName(argv[0]); /* optional but recommended */ + Py_Initialize(); + PyRun_SimpleString("from time import time,ctime\n" + "print 'Today is',ctime(time())\n"); + Py_Finalize(); + return 0; +} diff --git a/recipes/cpython/all/test_v1_package/py3/test_module.c b/recipes/cpython/all/test_v1_package/py3/test_module.c new file mode 100644 index 0000000..7372ac3 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/py3/test_module.c @@ -0,0 +1,52 @@ +#include + +#include + +static PyObject *SpamError; + +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + if (sts < 0) { + PyErr_SetString(SpamError, "System command failed"); + return NULL; + } + return PyLong_FromLong(sts); +} + +const char spam_doc[] = "This is an example spam doc."; + +static PyMethodDef SpamMethods[] = { + {"system", spam_system, METH_VARARGS, "Execute a shell command."}, + {NULL, NULL, 0, NULL} /* Sentinel */ +}; + +static struct PyModuleDef spammodule = { + PyModuleDef_HEAD_INIT, + "spam", /* name of module */ + spam_doc, /* module documentation, may be NULL */ + -1, /* size of per-interpreter state of the module, + or -1 if the module keeps state in global variables. */ + SpamMethods +}; + +PyMODINIT_FUNC +PyInit_spam(void) +{ + PyObject *m; + + m = PyModule_Create(&spammodule); + if (m == NULL) + return NULL; + + SpamError = PyErr_NewException("spam.error", NULL, NULL); + Py_INCREF(SpamError); + PyModule_AddObject(m, "error", SpamError); + return m; +} diff --git a/recipes/cpython/all/test_v1_package/py3/test_package.c b/recipes/cpython/all/test_v1_package/py3/test_package.c new file mode 100644 index 0000000..cf1688e --- /dev/null +++ b/recipes/cpython/all/test_v1_package/py3/test_package.c @@ -0,0 +1,20 @@ +#define PY_SSIZE_T_CLEAN +#include + +int +main(int argc, char *argv[]) +{ + wchar_t *program = Py_DecodeLocale(argv[0], NULL); + if (program == NULL) { + fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); + exit(1); + } + Py_Initialize(); + PyRun_SimpleString("from time import time, ctime\n" + "print('Today is', ctime(time()))\n"); + if (Py_FinalizeEx() < 0) { + exit(120); + } + PyMem_RawFree(program); + return 0; +} diff --git a/recipes/cpython/all/test_v1_package/setup.py b/recipes/cpython/all/test_v1_package/setup.py new file mode 100644 index 0000000..526a552 --- /dev/null +++ b/recipes/cpython/all/test_v1_package/setup.py @@ -0,0 +1,35 @@ +import os +import sys + +# Hack to work around Python 3.8+ secure dll loading: +# see https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew +if hasattr(os, "add_dll_directory"): + for directory in os.environ.get("PATH", "").split(os.pathsep): + if os.path.isdir(directory): + os.add_dll_directory(directory) + +PY2 = (2, 0) <= sys.version_info < (3, 0) +PY3 = (3, 0) <= sys.version_info < (4, 0) + +if PY2: + subdir = "py2" + from distutils.core import setup, Extension + use_2to3 = True +elif PY3: + subdir = "py3" + from setuptools import setup, Extension, __version__ as setuptools_version + import pkg_resources + # use_2to3 is deprecated in this version + use_2to3 = pkg_resources.parse_version(setuptools_version) < pkg_resources.parse_version("46.2.0") +else: + raise Exception + + +setup( + name="test_package", + version="1.0", + use_2to3=use_2to3, + ext_modules=[ + Extension("spam", [os.path.join(subdir, "test_module.c")]), + ], +) diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml index afce2ce..d4b95ed 100644 --- a/recipes/cpython/config.yml +++ b/recipes/cpython/config.yml @@ -1,3 +1,7 @@ versions: - "3.10.4": + "3.12.1": + folder: "all" + "3.11.7": + folder: "all" + "3.10.13": folder: "all" From b89471a0a15e7d9d0927ace0ce3580ab4efbbe46 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 6 Feb 2024 10:07:02 +0100 Subject: [PATCH 02/39] Only export 3.12.x Workflows seem to be broken to export multiple versions Contribute to CURA-11079 --- recipes/cpython/config.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml index d4b95ed..61fae49 100644 --- a/recipes/cpython/config.yml +++ b/recipes/cpython/config.yml @@ -1,7 +1,3 @@ versions: "3.12.1": folder: "all" - "3.11.7": - folder: "all" - "3.10.13": - folder: "all" From 6220aaa33c8cdb6adcced8cbe4669d2f425760d2 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 9 Feb 2024 10:50:28 +0100 Subject: [PATCH 03/39] Use CPython 3.12.2 Contributes to CURA-11079 --- recipes/cpython/all/conandata.yml | 16 ++++++++-------- recipes/cpython/config.yml | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/recipes/cpython/all/conandata.yml b/recipes/cpython/all/conandata.yml index 8b2d6fb..3ca1af7 100644 --- a/recipes/cpython/all/conandata.yml +++ b/recipes/cpython/all/conandata.yml @@ -1,10 +1,10 @@ sources: - "3.12.1": - url: "https://www.python.org/ftp/python/3.12.1/Python-3.12.1.tgz" - sha256: "d01ec6a33bc10009b09c17da95cc2759af5a580a7316b3a446eb4190e13f97b2" - "3.11.7": - url: "https://www.python.org/ftp/python/3.11.7/Python-3.11.7.tgz" - sha256: "068c05f82262e57641bd93458dfa883128858f5f4997aad7a36fd25b13b29209" + "3.12.2": + url: "https://www.python.org/ftp/python/3.12.2/Python-3.12.2.tgz" + sha256: "a7c4f6a9dc423d8c328003254ab0c9338b83037bd787d680826a5bf84308116e" + "3.11.8": + url: "https://www.python.org/ftp/python/3.11.8/Python-3.11.8.tgz" + sha256: "d3019a613b9e8761d260d9ebe3bd4df63976de30464e5c0189566e1ae3f61889" "3.10.13": url: "https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz" sha256: "698ec55234c1363bd813b460ed53b0f108877c7a133d48bde9a50a1eb57b7e65" @@ -21,12 +21,12 @@ sources: url: "https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz" sha256: "da3080e3b488f648a3d7a4560ddee895284c3380b11d6de75edb986526b9a814" patches: - "3.12.1": + "3.12.2": - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - patch_file: "patches/3.12/3.12.1-0001-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - patch_file: "patches/3.12/3.12.1-0002-remove-module-deps.patch" - "3.11.7": + "3.11.8": - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - patch_file: "patches/3.11/3.11.7-0001-_ctypes-ffi.patch" - patch_file: "patches/3.x-0001-relocatable-python-config.patch" diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml index 61fae49..b23790e 100644 --- a/recipes/cpython/config.yml +++ b/recipes/cpython/config.yml @@ -1,3 +1,3 @@ versions: - "3.12.1": + "3.12.2": folder: "all" From f2fbfb43b85d34fd34db661f67290e83cac30528 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 12 Feb 2024 11:31:35 +0100 Subject: [PATCH 04/39] Use Conan v2 Contributes to CURA-11079 --- .github/workflows/conan-package.yml | 42 ++++--------- recipes/clipper/all/conanfile.py | 5 +- recipes/pyprojecttoolchain/all/conanfile.py | 40 +++++++----- recipes/sipbuildtool/all/conanfile.py | 14 +++-- recipes/translationextractor/all/conanfile.py | 62 ++++++++++++------- 5 files changed, 85 insertions(+), 78 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 3318641..328dba2 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -7,6 +7,8 @@ on: branches: - main - 'CURA-*' + - 'PP-*' + - 'NP-*' permissions: contents: read @@ -30,9 +32,10 @@ jobs: with: PATTERNS: | recipes/**/*.* - + +# FIXME: use main once merged - name: Sync pip requirements - run: wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/main/.github/workflows/requirements-runner.txt -O .github/workflows/requirements-runner.txt + run: wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/CURA-11622_conan_v2/.github/workflows/requirements-runner.txt -O .github/workflows/requirements-runner.txt - name: Setup Python and pip uses: actions/setup-python@v4 @@ -44,38 +47,19 @@ jobs: - name: Install Python requirements and Create default Conan profile run: pip install -r .github/workflows/requirements-runner.txt - - name: Setup pipeline caches - run: | - mkdir -p /home/runner/.conan/downloads - mkdir -p /home/runner/.conan/data - - name: Create default Conan profile - run: conan profile new default --detect + run: conan profile detect -f +# FIXME: use runner.os/runner.arch after merge: conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/runner.os/runner.arch" - name: Get Conan configuration run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Cache Conan packages - uses: actions/cache@v3 - with: - path: /home/runner/.conan/data - key: ${{ runner.os }}-conan-data-${{ github.run_id }} - restore-keys: | - ${{ runner.os }}-conan-data- - - - name: Cache Conan downloads - uses: actions/cache@v3 - with: - path: /home/runner/.conan/downloads - key: ${{ runner.os }}-conan-downloads-${{ github.run_id }} - restore-keys: | - ${{ runner.os }}-conan-downloads- + conan config install https://github.com/Ultimaker/conan-config.git -a "-b CURA-11622_conan_v2" + conan remote login -p ${{ secrets.CONAN_PASS }} cura-conan-v2 ${{ secrets.CONAN_USER }} + #conan remote disable cura-private - # TODO: Change to main once merged +# TODO: Change to main once merged - name: Export changed recipes run: | mkdir runner_scripts - wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/main/runner_scripts/upload_conan_recipes.py -O runner_scripts/upload_conan_recipes.py - python runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura ${{ env.GIT_DIFF_FILTERED }} + wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/CURA-11622_conan_v2/runner_scripts/upload_conan_recipes.py -O runner_scripts/upload_conan_recipes.py + python runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan-v2 ${{ env.GIT_DIFF_FILTERED }} diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index 7a708b5..2da22e4 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -1,11 +1,10 @@ -from io import StringIO +import os +from shutil import which from conan import ConanFile from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, rmdir from conan.errors import ConanInvalidConfiguration -from conans.tools import which -import os required_conan_version = ">=1.54.0" diff --git a/recipes/pyprojecttoolchain/all/conanfile.py b/recipes/pyprojecttoolchain/all/conanfile.py index b7b77c4..2dfc4cf 100644 --- a/recipes/pyprojecttoolchain/all/conanfile.py +++ b/recipes/pyprojecttoolchain/all/conanfile.py @@ -10,8 +10,8 @@ from conan.tools.gnu.autotoolstoolchain import AutotoolsToolchain from conan.tools.files import save from conan.errors import ConanInvalidConfiguration -from conan.tools._check_build_profile import check_using_build_profile -from conans.tools import Version +from conan.tools.scm import Version +from conan.tools import CppInfo class BuildSystemBlock(Block): @@ -55,8 +55,8 @@ def context(self): mod_version = Version(self._conanfile.version) pypi_version = f"{mod_version.major}.{mod_version.minor}.{mod_version.patch}" - if mod_version.prerelease != "": - split_prerelease = mod_version.prerelease.split(".") + if mod_version.pre != "": + split_prerelease = str(mod_version.pre).split(".") if len(split_prerelease) > 1: pypi_version += f"{split_prerelease[0][0]}{split_prerelease[1]}" else: @@ -89,10 +89,11 @@ def context(self): if py_lib_dir is None: try: - py_lib_dir = Path(self._conanfile.deps_cpp_info['cpython'].rootpath, self._conanfile.deps_cpp_info['cpython'].components["python"].bindirs[0], "libs").as_posix() - py_lib = self._conanfile.deps_cpp_info['cpython'].libs[0] + cpython_cpp = self._conanfile.dependencies["cpython"].cpp_info + py_lib_dir = Path(cpython_cpp.components["python"].libdirs[0]).as_posix() + py_lib = cpython_cpp.components["python"].libs[0] except: - self._conanfile.output.warn( + self._conanfile.output.warning( "No include directory set for Python.h, either add the options: 'py_include' of add cpython as a Conan dependency!") else: py_lib_dir = Path(py_lib_dir).as_posix() @@ -128,7 +129,7 @@ def context(self): try: python_version = self._conanfile.dependencies["cpython"].ref.version except: - self._conanfile.output.warn( + self._conanfile.output.warning( "No minimum required Python version specified, either add the options: 'py_version' of add cpython as a Conan dependency!") if python_version is not None: @@ -137,12 +138,11 @@ def context(self): if py_include_dir is None: try: header_path = "" if self._conanfile.settings.os == "Windows" else f"python{py_version.major}.{py_version.minor}" - py_include_dir = Path(self._conanfile.deps_cpp_info['cpython'].rootpath, - self._conanfile.deps_cpp_info['cpython'].components["python"].includedirs[0], - header_path).as_posix() + cpython_cpp = self._conanfile.dependencies["cpython"].cpp_info + py_include_dir = Path(cpython_cpp.components["python"].includedirs[0], header_path).as_posix() py_include_dir = f"py-include-dir = \"{py_include_dir}\"" except: - self._conanfile.output.warn( + self._conanfile.output.warning( "No include directory set for Python.h, either add the options: 'py_include' of add cpython as a Conan dependency!") else: py_include_dir = f"py-include-dir = \"{Path(py_include_dir).as_posix()}\"" @@ -210,13 +210,19 @@ class ToolSipBindingsBlock(Block): def context(self): settings = self._conanfile.settings - deps_cpp_info = self._conanfile.deps_cpp_info + aggregated_cpp_info = CppInfo(self._conanfile) + deps = self._conanfile.dependencies.host.topological_sort + deps = [dep for dep in reversed(deps.values())] + for dep in deps: + dep_cppinfo = dep.cpp_info.aggregated_components() + aggregated_cpp_info.merge(dep_cppinfo) + build_type = settings.get_safe("build_type", "Release") shared = settings.get_safe("shared", True) - libs = deps_cpp_info.libs - libdirs = [Path(d).as_posix() for d in deps_cpp_info.libdirs] - includedirs = [Path(d).as_posix() for d in deps_cpp_info.includedirs] + libs = aggregated_cpp_info.libs + libdirs = [Path(d).as_posix() for d in aggregated_cpp_info.libdirs] + includedirs = [Path(d).as_posix() for d in aggregated_cpp_info.includedirs] if self._conanfile.cpp.source.includedirs: includedirs.extend(self._conanfile.cpp.source.includedirs) @@ -243,7 +249,6 @@ class PyProjectToolchain(AutotoolsToolchain): def __init__(self, conanfile: ConanFile, namespace = None): super().__init__(conanfile, namespace) - check_using_build_profile(self._conanfile) blocks = [ ("build_system", BuildSystemBlock), @@ -283,3 +288,4 @@ def generate(self, env = None, scope = "build"): class PyProjectToolchainPkg(ConanFile): name = "pyprojecttoolchain" + package_type = "build-scripts" diff --git a/recipes/sipbuildtool/all/conanfile.py b/recipes/sipbuildtool/all/conanfile.py index ed0e76d..7d04df1 100644 --- a/recipes/sipbuildtool/all/conanfile.py +++ b/recipes/sipbuildtool/all/conanfile.py @@ -1,7 +1,8 @@ import os from conan import ConanFile -from conans import tools +from conan.tools.files import chdir, copy + from conans.client.subsystems import subsystem_path, deduce_subsystem @@ -16,29 +17,32 @@ class SipBuildTool(object): sip.configure() sip.generate("projectName") """ + def __init__(self, conanfile: ConanFile): self._conanfile = conanfile self._sip_install_executable = "sip-build" - def configure(self, sip_install_executable = None): + def configure(self, sip_install_executable=None): if sip_install_executable: self._sip_install_executable = sip_install_executable def build(self): - with tools.chdir(self._conanfile.source_folder): + with chdir(self, self._conanfile.source_folder): sip_cmd = self._sip_install_executable - subsystem = deduce_subsystem(self._conanfile, scope = "build") + subsystem = deduce_subsystem(self._conanfile, scope="build") sip_cmd = subsystem_path(subsystem, sip_cmd) cmd = '"{}"'.format(sip_cmd) self._conanfile.output.info(f"Calling:\n > {cmd}") self._conanfile.run(cmd) + class Pkg(ConanFile): name = "sipbuildtool" + package_type = "build-scripts" exports_sources = "SIPMacros.cmake" def package(self): - self.copy("SIPMacros.cmake", "cmake") + copy(self, pattern="*.cmake", src=self.export_sources_folder, dst=os.path.join(self.package_folder, "cmake")) def package_info(self): self.cpp_info.set_property("name", "sip") diff --git a/recipes/translationextractor/all/conanfile.py b/recipes/translationextractor/all/conanfile.py index bcdafb8..74d8922 100644 --- a/recipes/translationextractor/all/conanfile.py +++ b/recipes/translationextractor/all/conanfile.py @@ -19,7 +19,8 @@ def __init__(self, conanfile: ConanFile, gettext_bindir): self._conanfile = conanfile self._gettext_bindir = gettext_bindir self._translations_root_path = self._conanfile.source_path.joinpath("resources", "i18n") - self._all_strings_pot_path = self._translations_root_path.joinpath(self._conanfile.name + ".pot") # pot file containing all strings untranslated + self._all_strings_pot_path = self._translations_root_path.joinpath( + self._conanfile.name + ".pot") # pot file containing all strings untranslated self._pot_content = {} self._pot_are_updated = False @@ -31,14 +32,17 @@ def _update_po_files_all_languages(self) -> None: self._conanfile.output.info(f"Updating {po_file}") if lang_folder.is_dir() and not po_file.exists(): po_file.touch() - self._conanfile.run(f"{self._gettext_bindir}/msginit --no-translator -i {pot_file} -o {po_file} --locale=en") - self._conanfile.run(f"{self._gettext_bindir}/msgmerge --add-location=never --no-wrap --no-fuzzy-matching --sort-output -o {po_file} {po_file} {pot_file}", env = "conanbuild", run_environment = True) + self._conanfile.run( + f"{self._gettext_bindir}/msginit --no-translator -i {pot_file} -o {po_file} --locale=en") + self._conanfile.run( + f"{self._gettext_bindir}/msgmerge --add-location=never --no-wrap --no-fuzzy-matching --sort-output -o {po_file} {po_file} {pot_file}", + env="conanbuild") def _remove_pot_header(self, content: str) -> str: - return "".join(content.splitlines(keepends = True)[20:]) + return "".join(content.splitlines(keepends=True)[20:]) def _remove_comments(self, content: str) -> str: - return "".join([line for line in content.splitlines(keepends = True) if not line.startswith("#")]) + return "".join([line for line in content.splitlines(keepends=True) if not line.startswith("#")]) def _load_pot_content(self) -> None: for pot_file in Path(self._translations_root_path).rglob("*.pot"): @@ -48,7 +52,8 @@ def _load_pot_content(self) -> None: def _is_pot_content_changed(self, pot_file: str) -> bool: if pot_file not in self._pot_content: return False - return self._remove_comments(self._remove_pot_header(self._pot_content[pot_file])) != self._remove_comments(self._remove_pot_header(load(self._conanfile, pot_file))) + return self._remove_comments(self._remove_pot_header(self._pot_content[pot_file])) != self._remove_comments( + self._remove_pot_header(load(self._conanfile, pot_file))) def _only_update_pot_files_when_changed(self) -> None: """restore the previous content of the pot files if the content hasn't changed""" @@ -78,7 +83,7 @@ def _extract_python(self) -> None: continue self._conanfile.run( f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=python --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", - env = "conanbuild", run_environment = True) + env="conanbuild") def _extract_qml(self) -> None: """ Extract all i18n strings from qml files inside the root path """ @@ -87,7 +92,7 @@ def _extract_qml(self) -> None: continue self._conanfile.run( f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=javascript --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", - env = "conanbuild", run_environment = True) + env="conanbuild") def _extract_plugin(self) -> None: """ Extract the name and description from all plugins """ @@ -96,28 +101,31 @@ def _extract_plugin(self) -> None: translation_entries = "" # Extract translations from plugin.json - plugin_dict = json.loads(load(self._conanfile, path), object_pairs_hook = collections.OrderedDict) - if "name" not in plugin_dict or ("api" not in plugin_dict and "supported_sdk_versions" not in plugin_dict) or "version" not in plugin_dict: + plugin_dict = json.loads(load(self._conanfile, path), object_pairs_hook=collections.OrderedDict) + if "name" not in plugin_dict or ( + "api" not in plugin_dict and "supported_sdk_versions" not in plugin_dict) or "version" not in plugin_dict: self._conanfile.output.warn(f"The plugin.json is invalid, ignoring it: {path}") else: if "description" in plugin_dict: - translation_entries += self._create_translation_entry(path, "description", plugin_dict["description"]) + translation_entries += self._create_translation_entry(path, "description", + plugin_dict["description"]) if "name" in plugin_dict: translation_entries += self._create_translation_entry(path, "name", plugin_dict["name"]) # Write plugin name & description to output pot file if translation_entries: - save(self._conanfile, self._all_strings_pot_path, translation_entries, append = True) + save(self._conanfile, self._all_strings_pot_path, translation_entries, append=True) def _extract_settings(self) -> None: """ Extract strings from settings json files to pot file with a matching name """ - setting_json_paths = [path for path in self._conanfile.source_path.rglob("*.def.json") if "test" not in str(path)] + setting_json_paths = [path for path in self._conanfile.source_path.rglob("*.def.json") if + "test" not in str(path)] for path in setting_json_paths: self._write_setting_text(path, self._translations_root_path) def _write_setting_text(self, json_path: Path, destination_path: Path) -> bool: """ Writes settings text from json file to pot file. Returns true if a file was written. """ - setting_dict = json.loads(load(self._conanfile, json_path), object_pairs_hook = collections.OrderedDict) + setting_dict = json.loads(load(self._conanfile, json_path), object_pairs_hook=collections.OrderedDict) if "inherits" not in setting_dict: if "settings" in setting_dict: @@ -138,24 +146,31 @@ def _process_settings(self, file, settings) -> str: if "label" in value: translation_entries += self._create_setting_translation_entry(file, name, "label", value["label"]) if "description" in value: - translation_entries += self._create_setting_translation_entry(file, name, "description", value["description"]) + translation_entries += self._create_setting_translation_entry(file, name, "description", + value["description"]) if "warning_description" in value: - translation_entries += self._create_setting_translation_entry(file, name, "warning_description", value["warning_description"]) + translation_entries += self._create_setting_translation_entry(file, name, "warning_description", + value["warning_description"]) if "error_description" in value: - translation_entries += self._create_setting_translation_entry(file, name, "error_description", value["error_description"]) + translation_entries += self._create_setting_translation_entry(file, name, "error_description", + value["error_description"]) if "options" in value: for item, description in value["options"].items(): - translation_entries += self._create_setting_translation_entry(file, name, "option {0}".format(item), description) + translation_entries += self._create_setting_translation_entry(file, name, "option {0}".format(item), + description) if "children" in value: translation_entries += self._process_settings(file, value["children"]) return translation_entries def _create_setting_translation_entry(self, filename: str, setting: str, field: str, value: str) -> str: - return "msgctxt \"{0} {1}\"\nmsgid \"{2}\"\nmsgstr \"\"\n\n".format(setting, field, value.replace("\n", "\\n").replace("\"", "\\\"")) + return "msgctxt \"{0} {1}\"\nmsgid \"{2}\"\nmsgstr \"\"\n\n".format(setting, field, + value.replace("\n", "\\n").replace("\"", + "\\\"")) def _create_translation_entry(self, filename: str, field: str, value: str) -> str: - return "msgctxt \"{0}\"\nmsgid \"{1}\"\nmsgstr \"\"\n\n".format(field, value.replace("\n", "\\n").replace("\"", "\\\"")) + return "msgctxt \"{0}\"\nmsgid \"{1}\"\nmsgstr \"\"\n\n".format(field, value.replace("\n", "\\n").replace("\"", + "\\\"")) def _create_pot_header(self) -> str: """ Creates a pot file header """ @@ -187,7 +202,9 @@ def _sanitize_pot_files(self) -> None: self._conanfile.output.warn(f"Removing empty pot file: {path}") rm(self._conanfile, path.name, path.parent) else: - save(self._conanfile, path, content.replace(f"#: {self._conanfile.source_path}/", "#: ").replace("charset=CHARSET", "charset=UTF-8")) + save(self._conanfile, path, + content.replace(f"#: {self._conanfile.source_path}/", "#: ").replace("charset=CHARSET", + "charset=UTF-8")) def generate(self): self._load_pot_content() @@ -202,8 +219,5 @@ def generate(self): class Pkg(ConanFile): name = "translationextractor" - def package(self): - self.copy("*", ".") - def package_info(self): self.cpp_info.set_property("name", "translationextractor") From 283916467914c230549dc957b58bdd64014d1bcc Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 12 Feb 2024 11:35:51 +0100 Subject: [PATCH 05/39] Bump versions Contributes to CURA-11079 --- recipes/clipper/config.yml | 2 ++ recipes/cpython/config.yml | 2 ++ recipes/pyprojecttoolchain/config.yml | 2 +- recipes/sipbuildtool/config.yml | 2 +- recipes/standardprojectsettings/config.yml | 2 +- recipes/translationextractor/config.yml | 2 +- 6 files changed, 8 insertions(+), 4 deletions(-) diff --git a/recipes/clipper/config.yml b/recipes/clipper/config.yml index d70ae32..67d4ee2 100644 --- a/recipes/clipper/config.yml +++ b/recipes/clipper/config.yml @@ -1,3 +1,5 @@ versions: "6.4.2": folder: all + "4.10.0": + folder: all \ No newline at end of file diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml index b23790e..0e2ea8a 100644 --- a/recipes/cpython/config.yml +++ b/recipes/cpython/config.yml @@ -1,3 +1,5 @@ versions: "3.12.2": folder: "all" + "3.10.13": + folder: "all" \ No newline at end of file diff --git a/recipes/pyprojecttoolchain/config.yml b/recipes/pyprojecttoolchain/config.yml index f088825..c8af655 100644 --- a/recipes/pyprojecttoolchain/config.yml +++ b/recipes/pyprojecttoolchain/config.yml @@ -1,3 +1,3 @@ versions: - "0.1.7": + "0.2.0": folder: "all" diff --git a/recipes/sipbuildtool/config.yml b/recipes/sipbuildtool/config.yml index 4261443..4e597ca 100644 --- a/recipes/sipbuildtool/config.yml +++ b/recipes/sipbuildtool/config.yml @@ -1,3 +1,3 @@ versions: - "0.2.4": + "0.3.0": folder: "all" diff --git a/recipes/standardprojectsettings/config.yml b/recipes/standardprojectsettings/config.yml index 4dc260e..c8af655 100644 --- a/recipes/standardprojectsettings/config.yml +++ b/recipes/standardprojectsettings/config.yml @@ -1,3 +1,3 @@ versions: - "0.1.1": + "0.2.0": folder: "all" diff --git a/recipes/translationextractor/config.yml b/recipes/translationextractor/config.yml index 14868c8..33ababb 100644 --- a/recipes/translationextractor/config.yml +++ b/recipes/translationextractor/config.yml @@ -1,3 +1,3 @@ versions: - "2.2.0": + "2.3.0": folder: "all" From 0dde82a08af0799ba63419234c21c23e366afec2 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Wed, 4 Sep 2024 13:33:02 +0200 Subject: [PATCH 06/39] Make cpython compilation work on powershell. Powershell uses ; as a command-separator, so the way the msbuild targets joins the list with those ';' would make it interpret the next target as the next command instead. done as part of CURA-11622 --- recipes/cpython/all/conanfile.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index d2f5f24..2598a24 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -587,8 +587,10 @@ def _msvc_build(self): sln = os.path.join(self.source_folder, "PCbuild", "pcbuild.sln") # FIXME: Solution files do not pick up the toolset automatically. - cmd = msbuild.command(sln, targets=projects) - self.run(f"{cmd} /p:PlatformToolset={msvs_toolset(self)}") + for project in projects: + # To make this work in Powershell too (which uses ';' as command seperation), do each project separately. + cmd = msbuild.command(sln, targets=[project]) + self.run(f"{cmd} /p:PlatformToolset={msvs_toolset(self)}") def build(self): self._patch_sources() From 1a100a52da51f7ba4f06516c649b5cd0aa513434 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Thu, 5 Sep 2024 16:01:40 +0200 Subject: [PATCH 07/39] Use common setup action --- .github/workflows/conan-package.yml | 41 +++++------------------------ 1 file changed, 6 insertions(+), 35 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 328dba2..73f04ab 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -13,53 +13,24 @@ on: permissions: contents: read -env: - CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} - jobs: conan-package-export: name: Conan Package Export runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v4 +# FIXME: use main once merged + - name: Setup the build environment + uses: ultimaker/cura-workflows/.github/actions/setup-build-environment@CURA-11622_conan_v2 with: - fetch-depth: 1 + conan_user: ${{ secrets.CONAN_USER }} + conan_password: ${{ secrets.CONAN_PASS }} - uses: technote-space/get-diff-action@v6 with: PATTERNS: | recipes/**/*.* -# FIXME: use main once merged - - name: Sync pip requirements - run: wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/CURA-11622_conan_v2/.github/workflows/requirements-runner.txt -O .github/workflows/requirements-runner.txt - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: 3.11.x - cache: pip - cache-dependency-path: .github/workflows/requirements-runner.txt - - - name: Install Python requirements and Create default Conan profile - run: pip install -r .github/workflows/requirements-runner.txt - - - name: Create default Conan profile - run: conan profile detect -f - -# FIXME: use runner.os/runner.arch after merge: conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/runner.os/runner.arch" - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git -a "-b CURA-11622_conan_v2" - conan remote login -p ${{ secrets.CONAN_PASS }} cura-conan-v2 ${{ secrets.CONAN_USER }} - #conan remote disable cura-private - -# TODO: Change to main once merged - name: Export changed recipes run: | - mkdir runner_scripts - wget https://raw.githubusercontent.com/Ultimaker/cura-workflows/CURA-11622_conan_v2/runner_scripts/upload_conan_recipes.py -O runner_scripts/upload_conan_recipes.py - python runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan-v2 ${{ env.GIT_DIFF_FILTERED }} + python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2-dev ${{ env.GIT_DIFF_FILTERED }} From 41c79c7ccc1833e9f2d438eab528746affac6984 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 25 Sep 2024 10:35:55 +0200 Subject: [PATCH 08/39] Use project-defined folders for source files --- recipes/translationextractor/all/conanfile.py | 31 +++++++++++-------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/recipes/translationextractor/all/conanfile.py b/recipes/translationextractor/all/conanfile.py index 9cde297..e10bbe8 100644 --- a/recipes/translationextractor/all/conanfile.py +++ b/recipes/translationextractor/all/conanfile.py @@ -18,7 +18,7 @@ class ExtractTranslations(object): def __init__(self, conanfile: ConanFile, gettext_bindir): self._conanfile = conanfile self._gettext_bindir = gettext_bindir - self._translations_root_path = self._conanfile.source_path.joinpath("resources", "i18n") + self._translations_root_path = Path(self._conanfile.source_folder).joinpath("resources", "i18n") self._all_strings_pot_path = self._translations_root_path.joinpath( self._conanfile.name + ".pot") # pot file containing all strings untranslated self._pot_content = {} @@ -76,27 +76,33 @@ def _extract_strings_to_pot_files(self) -> None: self._extract_plugin() self._extract_settings() + def _extract_source_files(self, prefix, extension_wildcard): + source_files = [] + + key = f"{prefix}_translation_source_folders" + if self._conanfile.conan_data is not None and key in self._conanfile.conan_data: + for translation_folder in self._conanfile.conan_data[key]: + source_files += Path(self._conanfile.source_folder, translation_folder).rglob(extension_wildcard) + + return source_files + def _extract_python(self) -> None: - """ Extract i18n strings from all .py files in root_path""" - for path in self._conanfile.source_path.rglob("*.py"): - if "venv" in path.parts: - continue + """ Extract i18n strings from all .py files""" + for path in self._extract_source_files("python", "*.py"): self._conanfile.run( f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=python --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", env="conanbuild") def _extract_qml(self) -> None: - """ Extract all i18n strings from qml files inside the root path """ - for path in self._conanfile.source_path.rglob("*.qml"): - if "venv" in path.parts: - continue + """ Extract all i18n strings from qml files""" + for path in self._extract_source_files("qml", "*.qml"): self._conanfile.run( f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=javascript --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", env="conanbuild") def _extract_plugin(self) -> None: """ Extract the name and description from all plugins """ - plugin_paths = [path for path in self._conanfile.source_path.rglob("plugin.json") if "test" not in str(path)] + plugin_paths = [path for path in Path(self._conanfile.source_folder).rglob("plugin.json") if "test" not in str(path)] for path in plugin_paths: translation_entries = "" @@ -118,7 +124,7 @@ def _extract_plugin(self) -> None: def _extract_settings(self) -> None: """ Extract strings from settings json files to pot file with a matching name """ - setting_json_paths = [path for path in self._conanfile.source_path.rglob("*.def.json") if + setting_json_paths = [path for path in Path(self._conanfile.source_folder).rglob("*.def.json") if "test" not in str(path)] for path in setting_json_paths: self._write_setting_text(path, self._translations_root_path) @@ -203,8 +209,7 @@ def _sanitize_pot_files(self) -> None: rm(self._conanfile, path.name, path.parent) else: save(self._conanfile, path, - content.replace(f"#: {self._conanfile.source_path}/", "#: ").replace("charset=CHARSET", - "charset=UTF-8")) + content.replace(f"#: {self._conanfile.source_folder}/", "#: ").replace("charset=CHARSET", "charset=UTF-8")) def generate(self): self._load_pot_content() From 42309dbbf02d17da20d38db8cd08d3c33bcc2e9f Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 10:54:11 +0100 Subject: [PATCH 09/39] Change the way of enabling sentry --- recipes/clipper/all/conanfile.py | 39 ++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index 6a4aa20..b3375c1 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -22,11 +22,13 @@ class ClipperConan(ConanFile): "shared": [True, False], "fPIC": [True, False], "enable_sentry": [True, False], + "sentry_project": ["ANY"], } default_options = { "shared": False, "fPIC": True, "enable_sentry": False, + "sentry_project": name, } def export_sources(self): @@ -43,6 +45,12 @@ def configure(self): def layout(self): cmake_layout(self, src_folder="src") + def validate(self): + if self.options.enable_sentry: + for sentry_setting in ["organization", "token"]: + if self.conf.get(f"user.sentry:{sentry_setting}", "", check_type=str) == "": + raise ConanInvalidConfiguration(f"Unable to enable Sentry because no {sentry_setting} was configured") + def source(self): get(self, **self.conan_data["sources"][self.version]) @@ -60,22 +68,23 @@ def build(self): cmake.configure(build_script_folder=os.path.join(self.source_folder, "cpp")) cmake.build() - sentry_project = self.conf.get("user.curaengine:sentry_project", "", check_type=str) - sentry_org = self.conf.get("user.curaengine:sentry_org", "", check_type=str) - if self.options.get_safe("enable_sentry", False) and os.environ.get('SENTRY_TOKEN', None) and sentry_project != "" and sentry_org != "": + sentry_project = self.options.sentry_project + sentry_organization = self.conf.get("user.sentry:organization", "", check_type=str) + sentry_token = self.conf.get("user.sentry:token", "", check_type=str) + if self.options.enable_sentry: if which("sentry-cli") is None: - self.output.warn("sentry-cli is not installed, skipping uploading debug symbols") - else: - if self.settings.os == "Linux": - self.output.info("Stripping debug symbols from binary") - ext = ".so" if self.options.shared else ".a" - self.run(f"objcopy --only-keep-debug --compress-debug-sections=zlib libpolyclipping{ext} libpolyclipping.debug") - self.run(f"objcopy --strip-debug --strip-unneeded libpolyclipping{ext}") - self.run(f"objcopy --add-gnu-debuglink=libpolyclipping.debug libpolyclipping{ext}") - - build_source_dir = self.build_path.parent.parent.as_posix() - self.output.info("Uploading debug symbols to sentry") - self.run(f"sentry-cli --auth-token {os.environ['SENTRY_TOKEN']} debug-files upload --include-sources -o {sentry_org} -p {sentry_project} {build_source_dir}") + raise ConanException("sentry-cli is not installed, unable to upload debug symbols") + + if self.settings.os == "Linux": + self.output.info("Stripping debug symbols from binary") + ext = ".so" if self.options.shared else ".a" + self.run(f"objcopy --only-keep-debug --compress-debug-sections=zlib libpolyclipping{ext} libpolyclipping.debug") + self.run(f"objcopy --strip-debug --strip-unneeded libpolyclipping{ext}") + self.run(f"objcopy --add-gnu-debuglink=libpolyclipping.debug libpolyclipping{ext}") + + build_source_dir = self.build_path.parent.parent.as_posix() + self.output.info("Uploading debug symbols to sentry") + self.run(f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") def package(self): copy(self, "License.txt", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) From 866aa1628b50fd57516161533fd9ba9a2b86cfa6 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 12:42:30 +0100 Subject: [PATCH 10/39] Add common recipe for libraries embedding Sentry --- recipes/clipper/all/conanfile.py | 42 +++++-------- recipes/sentrylibrary/all/conanfile.py | 86 ++++++++++++++++++++++++++ recipes/sentrylibrary/config.yml | 3 + 3 files changed, 103 insertions(+), 28 deletions(-) create mode 100644 recipes/sentrylibrary/all/conanfile.py create mode 100644 recipes/sentrylibrary/config.yml diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index b3375c1..7636473 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -7,7 +7,7 @@ from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, rmdir from conan.errors import ConanInvalidConfiguration -required_conan_version = ">=1.54.0" +required_conan_version = ">=2.7.0" class ClipperConan(ConanFile): @@ -18,39 +18,40 @@ class ClipperConan(ConanFile): url = "https://github.com/conan-io/conan-center-index" homepage = "http://www.angusj.com/delphi/clipper.php" settings = "os", "arch", "compiler", "build_type" + python_requires = "sentrylibrary/1.0@ultimaker/cura_11622" # FIXME: use main after merge + python_requires_extend = "sentrylibrary.SentryLibrary" + options = { "shared": [True, False], "fPIC": [True, False], - "enable_sentry": [True, False], - "sentry_project": ["ANY"], } default_options = { "shared": False, "fPIC": True, - "enable_sentry": False, - "sentry_project": name, } + def init(self): + base = self.python_requires["sentrylibrary"].module.SentryLibrary + self.options.update(base.options, base.default_options) + def export_sources(self): export_conandata_patches(self) def config_options(self): + super().config_options() + if self.settings.os == "Windows": del self.options.fPIC def configure(self): + super().configure() + if self.options.shared: self.options.rm_safe("fPIC") def layout(self): cmake_layout(self, src_folder="src") - def validate(self): - if self.options.enable_sentry: - for sentry_setting in ["organization", "token"]: - if self.conf.get(f"user.sentry:{sentry_setting}", "", check_type=str) == "": - raise ConanInvalidConfiguration(f"Unable to enable Sentry because no {sentry_setting} was configured") - def source(self): get(self, **self.conan_data["sources"][self.version]) @@ -60,6 +61,7 @@ def generate(self): tc.variables["CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS"] = True # To install relocatable shared libs on Macos tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0042"] = "NEW" + self.setup_cmake_toolchain_sentry(tc) tc.generate() def build(self): @@ -68,23 +70,7 @@ def build(self): cmake.configure(build_script_folder=os.path.join(self.source_folder, "cpp")) cmake.build() - sentry_project = self.options.sentry_project - sentry_organization = self.conf.get("user.sentry:organization", "", check_type=str) - sentry_token = self.conf.get("user.sentry:token", "", check_type=str) - if self.options.enable_sentry: - if which("sentry-cli") is None: - raise ConanException("sentry-cli is not installed, unable to upload debug symbols") - - if self.settings.os == "Linux": - self.output.info("Stripping debug symbols from binary") - ext = ".so" if self.options.shared else ".a" - self.run(f"objcopy --only-keep-debug --compress-debug-sections=zlib libpolyclipping{ext} libpolyclipping.debug") - self.run(f"objcopy --strip-debug --strip-unneeded libpolyclipping{ext}") - self.run(f"objcopy --add-gnu-debuglink=libpolyclipping.debug libpolyclipping{ext}") - - build_source_dir = self.build_path.parent.parent.as_posix() - self.output.info("Uploading debug symbols to sentry") - self.run(f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") + self.send_sentry_debug_files() def package(self): copy(self, "License.txt", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py new file mode 100644 index 0000000..1cfab3d --- /dev/null +++ b/recipes/sentrylibrary/all/conanfile.py @@ -0,0 +1,86 @@ +from conan import ConanFile + +from shutil import which + +from conan.errors import ConanInvalidConfiguration, ConanException + +required_conan_version = ">=2.7.0" + + +class SentryLibrary: + options = { + "enable_sentry": [True, False], + "sentry_project": ["ANY"], + } + default_options = { + "enable_sentry": False, + "sentry_project": "", + } + + def config_options(self): + if self.options.sentry_project == "": + self.options.sentry_project = self.name + + def configure(self): + if self.options.enable_sentry: + self.options["sentry-native"].backend = "breakpad" + + def validate(self): + if self.options.enable_sentry: + for sentry_conf in ["organization", "url", "token"]: + conf_name = f"user.sentry:{sentry_conf}" + if self.conf.get(conf_name, "", check_type=str) == "": + raise ConanInvalidConfiguration(f"Unable to enable Sentry because no {conf_name} was configured (use '-c {conf_name}={sentry_conf}')") + + def requirements(self): + if self.options.enable_sentry: + self.requires("sentry-native/0.7.0") + + def setup_cmake_toolchain_sentry(self, cmake_toolchain): + ''' + Method to be called by actual packages at generate() time to setup the cmake toolchain according to the sentry configuration + ''' + cmake_toolchain.variables["ENABLE_SENTRY"] = self.options.enable_sentry + cmake_toolchain.variables["SENTRY_URL"] = self.conf.get("user.sentry:url", "", check_type=str) + + def send_sentry_debug_files(self): + ''' + Method to be called by actual packages at build() time, after the actual build has been done, to send the binary files to sentry + ''' + if self.options.enable_sentry: + sentry_project = self.options.sentry_project + sentry_organization = self.conf.get("user.sentry:organization", "", check_type=str) + sentry_token = self.conf.get("user.sentry:token", "", check_type=str) + + if which("sentry-cli") is None: + raise ConanException("sentry-cli is not installed, unable to upload debug symbols") + + if self.settings.os == "Linux": + self.output.info("Stripping debug symbols from binary") + self.run("objcopy --only-keep-debug --compress-debug-sections=zlib CuraEngine CuraEngine.debug") + self.run("objcopy --strip-debug --strip-unneeded CuraEngine") + self.run("objcopy --add-gnu-debuglink=CuraEngine.debug CuraEngine") + elif self.settings.os == "Macos": + self.run("dsymutil CuraEngine") + + self.output.info("Uploading debug symbols to sentry") + build_source_dir = self.build_path.parent.parent.as_posix() + self.run( + f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") + + # create a sentry release and link it to the commit this is based upon + self.output.info( + f"Creating a new release {self.version} in Sentry and linking it to the current commit {self.conan_data['commit']}") + self.run( + f"sentry-cli --auth-token {sentry_token} releases new -o {sentry_organization} -p {sentry_project} {self.version}") + self.run( + f"sentry-cli --auth-token {sentry_token} releases set-commits -o {sentry_organization} -p {sentry_project} --commit \"Ultimaker/CuraEngine@{self.conan_data['commit']}\" {self.version}") + self.run( + f"sentry-cli --auth-token {sentry_token} releases finalize -o {sentry_organization} -p {sentry_project} {self.version}") + + +class PyReq(ConanFile): + name = "sentrylibrary" + version = "1.0" + description = "This is a base conan file description for C++ libraries/applications that can embed sentry" + package_type = "python-require" diff --git a/recipes/sentrylibrary/config.yml b/recipes/sentrylibrary/config.yml new file mode 100644 index 0000000..c7f1363 --- /dev/null +++ b/recipes/sentrylibrary/config.yml @@ -0,0 +1,3 @@ +versions: + "1.0.0": + folder: "all" From 21fb14624c935ac0bb1864d4a2b60f05bbf6240d Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 12:43:21 +0100 Subject: [PATCH 11/39] Remove custom CPython recipe which is (hopefully) useless now --- recipes/cpython/all/conandata.yml | 55 - recipes/cpython/all/conanfile.py | 951 ------------------ .../all/patches/2.7/2.7.18-0001-msvc.patch | 93 -- .../2.7/2.7.18-0002-add-support-msvc-14.patch | 59 -- .../2.7/2.7.18-0003-msvc-fix-static.patch | 11 - .../3.10/3.10.0-0003-_ctypes-ffi.patch | 50 - .../3.11/3.11.7-0001-_ctypes-ffi.patch | 37 - .../3.12/3.12.1-0001-_ctypes-ffi.patch | 37 - .../3.12/3.12.1-0002-remove-module-deps.patch | 50 - .../all/patches/3.7/3.7.9-0001-msvc.patch | 19 - .../patches/3.8/3.8.12-0002-_ctypes-ffi.patch | 67 -- .../patches/3.9/3.9.7-0002-_msi-vcxproj.patch | 11 - .../patches/3.9/3.9.7-0003-_ctypes-ffi.patch | 51 - .../3.x-0001-relocatable-python-config.patch | 11 - .../patches/3.x-0002-remove-module-deps.patch | 10 - .../cpython/all/test_package/CMakeLists.txt | 103 -- recipes/cpython/all/test_package/conanfile.py | 248 ----- .../all/test_package/py2/test_module.c | 42 - .../all/test_package/py2/test_package.c | 12 - .../all/test_package/py3/test_module.c | 52 - .../all/test_package/py3/test_package.c | 20 - recipes/cpython/all/test_package/setup.py | 36 - .../cpython/all/test_package/test_package.py | 226 ----- .../all/test_v1_package/CMakeLists.txt | 100 -- .../cpython/all/test_v1_package/conanfile.py | 212 ---- .../all/test_v1_package/py2/test_module.c | 42 - .../all/test_v1_package/py2/test_package.c | 12 - .../all/test_v1_package/py3/test_module.c | 52 - .../all/test_v1_package/py3/test_package.c | 20 - recipes/cpython/all/test_v1_package/setup.py | 35 - recipes/cpython/config.yml | 5 - 31 files changed, 2729 deletions(-) delete mode 100644 recipes/cpython/all/conandata.yml delete mode 100644 recipes/cpython/all/conanfile.py delete mode 100644 recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch delete mode 100644 recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch delete mode 100644 recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch delete mode 100644 recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch delete mode 100644 recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch delete mode 100644 recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch delete mode 100644 recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch delete mode 100644 recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch delete mode 100644 recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch delete mode 100644 recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch delete mode 100644 recipes/cpython/all/patches/3.x-0001-relocatable-python-config.patch delete mode 100644 recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch delete mode 100644 recipes/cpython/all/test_package/CMakeLists.txt delete mode 100644 recipes/cpython/all/test_package/conanfile.py delete mode 100644 recipes/cpython/all/test_package/py2/test_module.c delete mode 100644 recipes/cpython/all/test_package/py2/test_package.c delete mode 100644 recipes/cpython/all/test_package/py3/test_module.c delete mode 100644 recipes/cpython/all/test_package/py3/test_package.c delete mode 100644 recipes/cpython/all/test_package/setup.py delete mode 100644 recipes/cpython/all/test_package/test_package.py delete mode 100644 recipes/cpython/all/test_v1_package/CMakeLists.txt delete mode 100644 recipes/cpython/all/test_v1_package/conanfile.py delete mode 100644 recipes/cpython/all/test_v1_package/py2/test_module.c delete mode 100644 recipes/cpython/all/test_v1_package/py2/test_package.c delete mode 100644 recipes/cpython/all/test_v1_package/py3/test_module.c delete mode 100644 recipes/cpython/all/test_v1_package/py3/test_package.c delete mode 100644 recipes/cpython/all/test_v1_package/setup.py delete mode 100644 recipes/cpython/config.yml diff --git a/recipes/cpython/all/conandata.yml b/recipes/cpython/all/conandata.yml deleted file mode 100644 index 3ca1af7..0000000 --- a/recipes/cpython/all/conandata.yml +++ /dev/null @@ -1,55 +0,0 @@ -sources: - "3.12.2": - url: "https://www.python.org/ftp/python/3.12.2/Python-3.12.2.tgz" - sha256: "a7c4f6a9dc423d8c328003254ab0c9338b83037bd787d680826a5bf84308116e" - "3.11.8": - url: "https://www.python.org/ftp/python/3.11.8/Python-3.11.8.tgz" - sha256: "d3019a613b9e8761d260d9ebe3bd4df63976de30464e5c0189566e1ae3f61889" - "3.10.13": - url: "https://www.python.org/ftp/python/3.10.13/Python-3.10.13.tgz" - sha256: "698ec55234c1363bd813b460ed53b0f108877c7a133d48bde9a50a1eb57b7e65" - "3.9.18": - url: "https://www.python.org/ftp/python/3.9.18/Python-3.9.18.tgz" - sha256: "504ce8cfd59addc04c22f590377c6be454ae7406cb1ebf6f5a350149225a9354" - "3.8.18": - url: "https://www.python.org/ftp/python/3.8.18/Python-3.8.18.tgz" - sha256: "7c5df68bab1be81a52dea0cc2e2705ea00553b67107a301188383d7b57320b16" - "3.7.17": - url: "https://www.python.org/ftp/python/3.7.17/Python-3.7.17.tgz" - sha256: "fd50161bc2a04f4c22a0971ff0f3856d98b4bf294f89740a9f06b520aae63b49" - "2.7.18": - url: "https://www.python.org/ftp/python/2.7.18/Python-2.7.18.tgz" - sha256: "da3080e3b488f648a3d7a4560ddee895284c3380b11d6de75edb986526b9a814" -patches: - "3.12.2": - - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - - patch_file: "patches/3.12/3.12.1-0001-_ctypes-ffi.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.12/3.12.1-0002-remove-module-deps.patch" - "3.11.8": - - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - - patch_file: "patches/3.11/3.11.7-0001-_ctypes-ffi.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.x-0002-remove-module-deps.patch" - "3.10.13": - - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - - patch_file: "patches/3.10/3.10.0-0003-_ctypes-ffi.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.x-0002-remove-module-deps.patch" - "3.9.18": - - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" - - patch_file: "patches/3.9/3.9.7-0003-_ctypes-ffi.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.x-0002-remove-module-deps.patch" - "3.8.18": - - patch_file: "patches/3.8/3.8.12-0002-_ctypes-ffi.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.x-0002-remove-module-deps.patch" - "3.7.17": - - patch_file: "patches/3.7/3.7.9-0001-msvc.patch" - - patch_file: "patches/3.x-0001-relocatable-python-config.patch" - - patch_file: "patches/3.x-0002-remove-module-deps.patch" - "2.7.18": - - patch_file: "patches/2.7/2.7.18-0001-msvc.patch" - - patch_file: "patches/2.7/2.7.18-0002-add-support-msvc-14.patch" - - patch_file: "patches/2.7/2.7.18-0003-msvc-fix-static.patch" diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py deleted file mode 100644 index 2598a24..0000000 --- a/recipes/cpython/all/conanfile.py +++ /dev/null @@ -1,951 +0,0 @@ -import os -import re -import textwrap - -from conan import ConanFile -from conan.errors import ConanInvalidConfiguration, ConanException -from conan.tools.apple import is_apple_os, fix_apple_shared_install_name -from conan.tools.env import VirtualRunEnv -from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, load, mkdir, replace_in_file, rm, rmdir, save, unzip -from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps, PkgConfigDeps -from conan.tools.layout import basic_layout -from conan.tools.microsoft import MSBuildDeps, MSBuildToolchain, MSBuild, is_msvc, is_msvc_static_runtime, msvc_runtime_flag, msvs_toolset -from conan.tools.scm import Version - -required_conan_version = ">=1.58.0" - - -class CPythonConan(ConanFile): - name = "cpython" - description = "Python is a programming language that lets you work quickly and integrate systems more effectively." - license = "Python-2.0" - url = "https://github.com/conan-io/conan-center-index" - homepage = "https://www.python.org" - topics = ("python", "cpython", "language", "script") - - package_type = "library" - settings = "os", "arch", "compiler", "build_type" - options = { - "shared": [True, False], - "fPIC": [True, False], - "optimizations": [True, False], - "lto": [True, False], - "docstrings": [True, False], - "pymalloc": [True, False], - "with_bz2": [True, False], - "with_gdbm": [True, False], - "with_nis": [True, False], - "with_sqlite3": [True, False], - "with_tkinter": [True, False], - "with_curses": [True, False], - - # Python 2 options - "unicode": ["ucs2", "ucs4"], - "with_bsddb": [True, False], - # Python 3 options - "with_lzma": [True, False], - - # options that don't change package id - "env_vars": [True, False], # set environment variables - } - default_options = { - "shared": False, - "fPIC": True, - "optimizations": False, - "lto": False, - "docstrings": True, - "pymalloc": True, - "with_bz2": True, - "with_gdbm": True, - "with_nis": False, - "with_sqlite3": True, - "with_tkinter": True, - "with_curses": True, - - # Python 2 options - "unicode": "ucs2", - "with_bsddb": False, # True, # FIXME: libdb package missing (#5309/#5392) - # Python 3 options - "with_lzma": True, - - # options that don't change package id - "env_vars": True, - } - - @property - def _supports_modules(self): - return not is_msvc(self) or self.options.shared - - @property - def _version_suffix(self): - v = Version(self.version) - joiner = "" if is_msvc(self) else "." - return f"{v.major}{joiner}{v.minor}" - - @property - def _is_py3(self): - return Version(self.version).major == 3 - - @property - def _is_py2(self): - return Version(self.version).major == 2 - - def export_sources(self): - export_conandata_patches(self) - - def config_options(self): - if self.settings.os == "Windows": - del self.options.fPIC - if is_msvc(self): - del self.options.lto - del self.options.docstrings - del self.options.pymalloc - del self.options.with_curses - del self.options.with_gdbm - del self.options.with_nis - if self._is_py2: - # Python 2.xx does not support following options - del self.options.with_lzma - elif self._is_py3: - # Python 3.xx does not support following options - del self.options.with_bsddb - del self.options.unicode - - self.settings.compiler.rm_safe("libcxx") - self.settings.compiler.rm_safe("cppstd") - - def configure(self): - if self.options.shared: - self.options.rm_safe("fPIC") - if not self._supports_modules: - self.options.rm_safe("with_bz2") - self.options.rm_safe("with_sqlite3") - self.options.rm_safe("with_tkinter") - - self.options.rm_safe("with_bsddb") - self.options.rm_safe("with_lzma") - - def layout(self): - basic_layout(self, src_folder="src") - - @property - def _use_vendored_libffi(self): - # cpython < 3.8 on MSVC uses an ancient libffi 2.00-beta - # (which is not available at cci, and is API/ABI incompatible with current 3.2+) - return Version(self.version) < "3.8" and is_msvc(self) - - @property - def _with_libffi(self): - return self._supports_modules and not self._use_vendored_libffi - - def build_requirements(self): - if Version(self.version) >= "3.11" and not is_msvc(self) and not self.conf.get("tools.gnu:pkg_config", check_type=str): - self.tool_requires("pkgconf/2.1.0") - - def requirements(self): - self.requires("zlib/[>=1.2.11 <2]") - if self._supports_modules: - self.requires("openssl/[>=1.1 <4]") - self.requires("expat/2.5.0") - if self._with_libffi: - self.requires("libffi/3.4.4") - if Version(self.version) < "3.8": - self.requires("mpdecimal/2.4.2") - elif Version(self.version) < "3.10" or is_apple_os(self): - # FIXME: mpdecimal > 2.5.0 on MacOS causes the _decimal module to not be importable - self.requires("mpdecimal/2.5.0") - else: - self.requires("mpdecimal/2.5.1") - if self.settings.os != "Windows": - if not is_apple_os(self): - self.requires("util-linux-libuuid/2.39.2") - # If crypt.h is detected, it is included in the public headers. - self.requires("libxcrypt/4.4.36", transitive_headers=True, transitive_libs=True) - if self.options.get_safe("with_bz2"): - self.requires("bzip2/1.0.8") - if self.options.get_safe("with_gdbm", False): - self.requires("gdbm/1.23") - if self.options.get_safe("with_nis", False): - # TODO: Add nis when available. - raise ConanInvalidConfiguration("nis is not available on CCI (yet)") - if self.options.get_safe("with_sqlite3"): - self.requires("sqlite3/3.44.2") - if self.options.get_safe("with_tkinter"): - self.requires("tk/8.6.10") - if self.options.get_safe("with_curses", False): - # Used in a public header - # https://github.com/python/cpython/blob/v3.10.13/Include/py_curses.h#L34 - self.requires("ncurses/6.4", transitive_headers=True, transitive_libs=True) - if self.options.get_safe("with_bsddb", False): - self.requires("libdb/5.3.28") - if self.options.get_safe("with_lzma", False): - self.requires("xz_utils/5.4.5") - - def package_id(self): - del self.info.options.env_vars - - def validate(self): - if self.options.shared: - if is_msvc_static_runtime(self): - raise ConanInvalidConfiguration( - "cpython does not support MT(d) runtime when building a shared cpython library" - ) - if is_msvc(self): - if self.options.optimizations: - raise ConanInvalidConfiguration( - "This recipe does not support optimized MSVC cpython builds (yet)" - ) - # FIXME: should probably throw when cross building - # FIXME: optimizations for Visual Studio, before building the final `build_type`: - # 1. build the MSVC PGInstrument build_type, - # 2. run the instrumented binaries, (PGInstrument should have created a `python.bat` file in the PCbuild folder) - # 3. build the MSVC PGUpdate build_type - if self.settings.build_type == "Debug" and "d" not in msvc_runtime_flag(self): - raise ConanInvalidConfiguration( - "Building debug cpython requires a debug runtime (Debug cpython requires _CrtReportMode" - " symbol, which only debug runtimes define)" - ) - if str(self.settings.arch) not in self._msvc_archs: - raise ConanInvalidConfiguration("Visual Studio does not support this architecture") - if not self.options.shared and Version(self.version) >= "3.10": - # Static CPython on Windows is only loosely supported, see https://github.com/python/cpython/issues/110234 - # 3.10 fails during the test, 3.11 fails during the build (missing symbol that seems to be DLL specific: PyWin_DLLhModule) - raise ConanInvalidConfiguration("Static msvc build disabled (>=3.10) due to \"AttributeError: module 'sys' has no attribute 'winver'\"") - - if self.options.get_safe("with_curses", False) and not self.dependencies["ncurses"].options.with_widec: - raise ConanInvalidConfiguration("cpython requires ncurses with wide character support") - - if self._supports_modules: - if Version(self.version) < "3.8.0": - if self.dependencies["mpdecimal"].ref.version >= Version("2.5.0"): - raise ConanInvalidConfiguration("cpython versions lesser then 3.8.0 require a mpdecimal lesser then 2.5.0") - elif Version(self.version) >= "3.9.0": - if self.dependencies["mpdecimal"].ref.version < Version("2.5.0"): - raise ConanInvalidConfiguration("cpython 3.9.0 (and newer) requires (at least) mpdecimal 2.5.0") - - if is_apple_os(self) and self.settings.arch == "armv8" and Version(self.version) < "3.8.0": - raise ConanInvalidConfiguration("cpython 3.7 and older does not support Apple ARM CPUs") - - if self.settings.compiler == "gcc" and Version(self.settings.compiler.version).major == 9 and Version(self.version) == "3.12.1": - raise ConanInvalidConfiguration("FIXME: GCC 9 produces an internal compiler error locally, and a link error in CCI") - - def source(self): - get(self, **self.conan_data["sources"][self.version], strip_root=True) - - def _generate_autotools(self): - tc = AutotoolsToolchain(self, prefix=self.package_folder) - yes_no = lambda v: "yes" if v else "no" - tc.configure_args += [ - "--with-doc-strings={}".format(yes_no(self.options.docstrings)), - "--with-pymalloc={}".format(yes_no(self.options.pymalloc)), - "--with-system-expat", - "--enable-optimizations={}".format(yes_no(self.options.optimizations)), - "--with-lto={}".format(yes_no(self.options.lto)), - "--with-pydebug={}".format(yes_no(self.settings.build_type == "Debug")), - "--disable-test-modules", - ] - if not self._use_vendored_libffi: - tc.configure_args += ["--with-system-ffi"] - if self._is_py2: - tc.configure_args += ["--enable-unicode={}".format(yes_no(self.options.unicode))] - if self._is_py3: - tc.configure_args += [ - "--with-system-libmpdec", - "--with-openssl={}".format(self.dependencies["openssl"].package_folder), - "--enable-loadable-sqlite-extensions={}".format( - yes_no(not self.dependencies["sqlite3"].options.omit_load_extension) - ), - ] - if self.settings.compiler == "intel-cc": - tc.configure_args.append("--with-icc") - if os.environ.get("CC") or self.settings.compiler != "gcc": - tc.configure_args.append("--without-gcc") - if self.options.with_tkinter and Version(self.version) < "3.11": - tcltk_includes = [] - tcltk_libs = [] - # FIXME: collect using some conan util (https://github.com/conan-io/conan/issues/7656) - for dep in ("tcl", "tk", "zlib"): - cpp_info = self.dependencies[dep].cpp_info.aggregated_components() - tcltk_includes += [f"-I{d}" for d in cpp_info.includedirs] - tcltk_libs += [f"-L{lib}" for lib in cpp_info.libdirs] - tcltk_libs += [f"-l{lib}" for lib in cpp_info.libs] - if self.settings.os in ["Linux", "FreeBSD"] and not self.dependencies["tk"].options.shared: - # FIXME: use info from xorg.components (x11, xscrnsaver) - tcltk_libs.extend([f"-l{lib}" for lib in ("X11", "Xss")]) - tc.configure_args += [ - "--with-tcltk-includes={}".format(" ".join(tcltk_includes)), - "--with-tcltk-libs={}".format(" ".join(tcltk_libs)), - ] - if not is_apple_os(self): - tc.extra_ldflags.append('-Wl,--as-needed') - - tc.generate() - - deps = AutotoolsDeps(self) - deps.generate() - if Version(self.version) >= "3.11": - pkgdeps = PkgConfigDeps(self) - pkgdeps.generate() - - def generate(self): - VirtualRunEnv(self).generate(scope="build") - - if is_msvc(self): - # The msbuild generator only works with Visual Studio - deps = MSBuildDeps(self) - deps.generate() - # The toolchain.props is not injected yet, but it also generates VCVars - toolchain = MSBuildToolchain(self) - toolchain.properties["IncludeExternals"] = "true" - toolchain.generate() - else: - self._generate_autotools() - - def _msvc_project_path(self, name): - return os.path.join(self.source_folder, "PCBuild", f"{name}.vcxproj") - - def _regex_replace_in_file(self, filename, pattern, replacement): - content = load(self, filename) - content = re.sub(pattern, replacement, content) - save(self, filename, content) - - def _inject_conan_props_file(self, project_basename, dep_name, condition=True): - if condition: - search = '' if self._is_py3 else '' - replace_in_file(self, - self._msvc_project_path(project_basename), - search, - search + f'') - - def _patch_setup_py(self): - setup_py = os.path.join(self.source_folder, "setup.py") - if self._is_py3 and Version(self.version) < "3.10": - replace_in_file(self, setup_py, ":libmpdec.so.2", "mpdec") - - if self.options.get_safe("with_curses", False): - # FIXME: this will link to ALL libraries of ncurses. Only need to link to ncurses(w) (+ eventually tinfo) - ncurses_info = self.dependencies["ncurses"].cpp_info.aggregated_components() - replace_in_file(self, setup_py, - "curses_libs = ", - "curses_libs = {} #".format(repr(ncurses_info.libs + ncurses_info.system_libs))) - - if self._supports_modules: - openssl = self.dependencies["openssl"].cpp_info.aggregated_components() - zlib = self.dependencies["zlib"].cpp_info.aggregated_components() - if self._is_py2: - replace_in_file(self, setup_py, "'/usr/local/ssl/include',", f"{(openssl.includedirs + zlib.includedirs)[1:-2]}") - replace_in_file(self, setup_py, "'/usr/contrib/ssl/include/'", "") - replace_in_file(self, setup_py, "lib_dirs = []", f"lib_dirs = {openssl.libdirs + zlib.libdirs}") - replace_in_file(self, setup_py, "libraries = ['ssl', 'crypto'],", f"libraries = {openssl.libs + zlib.libs}, #") - elif Version(self.version) < "3.11": - replace_in_file(self, setup_py, - "openssl_includes = ", - f"openssl_includes = {openssl.includedirs + zlib.includedirs} #") - replace_in_file(self, setup_py, - "openssl_libdirs = ", - f"openssl_libdirs = {openssl.libdirs + zlib.libdirs} #") - replace_in_file(self, setup_py, - "openssl_libs = ", - f"openssl_libs = {openssl.libs + zlib.libs} #") - - if Version(self.version) < "3.8": - replace_in_file(self, setup_py, "self.detect_tkinter_darwin(inc_dirs, lib_dirs)", "False") - elif Version(self.version) < "3.11": - replace_in_file(self, setup_py, "if (MACOS and self.detect_tkinter_darwin())", "if (False)") - - def _patch_msvc_projects(self): - self._regex_replace_in_file(self._msvc_project_path("_bz2" if self._is_py3 else "bz2"), r'.*Include=\"\$\(bz2Dir\).*', "") - if self._with_libffi: - replace_in_file(self, self._msvc_project_path("_ctypes"), '', "") - if Version(self.version) < "3.11": - replace_in_file(self, self._msvc_project_path("_ctypes"), "FFI_BUILDING;", "") - - if self._is_py3: - replace_in_file(self, self._msvc_project_path("_hashlib"), '', "") - replace_in_file(self, self._msvc_project_path("_ssl"), '', "") - - # For mpdecimal, we need to remove all headers and all c files *except* the main module file, _decimal.c - self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\.*\.h.*', "") - self._regex_replace_in_file(self._msvc_project_path("_decimal"), r'.*Include=\"\.\.\\Modules\\_decimal\\libmpdec\\.*\.c.*', "") - # There is also an assembly file with a complicated build step as part of the mpdecimal build - replace_in_file(self, self._msvc_project_path("_decimal"), "", "-->") - # Remove extra include directory - replace_in_file(self, self._msvc_project_path("_decimal"), "..\Modules\_decimal\libmpdec;", "") - - replace_in_file(self, self._msvc_project_path("_sqlite3"), - '', - '') - - if self._is_py3: - replace_in_file(self, self._msvc_project_path("_lzma"), "", "$(ConanPreprocessorDefinitions);") - replace_in_file(self, self._msvc_project_path("_lzma"), "$(OutDir)liblzma$(PyDebugExt).lib;", "") - replace_in_file(self, self._msvc_project_path("_lzma"), - '', - '') - - replace_in_file(self, self._msvc_project_path("pyexpat"), - "$(PySourcePath)Modules\expat;", - "") - replace_in_file(self, self._msvc_project_path("pyexpat"), ("HAVE_EXPAT_H;" if self._is_py3 and Version(self.version) < "3.11" else "") + "XML_STATIC;", "") - self._regex_replace_in_file(self._msvc_project_path("pyexpat"), r'.*Include=\"\.\.\\Modules\\expat\\.*" />', "") - - replace_in_file(self, self._msvc_project_path("_elementtree"), - "..\Modules\expat;", - "") - replace_in_file(self, self._msvc_project_path("_elementtree"), "XML_STATIC;", "") - self._regex_replace_in_file(self._msvc_project_path("_elementtree"), r'.*Include=\"\.\.\\Modules\\expat\\.*" />', "") - - if self._is_py3: - if Version(self.version) >= "3.9": - # deflate.c has warning 4244 disabled, need special patching else it breaks the regex below - # Add an extra space to avoid being picked up by the regex - replace_in_file(self, self._msvc_project_path("pythoncore"), - r'', - r'') - self._regex_replace_in_file(self._msvc_project_path("pythoncore"), r'.*Include=\"\$\(zlibDir\).*', "") - - replace_in_file(self, self._msvc_project_path("_tkinter"), "$(tcltkDir)include;", "") - replace_in_file(self, self._msvc_project_path("_tkinter"), "$(tcltkLib);", "") - if self._is_py3: - replace_in_file(self, self._msvc_project_path("_tkinter"), - "", - "") - self._regex_replace_in_file(self._msvc_project_path("_tkinter"), r'.*Include=\"\$\(tcltkdir\).*', "") - - if self._is_py3: - # Disable "ValidateUcrtbase" target - replace_in_file(self, self._msvc_project_path("python"), "$(Configuration) != 'PGInstrument'", "False") - - if Version(self.version) < "3.11": - replace_in_file(self, self._msvc_project_path("_freeze_importlib"), - "', - r'') - - self._inject_conan_props_file("_bz2" if self._is_py3 else "bz2", "bzip2", self.options.get_safe("with_bz2")) - self._inject_conan_props_file("_elementtree", "expat", self._supports_modules) - self._inject_conan_props_file("pyexpat", "expat", self._supports_modules) - self._inject_conan_props_file("_hashlib", "openssl", self._supports_modules) - self._inject_conan_props_file("_ssl", "openssl", self._supports_modules) - self._inject_conan_props_file("_sqlite3", "sqlite3", self.options.get_safe("with_sqlite3")) - self._inject_conan_props_file("_tkinter", "tk", self.options.get_safe("with_tkinter")) - self._inject_conan_props_file("pythoncore", "zlib") - self._inject_conan_props_file("python", "zlib") - self._inject_conan_props_file("pythonw", "zlib") - self._inject_conan_props_file("_ctypes", "libffi", self._with_libffi) - self._inject_conan_props_file("_decimal", "mpdecimal", self._is_py3 and self._supports_modules) - self._inject_conan_props_file("_lzma", "xz_utils", self.options.get_safe("with_lzma")) - self._inject_conan_props_file("_bsddb", "libdb", self.options.get_safe("with_bsddb")) - - def _patch_sources(self): - apply_conandata_patches(self) - # <=3.10 requires a lot of manual injection of dependencies through setup.py - # 3.12 removes setup.py completely, and uses pkgconfig dependencies - # 3.11 is an in awkward transition state where some dependencies use pkgconfig, and others use setup.py - if Version(self.version) < "3.12": - self._patch_setup_py() - if Version(self.version) >= "3.11": - replace_in_file(self, os.path.join(self.source_folder, "configure"), - 'OPENSSL_LIBS="-lssl -lcrypto"', - 'OPENSSL_LIBS="-lssl -lcrypto -lz"') - if is_msvc(self): - runtime_library = { - "MT": "MultiThreaded", - "MTd": "MultiThreadedDebug", - "MD": "MultiThreadedDLL", - "MDd": "MultiThreadedDebugDLL", - }[msvc_runtime_flag(self)] - self.output.info("Patching runtime") - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pyproject.props"), - "MultiThreadedDLL", runtime_library) - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pyproject.props"), - "MultiThreadedDebugDLL", runtime_library) - - # Remove vendored packages - rmdir(self, os.path.join(self.source_folder, "Modules", "_decimal", "libmpdec")) - rmdir(self, os.path.join(self.source_folder, "Modules", "expat")) - - if self._is_py3 and Version(self.version) < "3.12": - replace_in_file(self, os.path.join(self.source_folder, "Makefile.pre.in"), - "$(RUNSHARED) CC='$(CC)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)'", - "$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)'") - - # Enable static MSVC cpython - if not self.options.shared: - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), - "", - "Py_NO_BUILD_SHARED;") - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), - "Py_ENABLE_SHARED", - "Py_NO_ENABLE_SHARED") - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), - "DynamicLibrary", - "StaticLibrary") - - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "python.vcxproj"), - "", - "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "python.vcxproj"), - "", - "Py_NO_ENABLE_SHARED;") - - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythonw.vcxproj"), - "", - "shlwapi.lib;ws2_32.lib;pathcch.lib;version.lib;%(AdditionalDependencies)") - replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythonw.vcxproj"), - "", - "Py_NO_ENABLE_SHARED;%(PreprocessorDefinitions)") - - conantoolchain_props = os.path.join(self.generators_folder, MSBuildToolchain.filename) - replace_in_file( - self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"), - '', - f'', - ) - - if is_msvc(self): - self._patch_msvc_projects() - - @property - def _solution_projects(self): - if self.options.shared: - solution_path = os.path.join(self.source_folder, "PCbuild", "pcbuild.sln") - projects = set(m.group(1) for m in re.finditer('"([^"]+)\\.vcxproj"', open(solution_path).read())) - - def project_build(name): - if os.path.basename(name) in self._msvc_discarded_projects: - return False - if "test" in name: - return False - return True - - projects = list(filter(project_build, projects)) - return projects - else: - return ["pythoncore", "python", "pythonw"] - - @property - def _msvc_discarded_projects(self): - discarded = { - "python_uwp", - "pythonw_uwp", - "_freeze_importlib", - "sqlite3", - "bdist_wininst", - } - if not self.options.with_bz2: - discarded.add("bz2") - if not self.options.with_sqlite3: - discarded.add("_sqlite3") - if not self.options.with_tkinter: - discarded.add("_tkinter") - if self._is_py2: - # Python 2 Visual Studio projects NOT to build - discarded = discarded.union({ - "libeay", - "ssleay", - "tcl", - "tk", - "tix", - }) - if not self.options.with_bsddb: - discarded.add("_bsddb") - elif self._is_py3: - discarded = discarded.union({ - "liblzma", - "openssl", - "xxlimited", - }) - if not self.options.with_lzma: - discarded.add("_lzma") - return discarded - - @property - def _msvc_archs(self): - archs = { - "x86": "Win32", - "x86_64": "x64", - } - if Version(self.version) >= "3.8": - archs.update({ - "armv7": "ARM", - "armv8_32": "ARM", - "armv8": "ARM64", - }) - return archs - - def _msvc_build(self): - msbuild = MSBuild(self) - msbuild.platform = self._msvc_archs[str(self.settings.arch)] - - projects = self._solution_projects - self.output.info(f"Building {len(projects)} Visual Studio projects: {projects}") - - sln = os.path.join(self.source_folder, "PCbuild", "pcbuild.sln") - # FIXME: Solution files do not pick up the toolset automatically. - for project in projects: - # To make this work in Powershell too (which uses ';' as command seperation), do each project separately. - cmd = msbuild.command(sln, targets=[project]) - self.run(f"{cmd} /p:PlatformToolset={msvs_toolset(self)}") - - def build(self): - self._patch_sources() - if is_msvc(self): - self._msvc_build() - else: - autotools = Autotools(self) - # For debugging configure errors - try: - autotools.configure() - except ConanException: - with open(os.path.join(self.build_folder, "config.log"), 'r') as f: - self.output.info(f.read()) - raise - autotools.make() - - @property - def _msvc_artifacts_path(self): - build_subdir_lut = { - "x86_64": "amd64", - "x86": "win32", - } - if Version(self.version) >= "3.8": - build_subdir_lut.update({ - "armv7": "arm32", - "armv8_32": "arm32", - "armv8": "arm64", - }) - return os.path.join(self.source_folder, "PCbuild", build_subdir_lut[str(self.settings.arch)]) - - @property - def _msvc_install_subprefix(self): - return "bin" - - def _copy_essential_dlls(self): - if is_msvc(self): - # Until MSVC builds support cross building, copy dll's of essential (shared) dependencies to python binary location. - # These dll's are required when running the layout tool using the newly built python executable. - dest_path = os.path.join(self.build_folder, self._msvc_artifacts_path) - if self._with_libffi: - for bin_path in self.dependencies["libffi"].cpp_info.bindirs: - copy(self, "*.dll", src=bin_path, dst=dest_path) - for bin_path in self.dependencies["expat"].cpp_info.bindirs: - copy(self, "*.dll", src=bin_path, dst=dest_path) - for bin_path in self.dependencies["zlib"].cpp_info.bindirs: - copy(self, "*.dll", src=bin_path, dst=dest_path) - - def _msvc_package_layout(self): - self._copy_essential_dlls() - install_prefix = os.path.join(self.package_folder, self._msvc_install_subprefix) - mkdir(self, install_prefix) - build_path = self._msvc_artifacts_path - infix = "_d" if self.settings.build_type == "Debug" else "" - # FIXME: if cross building, use a build python executable here - python_built = os.path.join(build_path, f"python{infix}.exe") - layout_args = [ - os.path.join(self.source_folder, "PC", "layout", "main.py"), - "-v", - "-s", self.source_folder, - "-b", build_path, - "--copy", install_prefix, - "-p", - "--include-pip", - "--include-venv", - "--include-dev", - ] - if self.options.with_tkinter: - layout_args.append("--include-tcltk") - if self.settings.build_type == "Debug": - layout_args.append("-d") - python_args = " ".join(f'"{a}"' for a in layout_args) - self.run(f"{python_built} {python_args}") - - rmdir(self, os.path.join(self.package_folder, "bin", "tcl")) - - for file in os.listdir(install_prefix): - if re.match("vcruntime.*", file): - os.unlink(os.path.join(install_prefix, file)) - continue - os.unlink(os.path.join(install_prefix, "LICENSE.txt")) - for file in os.listdir(os.path.join(install_prefix, "libs")): - if not re.match("python.*", file): - os.unlink(os.path.join(install_prefix, "libs", file)) - - def _msvc_package_copy(self): - build_path = self._msvc_artifacts_path - infix = "_d" if self.settings.build_type == "Debug" else "" - copy(self, "*.exe", - src=build_path, - dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) - copy(self, "*.dll", - src=build_path, - dst=os.path.join(self.package_folder, self._msvc_install_subprefix)) - copy(self, "*.pyd", - src=build_path, - dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "DLLs")) - copy(self, f"python{self._version_suffix}{infix}.lib", - src=build_path, - dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "libs")) - copy(self, "*", - src=os.path.join(self.source_folder, "Include"), - dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) - copy(self, "pyconfig.h", - src=os.path.join(self.source_folder, "PC"), - dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "include")) - copy(self, "*.py", - src=os.path.join(self.source_folder, "lib"), - dst=os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib")) - rmdir(self, os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib", "test")) - - packages = {} - get_name_version = lambda fn: fn.split(".", 2)[:2] - whldir = os.path.join(self.source_folder, "Lib", "ensurepip", "_bundled") - for fn in filter(lambda n: n.endswith(".whl"), os.listdir(whldir)): - name, version = get_name_version(fn) - add = True - if name in packages: - pname, pversion = get_name_version(packages[name]) - add = Version(version) > Version(pversion) - if add: - packages[name] = fn - for fname in packages.values(): - unzip(self, filename=os.path.join(whldir, fname), - destination=os.path.join(self.package_folder, "bin", "Lib", "site-packages")) - - interpreter_path = os.path.join(build_path, self._cpython_interpreter_name) - lib_dir_path = os.path.join(self.package_folder, self._msvc_install_subprefix, "Lib").replace("\\", "/") - self.run(f"{interpreter_path} -c \"import compileall; compileall.compile_dir('{lib_dir_path}')\"") - - def package(self): - copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) - if is_msvc(self): - if self._is_py2 or not self.options.shared: - self._msvc_package_copy() - else: - self._msvc_package_layout() - rm(self, "vcruntime*", os.path.join(self.package_folder, "bin"), recursive=True) - else: - # FIXME: C3I sometimes has a `lib` folder in the package folder, only on MacOS. - # Shot in the dark attempt: If it fails, remove the entire package folder and try again - try: - autotools = Autotools(self) - # FIXME: Autotools.install() always adds DESTDIR, we don't want this argument. - # Use .make() directly instead - autotools.make(target="altinstall") - except: - if (os.path.isfile(os.path.join(self.package_folder, "lib"))): - # FIXME not sure where this file comes from - self.output.info(f"{os.path.join(self.package_folder, 'lib')} exists, but it shouldn't.") - rmdir(self, self.package_folder) - mkdir(self, self.package_folder) - - copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) - autotools = Autotools(self) - autotools.make(target="altinstall") - - rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) - rmdir(self, os.path.join(self.package_folder, "share")) - - # Rewrite shebangs of python scripts - for filename in os.listdir(os.path.join(self.package_folder, "bin")): - filepath = os.path.join(self.package_folder, "bin", filename) - if not os.path.isfile(filepath): - continue - if os.path.islink(filepath): - continue - with open(filepath, "rb") as fn: - firstline = fn.readline(1024) - if not(firstline.startswith(b"#!") and b"/python" in firstline and b"/bin/sh" not in firstline): - continue - text = fn.read() - self.output.info(f"Rewriting shebang of {filename}") - with open(filepath, "wb") as fn: - fn.write(textwrap.dedent(f"""\ - #!/bin/sh - ''':' - __file__="$0" - while [ -L "$__file__" ]; do - __file__="$(dirname "$__file__")/$(readlink "$__file__")" - done - exec "$(dirname "$__file__")/python{self._version_suffix}" "$0" "$@" - ''' - """).encode()) - fn.write(text) - - if not os.path.exists(self._cpython_symlink): - os.symlink(f"python{self._version_suffix}", self._cpython_symlink) - fix_apple_shared_install_name(self) - - @property - def _cpython_symlink(self): - symlink = os.path.join(self.package_folder, "bin", "python") - if self.settings.os == "Windows": - symlink += ".exe" - return symlink - - @property - def _cpython_interpreter_name(self): - python = "python" - if is_msvc(self): - if self.settings.build_type == "Debug": - python += "_d" - else: - python += self._version_suffix - if self.settings.os == "Windows": - python += ".exe" - return python - - @property - def _cpython_interpreter_path(self): - return os.path.join(self.package_folder, "bin", self._cpython_interpreter_name) - - @property - def _abi_suffix(self): - res = "" - if self._is_py3: - if self.settings.build_type == "Debug": - res += "d" - if Version(self.version) < "3.8": - if self.options.get_safe("pymalloc", False): - res += "m" - return res - - @property - def _lib_name(self): - if is_msvc(self): - if self.settings.build_type == "Debug": - lib_ext = "_d" - else: - lib_ext = "" - else: - lib_ext = self._abi_suffix + ( - ".dll.a" if self.options.shared and self.settings.os == "Windows" else "" - ) - return f"python{self._version_suffix}{lib_ext}" - - def package_info(self): - # FIXME: conan components Python::Interpreter component, need a target type - # self.cpp_info.names["cmake_find_package"] = "Python" - # self.cpp_info.names["cmake_find_package_multi"] = "Python" - # FIXME: conan components need to generate multiple .pc files (python2, python-27) - - py_version = Version(self.version) - # python component: "Build a C extension for Python" - if is_msvc(self): - self.cpp_info.components["python"].includedirs = [os.path.join(self._msvc_install_subprefix, "include")] - libdir = os.path.join(self._msvc_install_subprefix, "libs") - else: - self.cpp_info.components["python"].includedirs.append( - os.path.join("include", f"python{self._version_suffix}{self._abi_suffix}") - ) - libdir = "lib" - if self.options.shared: - self.cpp_info.components["python"].defines.append("Py_ENABLE_SHARED") - else: - self.cpp_info.components["python"].defines.append("Py_NO_ENABLE_SHARED") - if self.settings.os in ["Linux", "FreeBSD"]: - self.cpp_info.components["python"].system_libs.extend(["dl", "m", "pthread", "util"]) - elif self.settings.os == "Windows": - self.cpp_info.components["python"].system_libs.extend( - ["pathcch", "shlwapi", "version", "ws2_32"] - ) - self.cpp_info.components["python"].requires = ["zlib::zlib"] - if self.settings.os != "Windows": - self.cpp_info.components["python"].requires.append("libxcrypt::libxcrypt") - self.cpp_info.components["python"].set_property( - "pkg_config_name", f"python-{py_version.major}.{py_version.minor}" - ) - self.cpp_info.components["python"].libdirs = [] - - self.cpp_info.components["_python_copy"].set_property("pkg_config_name", f"python{py_version.major}") - self.cpp_info.components["_python_copy"].requires = ["python"] - self.cpp_info.components["_python_copy"].includedirs = [] - self.cpp_info.components["_python_copy"].libdirs = [] - - # embed component: "Embed Python into an application" - self.cpp_info.components["embed"].libs = [self._lib_name] - self.cpp_info.components["embed"].libdirs = [libdir] - self.cpp_info.components["embed"].includedirs = [] - self.cpp_info.components["embed"].set_property( - "pkg_config_name", f"python-{py_version.major}.{py_version.minor}-embed" - ) - self.cpp_info.components["embed"].requires = ["python"] - - self.cpp_info.components["_embed_copy"].requires = ["embed"] - self.cpp_info.components["_embed_copy"].includedirs = [] - self.cpp_info.components["_embed_copy"].set_property( - "pkg_config_name", f"python{py_version.major}-embed" - ) - self.cpp_info.components["_embed_copy"].libdirs = [] - - if self._supports_modules: - # hidden components: the C extensions of python are built as dynamically loaded shared libraries. - # C extensions or applications with an embedded Python should not need to link to them.. - self.cpp_info.components["_hidden"].requires = [ - "openssl::openssl", - "expat::expat", - "mpdecimal::mpdecimal", - ] - if self._with_libffi: - self.cpp_info.components["_hidden"].requires.append("libffi::libffi") - if self.settings.os != "Windows": - if not is_apple_os(self): - self.cpp_info.components["_hidden"].requires.append("util-linux-libuuid::util-linux-libuuid") - self.cpp_info.components["_hidden"].requires.append("libxcrypt::libxcrypt") - if self.options.with_bz2: - self.cpp_info.components["_hidden"].requires.append("bzip2::bzip2") - if self.options.get_safe("with_gdbm", False): - self.cpp_info.components["_hidden"].requires.append("gdbm::gdbm") - if self.options.with_sqlite3: - self.cpp_info.components["_hidden"].requires.append("sqlite3::sqlite3") - if self.options.get_safe("with_curses", False): - self.cpp_info.components["_hidden"].requires.append("ncurses::ncurses") - if self.options.get_safe("with_bsddb"): - self.cpp_info.components["_hidden"].requires.append("libdb::libdb") - if self.options.get_safe("with_lzma"): - self.cpp_info.components["_hidden"].requires.append("xz_utils::xz_utils") - if self.options.get_safe("with_tkinter"): - self.cpp_info.components["_hidden"].requires.append("tk::tk") - self.cpp_info.components["_hidden"].includedirs = [] - self.cpp_info.components["_hidden"].libdirs = [] - - if self.options.env_vars: - bindir = os.path.join(self.package_folder, "bin") - self.output.info(f"Appending PATH environment variable: {bindir}") - self.env_info.PATH.append(bindir) - - python = self._cpython_interpreter_path - self.conf_info.define("user.cpython:python", python) - self.user_info.python = python - if self.options.env_vars: - self.env_info.PYTHON = python - - if is_msvc(self): - pythonhome = os.path.join(self.package_folder, "bin") - else: - pythonhome = self.package_folder - self.conf_info.define("user.cpython:pythonhome", pythonhome) - self.user_info.pythonhome = pythonhome - - pythonhome_required = is_msvc(self) or is_apple_os(self) - self.conf_info.define("user.cpython:module_requires_pythonhome", pythonhome_required) - self.user_info.module_requires_pythonhome = pythonhome_required - - if is_msvc(self): - if self.options.env_vars: - self.output.info(f"Setting PYTHONHOME environment variable: {pythonhome}") - self.env_info.PYTHONHOME = pythonhome - - if self._is_py2: - python_root = "" - else: - python_root = self.package_folder - if self.options.env_vars: - self.output.info(f"Setting PYTHON_ROOT environment variable: {python_root}") - self.env_info.PYTHON_ROOT = python_root - self.conf_info.define("user.cpython:python_root", python_root) - self.user_info.python_root = python_root diff --git a/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch b/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch deleted file mode 100644 index 3cb9b50..0000000 --- a/recipes/cpython/all/patches/2.7/2.7.18-0001-msvc.patch +++ /dev/null @@ -1,93 +0,0 @@ ---- PCbuild/_bsddb.vcxproj -+++ PCbuild/_bsddb.vcxproj -@@ -75,7 +75,7 @@ - - - -- -+ - - - ---- PCbuild/_hashlib.vcxproj -+++ PCbuild/_hashlib.vcxproj -@@ -64,7 +64,7 @@ - $(opensslIncludeDir);%(AdditionalIncludeDirectories) - - -- ws2_32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) -+ ws2_32.lib;%(AdditionalDependencies) - - - -@@ -75,14 +75,14 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - ---- PCbuild/_ssl.vcxproj -+++ PCbuild/_ssl.vcxproj -@@ -64,7 +64,7 @@ - $(opensslIncludeDir);%(AdditionalIncludeDirectories) - - -- ws2_32.lib;crypt32.lib;$(OutDir)libeay$(PyDebugExt).lib;$(OutDir)ssleay$(PyDebugExt).lib;%(AdditionalDependencies) -+ ws2_32.lib;crypt32.lib;%(AdditionalDependencies) - - - -@@ -75,14 +75,14 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - {86937f53-c189-40ef-8ce8-8759d8e7d480} - false ---- PCbuild/_tkinter.vcxproj -+++ PCbuild/_tkinter.vcxproj -@@ -77,12 +77,12 @@ - {cf7ac3d1-e2df-41d2-bea6-1e2556cdea26} - false - -- -+ - - - diff --git a/recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch b/recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch deleted file mode 100644 index 6034410..0000000 --- a/recipes/cpython/all/patches/2.7/2.7.18-0002-add-support-msvc-14.patch +++ /dev/null @@ -1,59 +0,0 @@ -Patches from https://bugs.python.org/issue30742 - ---- Modules/posixmodule.c -+++ Modules/posixmodule.c -@@ -563,7 +563,10 @@ typedef struct { - char osfile; - } my_ioinfo; - -+#if _MSC_VER < 1900 // MSVS2013 and lower (https://bugs.python.org/issue30742) - extern __declspec(dllimport) char * __pioinfo[]; -+#endif -+ - #define IOINFO_L2E 5 - #define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E) - #define IOINFO_ARRAYS 64 -@@ -575,6 +578,7 @@ extern __declspec(dllimport) char * __pioinfo[]; - int - _PyVerify_fd(int fd) - { -+#if _MSC_VER < 1900 // MSVS2013 and lower (https://bugs.python.org/issue30742) - const int i1 = fd >> IOINFO_L2E; - const int i2 = fd & ((1 << IOINFO_L2E) - 1); - -@@ -607,6 +611,13 @@ _PyVerify_fd(int fd) - fail: - errno = EBADF; - return 0; -+#else -+ //a call to _get_osfhandle with invalid fd sets errno to EBADF -+ if (_get_osfhandle(fd) == INVALID_HANDLE_VALUE) -+ return 0; -+ else -+ return 1; -+#endif - } - - /* the special case of checking dup2. The target fd must be in a sensible range */ ---- Modules/timemodule.c -+++ Modules/timemodule.c -@@ -803,7 +803,18 @@ inittimezone(PyObject *m) { - - And I'm lazy and hate C so nyer. - */ --#if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) -+#if defined(HAVE_TZNAME) && (_MSC_VER >= 1900) //MSVS2015+ (https://bugs.python.org/issue30742) -+ tzset(); -+ PyModule_AddIntConstant(m, "timezone", _timezone); -+#ifdef HAVE_ALTZONE -+ PyModule_AddIntConstant(m, "altzone", altzone); -+#else -+ PyModule_AddIntConstant(m, "altzone", _timezone - 3600); -+#endif -+ PyModule_AddIntConstant(m, "daylight", _daylight); -+ PyModule_AddObject(m, "tzname", -+ Py_BuildValue("(zz)", _tzname[0], _tzname[1])); -+#elif defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) - tzset(); - #ifdef PYOS_OS2 - PyModule_AddIntConstant(m, "timezone", _timezone); diff --git a/recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch b/recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch deleted file mode 100644 index 9eb0794..0000000 --- a/recipes/cpython/all/patches/2.7/2.7.18-0003-msvc-fix-static.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- PC/dl_nt.c -+++ PC/dl_nt.c -@@ -107,5 +107,7 @@ - } - return TRUE; - } -- -+#else -+ULONG_PTR _Py_ActivateActCtx() { return 0; } -+void _Py_DeactivateActCtx(ULONG_PTR cookie) {} - #endif /* Py_ENABLE_SHARED */ diff --git a/recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch deleted file mode 100644 index 4bc35cf..0000000 --- a/recipes/cpython/all/patches/3.10/3.10.0-0003-_ctypes-ffi.patch +++ /dev/null @@ -1,50 +0,0 @@ ---- Modules/_ctypes/cfield.c -+++ Modules/_ctypes/cfield.c -@@ -1472,7 +1472,11 @@ - return PyLong_FromVoidPtr(*(void **)ptr); - } - --static struct fielddesc formattable[] = { -+#define FORMATTABLE_SIZE 30 -+static struct fielddesc formattable[FORMATTABLE_SIZE]; -+ -+static void formattable_init(void) { -+struct fielddesc my_formattable[] = { - { 's', s_set, s_get, &ffi_type_pointer}, - { 'b', b_set, b_get, &ffi_type_schar}, - { 'B', B_set, B_get, &ffi_type_uchar}, -@@ -1524,6 +1528,11 @@ - { 'O', O_set, O_get, &ffi_type_pointer}, - { 0, NULL, NULL, NULL}, - }; -+ size_t nb = 1; -+ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); -+ if (FORMATTABLE_SIZE < nb) abort(); -+ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); -+} - - /* - Ideas: Implement VARIANT in this table, using 'V' code. -@@ -1538,5 +1547,6 @@ - - if (!initialized) { - initialized = 1; -+ formattable_init(); - if (sizeof(wchar_t) == sizeof(short)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; -@@ -1598,7 +1608,7 @@ typedef struct _ffi_type - struct _ffi_type **elements; - } ffi_type; - */ -- -+#if 0 - /* align and size are bogus for void, but they must not be zero */ - ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; - -@@ -1625,5 +1635,5 @@ - FFI_TYPE_LONGDOUBLE }; - - ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; -- -+#endif - /*---------------- EOF ----------------*/ diff --git a/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch deleted file mode 100644 index 65027b6..0000000 --- a/recipes/cpython/all/patches/3.11/3.11.7-0001-_ctypes-ffi.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c -index 9bdf1db856..799f99e809 100644 ---- a/Modules/_ctypes/cfield.c -+++ b/Modules/_ctypes/cfield.c -@@ -1473,7 +1473,11 @@ P_get(void *ptr, Py_ssize_t size) - return PyLong_FromVoidPtr(*(void **)ptr); - } - --static struct fielddesc formattable[] = { -+#define FORMATTABLE_SIZE 30 -+static struct fielddesc formattable[FORMATTABLE_SIZE]; -+ -+static void formattable_init(void) { -+struct fielddesc my_formattable[] = { - { 's', s_set, s_get, NULL}, - { 'b', b_set, b_get, NULL}, - { 'B', B_set, B_get, NULL}, -@@ -1510,6 +1514,11 @@ static struct fielddesc formattable[] = { - { 'O', O_set, O_get, NULL}, - { 0, NULL, NULL, NULL}, - }; -+ size_t nb = 1; -+ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); -+ if (FORMATTABLE_SIZE < nb) abort(); -+ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); -+} - - /* - Ideas: Implement VARIANT in this table, using 'V' code. -@@ -1597,6 +1606,7 @@ _ctypes_get_fielddesc(const char *fmt) - - if (!initialized) { - initialized = 1; -+ formattable_init(); - _ctypes_init_fielddesc(); - } - diff --git a/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch deleted file mode 100644 index 06bb62c..0000000 --- a/recipes/cpython/all/patches/3.12/3.12.1-0001-_ctypes-ffi.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c -index 128506a9ee..ee9ade67b8 100644 ---- a/Modules/_ctypes/cfield.c -+++ b/Modules/_ctypes/cfield.c -@@ -1448,7 +1448,11 @@ P_get(void *ptr, Py_ssize_t size) - return PyLong_FromVoidPtr(*(void **)ptr); - } - --static struct fielddesc formattable[] = { -+#define FORMATTABLE_SIZE 30 -+static struct fielddesc formattable[FORMATTABLE_SIZE]; -+ -+static void formattable_init(void) { -+struct fielddesc my_formattable[] = { - { 's', s_set, s_get, NULL}, - { 'b', b_set, b_get, NULL}, - { 'B', B_set, B_get, NULL}, -@@ -1485,6 +1489,11 @@ static struct fielddesc formattable[] = { - { 'O', O_set, O_get, NULL}, - { 0, NULL, NULL, NULL}, - }; -+ size_t nb = 1; -+ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); -+ if (FORMATTABLE_SIZE < nb) abort(); -+ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); -+} - - /* - Ideas: Implement VARIANT in this table, using 'V' code. -@@ -1572,6 +1581,7 @@ _ctypes_get_fielddesc(const char *fmt) - - if (!initialized) { - initialized = 1; -+ formattable_init(); - _ctypes_init_fielddesc(); - } - diff --git a/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch b/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch deleted file mode 100644 index 1d9d31f..0000000 --- a/recipes/cpython/all/patches/3.12/3.12.1-0002-remove-module-deps.patch +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/PCbuild/pcbuild.sln b/PCbuild/pcbuild.sln -index bdddec60da..f6a30955bf 100644 ---- a/PCbuild/pcbuild.sln -+++ b/PCbuild/pcbuild.sln -@@ -9,45 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {9E48B300-37D1-11DD-8C41-005056C00008} = {9E48B300-37D1-11DD-8C41-005056C00008} -- {9EC7190A-249F-4180-A900-548FDCF3055F} = {9EC7190A-249F-4180-A900-548FDCF3055F} -- {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} = {78D80A15-BD8C-44E2-B49E-1F05B0A0A687} -- {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} = {6901D91C-6E48-4BB7-9FEC-700C8131DF1D} -- {54B1431F-B86B-4ACB-B28C-88BCF93191D8} = {54B1431F-B86B-4ACB-B28C-88BCF93191D8} -- {F749B822-B489-4CA5-A3AD-CE078F5F338A} = {F749B822-B489-4CA5-A3AD-CE078F5F338A} -- {D06B6426-4762-44CC-8BAD-D79052507F2F} = {D06B6426-4762-44CC-8BAD-D79052507F2F} -- {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} = {36D0C52C-DF4E-45D0-8BC7-E294C3ABC781} -- {CB435430-EBB1-478B-8F4E-C256F6838F55} = {CB435430-EBB1-478B-8F4E-C256F6838F55} -- {17E1E049-C309-4D79-843F-AE483C264AEA} = {17E1E049-C309-4D79-843F-AE483C264AEA} -- {384C224A-7474-476E-A01B-750EA7DE918C} = {384C224A-7474-476E-A01B-750EA7DE918C} -- {12728250-16EC-4DC6-94D7-E21DD88947F8} = {12728250-16EC-4DC6-94D7-E21DD88947F8} -- {86937F53-C189-40EF-8CE8-8759D8E7D480} = {86937F53-C189-40EF-8CE8-8759D8E7D480} -- {28B5D777-DDF2-4B6B-B34F-31D938813856} = {28B5D777-DDF2-4B6B-B34F-31D938813856} -- {31FFC478-7B4A-43E8-9954-8D03E2187E9C} = {31FFC478-7B4A-43E8-9954-8D03E2187E9C} -- {F9D71780-F393-11E0-BE50-0800200C9A66} = {F9D71780-F393-11E0-BE50-0800200C9A66} -- {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} = {494BAC80-A60C-43A9-99E7-ACB691CE2C4D} -- {C6E20F84-3247-4AD6-B051-B073268F73BA} = {C6E20F84-3247-4AD6-B051-B073268F73BA} -- {B244E787-C445-441C-BDF4-5A4F1A3A1E51} = {B244E787-C445-441C-BDF4-5A4F1A3A1E51} -- {18CAE28C-B454-46C1-87A0-493D91D97F03} = {18CAE28C-B454-46C1-87A0-493D91D97F03} -- {13CECB97-4119-4316-9D42-8534019A5A44} = {13CECB97-4119-4316-9D42-8534019A5A44} -- {885D4898-D08D-4091-9C40-C700CFE3FC5A} = {885D4898-D08D-4091-9C40-C700CFE3FC5A} -- {447F05A8-F581-4CAC-A466-5AC7936E207E} = {447F05A8-F581-4CAC-A466-5AC7936E207E} -- {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} = {ECC7CEAC-A5E5-458E-BB9E-2413CC847881} -- {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} = {4946ECAC-2E69-4BF8-A90A-F5136F5094DF} -- {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} = {FDB84CBB-2FB6-47C8-A2D6-091E0833239D} -- {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} = {73FCD2BD-F133-46B7-8EC1-144CD82A59D5} -- {2097F1C1-597C-4167-93E3-656A7D6339B2} = {2097F1C1-597C-4167-93E3-656A7D6339B2} -- {A2697BD3-28C1-4AEC-9106-8B748639FD16} = {A2697BD3-28C1-4AEC-9106-8B748639FD16} -- {900342D7-516A-4469-B1AD-59A66E49A25F} = {900342D7-516A-4469-B1AD-59A66E49A25F} -- {6DAC66D9-E703-4624-BE03-49112AB5AA62} = {6DAC66D9-E703-4624-BE03-49112AB5AA62} -- {0E9791DB-593A-465F-98BC-681011311617} = {0E9791DB-593A-465F-98BC-681011311617} -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} = {EB6E69DD-04BF-4543-9B92-49FAABCEAC2E} -- {16BFE6F0-22EF-40B5-B831-7E937119EF10} = {16BFE6F0-22EF-40B5-B831-7E937119EF10} -- {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} = {FCBE1EF2-E0F0-40B1-88B5-00A35D378742} -- {A840DDFB-ED50-484B-B527-B32E7CF90FD5} = {A840DDFB-ED50-484B-B527-B32E7CF90FD5} -- EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pythoncore", "pythoncore.vcxproj", "{CF7AC3D1-E2DF-41D2-BEA6-1E2556CDEA26}" - ProjectSection(ProjectDependencies) = postProject diff --git a/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch b/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch deleted file mode 100644 index be1387c..0000000 --- a/recipes/cpython/all/patches/3.7/3.7.9-0001-msvc.patch +++ /dev/null @@ -1,19 +0,0 @@ ---- PCbuild/openssl.vcxproj -+++ PCbuild/openssl.vcxproj -@@ -74,6 +74,6 @@ nmake - - - -- -+ - - - diff --git a/recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch deleted file mode 100644 index 04b8705..0000000 --- a/recipes/cpython/all/patches/3.8/3.8.12-0002-_ctypes-ffi.patch +++ /dev/null @@ -1,67 +0,0 @@ -comments --- Modules/_ctypes/malloc_closure.c -comments +++ Modules/_ctypes/malloc_closure.c -comments @@ -87,7 +87,7 @@ -comments } -comments -comments /******************************************************************/ -comments - -comments +#if 0 -comments /* put the item back into the free list */ -comments void ffi_closure_free(void *p) -comments { -comments @@ -114,3 +114,4 @@ -comments #endif -comments return (void *)item; -comments } -comments +#endif ---- Modules/_ctypes/cfield.c -+++ Modules/_ctypes/cfield.c -@@ -1510,7 +1510,11 @@ - return PyLong_FromVoidPtr(*(void **)ptr); - } - --static struct fielddesc formattable[] = { -+#define FORMATTABLE_SIZE 30 -+static struct fielddesc formattable[FORMATTABLE_SIZE]; -+ -+static void formattable_init(void) { -+struct fielddesc my_formattable[] = { - { 's', s_set, s_get, &ffi_type_pointer}, - { 'b', b_set, b_get, &ffi_type_schar}, - { 'B', B_set, B_get, &ffi_type_uchar}, -@@ -1564,6 +1568,11 @@ - { 'O', O_set, O_get, &ffi_type_pointer}, - { 0, NULL, NULL, NULL}, - }; -+ size_t nb = 1; -+ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); -+ if (FORMATTABLE_SIZE < nb) abort(); -+ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); -+} - - /* - Ideas: Implement VARIANT in this table, using 'V' code. -@@ -1578,6 +1587,7 @@ - - if (!initialized) { - initialized = 1; -+ formattable_init(); - #ifdef CTYPES_UNICODE - if (sizeof(wchar_t) == sizeof(short)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; -@@ -1640,7 +1650,7 @@ - struct _ffi_type **elements; - } ffi_type; - */ -- -+#if 0 - /* align and size are bogus for void, but they must not be zero */ - ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; - -@@ -1667,5 +1677,5 @@ - FFI_TYPE_LONGDOUBLE }; - - ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; -- -+#endif - /*---------------- EOF ----------------*/ diff --git a/recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch b/recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch deleted file mode 100644 index 0dd3651..0000000 --- a/recipes/cpython/all/patches/3.9/3.9.7-0002-_msi-vcxproj.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- PCbuild/_msi.vcxproj -+++ PCbuild/_msi.vcxproj -@@ -23,7 +23,7 @@ - - - PGInstrument -- ARM4 -+ ARM64 - - - PGInstrument diff --git a/recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch b/recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch deleted file mode 100644 index aecf32f..0000000 --- a/recipes/cpython/all/patches/3.9/3.9.7-0003-_ctypes-ffi.patch +++ /dev/null @@ -1,51 +0,0 @@ ---- Modules/_ctypes/cfield.c -+++ Modules/_ctypes/cfield.c -@@ -1504,7 +1504,11 @@ - return PyLong_FromVoidPtr(*(void **)ptr); - } - --static struct fielddesc formattable[] = { -+#define FORMATTABLE_SIZE 30 -+static struct fielddesc formattable[FORMATTABLE_SIZE]; -+ -+static void formattable_init(void) { -+struct fielddesc my_formattable[] = { - { 's', s_set, s_get, &ffi_type_pointer}, - { 'b', b_set, b_get, &ffi_type_schar}, - { 'B', B_set, B_get, &ffi_type_uchar}, -@@ -1558,6 +1562,11 @@ - { 'O', O_set, O_get, &ffi_type_pointer}, - { 0, NULL, NULL, NULL}, - }; -+ size_t nb = 1; -+ for (struct fielddesc *pos = my_formattable; pos->code; ++pos, ++nb); -+ if (FORMATTABLE_SIZE < nb) abort(); -+ memcpy(formattable, my_formattable, nb * sizeof(struct fielddesc)); -+} - - /* - Ideas: Implement VARIANT in this table, using 'V' code. -@@ -1572,6 +1581,7 @@ - - if (!initialized) { - initialized = 1; -+ formattable_init(); - #ifdef CTYPES_UNICODE - if (sizeof(wchar_t) == sizeof(short)) - _ctypes_get_fielddesc("u")->pffi_type = &ffi_type_sshort; -@@ -1634,7 +1644,7 @@ - struct _ffi_type **elements; - } ffi_type; - */ -- -+#if 0 - /* align and size are bogus for void, but they must not be zero */ - ffi_type ffi_type_void = { 1, 1, FFI_TYPE_VOID }; - -@@ -1661,5 +1671,5 @@ - FFI_TYPE_LONGDOUBLE }; - - ffi_type ffi_type_pointer = { sizeof(void *), VOID_P_ALIGN, FFI_TYPE_POINTER }; -- -+#endif - /*---------------- EOF ----------------*/ diff --git a/recipes/cpython/all/patches/3.x-0001-relocatable-python-config.patch b/recipes/cpython/all/patches/3.x-0001-relocatable-python-config.patch deleted file mode 100644 index 113aa21..0000000 --- a/recipes/cpython/all/patches/3.x-0001-relocatable-python-config.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- Misc/python-config.sh.in -+++ Misc/python-config.sh.in -@@ -30,7 +30,7 @@ - # locations. Keep prefix & exec_prefix using their original values in case - # they are referenced in other configure variables, to prevent double - # substitution, issue #22140. --prefix="@prefix@" -+prefix="$PYTHON_ROOT" - exec_prefix="@exec_prefix@" - exec_prefix_real=${prefix_real} - includedir=$(echo "@includedir@" | sed "s#$prefix#$prefix_real#") diff --git a/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch b/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch deleted file mode 100644 index 38a6425..0000000 --- a/recipes/cpython/all/patches/3.x-0002-remove-module-deps.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- PCbuild/pcbuild.sln -+++ PCbuild/pcbuild.sln -@@ -9,7 +9,4 @@ - EndProjectSection - EndProject - Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "python", "python.vcxproj", "{B11D750F-CD1F-4A96-85CE-E69A5C5259F9}" -- ProjectSection(ProjectDependencies) = postProject -- {0E9791DB-593A-465F-98BC-681011311618} = {0E9791DB-593A-465F-98BC-681011311618} -- EndProjectSection - EndProject diff --git a/recipes/cpython/all/test_package/CMakeLists.txt b/recipes/cpython/all/test_package/CMakeLists.txt deleted file mode 100644 index fe9f422..0000000 --- a/recipes/cpython/all/test_package/CMakeLists.txt +++ /dev/null @@ -1,103 +0,0 @@ -cmake_minimum_required(VERSION 3.15) -project(test_package C) - -find_package(cpython REQUIRED CONFIG) - -# FIXME: We can't modify CMake's FindPython to link dependencies pulled by -# Conan, so here we just include them globally. This is mainly necessary for -# MacOS missing crypt.h, which is available at configure time (in the main recipe) -# but otherwise not at build time (in consumer packages). -link_libraries(cpython::python) - -set(PY_VERSION_MAJOR "" CACHE STRING "MAJOR version of python") -set(PY_VERSION_MAJOR_MINOR "" CACHE STRING "MAJOR.MINOR version of python") -set(PY_VERSION "" CACHE STRING "Required version of python") -set(PY_VERSION_SUFFIX "" CACHE STRING "Suffix of python") - -set(Python_ADDITIONAL_VERSIONS ${PY_VERSION}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR_MINOR}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR}${PY_VERSION_SUFFIX} ${PY_VERSION} ${PY_VERSION_MAJOR_MINOR} ${PY_VERSION_MAJOR}) -message("Using Python_ADDITIONAL_VERSIONS: ${Python_ADDITIONAL_VERSIONS}") - -find_package(PythonInterp REQUIRED) -find_package(PythonLibs REQUIRED) - -string(FIND "${PYTHON_EXECUTABLE}" "${CONAN_CPYTHON_ROOT}" ROOT_SUBPOS) -if(ROOT_SUBPOS EQUAL -1) - message(FATAL_ERROR "found wrong python interpreter: ${PYTHON_EXECUTABLE}") -endif() - -message(STATUS "FindPythonInterp:") -message(STATUS "PYTHON_VERSION_STRING: ${PYTHON_VERSION_STRING}") -message(STATUS "PYTHON_VERSION_MAJOR: ${PYTHON_VERSION_MAJOR}") -message(STATUS "PYTHON_VERSION_MINOR: ${PYTHON_VERSION_MINOR}") -message(STATUS "PYTHON_VERSION_PATCH: ${PYTHON_VERSION_PATCH}") -message(STATUS "=============================================") -message(STATUS "FindPythonLibs:") -message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}") -message(STATUS "PYTHON_INCLUDE_PATH: ${PYTHON_INCLUDE_PATH} (deprecated)") -message(STATUS "PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}") -message(STATUS "PYTHON_DEBUG_LIBRARIES: ${PYTHON_DEBUG_LIBRARIES} (deprecated)") -message(STATUS "PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}") - -if(NOT PYTHON_VERSION_STRING AND NOT PYTHONLIBS_VERSION_STRING) - message(FATAL_ERROR "Version of python interpreter and libraries not found") -endif() - -if(PYTHON_VERSION_STRING) - if(NOT PYTHON_VERSION_STRING VERSION_EQUAL "${PY_VERSION}") - message("PYTHON_VERSION_STRING does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() -endif() - -if(PYTHONLIBS_VERSION_STRING) - if(NOT PYTHONLIBS_VERSION_STRING STREQUAL "${PY_FULL_VERSION}") - message("PYTHONLIBS_VERSION_STRING does not match PY_FULL_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() -endif() - -option(BUILD_MODULE "Build python module") - -if(BUILD_MODULE) - add_library(spam MODULE "py${PY_VERSION_MAJOR}/test_module.c") - target_include_directories(spam - PRIVATE - ${PYTHON_INCLUDE_DIRS} - ) - target_link_libraries(spam PRIVATE - ${PYTHON_LIBRARIES} - ) - set_property(TARGET spam PROPERTY PREFIX "") - if(MSVC) - set_target_properties(spam PROPERTIES - DEBUG_POSTFIX "_d" - SUFFIX ".pyd" - ) - endif() - - option(USE_FINDPYTHON_X "Use new-style FindPythonX module") - if(USE_FINDPYTHON_X AND NOT CMAKE_VERSION VERSION_LESS "3.16") - # Require CMake 3.16 because this version introduces Python${PY_VERSION_MAJOR}_FIND_ABI - find_package(Python${PY_VERSION_MAJOR} REQUIRED COMPONENTS Interpreter Development) - message("Python${PY_VERSION_MAJOR}_EXECUTABLE: ${Python${PY_VERSION_MAJOR}_EXECUTABLE}") - message("Python${PY_VERSION_MAJOR}_INTERPRETER_ID: ${Python${PY_VERSION_MAJOR}_INTERPRETER_ID}") - message("Python${PY_VERSION_MAJOR}_VERSION: ${Python${PY_VERSION_MAJOR}_VERSION}") - message("Python${PY_VERSION_MAJOR}_INCLUDE_DIRS: ${Python${PY_VERSION_MAJOR}_INCLUDE_DIRS}") - message("Python${PY_VERSION_MAJOR}_LIBRARIES: ${Python${PY_VERSION_MAJOR}_LIBRARIES}") - if(NOT Python${PY_VERSION_MAJOR}_VERSION STREQUAL "${PY_VERSION}") - message("Python_ADDITIONAL_VERSIONS does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() - - if(PY_VERSION_MAJOR STREQUAL "2") - python2_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") - elseif(PY_VERSION_MAJOR STREQUAL "3") - python3_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") - else() - message(FATAL_ERROR "Unknown PY_VERSION_MAJOR") - endif() - endif() -endif() - -add_executable(${PROJECT_NAME} "py${PY_VERSION_MAJOR}/test_package.c") -target_link_libraries(${PROJECT_NAME} PRIVATE cpython::embed) diff --git a/recipes/cpython/all/test_package/conanfile.py b/recipes/cpython/all/test_package/conanfile.py deleted file mode 100644 index f9fc84c..0000000 --- a/recipes/cpython/all/test_package/conanfile.py +++ /dev/null @@ -1,248 +0,0 @@ -import os -from io import StringIO - -from conan import ConanFile, conan_version -from conan.errors import ConanException -from conan.tools.apple import is_apple_os -from conan.tools.build import can_run -from conan.tools.cmake import CMake, CMakeToolchain, cmake_layout -from conan.tools.env import VirtualRunEnv -from conan.tools.gnu import AutotoolsDeps -from conan.tools.microsoft import is_msvc, VCVars -from conan.tools.scm import Version - -conan2 = conan_version.major >= 2 - -class CmakePython3Abi(object): - def __init__(self, debug, pymalloc, unicode): - self.debug, self.pymalloc, self.unicode = debug, pymalloc, unicode - - _cmake_lut = { - None: "ANY", - True: "ON", - False: "OFF", - } - - @property - def suffix(self): - suffix = "" - if self.debug: - suffix += "d" - if self.pymalloc: - suffix += "m" - if self.unicode: - suffix += "u" - return suffix - - @property - def cmake_arg(self): - return ";".join(self._cmake_lut[a] for a in (self.debug, self.pymalloc, self.unicode)) - - -class TestPackageConan(ConanFile): - settings = "os", "arch", "compiler", "build_type" - generators = "CMakeDeps" - test_type = "explicit" - - def requirements(self): - self.requires(self.tested_reference_str) - - def build_requirements(self): - # The main recipe does not require CMake, but we test with it. - # The interesting problem that arises here is if you have CMake installed - # with your global pip, then it will fail to run in this test package. - # To avoid that, just add a requirement on CMake. - self.tool_requires("cmake/[>=3.15 <4]") - - def layout(self): - cmake_layout(self) - - @property - def _python(self): - if conan2: - return self.dependencies["cpython"].conf_info.get("user.cpython:python", check_type=str) - else: - return self.deps_user_info["cpython"].python - - @property - def _clean_py_version(self): - return str(self._py_version) - - @property - def _py_version(self): - if conan2: - return Version(self.dependencies["cpython"].ref.version) - else: - return Version(self.deps_cpp_info["cpython"].version) - - @property - def _test_setuptools(self): - # TODO Should we still try to test this? - # https://github.com/python/cpython/pull/101039 - return can_run(self) and self._supports_modules and self._py_version < "3.12" - - @property - def _pymalloc(self): - if conan2: - return bool(self.dependencies["cpython"].options.get_safe("pymalloc", False)) - else: - return bool("pymalloc" in self.options["cpython"] and self.options["cpython"].pymalloc) - - @property - def _cmake_abi(self): - if self._py_version < "3.8": - return CmakePython3Abi(debug=self.settings.build_type == "Debug", pymalloc=self._pymalloc, unicode=False) - else: - return CmakePython3Abi(debug=self.settings.build_type == "Debug", pymalloc=False, unicode=False) - - @property - def _cmake_try_FindPythonX(self): - return not is_msvc(self) or self.settings.build_type != "Debug" - - @property - def _supports_modules(self): - if conan2: - return not is_msvc(self) or self.dependencies["cpython"].options.shared - else: - return not is_msvc(self) or self.options["cpython"].shared - - def generate(self): - tc = CMakeToolchain(self) - version = self._py_version - py_major = str(version.major) - tc.cache_variables["BUILD_MODULE"] = self._supports_modules - tc.cache_variables["PY_VERSION_MAJOR"] = py_major - tc.cache_variables["PY_VERSION_MAJOR_MINOR"] = f"{version.major}.{version.minor}" - tc.cache_variables["PY_FULL_VERSION"] = str(version) - tc.cache_variables["PY_VERSION"] = self._clean_py_version - tc.cache_variables["PY_VERSION_SUFFIX"] = self._cmake_abi.suffix - tc.cache_variables["PYTHON_EXECUTABLE"] = self._python - tc.cache_variables["USE_FINDPYTHON_X".format(py_major)] = self._cmake_try_FindPythonX - tc.cache_variables[f"Python{py_major}_EXECUTABLE"] = self._python - tc.cache_variables[f"Python{py_major}_ROOT_DIR"] = self.dependencies["cpython"].package_folder - tc.cache_variables[f"Python{py_major}_USE_STATIC_LIBS"] = not self.dependencies["cpython"].options.shared - tc.cache_variables[f"Python{py_major}_FIND_FRAMEWORK"] = "NEVER" - tc.cache_variables[f"Python{py_major}_FIND_REGISTRY"] = "NEVER" - tc.cache_variables[f"Python{py_major}_FIND_IMPLEMENTATIONS"] = "CPython" - tc.cache_variables[f"Python{py_major}_FIND_STRATEGY"] = "LOCATION" - if not is_msvc(self) and self._py_version < "3.8": - tc.cache_variables[f"Python{py_major}_FIND_ABI"] = self._cmake_abi.cmake_arg - tc.generate() - - try: - # CMakeToolchain might generate VCVars, but we need it - # unconditionally for the setuptools build. - VCVars(self).generate() - except ConanException: - pass - - # The build also needs access to the run environment to run the python executable - VirtualRunEnv(self).generate(scope="run") - VirtualRunEnv(self).generate(scope="build") - - if self._test_setuptools: - # Just for the distutils build - AutotoolsDeps(self).generate(scope="build") - - def build(self): - cmake = CMake(self) - cmake.configure() - cmake.build() - - if self._test_setuptools: - os.environ["DISTUTILS_USE_SDK"] = "1" - os.environ["MSSdk"] = "1" - setup_args = [ - os.path.join(self.source_folder, "setup.py"), - "build", - "--build-base", self.build_folder, - "--build-platlib", os.path.join(self.build_folder, "lib_setuptools"), - ] - if self.settings.build_type == "Debug": - setup_args.append("--debug") - args = " ".join(f'"{a}"' for a in setup_args) - self.run(f"{self._python} {args}") - - def _test_module(self, module, should_work): - try: - self.run(f"{self._python} {self.source_folder}/test_package.py -b {self.build_folder} -t {module}", env="conanrun") - except ConanException: - if should_work: - self.output.warning(f"Module '{module}' does not work, but should have worked") - raise - self.output.info("Module failed as expected") - return - if not should_work: - raise ConanException(f"Module '{module}' works, but should not have worked") - self.output.info("Module worked as expected") - - def _cpython_option(self, name): - if conan2: - return self.dependencies["cpython"].options.get_safe(name, False) - else: - try: - return getattr(self.options["cpython"], name, False) - except ConanException: - return False - - def test(self): - if can_run(self): - self.run(f"{self._python} --version", env="conanrun") - - self.run(f"{self._python} -c \"print('hello world')\"", env="conanrun") - - buffer = StringIO() - self.run(f"{self._python} -c \"import sys; print('.'.join(str(s) for s in sys.version_info[:3]))\"", buffer, env="conanrun") - self.output.info(buffer.getvalue()) - version_detected = buffer.getvalue().splitlines()[-1].strip() - if self._clean_py_version != version_detected: - raise ConanException( - f"python reported wrong version. Expected {self._clean_py_version}. Got {version_detected}." - ) - - if self._supports_modules: - self._test_module("gdbm", self._cpython_option("with_gdbm")) - self._test_module("bz2", self._cpython_option("with_bz2")) - if self._py_version.major < 3: - self._test_module("bsddb", self._cpython_option("with_bsddb")) - self._test_module("lzma", self._cpython_option("with_lzma")) - self._test_module("tkinter", self._cpython_option("with_tkinter")) - os.environ["TERM"] = "ansi" - self._test_module("curses", self._cpython_option("with_curses")) - - self._test_module("expat", True) - self._test_module("sqlite3", self._cpython_option("with_sqlite3")) - self._test_module("decimal", True) - self._test_module("ctypes", True) - skip_ssl_test = is_msvc(self) and self._py_version < "3.8" and self._cpython_option("shared") - if not skip_ssl_test: - # Unsure cause of failure in this oddly specific combo, but these versions are EOL so not concerned with fixing. - self._test_module("ssl", True) - - if is_apple_os(self) and not self._cpython_option("shared"): - self.output.info( - "Not testing the module, because these seem not to work on apple when cpython is built as" - " a static library" - ) - # FIXME: find out why cpython on apple does not allow to use modules linked against a static python - else: - if self._supports_modules: - os.environ["PYTHONPATH"] = os.path.join(self.build_folder, self.cpp.build.libdirs[0]) - self.output.info("Testing module (spam) using cmake built module") - self._test_module("spam", True) - - if self._test_setuptools: - os.environ["PYTHONPATH"] = os.path.join(self.build_folder, "lib_setuptools") - self.output.info("Testing module (spam) using setup.py built module") - self._test_module("spam", True) - - del os.environ["PYTHONPATH"] - - # MSVC builds need PYTHONHOME set. Linux and Mac don't require it to be set if tested after building, - # but if the package is relocated then it needs to be set. - if conan2: - os.environ["PYTHONHOME"] = self.dependencies["cpython"].conf_info.get("user.cpython:pythonhome", check_type=str) - else: - os.environ["PYTHONHOME"] = self.deps_user_info["cpython"].pythonhome - bin_path = os.path.join(self.cpp.build.bindirs[0], "test_package") - self.run(bin_path, env="conanrun") diff --git a/recipes/cpython/all/test_package/py2/test_module.c b/recipes/cpython/all/test_package/py2/test_module.c deleted file mode 100644 index 9c5af39..0000000 --- a/recipes/cpython/all/test_package/py2/test_module.c +++ /dev/null @@ -1,42 +0,0 @@ -#include - -#include - -static PyObject *SpamError; - -static PyObject * -spam_system(PyObject *self, PyObject *args) -{ - const char *command; - int sts; - - if (!PyArg_ParseTuple(args, "s", &command)) - return NULL; - sts = system(command); - if (sts < 0) { - PyErr_SetString(SpamError, "System command failed"); - return NULL; - } - return PyLong_FromLong(sts); -} - -const char spam_doc[] = "This is an example spam doc."; - -static PyMethodDef SpamMethods[] = { - {"system", spam_system, METH_VARARGS, "Execute a shell command."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC -initspam(void) -{ - PyObject *m; - - m = Py_InitModule("spam", SpamMethods); - if (m == NULL) - return; - PyModule_AddStringConstant(m, "__doc__", spam_doc); - SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); -} diff --git a/recipes/cpython/all/test_package/py2/test_package.c b/recipes/cpython/all/test_package/py2/test_package.c deleted file mode 100644 index 5e5d839..0000000 --- a/recipes/cpython/all/test_package/py2/test_package.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -int -main(int argc, char *argv[]) -{ - Py_SetProgramName(argv[0]); /* optional but recommended */ - Py_Initialize(); - PyRun_SimpleString("from time import time,ctime\n" - "print 'Today is',ctime(time())\n"); - Py_Finalize(); - return 0; -} diff --git a/recipes/cpython/all/test_package/py3/test_module.c b/recipes/cpython/all/test_package/py3/test_module.c deleted file mode 100644 index 7372ac3..0000000 --- a/recipes/cpython/all/test_package/py3/test_module.c +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include - -static PyObject *SpamError; - -static PyObject * -spam_system(PyObject *self, PyObject *args) -{ - const char *command; - int sts; - - if (!PyArg_ParseTuple(args, "s", &command)) - return NULL; - sts = system(command); - if (sts < 0) { - PyErr_SetString(SpamError, "System command failed"); - return NULL; - } - return PyLong_FromLong(sts); -} - -const char spam_doc[] = "This is an example spam doc."; - -static PyMethodDef SpamMethods[] = { - {"system", spam_system, METH_VARARGS, "Execute a shell command."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static struct PyModuleDef spammodule = { - PyModuleDef_HEAD_INIT, - "spam", /* name of module */ - spam_doc, /* module documentation, may be NULL */ - -1, /* size of per-interpreter state of the module, - or -1 if the module keeps state in global variables. */ - SpamMethods -}; - -PyMODINIT_FUNC -PyInit_spam(void) -{ - PyObject *m; - - m = PyModule_Create(&spammodule); - if (m == NULL) - return NULL; - - SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); - return m; -} diff --git a/recipes/cpython/all/test_package/py3/test_package.c b/recipes/cpython/all/test_package/py3/test_package.c deleted file mode 100644 index cf1688e..0000000 --- a/recipes/cpython/all/test_package/py3/test_package.c +++ /dev/null @@ -1,20 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include - -int -main(int argc, char *argv[]) -{ - wchar_t *program = Py_DecodeLocale(argv[0], NULL); - if (program == NULL) { - fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); - exit(1); - } - Py_Initialize(); - PyRun_SimpleString("from time import time, ctime\n" - "print('Today is', ctime(time()))\n"); - if (Py_FinalizeEx() < 0) { - exit(120); - } - PyMem_RawFree(program); - return 0; -} diff --git a/recipes/cpython/all/test_package/setup.py b/recipes/cpython/all/test_package/setup.py deleted file mode 100644 index 0f28378..0000000 --- a/recipes/cpython/all/test_package/setup.py +++ /dev/null @@ -1,36 +0,0 @@ -import os -import sys - -# Hack to work around Python 3.8+ secure dll loading: -# see https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew -if hasattr(os, "add_dll_directory"): - for directory in os.environ.get("PATH", "").split(os.pathsep): - if os.path.isdir(directory): - os.add_dll_directory(directory) - -PY2 = sys.version_info[0] == 2 -PY3 = sys.version_info[0] == 3 - -if PY2: - subdir = "py2" - from distutils.core import setup, Extension - use_2to3 = True -elif PY3: - subdir = "py3" - from setuptools import setup, Extension, __version__ as setuptools_version - import pkg_resources - # use_2to3 is deprecated in this version - use_2to3 = pkg_resources.parse_version(setuptools_version) < pkg_resources.parse_version("46.2.0") -else: - raise Exception - -script_dir = os.path.dirname(os.path.realpath(__file__)) - -setup( - name="test_package", - version="1.0", - use_2to3=use_2to3, - ext_modules=[ - Extension("spam", [os.path.join(script_dir, subdir, "test_module.c")]), - ], -) diff --git a/recipes/cpython/all/test_package/test_package.py b/recipes/cpython/all/test_package/test_package.py deleted file mode 100644 index b682818..0000000 --- a/recipes/cpython/all/test_package/test_package.py +++ /dev/null @@ -1,226 +0,0 @@ -import argparse -import os -import sys - -# Hack to work around Python 3.8+ secure dll loading -# See https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew -if hasattr(os, "add_dll_directory"): - for directory in os.environ.get("PATH", "").split(os.pathsep): - if os.path.isdir(directory): - os.add_dll_directory(directory) - -ALL_TESTS = dict() - - -def add_test(fn): - global ALL_TESTS - name = fn.__name__[fn.__name__.find("_") + 1 :] - - def inner_fn(): - print("testing {}".format(name)) - sys.stdout.flush() - fn() - - ALL_TESTS[name] = inner_fn - return fn - - -@add_test -def test_expat(): - import xml.parsers.expat - - # 3 handler functions - def start_element(name, attrs): - print("Start element:", name, attrs) - - def end_element(name): - print("End element:", name) - - def char_data(data): - print("Character data:", repr(data)) - - p = xml.parsers.expat.ParserCreate() - - p.StartElementHandler = start_element - p.EndElementHandler = end_element - p.CharacterDataHandler = char_data - - p.Parse( - """ - Text goes here - More text - """, - 1, - ) - - -@add_test -def test_gdbm(): - if sys.version_info < (3, 0): - import gdbm - else: - import dbm.gnu as gdbm - - dbfile = "gdbm.db" - - db = gdbm.open(dbfile, "c") - db["key1"] = "data1" - db["key2"] = "data2" - db.close() - - db = gdbm.open(dbfile, "r") - print("keys read from", dbfile, "are", db.keys()) - if len(db.keys()) != 2: - raise Exception("Wrong length") - if b"key1" not in db.keys(): - raise Exception("key1 not present") - if b"key2" not in db.keys(): - raise Exception("key2 not present") - - -@add_test -def test_spam(): - import platform - - print("About to import spam") - sys.stdout.flush() - import spam - - if "This is an example spam doc." not in spam.__doc__: - raise Exception("spam.__doc__ does not contain the expected text") - - cmd = {"Windows": "dir"}.get(platform.system(), "ls") - print('About to run spam.system("{}")'.format(cmd)) - sys.stdout.flush() - - spam.system(cmd) - - -@add_test -def test_bz2(): - import bz2 - - compressed = bz2.compress(b"hellow world") - if compressed is None: - raise Exception("bz2.compress returned no data") - - -@add_test -def test_bsddb(): - import bsddb - - db = bsddb.btopen("bsddb.db", "c") - db["key1"] = "value1" - db["key2"] = "value2" - db.close() - - db = bsddb.btopen("bsddb.db", "r") - if len(db) != 2: - raise Exception("Wrong length") - if db["key1"] != "value1": - raise Exception("value1 incorrect {}".format(db["key1"])) - if db["key2"] != "value2": - raise Exception("value2 incorrect {}".format(db["key2"])) - - -@add_test -def test_lzma(): - import lzma - - data = lzma.compress(b"hello world") - if data is None: - raise Exception("lzma.compress returned no data") - - -@add_test -def test_sqlite3(): - import sqlite3 - - conn = sqlite3.connect("sqlite3.db") - - c = conn.cursor() - c.execute("""CREATE TABLE stocks - (date text, trans text, symbol text, qty real, price real)""") - c.execute("INSERT INTO stocks VALUES ('2006-01-05','BUY','RHAT',100,35.14)") - conn.commit() - - t = ("RHAT",) - c.execute("SELECT * FROM stocks WHERE symbol=?", t) - - # Larger example that inserts many records at a time - purchases = [ - ("2006-03-28", "BUY", "IBM", 1000, 45.00), - ("2006-04-05", "BUY", "MSFT", 1000, 72.00), - ("2006-04-06", "SELL", "IBM", 500, 53.00), - ] - c.executemany("INSERT INTO stocks VALUES (?,?,?,?,?)", purchases) - conn.commit() - conn.close() - conn = sqlite3.connect("sqlite3.db") - c = conn.cursor() - c.execute("SELECT * from stocks") - data = c.fetchall() - if len(data) != 4: - raise Exception("Need 4 stocks") - print(data) - conn.close() - # Remove the file so subsequent tests don't fail - os.remove("sqlite3.db") - - -@add_test -def test_decimal(): - if sys.version_info >= (3,): - # Check whether the _decimal package was built successfully - import _decimal as decimal - else: - import decimal - decimal.getcontext().prec = 6 - print("1/7 =", decimal.Decimal(1) / decimal.Decimal(7)) - decimal.getcontext().prec = 40 - print("1/7 =", decimal.Decimal(1) / decimal.Decimal(7)) - - -@add_test -def test_curses(): - import _curses - - print("Using _curses version {}".format(_curses.version)) - - -@add_test -def test_ctypes(): - import _ctypes - - errno = _ctypes.get_errno() - print("errno={}".format(errno)) - - -@add_test -def test_tkinter(): - import _tkinter - - print("tcl version: {}".format(_tkinter.TCL_VERSION)) - print("tk version: {}".format(_tkinter.TK_VERSION)) - - -@add_test -def test_ssl(): - import ssl - - default_context = ssl.create_default_context() - print("default_context.options={}".format(default_context.options)) - - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("-b", dest="build_folder", help="build_folder", required=True) - parser.add_argument("-t", dest="test_module", help="test python module") - ns = parser.parse_args() - - os.chdir(ns.build_folder) - ALL_TESTS[ns.test_module]() - - -if __name__ == "__main__": - main() diff --git a/recipes/cpython/all/test_v1_package/CMakeLists.txt b/recipes/cpython/all/test_v1_package/CMakeLists.txt deleted file mode 100644 index 5253293..0000000 --- a/recipes/cpython/all/test_v1_package/CMakeLists.txt +++ /dev/null @@ -1,100 +0,0 @@ -cmake_minimum_required(VERSION 3.1) -project(test_package C) - -include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") -conan_basic_setup() - -set(CACHE PY_VERSION_MAJOR "" CACHE STRING "MAJOR version of python") -set(CACHE PY_VERSION_MAJOR_MINOR "" CACHE STRING "MAJOR.MINOR version of python") -set(CACHE PY_VERSION "" CACHE STRING "Required version of python") -set(CACHE PY_VERSION_SUFFIX "" CACHE STRING "Suffix of python") - -set(Python_ADDITIONAL_VERSIONS ${PY_VERSION}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR_MINOR}${PY_VERSION_SUFFIX} ${PY_VERSION_MAJOR}${PY_VERSION_SUFFIX} ${PY_VERSION} ${PY_VERSION_MAJOR_MINOR} ${PY_VERSION_MAJOR}) -message("Using Python_ADDITIONAL_VERSIONS: ${Python_ADDITIONAL_VERSIONS}") - -find_package(PythonInterp REQUIRED) -find_package(PythonLibs REQUIRED) - -string(FIND "${PYTHON_EXECUTABLE}" "${CONAN_CPYTHON_ROOT}" ROOT_SUBPOS) -if(ROOT_SUBPOS EQUAL -1) - message(FATAL_ERROR "found wrong python interpreter: ${PYTHON_EXECUTABLE}") -endif() - -message(STATUS "FindPythonInterp:") -message(STATUS "PYTHON_VERSION_STRING: ${PYTHON_VERSION_STRING}") -message(STATUS "PYTHON_VERSION_MAJOR: ${PYTHON_VERSION_MAJOR}") -message(STATUS "PYTHON_VERSION_MINOR: ${PYTHON_VERSION_MINOR}") -message(STATUS "PYTHON_VERSION_PATCH: ${PYTHON_VERSION_PATCH}") -message(STATUS "=============================================") -message(STATUS "FindPythonLibs:") -message(STATUS "PYTHON_LIBRARIES: ${PYTHON_LIBRARIES}") -message(STATUS "PYTHON_INCLUDE_PATH: ${PYTHON_INCLUDE_PATH} (deprecated)") -message(STATUS "PYTHON_INCLUDE_DIRS: ${PYTHON_INCLUDE_DIRS}") -message(STATUS "PYTHON_DEBUG_LIBRARIES: ${PYTHON_DEBUG_LIBRARIES} (deprecated)") -message(STATUS "PYTHONLIBS_VERSION_STRING: ${PYTHONLIBS_VERSION_STRING}") - -if(NOT PYTHON_VERSION_STRING AND NOT PYTHONLIBS_VERSION_STRING) - message(FATAL_ERROR "Version of python interpreter and libraries not found") -endif() - -if(PYTHON_VERSION_STRING) - if(NOT PYTHON_VERSION_STRING VERSION_EQUAL "${PY_VERSION}") - message("PYTHON_VERSION_STRING does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() -endif() - -if(PYTHONLIBS_VERSION_STRING) - if(NOT PYTHONLIBS_VERSION_STRING STREQUAL "${PY_FULL_VERSION}") - message("PYTHONLIBS_VERSION_STRING does not match PY_FULL_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() -endif() - -option(BUILD_MODULE "Build python module") - -if(BUILD_MODULE) - add_library(spam MODULE "py${PY_VERSION_MAJOR}/test_module.c") - target_include_directories(spam - PRIVATE - ${PYTHON_INCLUDE_DIRS} - ) - target_link_libraries(spam PRIVATE - ${PYTHON_LIBRARIES} - ) - set_property(TARGET spam PROPERTY PREFIX "") - if(MSVC) - if(CONAN_SETTINGS_BUILD_TYPE STREQUAL "Debug") - set(SUFFIX "_d.pyd") - else() - set(SUFFIX ".pyd") - endif() - set_property(TARGET spam PROPERTY SUFFIX "${SUFFIX}") - endif() - - option(USE_FINDPYTHON_X "Use new-style FindPythonX module") - if(USE_FINDPYTHON_X AND NOT (CMAKE_VERSION VERSION_LESS "3.16")) - # Require CMake 3.16 because this version introduces Python${PY_VERSION_MAJOR}_FIND_ABI - find_package(Python${PY_VERSION_MAJOR} REQUIRED COMPONENTS Interpreter Development) - message("Python${PY_VERSION_MAJOR}_EXECUTABLE: ${Python${PY_VERSION_MAJOR}_EXECUTABLE}") - message("Python${PY_VERSION_MAJOR}_INTERPRETER_ID: ${Python${PY_VERSION_MAJOR}_INTERPRETER_ID}") - message("Python${PY_VERSION_MAJOR}_VERSION: ${Python${PY_VERSION_MAJOR}_VERSION}") - message("Python${PY_VERSION_MAJOR}_INCLUDE_DIRS: ${Python${PY_VERSION_MAJOR}_INCLUDE_DIRS}") - message("Python${PY_VERSION_MAJOR}_LIBRARIES: ${Python${PY_VERSION_MAJOR}_LIBRARIES}") - if(NOT Python${PY_VERSION_MAJOR}_VERSION STREQUAL "${PY_VERSION}") - message("Python_ADDITIONAL_VERSIONS does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() - - if(PY_VERSION_MAJOR STREQUAL "2") - python2_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") - elseif(PY_VERSION_MAJOR STREQUAL "3") - python3_add_library(spam2 "py${PY_VERSION_MAJOR}/test_module.c") - else() - message(FATAL_ERROR "Unknown PY_VERSION_MAJOR") - endif() - endif() -endif() - -add_executable(${PROJECT_NAME} "py${PY_VERSION_MAJOR}/test_package.c") -target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS}) diff --git a/recipes/cpython/all/test_v1_package/conanfile.py b/recipes/cpython/all/test_v1_package/conanfile.py deleted file mode 100644 index eecbd54..0000000 --- a/recipes/cpython/all/test_v1_package/conanfile.py +++ /dev/null @@ -1,212 +0,0 @@ -from conans import AutoToolsBuildEnvironment, ConanFile, CMake, tools, RunEnvironment -from conans.errors import ConanException -from conan.tools.env import VirtualRunEnv -from io import StringIO -import os -import re -import shutil - - -class CmakePython3Abi(object): - def __init__(self, debug, pymalloc, unicode): - self.debug, self.pymalloc, self.unicode = debug, pymalloc, unicode - - _cmake_lut = { - None: "ANY", - True: "ON", - False: "OFF", - } - - @property - def suffix(self): - return "{}{}{}".format( - "d" if self.debug else "", - "m" if self.pymalloc else "", - "u" if self.unicode else "", - ) - - @property - def cmake_arg(self): - return ";".join(self._cmake_lut[a] for a in (self.debug, self.pymalloc, self.unicode)) - - -class TestPackageConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake" - - @property - def _py_version(self): - return re.match(r"^([0-9.]+)", self.deps_cpp_info["cpython"].version).group(1) - - @property - def _test_setuptools(self): - # TODO Should we still try to test this? - # https://github.com/python/cpython/pull/101039 - return not tools.cross_building(self, skip_x64_x86=True) and self._supports_modules and self._py_version < tools.Version("3.12") - - @property - def _pymalloc(self): - return bool("pymalloc" in self.options["cpython"] and self.options["cpython"].pymalloc) - - @property - def _cmake_abi(self): - if self._py_version < tools.Version("3.8"): - return CmakePython3Abi( - debug=self.settings.build_type == "Debug", - pymalloc=self._pymalloc, - unicode=False, - ) - else: - return CmakePython3Abi( - debug=self.settings.build_type == "Debug", - pymalloc=False, - unicode=False, - ) - - @property - def _cmake_try_FindPythonX(self): - if self.settings.compiler == "Visual Studio" and self.settings.build_type == "Debug": - return False - return True - - @property - def _supports_modules(self): - return self.settings.compiler != "Visual Studio" or self.options["cpython"].shared - - def generate(self): - # The build also needs access to the run environment to run the python executable - VirtualRunEnv(self).generate(scope="run") - VirtualRunEnv(self).generate(scope="build") - - def build_requirements(self): - # The main recipe does not require CMake, but we test with it. - # The interesting problem that arises here is if you have CMake installed - # with your global pip, then it will fail to run in this test package. - # To avoid that, just add a requirement on CMake. - self.tool_requires("cmake/[>=3.15 <4]") - - def build(self): - if not tools.cross_building(self, skip_x64_x86=True): - command = "{} --version".format(self.deps_user_info["cpython"].python) - buffer = StringIO() - self.run(command, output=buffer, ignore_errors=True, run_environment=True) - self.output.info("output: %s" % buffer.getvalue()) - self.run(command, run_environment=True) - - cmake = CMake(self) - py_major = self.deps_cpp_info["cpython"].version.split(".")[0] - cmake.definitions["BUILD_MODULE"] = self._supports_modules - cmake.definitions["PY_VERSION_MAJOR"] = py_major - cmake.definitions["PY_VERSION_MAJOR_MINOR"] = ".".join(self._py_version.split(".")[:2]) - cmake.definitions["PY_FULL_VERSION"] = self.deps_cpp_info["cpython"].version - cmake.definitions["PY_VERSION"] = self._py_version - cmake.definitions["PY_VERSION_SUFFIX"] = self._cmake_abi.suffix - cmake.definitions["PYTHON_EXECUTABLE"] = self.deps_user_info["cpython"].python - cmake.definitions["USE_FINDPYTHON_X".format(py_major)] = self._cmake_try_FindPythonX - cmake.definitions["Python{}_EXECUTABLE".format(py_major)] = self.deps_user_info["cpython"].python - cmake.definitions["Python{}_ROOT_DIR".format(py_major)] = self.deps_cpp_info["cpython"].rootpath - cmake.definitions["Python{}_USE_STATIC_LIBS".format(py_major)] = not self.options["cpython"].shared - cmake.definitions["Python{}_FIND_FRAMEWORK".format(py_major)] = "NEVER" - cmake.definitions["Python{}_FIND_REGISTRY".format(py_major)] = "NEVER" - cmake.definitions["Python{}_FIND_IMPLEMENTATIONS".format(py_major)] = "CPython" - cmake.definitions["Python{}_FIND_STRATEGY".format(py_major)] = "LOCATION" - - if self.settings.compiler != "Visual Studio": - if tools.Version(self._py_version) < tools.Version("3.8"): - cmake.definitions["Python{}_FIND_ABI".format(py_major)] = self._cmake_abi.cmake_arg - - with tools.environment_append(RunEnvironment(self).vars): - cmake.configure() - cmake.build() - - if self._test_setuptools: - with tools.vcvars(self.settings) if self.settings.compiler == "Visual Studio" else tools.no_op(): - modsrcfolder = "py2" if tools.Version(self.deps_cpp_info["cpython"].version).major < "3" else "py3" - tools.mkdir(os.path.join(self.build_folder, modsrcfolder)) - for fn in os.listdir(os.path.join(self.source_folder, modsrcfolder)): - shutil.copy(os.path.join(self.source_folder, modsrcfolder, fn), os.path.join(self.build_folder, modsrcfolder, fn)) - shutil.copy(os.path.join(self.source_folder, "setup.py"), os.path.join(self.build_folder, "setup.py")) - env = { - "DISTUTILS_USE_SDK": "1", - "MSSdk": "1" - } - env.update(**AutoToolsBuildEnvironment(self).vars) - with tools.environment_append(env): - setup_args = [ - "{}/setup.py".format(self.source_folder), - # "conan", - # "--install-folder", self.build_folder, - "build", - "--build-base", self.build_folder, - "--build-platlib", os.path.join(self.build_folder, "lib_setuptools"), - ] - if self.settings.build_type == "Debug": - setup_args.append("--debug") - self.run("{} {}".format(self.deps_user_info["cpython"].python, " ".join("\"{}\"".format(a) for a in setup_args)), run_environment=True) - - def _test_module(self, module, should_work): - try: - self.run("{} {}/../test_package/test_package.py -b {} -t {} ".format( - self.deps_user_info["cpython"].python, self.source_folder, self.build_folder, module), run_environment=True) - works = True - except ConanException as e: - works = False - exception = e - if should_work == works: - self.output.info("Result of test was expected.") - else: - if works: - raise ConanException("Module '{}' works, but should not have worked".format(module)) - else: - self.output.warn("Module '{}' does not work, but should have worked".format(module)) - raise exception - - def _cpython_option(self, name): - try: - return getattr(self.options["cpython"], name, False) - except ConanException: - return False - - def test(self): - if not tools.cross_building(self, skip_x64_x86=True): - self.run("{} -c \"print('hello world')\"".format(self.deps_user_info["cpython"].python), run_environment=True) - - buffer = StringIO() - self.run("{} -c \"import sys; print('.'.join(str(s) for s in sys.version_info[:3]))\"".format(self.deps_user_info["cpython"].python), run_environment=True, output=buffer) - self.output.info(buffer.getvalue()) - version_detected = buffer.getvalue().splitlines()[-1].strip() - if self._py_version != version_detected: - raise ConanException("python reported wrong version. Expected {exp}. Got {res}.".format(exp=self._py_version, res=version_detected)) - - if self._supports_modules: - self._test_module("gdbm", self._cpython_option("with_gdbm")) - self._test_module("bz2", self._cpython_option("with_bz2")) - self._test_module("bsddb", self._cpython_option("with_bsddb")) - self._test_module("lzma", self._cpython_option("with_lzma")) - self._test_module("tkinter", self._cpython_option("with_tkinter")) - with tools.environment_append({"TERM": "ansi"}): - self._test_module("curses", self._cpython_option("with_curses")) - - self._test_module("expat", True) - self._test_module("sqlite3", True) - self._test_module("decimal", True) - self._test_module("ctypes", True) - - if tools.is_apple_os(self.settings.os) and not self.options["cpython"].shared: - self.output.info("Not testing the module, because these seem not to work on apple when cpython is built as a static library") - # FIXME: find out why cpython on apple does not allow to use modules linked against a static python - else: - if self._supports_modules: - with tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib")]}): - self.output.info("Testing module (spam) using cmake built module") - self._test_module("spam", True) - - if self._test_setuptools: - with tools.environment_append({"PYTHONPATH": [os.path.join(self.build_folder, "lib_setuptools")]}): - self.output.info("Testing module (spam) using setup.py built module") - self._test_module("spam", True) - - # MSVC builds need PYTHONHOME set. Linux and Mac don't require it to be set if tested after building, - # but if the package is relocated then it needs to be set. - with tools.environment_append({"PYTHONHOME": self.deps_user_info["cpython"].pythonhome}): - self.run(os.path.join("bin", "test_package"), run_environment=True) diff --git a/recipes/cpython/all/test_v1_package/py2/test_module.c b/recipes/cpython/all/test_v1_package/py2/test_module.c deleted file mode 100644 index 9c5af39..0000000 --- a/recipes/cpython/all/test_v1_package/py2/test_module.c +++ /dev/null @@ -1,42 +0,0 @@ -#include - -#include - -static PyObject *SpamError; - -static PyObject * -spam_system(PyObject *self, PyObject *args) -{ - const char *command; - int sts; - - if (!PyArg_ParseTuple(args, "s", &command)) - return NULL; - sts = system(command); - if (sts < 0) { - PyErr_SetString(SpamError, "System command failed"); - return NULL; - } - return PyLong_FromLong(sts); -} - -const char spam_doc[] = "This is an example spam doc."; - -static PyMethodDef SpamMethods[] = { - {"system", spam_system, METH_VARARGS, "Execute a shell command."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -PyMODINIT_FUNC -initspam(void) -{ - PyObject *m; - - m = Py_InitModule("spam", SpamMethods); - if (m == NULL) - return; - PyModule_AddStringConstant(m, "__doc__", spam_doc); - SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); -} diff --git a/recipes/cpython/all/test_v1_package/py2/test_package.c b/recipes/cpython/all/test_v1_package/py2/test_package.c deleted file mode 100644 index 5e5d839..0000000 --- a/recipes/cpython/all/test_v1_package/py2/test_package.c +++ /dev/null @@ -1,12 +0,0 @@ -#include - -int -main(int argc, char *argv[]) -{ - Py_SetProgramName(argv[0]); /* optional but recommended */ - Py_Initialize(); - PyRun_SimpleString("from time import time,ctime\n" - "print 'Today is',ctime(time())\n"); - Py_Finalize(); - return 0; -} diff --git a/recipes/cpython/all/test_v1_package/py3/test_module.c b/recipes/cpython/all/test_v1_package/py3/test_module.c deleted file mode 100644 index 7372ac3..0000000 --- a/recipes/cpython/all/test_v1_package/py3/test_module.c +++ /dev/null @@ -1,52 +0,0 @@ -#include - -#include - -static PyObject *SpamError; - -static PyObject * -spam_system(PyObject *self, PyObject *args) -{ - const char *command; - int sts; - - if (!PyArg_ParseTuple(args, "s", &command)) - return NULL; - sts = system(command); - if (sts < 0) { - PyErr_SetString(SpamError, "System command failed"); - return NULL; - } - return PyLong_FromLong(sts); -} - -const char spam_doc[] = "This is an example spam doc."; - -static PyMethodDef SpamMethods[] = { - {"system", spam_system, METH_VARARGS, "Execute a shell command."}, - {NULL, NULL, 0, NULL} /* Sentinel */ -}; - -static struct PyModuleDef spammodule = { - PyModuleDef_HEAD_INIT, - "spam", /* name of module */ - spam_doc, /* module documentation, may be NULL */ - -1, /* size of per-interpreter state of the module, - or -1 if the module keeps state in global variables. */ - SpamMethods -}; - -PyMODINIT_FUNC -PyInit_spam(void) -{ - PyObject *m; - - m = PyModule_Create(&spammodule); - if (m == NULL) - return NULL; - - SpamError = PyErr_NewException("spam.error", NULL, NULL); - Py_INCREF(SpamError); - PyModule_AddObject(m, "error", SpamError); - return m; -} diff --git a/recipes/cpython/all/test_v1_package/py3/test_package.c b/recipes/cpython/all/test_v1_package/py3/test_package.c deleted file mode 100644 index cf1688e..0000000 --- a/recipes/cpython/all/test_v1_package/py3/test_package.c +++ /dev/null @@ -1,20 +0,0 @@ -#define PY_SSIZE_T_CLEAN -#include - -int -main(int argc, char *argv[]) -{ - wchar_t *program = Py_DecodeLocale(argv[0], NULL); - if (program == NULL) { - fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); - exit(1); - } - Py_Initialize(); - PyRun_SimpleString("from time import time, ctime\n" - "print('Today is', ctime(time()))\n"); - if (Py_FinalizeEx() < 0) { - exit(120); - } - PyMem_RawFree(program); - return 0; -} diff --git a/recipes/cpython/all/test_v1_package/setup.py b/recipes/cpython/all/test_v1_package/setup.py deleted file mode 100644 index 526a552..0000000 --- a/recipes/cpython/all/test_v1_package/setup.py +++ /dev/null @@ -1,35 +0,0 @@ -import os -import sys - -# Hack to work around Python 3.8+ secure dll loading: -# see https://docs.python.org/3/whatsnew/3.8.html#bpo-36085-whatsnew -if hasattr(os, "add_dll_directory"): - for directory in os.environ.get("PATH", "").split(os.pathsep): - if os.path.isdir(directory): - os.add_dll_directory(directory) - -PY2 = (2, 0) <= sys.version_info < (3, 0) -PY3 = (3, 0) <= sys.version_info < (4, 0) - -if PY2: - subdir = "py2" - from distutils.core import setup, Extension - use_2to3 = True -elif PY3: - subdir = "py3" - from setuptools import setup, Extension, __version__ as setuptools_version - import pkg_resources - # use_2to3 is deprecated in this version - use_2to3 = pkg_resources.parse_version(setuptools_version) < pkg_resources.parse_version("46.2.0") -else: - raise Exception - - -setup( - name="test_package", - version="1.0", - use_2to3=use_2to3, - ext_modules=[ - Extension("spam", [os.path.join(subdir, "test_module.c")]), - ], -) diff --git a/recipes/cpython/config.yml b/recipes/cpython/config.yml deleted file mode 100644 index 0e2ea8a..0000000 --- a/recipes/cpython/config.yml +++ /dev/null @@ -1,5 +0,0 @@ -versions: - "3.12.2": - folder: "all" - "3.10.13": - folder: "all" \ No newline at end of file From 768c30aa949078a6076d27d300214dc7cadf60ce Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 13:49:26 +0100 Subject: [PATCH 12/39] Make common Sentry recipe truely generic --- recipes/clipper/all/conanfile.py | 3 ++- recipes/sentrylibrary/all/conanfile.py | 34 ++++++++++++++------------ 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index 7636473..6f65c40 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -18,6 +18,7 @@ class ClipperConan(ConanFile): url = "https://github.com/conan-io/conan-center-index" homepage = "http://www.angusj.com/delphi/clipper.php" settings = "os", "arch", "compiler", "build_type" + package_type = "library" python_requires = "sentrylibrary/1.0@ultimaker/cura_11622" # FIXME: use main after merge python_requires_extend = "sentrylibrary.SentryLibrary" @@ -70,7 +71,7 @@ def build(self): cmake.configure(build_script_folder=os.path.join(self.source_folder, "cpp")) cmake.build() - self.send_sentry_debug_files() + self.send_sentry_debug_files(binary_basename = "libpolyclipping") def package(self): copy(self, "License.txt", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 1cfab3d..543d99a 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -10,10 +10,12 @@ class SentryLibrary: options = { "enable_sentry": [True, False], + "sentry_create_release": [True, False], "sentry_project": ["ANY"], } default_options = { "enable_sentry": False, + "sentry_create_release": False, "sentry_project": "", } @@ -43,7 +45,7 @@ def setup_cmake_toolchain_sentry(self, cmake_toolchain): cmake_toolchain.variables["ENABLE_SENTRY"] = self.options.enable_sentry cmake_toolchain.variables["SENTRY_URL"] = self.conf.get("user.sentry:url", "", check_type=str) - def send_sentry_debug_files(self): + def send_sentry_debug_files(self, binary_basename): ''' Method to be called by actual packages at build() time, after the actual build has been done, to send the binary files to sentry ''' @@ -55,28 +57,30 @@ def send_sentry_debug_files(self): if which("sentry-cli") is None: raise ConanException("sentry-cli is not installed, unable to upload debug symbols") + if self.package_type == "application": + binary_name = binary_basename + else: + binary_name = binary_basename + ('.so' if self.options.get_safe("shared", True) else '.a') + if self.settings.os == "Linux": self.output.info("Stripping debug symbols from binary") - self.run("objcopy --only-keep-debug --compress-debug-sections=zlib CuraEngine CuraEngine.debug") - self.run("objcopy --strip-debug --strip-unneeded CuraEngine") - self.run("objcopy --add-gnu-debuglink=CuraEngine.debug CuraEngine") + self.run(f"objcopy --only-keep-debug --compress-debug-sections=zlib {binary_name} {binary_name}.debug") + self.run(f"objcopy --strip-debug --strip-unneeded {binary_name}") + self.run(f"objcopy --add-gnu-debuglink={binary_name}.debug {binary_name}") elif self.settings.os == "Macos": - self.run("dsymutil CuraEngine") + self.run(f"dsymutil {binary_name}") self.output.info("Uploading debug symbols to sentry") - build_source_dir = self.build_path.parent.parent.as_posix() + build_source_dir = self.build_folder.parent.parent.as_posix() self.run( f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") - # create a sentry release and link it to the commit this is based upon - self.output.info( - f"Creating a new release {self.version} in Sentry and linking it to the current commit {self.conan_data['commit']}") - self.run( - f"sentry-cli --auth-token {sentry_token} releases new -o {sentry_organization} -p {sentry_project} {self.version}") - self.run( - f"sentry-cli --auth-token {sentry_token} releases set-commits -o {sentry_organization} -p {sentry_project} --commit \"Ultimaker/CuraEngine@{self.conan_data['commit']}\" {self.version}") - self.run( - f"sentry-cli --auth-token {sentry_token} releases finalize -o {sentry_organization} -p {sentry_project} {self.version}") + if self.sentry_create_release: + # create a sentry release and link it to the commit this is based upon + self.output.info(f"Creating a new release {self.version} in Sentry and linking it to the current commit {self.conan_data['commit']}") + self.run(f"sentry-cli --auth-token {sentry_token} releases new -o {sentry_organization} -p {sentry_project} {self.version}") + self.run(f"sentry-cli --auth-token {sentry_token} releases set-commits -o {sentry_organization} -p {sentry_project} --commit \"Ultimaker/CuraEngine@{self.conan_data['commit']}\" {self.version}") + self.run(f"sentry-cli --auth-token {sentry_token} releases finalize -o {sentry_organization} -p {sentry_project} {self.version}") class PyReq(ConanFile): From b33fa31f45875be57196adc1e2f5390f094d09c4 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:09:08 +0100 Subject: [PATCH 13/39] Fix conan export repository --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 73f04ab..5c45c61 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -33,4 +33,4 @@ jobs: - name: Export changed recipes run: | - python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2-dev ${{ env.GIT_DIFF_FILTERED }} + python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ env.GIT_DIFF_FILTERED }} From 3de1efb429558c8136c634227308322a60a89d28 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:38:55 +0100 Subject: [PATCH 14/39] Make package export workflow manually runnable --- .github/workflows/conan-package.yml | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 5c45c61..f5ddba2 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -10,6 +10,14 @@ on: - 'PP-*' - 'NP-*' + workflow_call: + inputs: + recipes: + description: 'Path to the recipes to be exported, e.g. "recipes/clipper/all/conanfile.py recipes/sentrylibrary/all/conanfile.py". Leave empty to export all the recipes.' + default: '' + required: true + type: string + permissions: contents: read @@ -27,10 +35,26 @@ jobs: conan_password: ${{ secrets.CONAN_PASS }} - uses: technote-space/get-diff-action@v6 + id: get-diff + if: ${{ github.event_name == 'push' }} with: PATTERNS: | recipes/**/*.* + - name: Get recipes list + id: get-recipes-list + run: | + if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then + recipes_list="${{ inputs.recipes }}" + if [ -z "$recipes_list" ]; then + recipes_list = $(find . -maxdepth 4 -iname "conanfile.py") + fi + else + echo recipes_list="${{ env.GIT_DIFF_FILTERED }}" + fi + + echo "recipes_list=$recipes_list" >> $GITHUB_ENV + - name: Export changed recipes run: | - python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ env.GIT_DIFF_FILTERED }} + python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ steps.get-recipes-list.recipes_list }} From 2c2fe101ea2692078b24b4c3fa4a5630d6f343ab Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:51:18 +0100 Subject: [PATCH 15/39] Fix build folder not being a Path anymore --- recipes/sentrylibrary/all/conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 543d99a..ec7c76f 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -1,5 +1,6 @@ from conan import ConanFile +from pathlib import Path from shutil import which from conan.errors import ConanInvalidConfiguration, ConanException @@ -71,7 +72,7 @@ def send_sentry_debug_files(self, binary_basename): self.run(f"dsymutil {binary_name}") self.output.info("Uploading debug symbols to sentry") - build_source_dir = self.build_folder.parent.parent.as_posix() + build_source_dir = Path(self.build_folder).parent.parent.as_posix() self.run( f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") From d5556345c73f1ba4d2c751e79762f82ba92517a1 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:53:30 +0100 Subject: [PATCH 16/39] Fix recipes list not being retrieved --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index f5ddba2..85a9332 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -57,4 +57,4 @@ jobs: - name: Export changed recipes run: | - python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ steps.get-recipes-list.recipes_list }} + python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ steps.get-recipes-list.outputs.recipes_list }} From fb0c1654ec4457032c02b49278f0c32408c27d40 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:55:49 +0100 Subject: [PATCH 17/39] Re-export all recipes when workflow has changed --- .github/workflows/conan-package.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 85a9332..8c4e442 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -4,6 +4,7 @@ on: push: paths: - 'recipes/**' + - '.github/workflows/conan-package.yml' branches: - main - 'CURA-*' @@ -46,13 +47,14 @@ jobs: run: | if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then recipes_list="${{ inputs.recipes }}" - if [ -z "$recipes_list" ]; then - recipes_list = $(find . -maxdepth 4 -iname "conanfile.py") - fi else echo recipes_list="${{ env.GIT_DIFF_FILTERED }}" fi + if [ -z "$recipes_list" ]; then + recipes_list = $(find . -maxdepth 4 -iname "conanfile.py") + fi + echo "recipes_list=$recipes_list" >> $GITHUB_ENV - name: Export changed recipes From 1cf8effebffc7576b486d486976a22de429a41b3 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:57:13 +0100 Subject: [PATCH 18/39] Fix script syntax --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 8c4e442..4187b6e 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -48,7 +48,7 @@ jobs: if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then recipes_list="${{ inputs.recipes }}" else - echo recipes_list="${{ env.GIT_DIFF_FILTERED }}" + recipes_list="${{ env.GIT_DIFF_FILTERED }}" fi if [ -z "$recipes_list" ]; then From 6ffa620306b7f922c5d8c9ad86ae5aa0de67417b Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 14:58:46 +0100 Subject: [PATCH 19/39] Fix script syntax --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 4187b6e..dcf722c 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -52,7 +52,7 @@ jobs: fi if [ -z "$recipes_list" ]; then - recipes_list = $(find . -maxdepth 4 -iname "conanfile.py") + recipes_list=$(find . -maxdepth 4 -iname "conanfile.py") fi echo "recipes_list=$recipes_list" >> $GITHUB_ENV From d70ca1eeb5d7be73fe97b395a57723b9f0464970 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:00:04 +0100 Subject: [PATCH 20/39] Export variable to output instead of env --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index dcf722c..65bc3d7 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -55,7 +55,7 @@ jobs: recipes_list=$(find . -maxdepth 4 -iname "conanfile.py") fi - echo "recipes_list=$recipes_list" >> $GITHUB_ENV + echo "recipes_list=$recipes_list" >> $GITHUB_OUTPUT - name: Export changed recipes run: | From 6171fcb60d5d9f47c67dd3bd25b355ea59c1bbbb Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:05:29 +0100 Subject: [PATCH 21/39] Make a space separated list of recipes --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 65bc3d7..289794f 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -52,7 +52,7 @@ jobs: fi if [ -z "$recipes_list" ]; then - recipes_list=$(find . -maxdepth 4 -iname "conanfile.py") + recipes_list=$(find . -mindepth 4 -maxdepth 4 -iname "conanfile.py" -print0 | xargs -0 echo) fi echo "recipes_list=$recipes_list" >> $GITHUB_OUTPUT From 2ab833b270f5cf1941e304fdc0290ab8df569eff Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:28:21 +0100 Subject: [PATCH 22/39] Remove unused umbase package --- .../umbase/all/StandardProjectSettings.cmake | 197 ------------------ recipes/umbase/all/conanfile.py | 170 --------------- recipes/umbase/config.yml | 3 - 3 files changed, 370 deletions(-) delete mode 100644 recipes/umbase/all/StandardProjectSettings.cmake delete mode 100644 recipes/umbase/all/conanfile.py delete mode 100644 recipes/umbase/config.yml diff --git a/recipes/umbase/all/StandardProjectSettings.cmake b/recipes/umbase/all/StandardProjectSettings.cmake deleted file mode 100644 index 1cb2cc7..0000000 --- a/recipes/umbase/all/StandardProjectSettings.cmake +++ /dev/null @@ -1,197 +0,0 @@ -include(GNUInstallDirs) # Standard install dirs - -# Ultimaker uniform Thread linking method -function(use_threads project_name) - message(STATUS "Enabling threading support for ${project_name}") - set(CMAKE_THREAD_PREFER_PTHREAD TRUE) - set(THREADS_PREFER_PTHREAD_FLAG TRUE) - find_package(Threads) - get_target_property(type ${project_name} TYPE) - if (${type} STREQUAL "INTERFACE_LIBRARY") - target_link_libraries(${project_name} INTERFACE Threads::Threads) - else() - target_link_libraries(${project_name} PRIVATE Threads::Threads) - endif() -endfunction() - -# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md -function(set_project_warnings project_name) - message(STATUS "Setting warnings for ${project_name}") - set(MSVC_WARNINGS - /W4 # Baseline reasonable warnings - /w14242 # 'identifier': conversion from 'type1' to 'type1', possible loss of data - /w14254 # 'operator': conversion from 'type1:field_bits' to 'type2:field_bits', possible loss of data - /w14263 # 'function': member function does not override any base class virtual member function - /w14265 # 'classname': class has virtual functions, but destructor is not virtual instances of this class may not - # be destructed correctly - /w14287 # 'operator': unsigned/negative constant mismatch - /we4289 # nonstandard extension used: 'variable': loop control variable declared in the for-loop is used outside - # the for-loop scope - /w14296 # 'operator': expression is always 'boolean_value' - /w14311 # 'variable': pointer truncation from 'type1' to 'type2' - /w14545 # expression before comma evaluates to a function which is missing an argument list - /w14546 # function call before comma missing argument list - /w14547 # 'operator': operator before comma has no effect; expected operator with side-effect - /w14549 # 'operator': operator before comma has no effect; did you intend 'operator'? - /w14555 # expression has no effect; expected expression with side- effect - /w14619 # pragma warning: there is no warning number 'number' - /w14640 # Enable warning on thread un-safe static member initialization - /w14826 # Conversion from 'type1' to 'type_2' is sign-extended. This may cause unexpected runtime behavior. - /w14905 # wide string literal cast to 'LPSTR' - /w14906 # string literal cast to 'LPWSTR' - /w14928 # illegal copy-initialization; more than one user-defined conversion has been implicitly applied - /permissive- # standards conformance mode for MSVC compiler. - ) - - set(CLANG_WARNINGS - -Wall - -Wextra # reasonable and standard - -Wshadow # warn the user if a variable declaration shadows one from a parent context - -Wnon-virtual-dtor # warn the user if a class with virtual functions has a non-virtual destructor. This helps - # catch hard to track down memory errors - -Wold-style-cast # warn for c-style casts - -Wcast-align # warn for potential performance problem casts - -Wunused # warn on anything being unused - -Woverloaded-virtual # warn if you overload (not override) a virtual function - -Wpedantic # warn if non-standard C++ is used - -Wconversion # warn on type conversions that may lose data - -Wsign-conversion # warn on sign conversions - -Wnull-dereference # warn if a null dereference is detected - -Wdouble-promotion # warn if float is implicit promoted to double - -Wformat=2 # warn on security issues around functions that format output (ie printf) - ) - - set(GCC_WARNINGS - ${CLANG_WARNINGS} - -Wmisleading-indentation # warn if indentation implies blocks where blocks do not exist - -Wduplicated-cond # warn if if / else chain has duplicated conditions - -Wduplicated-branches # warn if if / else branches have duplicated code - -Wlogical-op # warn about logical operations being used where bitwise were probably wanted - -Wuseless-cast # warn if you perform a cast to the same type - ) - - if(MSVC) - set(PROJECT_WARNINGS ${MSVC_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - set(PROJECT_WARNINGS ${CLANG_WARNINGS}) - elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - set(PROJECT_WARNINGS ${GCC_WARNINGS}) - else() - message(AUTHOR_WARNING "No compiler warnings set for '${CMAKE_CXX_COMPILER_ID}' compiler.") - endif() - - get_target_property(type ${project_name} TYPE) - if (${type} STREQUAL "INTERFACE_LIBRARY") - target_compile_options(${project_name} INTERFACE ${PROJECT_WARNINGS}) - else() - target_compile_options(${project_name} PRIVATE ${PROJECT_WARNINGS}) - endif() -endfunction() - -function(enable_sanitizers project_name) - - if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - option(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE) - - if(ENABLE_COVERAGE) - target_compile_options(${project_name} INTERFACE --coverage -O0 -g) - target_link_libraries(${project_name} INTERFACE --coverage) - endif() - - set(SANITIZERS "") - - option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE) - if(ENABLE_SANITIZER_ADDRESS) - list(APPEND SANITIZERS "address") - endif() - - option(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE) - if(ENABLE_SANITIZER_LEAK) - list(APPEND SANITIZERS "leak") - endif() - - option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE) - if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR) - list(APPEND SANITIZERS "undefined") - endif() - - option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE) - if(ENABLE_SANITIZER_THREAD) - if("address" IN_LIST SANITIZERS OR "leak" IN_LIST SANITIZERS) - message(WARNING "Thread sanitizer does not work with Address and Leak sanitizer enabled") - else() - list(APPEND SANITIZERS "thread") - endif() - endif() - - option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE) - if(ENABLE_SANITIZER_MEMORY AND CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") - if("address" IN_LIST SANITIZERS - OR "thread" IN_LIST SANITIZERS - OR "leak" IN_LIST SANITIZERS) - message(WARNING "Memory sanitizer does not work with Address, Thread and Leak sanitizer enabled") - else() - list(APPEND SANITIZERS "memory") - endif() - endif() - - list( - JOIN - SANITIZERS - "," - LIST_OF_SANITIZERS) - - endif() - - if(LIST_OF_SANITIZERS) - if(NOT - "${LIST_OF_SANITIZERS}" - STREQUAL - "") - target_compile_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - target_link_options(${project_name} INTERFACE -fsanitize=${LIST_OF_SANITIZERS}) - endif() - endif() - -endfunction() - -option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF) -option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF) -option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF) - -if(ENABLE_CPPCHECK) - find_program(CPPCHECK cppcheck) - if(CPPCHECK) - message(STATUS "Using cppcheck") - set(CMAKE_CXX_CPPCHECK - ${CPPCHECK} - --suppress=missingInclude - --enable=all - --inline-suppr - --inconclusive - -i - ${CMAKE_SOURCE_DIR}/imgui/lib) - else() - message(WARNING "cppcheck requested but executable not found") - endif() -endif() - -if(ENABLE_CLANG_TIDY) - find_program(CLANGTIDY clang-tidy) - if(CLANGTIDY) - message(STATUS "Using clang-tidy") - set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} -extra-arg=-Wno-unknown-warning-option) - else() - message(WARNING "clang-tidy requested but executable not found") - endif() -endif() - -if(ENABLE_INCLUDE_WHAT_YOU_USE) - find_program(INCLUDE_WHAT_YOU_USE include-what-you-use) - if(INCLUDE_WHAT_YOU_USE) - message(STATUS "Using include-what-you-use") - set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE ${INCLUDE_WHAT_YOU_USE}) - else() - message(WARNING "include-what-you-use requested but executable not found") - endif() -endif() diff --git a/recipes/umbase/all/conanfile.py b/recipes/umbase/all/conanfile.py deleted file mode 100644 index a16f8a7..0000000 --- a/recipes/umbase/all/conanfile.py +++ /dev/null @@ -1,170 +0,0 @@ -import sys -import os - -from io import StringIO -from pathlib import Path -from typing import Optional - -from conans import ConanFile, tools -from conans.errors import ConanException - - -class UMBaseConanfile(object): - """ - Ultimaker base conanfile, for reusing Python code in our repositories - https://docs.conan.io/en/latest/extending/python_requires.html - """ - - def _um_data(self) -> dict: - """ - Extract the version specific data out of a conandata.yml - """ - try: - recipe_version = self.version - except ConanException: - recipe_version = "None" - - try: - channel = self.channel - except ConanException: - channel = "" - - if channel: - - if channel == "testing": - self.output.info(f"Using conandata.yml from channel: {channel}") - return self.conan_data["None"] - - elif channel == "stable" or channel == "_" or channel == "": - if recipe_version: - if recipe_version in self.conan_data: - self.output.info(f"Using conandata.yml from channel: {channel} and recipe version: {recipe_version}") - return self.conan_data[recipe_version] - - recipe_version = tools.Version(recipe_version) - all_versions = [] - for k in self.conan_data: - try: - v = tools.Version(k) - except ConanException: - continue - all_versions.append(v) - - # First try to find a version which might take into account prereleases - satifying_versions = sorted([v for v in all_versions if v <= recipe_version]) - if len(satifying_versions) == 0: - # Then try to find a version which only takes into account major.minor.patch - satifying_versions = sorted([v for v in all_versions if tools.Version(f"{v.major}.{v.minor}.{v.patch}") <= tools.Version(f"{recipe_version.major}.{recipe_version.minor}.{recipe_version.patch}")]) - if len(satifying_versions) == 0: - self.output.warn(f"Could not find a maximum satisfying version from channel: {channel} for {recipe_version} in {[str(v) for v in all_versions]}, defaulting to testing channel") - return self.conan_data["None"] - version = str(satifying_versions[-1]) - self.output.info(f"Using conandata.yml from channel: {channel} and recipe version: {version}") - return self.conan_data[version] - - elif channel in self.conan_data: - self.output.info(f"Using conandata.yml from channel: {channel}") - return self.conan_data[channel] - - self.output.info(f"Using conandata.yml defaulting to testing channel") - return self.conan_data["None"] - - @property - def _python_venv_bin_path(self) -> str: - if self.settings.os == "Windows": - return "Scripts" - return "bin" - - @property - def _python_interp(self) -> str: - """ - The Python interpreter to use. If the recipe has `cpython` as a dependency it uses that interpreter otherwise it will use the system - interpreter. Which in this case is the same as the Conan version. - :return: str with the path to the Python interpreter - """ - - if "cpython" in self.deps_user_info: - py_interp = Path(self.deps_user_info["cpython"].python) - else: - py_interp = Path(sys.executable) - - # When on Windows execute as Windows Path - if self.settings.os == "Windows": - py_interp = Path(*[f'"{p}"' if " " in p else p for p in py_interp.parts]) - - return str(py_interp) - - @property - def _py_venv_interp(self) -> str: - if self.__py_venv_interp is not None: - return self.__py_venv_interp - else: - self.output.warn("Virtual Python environment not yet generated, but requesting the path to interpreter") - py_venv_interp = Path(self.install_folder, self._venv_path, Path(sys.executable).stem + Path(sys.executable).suffix) - - if self.settings.os == "Windows": - py_venv_interp = Path(*[f'"{p}"' if " " in p else p for p in py_venv_interp.parts]) - - return str(py_venv_interp) - - @_py_venv_interp.setter - def _py_venv_interp(self, value: str): - self.__py_venv_interp = value - - def _site_packages_path(self, interp: str) -> str: - buffer = StringIO() - outer = '"' if self.settings.os == "Windows" else "'" - inner = "'" if self.settings.os == "Windows" else '"' - self.run(f"{interp} -c {outer}import sysconfig; print(sysconfig.get_path({inner}purelib{inner})){outer}", env = "conanrun", output = buffer) - pythonpath = buffer.getvalue().splitlines()[-1] - return pythonpath - - def _generate_virtual_python_env(self, *initial_reqs): - """ - Generates a virtual Python Environment and initializes is - - TODO: Check if we aren't in an actual virtual Python environment yet. Because running a venv in a venv is asking for troubles - - :param initial_reqs: Python modules which should be installed (strings) - """ - self.output.info("Generating virtual Python environment") - self.run(f"{self._python_interp} -m venv {self.install_folder}", run_environment = True, env = "conanrun") - - # Make sure there executable is named the same on all three OSes this allows it to be called with `python` - # simplifying GH Actions steps - if self.settings.os != "Windows": - py_venv_interp = Path(self.install_folder, self._python_venv_bin_path, "python") - if not py_venv_interp.exists(): - py_venv_interp.hardlink_to(Path(self.install_folder, self._python_venv_bin_path, Path(sys.executable).stem + Path(sys.executable).suffix)) - else: - py_venv_interp = Path(self.install_folder, self._python_venv_bin_path, Path(sys.executable).stem + Path(sys.executable).suffix) - - if not py_venv_interp.exists(): - raise ConanException(f"Virtual environment Python interpreter not found at: {py_venv_interp}") - if self.settings.os == "Windows": - py_venv_interp = Path(*[f'"{p}"' if " " in p else p for p in py_venv_interp.parts]) - - # Updating the run environment - self.runenv_info.define_path("VIRTUAL_ENV", self.install_folder) - self.runenv_info.prepend_path("PATH", os.path.join(self.install_folder, self._python_venv_bin_path)) - self.runenv_info.prepend_path("PYTHONPATH", self._site_packages_path(py_venv_interp)) - self.runenv_info.unset("PYTHONHOME") - - # Installing the initial_reqs - reqs = " ".join(initial_reqs) - self.run(f"{py_venv_interp} -m pip install {reqs}", run_environment = True, env = "conanrun") - - self.output.success(f"Created a Virtual Python Environment in {self.install_folder}") - self._py_venv_interp = str(py_venv_interp) - - -class Pkg(ConanFile): - name = "umbase" - exports_sources = "StandardProjectSettings.cmake" - - def package(self): - self.copy("StandardProjectSettings.cmake", "cmake") - - def package_info(self): - self.cpp_info.set_property("name", "umbase") - self.cpp_info.set_property("cmake_build_modules", [os.path.join("cmake", "StandardProjectSettings.cmake")]) diff --git a/recipes/umbase/config.yml b/recipes/umbase/config.yml deleted file mode 100644 index 575df84..0000000 --- a/recipes/umbase/config.yml +++ /dev/null @@ -1,3 +0,0 @@ -versions: - "0.1.6": - folder: "all" From fa6f78b3ef37ebd1fc88bb74a7bfcbfce639632d Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:31:48 +0100 Subject: [PATCH 23/39] Remove useless version in conanfile.py --- recipes/sentrylibrary/all/conanfile.py | 1 - 1 file changed, 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index ec7c76f..f5db322 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -86,6 +86,5 @@ def send_sentry_debug_files(self, binary_basename): class PyReq(ConanFile): name = "sentrylibrary" - version = "1.0" description = "This is a base conan file description for C++ libraries/applications that can embed sentry" package_type = "python-require" From c7f3c611da62c5cb121f2bbeb5dbf740c71f8305 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:47:57 +0100 Subject: [PATCH 24/39] Use proper sentrylibrary version --- recipes/clipper/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index 6f65c40..48d9455 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -19,7 +19,7 @@ class ClipperConan(ConanFile): homepage = "http://www.angusj.com/delphi/clipper.php" settings = "os", "arch", "compiler", "build_type" package_type = "library" - python_requires = "sentrylibrary/1.0@ultimaker/cura_11622" # FIXME: use main after merge + python_requires = "sentrylibrary/1.0.0@ultimaker/cura_11622" # FIXME: use main after merge python_requires_extend = "sentrylibrary.SentryLibrary" options = { From ca79873406fa7292959441bfca7029227f2131db Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:54:18 +0100 Subject: [PATCH 25/39] Fix enable_release option call --- recipes/sentrylibrary/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index f5db322..0b14a36 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -76,7 +76,7 @@ def send_sentry_debug_files(self, binary_basename): self.run( f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") - if self.sentry_create_release: + if self.options.sentry_create_release: # create a sentry release and link it to the commit this is based upon self.output.info(f"Creating a new release {self.version} in Sentry and linking it to the current commit {self.conan_data['commit']}") self.run(f"sentry-cli --auth-token {sentry_token} releases new -o {sentry_organization} -p {sentry_project} {self.version}") From 3fcfde6df3240bc64ab7a89fe744920e23738d83 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 15:58:49 +0100 Subject: [PATCH 26/39] Use updated diff action --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 289794f..b8bd107 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -35,7 +35,7 @@ jobs: conan_user: ${{ secrets.CONAN_USER }} conan_password: ${{ secrets.CONAN_PASS }} - - uses: technote-space/get-diff-action@v6 + - uses: greguintow/get-diff-action@v7 id: get-diff if: ${{ github.event_name == 'push' }} with: From 947017d27318a8b7fa13d030edff4d6038bc9f9e Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 16:43:30 +0100 Subject: [PATCH 27/39] Add sentry environment for development/production --- recipes/sentrylibrary/all/conanfile.py | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 0b14a36..59a2ec7 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -13,11 +13,13 @@ class SentryLibrary: "enable_sentry": [True, False], "sentry_create_release": [True, False], "sentry_project": ["ANY"], + "sentry_is_production": [True, False], } default_options = { "enable_sentry": False, "sentry_create_release": False, "sentry_project": "", + "sentry_is_production": False, } def config_options(self): @@ -77,11 +79,21 @@ def send_sentry_debug_files(self, binary_basename): f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") if self.options.sentry_create_release: + sentry_version = self.version + if not self.options.sentry_is_production: + sentry_version += f"+{self.conan_data['commit'][:6]}" + + sentry_auth = f"--auth-token {sentry_token} -o {sentry_organization} -p {sentry_project}" + # create a sentry release and link it to the commit this is based upon - self.output.info(f"Creating a new release {self.version} in Sentry and linking it to the current commit {self.conan_data['commit']}") - self.run(f"sentry-cli --auth-token {sentry_token} releases new -o {sentry_organization} -p {sentry_project} {self.version}") - self.run(f"sentry-cli --auth-token {sentry_token} releases set-commits -o {sentry_organization} -p {sentry_project} --commit \"Ultimaker/CuraEngine@{self.conan_data['commit']}\" {self.version}") - self.run(f"sentry-cli --auth-token {sentry_token} releases finalize -o {sentry_organization} -p {sentry_project} {self.version}") + self.output.info(f"Creating a new release {sentry_version} in Sentry and linking it to the current commit {self.conan_data['commit']}") + self.run(f"sentry-cli {sentry_auth} releases new {sentry_version}") + self.run(f"sentry-cli {sentry_auth} releases set-commits {sentry_version} --commit \"Ultimaker/{binary_basename}@{self.conan_data['commit']}\"") + self.run(f"sentry-cli {sentry_auth} releases finalize {sentry_version}") + + # Create a deploy to differentiate development/production releases + environment = "production" if self.options.sentry_is_production else "development" + self.run(f"sentry-cli {sentry_auth} deploys new --release {sentry_version} -e {environment}") class PyReq(ConanFile): From 2ef0d837fd2b1a30b2dbba5506a42b58033c82d6 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 16:51:20 +0100 Subject: [PATCH 28/39] Fix sentry-cli syntax --- recipes/sentrylibrary/all/conanfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 59a2ec7..0ff9728 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -87,9 +87,9 @@ def send_sentry_debug_files(self, binary_basename): # create a sentry release and link it to the commit this is based upon self.output.info(f"Creating a new release {sentry_version} in Sentry and linking it to the current commit {self.conan_data['commit']}") - self.run(f"sentry-cli {sentry_auth} releases new {sentry_version}") - self.run(f"sentry-cli {sentry_auth} releases set-commits {sentry_version} --commit \"Ultimaker/{binary_basename}@{self.conan_data['commit']}\"") - self.run(f"sentry-cli {sentry_auth} releases finalize {sentry_version}") + self.run(f"sentry-cli releases new {sentry_version} {sentry_auth} ") + self.run(f"sentry-cli releases set-commits {sentry_version} --commit \"Ultimaker/{binary_basename}@{self.conan_data['commit']}\" {sentry_auth} ") + self.run(f"sentry-cli releases finalize {sentry_version} {sentry_auth} ") # Create a deploy to differentiate development/production releases environment = "production" if self.options.sentry_is_production else "development" From 8f4c402ac855b098a1d4c5b9fd87c54502e28ea6 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 16:59:40 +0100 Subject: [PATCH 29/39] Fix sentry-cli syntax for deploy --- recipes/sentrylibrary/all/conanfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 0ff9728..bbaca34 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -75,15 +75,15 @@ def send_sentry_debug_files(self, binary_basename): self.output.info("Uploading debug symbols to sentry") build_source_dir = Path(self.build_folder).parent.parent.as_posix() + sentry_auth = f"--auth-token {sentry_token} -o {sentry_organization} -p {sentry_project}" self.run( - f"sentry-cli --auth-token {sentry_token} debug-files upload --include-sources -o {sentry_organization} -p {sentry_project} {build_source_dir}") + f"sentry-cli --auth-token debug-files upload --include-sources {build_source_dir} {sentry_auth}") if self.options.sentry_create_release: sentry_version = self.version if not self.options.sentry_is_production: sentry_version += f"+{self.conan_data['commit'][:6]}" - sentry_auth = f"--auth-token {sentry_token} -o {sentry_organization} -p {sentry_project}" # create a sentry release and link it to the commit this is based upon self.output.info(f"Creating a new release {sentry_version} in Sentry and linking it to the current commit {self.conan_data['commit']}") @@ -93,7 +93,7 @@ def send_sentry_debug_files(self, binary_basename): # Create a deploy to differentiate development/production releases environment = "production" if self.options.sentry_is_production else "development" - self.run(f"sentry-cli {sentry_auth} deploys new --release {sentry_version} -e {environment}") + self.run(f"sentry-cli deploys new --release {sentry_version} -e {environment} {sentry_auth}") class PyReq(ConanFile): From 939b0e74ddde7aed6335db3b0319fbacf69c1436 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 22 Nov 2024 17:04:02 +0100 Subject: [PATCH 30/39] Fix sentry upload binary syntax --- recipes/sentrylibrary/all/conanfile.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index bbaca34..153f606 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -76,8 +76,7 @@ def send_sentry_debug_files(self, binary_basename): self.output.info("Uploading debug symbols to sentry") build_source_dir = Path(self.build_folder).parent.parent.as_posix() sentry_auth = f"--auth-token {sentry_token} -o {sentry_organization} -p {sentry_project}" - self.run( - f"sentry-cli --auth-token debug-files upload --include-sources {build_source_dir} {sentry_auth}") + self.run(f"sentry-cli debug-files upload --include-sources {build_source_dir} {sentry_auth}") if self.options.sentry_create_release: sentry_version = self.version From 635904f27e90ca5ebb5fcb013f36d8fe86764738 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Mon, 25 Nov 2024 09:09:42 +0100 Subject: [PATCH 31/39] Do not send binaries to Sentry by default This will help at development time, sometimes you just want to send an event to Sentry but without having the binaries uploaded, which requires an authentication token and everything. --- recipes/sentrylibrary/all/conanfile.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 153f606..114b58f 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -11,12 +11,14 @@ class SentryLibrary: options = { "enable_sentry": [True, False], + "sentry_send_binaries": [True, False], "sentry_create_release": [True, False], "sentry_project": ["ANY"], "sentry_is_production": [True, False], } default_options = { "enable_sentry": False, + "sentry_send_binaries": False, "sentry_create_release": False, "sentry_project": "", "sentry_is_production": False, @@ -32,7 +34,11 @@ def configure(self): def validate(self): if self.options.enable_sentry: - for sentry_conf in ["organization", "url", "token"]: + required_confs = ["url"] + if self.options.sentry_send_binaries: + required_confs += ["organization", "token"] + + for sentry_conf in required_confs: conf_name = f"user.sentry:{sentry_conf}" if self.conf.get(conf_name, "", check_type=str) == "": raise ConanInvalidConfiguration(f"Unable to enable Sentry because no {conf_name} was configured (use '-c {conf_name}={sentry_conf}')") From 98fa3d1d9bb9bfb102e9d441b7843f0c57beb317 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Mon, 25 Nov 2024 12:03:39 +0100 Subject: [PATCH 32/39] Send binaries only if option active --- recipes/sentrylibrary/all/conanfile.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 114b58f..6263067 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -53,12 +53,13 @@ def setup_cmake_toolchain_sentry(self, cmake_toolchain): ''' cmake_toolchain.variables["ENABLE_SENTRY"] = self.options.enable_sentry cmake_toolchain.variables["SENTRY_URL"] = self.conf.get("user.sentry:url", "", check_type=str) + cmake_toolchain.variables["SENTRY_ENVIRONMENT"] = "production" if self.options.sentry_is_production else "development" def send_sentry_debug_files(self, binary_basename): ''' Method to be called by actual packages at build() time, after the actual build has been done, to send the binary files to sentry ''' - if self.options.enable_sentry: + if self.options.enable_sentry and self.options.sentry_send_binaries: sentry_project = self.options.sentry_project sentry_organization = self.conf.get("user.sentry:organization", "", check_type=str) sentry_token = self.conf.get("user.sentry:token", "", check_type=str) @@ -89,17 +90,12 @@ def send_sentry_debug_files(self, binary_basename): if not self.options.sentry_is_production: sentry_version += f"+{self.conan_data['commit'][:6]}" - # create a sentry release and link it to the commit this is based upon self.output.info(f"Creating a new release {sentry_version} in Sentry and linking it to the current commit {self.conan_data['commit']}") self.run(f"sentry-cli releases new {sentry_version} {sentry_auth} ") self.run(f"sentry-cli releases set-commits {sentry_version} --commit \"Ultimaker/{binary_basename}@{self.conan_data['commit']}\" {sentry_auth} ") self.run(f"sentry-cli releases finalize {sentry_version} {sentry_auth} ") - # Create a deploy to differentiate development/production releases - environment = "production" if self.options.sentry_is_production else "development" - self.run(f"sentry-cli deploys new --release {sentry_version} -e {environment} {sentry_auth}") - class PyReq(ConanFile): name = "sentrylibrary" From 098ce50845d1b1e3ffc623cc2530f9e788762b9c Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 27 Nov 2024 08:55:53 +0100 Subject: [PATCH 33/39] Set environment as a config instead of option --- recipes/sentrylibrary/all/conanfile.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 6263067..5188432 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -14,14 +14,12 @@ class SentryLibrary: "sentry_send_binaries": [True, False], "sentry_create_release": [True, False], "sentry_project": ["ANY"], - "sentry_is_production": [True, False], } default_options = { "enable_sentry": False, "sentry_send_binaries": False, "sentry_create_release": False, "sentry_project": "", - "sentry_is_production": False, } def config_options(self): @@ -47,13 +45,16 @@ def requirements(self): if self.options.enable_sentry: self.requires("sentry-native/0.7.0") + def _sentry_environment(self): + return self.conf.get("user.sentry:environment", default = 'development', check_type = str) + def setup_cmake_toolchain_sentry(self, cmake_toolchain): ''' Method to be called by actual packages at generate() time to setup the cmake toolchain according to the sentry configuration ''' cmake_toolchain.variables["ENABLE_SENTRY"] = self.options.enable_sentry cmake_toolchain.variables["SENTRY_URL"] = self.conf.get("user.sentry:url", "", check_type=str) - cmake_toolchain.variables["SENTRY_ENVIRONMENT"] = "production" if self.options.sentry_is_production else "development" + cmake_toolchain.variables["SENTRY_ENVIRONMENT"] = self._sentry_environment() def send_sentry_debug_files(self, binary_basename): ''' @@ -87,7 +88,7 @@ def send_sentry_debug_files(self, binary_basename): if self.options.sentry_create_release: sentry_version = self.version - if not self.options.sentry_is_production: + if self._sentry_environment() != "production": sentry_version += f"+{self.conan_data['commit'][:6]}" # create a sentry release and link it to the commit this is based upon From 1f523de626a6273670839c280705d236f5fb6b98 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 27 Nov 2024 11:16:42 +0100 Subject: [PATCH 34/39] Use gettext tools in path (experimental) --- recipes/translationextractor/all/conanfile.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/recipes/translationextractor/all/conanfile.py b/recipes/translationextractor/all/conanfile.py index e10bbe8..6ed846a 100644 --- a/recipes/translationextractor/all/conanfile.py +++ b/recipes/translationextractor/all/conanfile.py @@ -15,9 +15,8 @@ class ExtractTranslations(object): - def __init__(self, conanfile: ConanFile, gettext_bindir): + def __init__(self, conanfile: ConanFile): self._conanfile = conanfile - self._gettext_bindir = gettext_bindir self._translations_root_path = Path(self._conanfile.source_folder).joinpath("resources", "i18n") self._all_strings_pot_path = self._translations_root_path.joinpath( self._conanfile.name + ".pot") # pot file containing all strings untranslated @@ -33,9 +32,9 @@ def _update_po_files_all_languages(self) -> None: if lang_folder.is_dir() and not po_file.exists(): po_file.touch() self._conanfile.run( - f"{self._gettext_bindir}/msginit --no-translator -i {pot_file} -o {po_file} --locale=en") + f"msginit --no-translator -i {pot_file} -o {po_file} --locale=en", env="conanbuild") self._conanfile.run( - f"{self._gettext_bindir}/msgmerge --add-location=never --no-wrap --no-fuzzy-matching --sort-output -o {po_file} {po_file} {pot_file}", + f"msgmerge --add-location=never --no-wrap --no-fuzzy-matching --sort-output -o {po_file} {po_file} {pot_file}", env="conanbuild") def _remove_pot_header(self, content: str) -> str: @@ -90,14 +89,14 @@ def _extract_python(self) -> None: """ Extract i18n strings from all .py files""" for path in self._extract_source_files("python", "*.py"): self._conanfile.run( - f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=python --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", + f"xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=python --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", env="conanbuild") def _extract_qml(self) -> None: """ Extract all i18n strings from qml files""" for path in self._extract_source_files("qml", "*.qml"): self._conanfile.run( - f"{self._gettext_bindir}/xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=javascript --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", + f"xgettext --from-code=UTF-8 --join-existing --add-location=never --sort-output --language=javascript --no-wrap -ki18n:1 -ki18nc:1c,2 -ki18np:1,2 -ki18ncp:1c,2,3 -o {self._all_strings_pot_path} {path}", env="conanbuild") def _extract_plugin(self) -> None: From 5810189d12ae62e413fd182bbc0c7fd2c0ebc0ec Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Thu, 28 Nov 2024 11:37:32 +0100 Subject: [PATCH 35/39] Fix sip project generation --- recipes/pyprojecttoolchain/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/pyprojecttoolchain/all/conanfile.py b/recipes/pyprojecttoolchain/all/conanfile.py index 2dfc4cf..a99e197 100644 --- a/recipes/pyprojecttoolchain/all/conanfile.py +++ b/recipes/pyprojecttoolchain/all/conanfile.py @@ -55,7 +55,7 @@ def context(self): mod_version = Version(self._conanfile.version) pypi_version = f"{mod_version.major}.{mod_version.minor}.{mod_version.patch}" - if mod_version.pre != "": + if mod_version.pre is not None: split_prerelease = str(mod_version.pre).split(".") if len(split_prerelease) > 1: pypi_version += f"{split_prerelease[0][0]}{split_prerelease[1]}" From 6337e08c2aa1d0a864b147300501fe20a85bccb6 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Thu, 28 Nov 2024 11:39:44 +0100 Subject: [PATCH 36/39] Fix script syntax error --- .github/workflows/conan-package.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 8f8d83b..b8bd107 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -59,4 +59,4 @@ jobs: - name: Export changed recipes run: | - python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ steps.get-recipes-list.outputs.recipes_list } + python Cura-workflows/runner_scripts/upload_conan_recipes.py --user ultimaker --branch ${{ github.ref_name }} --remote cura-conan2 ${{ steps.get-recipes-list.outputs.recipes_list }} From 19410db3be9679a3429af6d453aea35248316f5b Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Fri, 29 Nov 2024 09:08:17 +0100 Subject: [PATCH 37/39] Bump sentry version --- recipes/sentrylibrary/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 5188432..497c950 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -43,7 +43,7 @@ def validate(self): def requirements(self): if self.options.enable_sentry: - self.requires("sentry-native/0.7.0") + self.requires("sentry-native/0.7.15") def _sentry_environment(self): return self.conf.get("user.sentry:environment", default = 'development', check_type = str) From 5a55f0199ea58e14695e5e760de9bf7a0dfd37df Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Mon, 2 Dec 2024 09:20:25 +0100 Subject: [PATCH 38/39] Fix dynamic library name on Macos --- recipes/sentrylibrary/all/conanfile.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/recipes/sentrylibrary/all/conanfile.py b/recipes/sentrylibrary/all/conanfile.py index 497c950..fb7ccf7 100644 --- a/recipes/sentrylibrary/all/conanfile.py +++ b/recipes/sentrylibrary/all/conanfile.py @@ -71,7 +71,11 @@ def send_sentry_debug_files(self, binary_basename): if self.package_type == "application": binary_name = binary_basename else: - binary_name = binary_basename + ('.so' if self.options.get_safe("shared", True) else '.a') + if self.options.get_safe("shared", True): + extension = "dylib" if self.settings.os == "Macos" else "so" + else: + extension = "a" + binary_name = f"{binary_basename}.{extension}" if self.settings.os == "Linux": self.output.info("Stripping debug symbols from binary") From a35944164a7ff82328c2371b36c4a7f49ed07e44 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 4 Dec 2024 08:22:27 +0100 Subject: [PATCH 39/39] Prepare for merge --- .github/workflows/conan-package.yml | 3 +-- recipes/clipper/all/conanfile.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index b8bd107..b3c8dcc 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -28,9 +28,8 @@ jobs: runs-on: ubuntu-latest steps: -# FIXME: use main once merged - name: Setup the build environment - uses: ultimaker/cura-workflows/.github/actions/setup-build-environment@CURA-11622_conan_v2 + uses: ultimaker/cura-workflows/.github/actions/setup-build-environment@main with: conan_user: ${{ secrets.CONAN_USER }} conan_password: ${{ secrets.CONAN_PASS }} diff --git a/recipes/clipper/all/conanfile.py b/recipes/clipper/all/conanfile.py index 48d9455..14c700b 100644 --- a/recipes/clipper/all/conanfile.py +++ b/recipes/clipper/all/conanfile.py @@ -19,7 +19,7 @@ class ClipperConan(ConanFile): homepage = "http://www.angusj.com/delphi/clipper.php" settings = "os", "arch", "compiler", "build_type" package_type = "library" - python_requires = "sentrylibrary/1.0.0@ultimaker/cura_11622" # FIXME: use main after merge + python_requires = "sentrylibrary/1.0.0" python_requires_extend = "sentrylibrary.SentryLibrary" options = {