From 10abf773aa61168d1adb01d0db6b49489af99feb Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 29 Aug 2023 09:25:28 +0200 Subject: [PATCH 1/3] "Update Python library requirements and enhance build scripts" In this commit, conandata.yml was deleted as the Python library requirements are now defined in conanfile.py. Incorporated a stricter check for the minimum required C++ standard and for specific compiler versions for better code compatibility. Moreover, modified the function calls in conanfile.py and test_package/conanfiles.py to use more updated and reliable methods. Adjusted build requirements and export sources to improve the building process. Finally, optimized the packaging process to ensure that all necessary files are included in the correct directories. Contributes to CURA-10951 --- conandata.yml | 12 ------ conanfile.py | 88 ++++++++++++++++++++++++++------------- test_package/conanfile.py | 37 ++++++++-------- 3 files changed, 79 insertions(+), 58 deletions(-) delete mode 100644 conandata.yml diff --git a/conandata.yml b/conandata.yml deleted file mode 100644 index dc43e09..0000000 --- a/conandata.yml +++ /dev/null @@ -1,12 +0,0 @@ -"5.3.0-alpha": - requirements: - - "savitar/5.2.2" - - "cpython/3.10.4" -"5.2.2": - requirements: - - "savitar/5.2.2" - - "cpython/3.10.4" -"5.2.0": - requirements: - - "savitar/5.2.0" - - "cpython/3.10.4" diff --git a/conanfile.py b/conanfile.py index a907c95..096fe58 100644 --- a/conanfile.py +++ b/conanfile.py @@ -1,14 +1,19 @@ import os from pathlib import Path +from os import path +from conan import ConanFile +from conan.errors import ConanInvalidConfiguration from conan.tools.cmake import CMakeToolchain, CMake, cmake_layout +from conan.tools.env import VirtualBuildEnv from conan.tools.files import copy, mkdir from conan.tools.build import check_min_cppstd -from conan import ConanFile +from conan.tools.microsoft import check_min_vs, is_msvc, is_msvc_static_runtime +from conan.tools.scm import Version -required_conan_version = ">=1.50.0" +required_conan_version = ">=1.56.0" class PySavitarConan(ConanFile): @@ -23,8 +28,7 @@ class PySavitarConan(ConanFile): exports = "LICENSE*" generators = "CMakeDeps", "VirtualBuildEnv", "VirtualRunEnv" - python_requires = "umbase/[>=0.1.7]@ultimaker/stable", "pyprojecttoolchain/[>=0.1.6]@ultimaker/stable", "sipbuildtool/[>=0.2.3]@ultimaker/stable" - python_requires_extend = "umbase.UMBaseConanfile" + python_requires = "pyprojecttoolchain/[>=0.1.7]@ultimaker/stable", "sipbuildtool/[>=0.2.4]@ultimaker/stable" options = { "shared": [True, False], @@ -38,45 +42,69 @@ class PySavitarConan(ConanFile): "py_build_requires": '"sip >=6, <7", "setuptools>=40.8.0", "wheel"', "py_build_backend": "sipbuild.api", } - scm = { - "type": "git", - "subfolder": ".", - "url": "auto", - "revision": "auto" - } def set_version(self): - if self.version is None: - self.version = self._umdefault_version() + if not self.version: + self.version = "5.3.0-alpha" + + @property + def _min_cppstd(self): + return 17 + + @property + def _compilers_minimum_version(self): + return { + "gcc": "9", + "clang": "9", + "apple-clang": "9", + "msvc": "192", + "visual_studio": "14", + } + + def export_sources(self): + copy(self, "CMakeLists.txt", self.recipe_folder, self.export_sources_folder) + copy(self, "*", path.join(self.recipe_folder, "python"), path.join(self.export_sources_folder, "python")) def requirements(self): - self.requires("standardprojectsettings/[>=0.1.0]@ultimaker/stable") # required for the CMake build modules - self.requires("sipbuildtool/0.2.3@ultimaker/stable") # required for the CMake build modules - for req in self._um_data()["requirements"]: - self.requires(req) + self.requires("savitar/5.2.0") + self.requires("cpython/3.10.4") + + def validate(self): + if self.settings.compiler.cppstd: + check_min_cppstd(self, self._min_cppstd) + check_min_vs(self, 192) # TODO: remove in Conan 2.0 + if not is_msvc(self): + minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False) + if minimum_version and Version(self.settings.compiler.version) < minimum_version: + raise ConanInvalidConfiguration( + f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support." + ) + + def build_requirements(self): + self.test_requires("standardprojectsettings/[>=0.1.0]@ultimaker/stable") + self.test_requires("sipbuildtool/[>=0.2.4]@ultimaker/stable") def config_options(self): - if self.options.shared and self.settings.compiler == "Visual Studio": + if self.settings.os == "Windows": del self.options.fPIC def configure(self): - self.options["savitar"].shared = self.options.shared + if self.options.shared: + self.options.rm_safe("fPIC") self.options["cpython"].shared = True - def validate(self): - if self.settings.compiler.get_safe("cppstd"): - check_min_cppstd(self, 17) - def generate(self): pp = self.python_requires["pyprojecttoolchain"].module.PyProjectToolchain(self) - pp.blocks["tool_sip_project"].values["sip_files_dir"] = Path("python").as_posix() - mkdir(self, self.build_path) # FIXME: bad, this should not be necessary + pp.blocks["tool_sip_project"].values["sip_files_dir"] = str(Path("python").as_posix()) pp.blocks["tool_sip_bindings"].values["name"] = "pySavitar" pp.blocks["tool_sip_metadata"].values["name"] = "pySavitar" pp.blocks.remove("extra_sources") pp.generate() tc = CMakeToolchain(self) + if is_msvc(self): + tc.variables["USE_MSVC_RUNTIME_LIBRARY_DLL"] = not is_msvc_static_runtime(self) + tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW" tc.variables["Python_EXECUTABLE"] = self.deps_user_info["cpython"].python.replace("\\", "/") tc.variables["Python_USE_STATIC_LIBS"] = not self.options["cpython"].shared tc.variables["Python_ROOT_DIR"] = self.deps_cpp_info["cpython"].rootpath.replace("\\", "/") @@ -87,6 +115,9 @@ def generate(self): tc.variables["Python_SITEARCH"] = "site-packages" tc.generate() + vb = VirtualBuildEnv(self) + vb.generate(scope="build") + # Generate the Source code from SIP sip = self.python_requires["sipbuildtool"].module.SipBuildTool(self) sip.configure() @@ -104,11 +135,12 @@ def build(self): cmake.build() def package(self): - for ext in (".pyi", ".so", ".lib", ".a", ".pyd"): - copy(self, f"pySavitar{ext}", self.build_folder, self.package_path.joinpath("lib"), keep_path = False) + copy(self, pattern="LICENSE*", dst="licenses", src=self.source_folder) + for ext in ("*.pyi", "*.so", "*.lib", "*.a", "*.pyd"): + copy(self, ext, src = self.build_folder, dst = path.join(self.package_folder, "lib"), keep_path = False) - for ext in (".dll", ".so", ".dylib"): - copy(self, f"pySavitar{ext}", self.build_folder, self.package_path.joinpath("bin"), keep_path = False) + for ext in ("*.dll", "*.so", "*.dylib"): + copy(self, ext, src = self.build_folder, dst = path.join(self.package_folder, "bin"), keep_path = False) def package_info(self): self.cpp_info.libdirs = [ os.path.join(self.package_folder, "lib")] diff --git a/test_package/conanfile.py b/test_package/conanfile.py index d415b9d..445ab73 100644 --- a/test_package/conanfile.py +++ b/test_package/conanfile.py @@ -3,37 +3,38 @@ from pathlib import Path from conan import ConanFile -from conan.tools.build import cross_building +from conan.tools.build import can_run from conan.tools.env import VirtualRunEnv from conan.errors import ConanException +from conan.tools.files import copy class PySavitarTestConan(ConanFile): settings = "os", "compiler", "build_type", "arch" generators = "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) def generate(self): venv = VirtualRunEnv(self) venv.generate() + cpp_info = self.dependencies[self.tested_reference_str].cpp_info + copy(self, "*.pyd", src = cpp_info.libdirs[0], dst =self.build_folder) + + for dep in self.dependencies.values(): + for bin_dir in dep.cpp_info.bindirs: + copy(self, "*.dll", src = bin_dir, dst = self.build_folder) + def build(self): - if not cross_building(self): + if can_run(self): shutil.copy(Path(self.source_folder).joinpath("test.py"), Path(self.build_folder).joinpath("test.py")) - def imports(self): - if self.settings.os == "Windows" and not cross_building(self): - self.copy("*.dll", dst=".", src="@bindirs") - self.copy("*.pyd", dst=".", src="@libdirs") - def test(self): - if not cross_building(self): - test_pysavitar = StringIO() - - try: - self.run("python test.py", env="conanrun", output=test_pysavitar) - except Exception: - print("Test Failed to run: ", test_pysavitar.getvalue()) - raise ConanException("pySavitar wasn't built correctly") - - if "True" not in test_pysavitar.getvalue(): - raise ConanException("pySavitar wasn't built correctly") + if can_run(self): + test_buf = StringIO() + self.run(f"python test.py", env = "conanrun", output = test_buf) + if "True" not in test_buf.getvalue(): + raise ConanException("pynest2d wasn't build correctly!") From 247badb30835756d877568ccf325750484b79481 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 29 Aug 2023 11:07:25 +0200 Subject: [PATCH 2/3] Use Savitar from CURA-10951 branch Contributes to CURA-10951 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 096fe58..22d747c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -66,7 +66,7 @@ def export_sources(self): copy(self, "*", path.join(self.recipe_folder, "python"), path.join(self.export_sources_folder, "python")) def requirements(self): - self.requires("savitar/5.2.0") + self.requires("savitar/(latest)/ultimaker/cura_10951") self.requires("cpython/3.10.4") def validate(self): From 2582cc476aa7b10b4189e1f966230957b0f9685f Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 29 Aug 2023 11:16:28 +0200 Subject: [PATCH 3/3] fixed savitar requirement ref Contributes to CURA-10951 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 22d747c..c7a02e5 100644 --- a/conanfile.py +++ b/conanfile.py @@ -66,7 +66,7 @@ def export_sources(self): copy(self, "*", path.join(self.recipe_folder, "python"), path.join(self.export_sources_folder, "python")) def requirements(self): - self.requires("savitar/(latest)/ultimaker/cura_10951") + self.requires("savitar/(latest)@ultimaker/cura_10951") self.requires("cpython/3.10.4") def validate(self):