From 1c290aa093f29eeba700e178b3da721ad630d72d Mon Sep 17 00:00:00 2001 From: Ahajha Date: Sat, 6 Apr 2024 01:46:57 -0400 Subject: [PATCH 01/11] Add native support for CMake's builtin FindPython(3) --- recipes/cpython/all/conanfile.py | 78 +++++++++++++++- .../cpython/all/test_package/CMakeLists.txt | 92 ++----------------- recipes/cpython/all/test_package/conanfile.py | 19 +--- 3 files changed, 82 insertions(+), 107 deletions(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index 2c579fc71772b..64e0ffd4aba81 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -6,7 +6,7 @@ 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, mkdir, replace_in_file, rm, rmdir, unzip +from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, mkdir, replace_in_file, rm, rmdir, save, unzip from conan.tools.gnu import Autotools, AutotoolsToolchain, AutotoolsDeps 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 @@ -512,6 +512,68 @@ def _msvc_package_copy(self): 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 _exact_lib_name(self, folder): + possible_extensions = ("a", "so", "dylib", "lib") + for file in os.listdir(folder): + for extension in possible_extensions: + if re.match(f".*\.{extension}", file): + return file + raise ConanException(f"No library files found in {folder}") + + @property + def _cmake_module_path(self): + if is_msvc(self): + return os.path.join(self._msvc_install_subprefix, "lib", "cmake") + else: + return os.path.join("lib", "cmake") + + def _write_cmake_findpython_wrapper_file(self): + template = textwrap.dedent(""" + if (DEFINED Python3_VERSION_STRING) + set(_CONAN_PYTHON_SUFFIX "3") + else() + set(_CONAN_PYTHON_SUFFIX "") + endif() + set(Python${{_CONAN_PYTHON_SUFFIX}}_EXECUTABLE {}) + set(Python${{_CONAN_PYTHON_SUFFIX}}_LIBRARY {}) + + # Fails if these are set beforehand + unset(Python${{_CONAN_PYTHON_SUFFIX}}_INCLUDE_DIRS) + unset(Python${{_CONAN_PYTHON_SUFFIX}}_INCLUDE_DIR) + + include(${{CMAKE_ROOT}}/Modules/FindPython${{_CONAN_PYTHON_SUFFIX}}.cmake) + + # Sanity check: The former comes from FindPython(3), the latter comes from the injected find module + if(NOT Python${{_CONAN_PYTHON_SUFFIX}}_VERSION STREQUAL "${{Python${{_CONAN_PYTHON_SUFFIX}}_VERSION_STRING}}") + message(FATAL_ERROR "CMake detected wrong cpython version - this is likely a bug with the cpython Conan package") + endif() + + if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::Module) + target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::Module INTERFACE cpython::python) + endif() + if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::SABIModule) + target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::SABIModule INTERFACE cpython::python) + endif() + if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::Python) + target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::Python INTERFACE cpython::embed) + endif() + """) + + # In order for the package to be relocatable, these variables must be relative to the installed CMake file + if is_msvc(self): + lib_folder = os.path.join(self.package_folder, self._msvc_install_subprefix, "libs") + lib_file = self._exact_lib_name(lib_folder) + python_exe = "${CMAKE_CURRENT_LIST_DIR}/../../" + self._cpython_interpreter_name + python_library = "${CMAKE_CURRENT_LIST_DIR}/../../" + lib_file + else: + lib_folder = os.path.join(self.package_folder, "lib") + lib_file = self._exact_lib_name(lib_folder) + python_exe = "${CMAKE_CURRENT_LIST_DIR}/../../bin/" + self._cpython_interpreter_name + python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + lib_file + + cmake_file = os.path.join(self.package_folder, self._cmake_module_path, "use_conan_python.cmake") + save(self, cmake_file, template.format(python_exe, python_library)) + def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) if is_msvc(self): @@ -556,6 +618,8 @@ def package(self): os.symlink(f"python{self._version_suffix}", self._cpython_symlink) fix_apple_shared_install_name(self) + self._write_cmake_findpython_wrapper_file() + @property def _cpython_symlink(self): symlink = os.path.join(self.package_folder, "bin", "python") @@ -600,10 +664,6 @@ def _lib_name(self): 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" - py_version = Version(self.version) # python component: "Build a C extension for Python" if is_msvc(self): @@ -634,6 +694,7 @@ def package_info(self): "pkg_config_aliases", f"python{py_version.major}" ) self.cpp_info.components["python"].libdirs = [] + self.cpp_info.components["python"].set_property("cmake_target_name", "cpython::python") # embed component: "Embed Python into an application" self.cpp_info.components["embed"].libs = [self._lib_name] @@ -646,6 +707,13 @@ def package_info(self): "pkg_config_aliases", f"python{py_version.major}-embed" ) self.cpp_info.components["embed"].requires = ["python"] + self.cpp_info.components["embed"].set_property("cmake_target_name", "cpython::embed") + + # Transparent integration with CMake's FindPython(3) + self.cpp_info.set_property("cmake_file_name", "Python3") + self.cpp_info.set_property("cmake_module_file_name", "Python") + self.cpp_info.set_property("cmake_find_mode", "both") + self.cpp_info.set_property("cmake_build_modules", [os.path.join(self._cmake_module_path, "use_conan_python.cmake")]) if self._supports_modules: # hidden components: the C extensions of python are built as dynamically loaded shared libraries. diff --git a/recipes/cpython/all/test_package/CMakeLists.txt b/recipes/cpython/all/test_package/CMakeLists.txt index 0d333d99af1e3..04d46740d1abd 100644 --- a/recipes/cpython/all/test_package/CMakeLists.txt +++ b/recipes/cpython/all/test_package/CMakeLists.txt @@ -1,95 +1,19 @@ 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_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} 3${PY_VERSION_SUFFIX} ${PY_VERSION} ${PY_VERSION_MAJOR_MINOR} 3) -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_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_VERSION}") - message("PYTHONLIBS_VERSION_STRING does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() -endif() +find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module Development.Embed) option(BUILD_MODULE "Build python module") if(BUILD_MODULE) - add_library(spam MODULE "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 Python3_FIND_ABI - find_package(Python3 REQUIRED COMPONENTS Interpreter Development) - message("Python3_EXECUTABLE: ${Python3_EXECUTABLE}") - message("Python3_INTERPRETER_ID: ${Python3_INTERPRETER_ID}") - message("Python3_VERSION: ${Python3_VERSION}") - message("Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}") - message("Python3_LIBRARIES: ${Python3_LIBRARIES}") - if(NOT Python3_VERSION STREQUAL "${PY_VERSION}") - message("Python_ADDITIONAL_VERSIONS does not match PY_VERSION") - message(FATAL_ERROR "CMake detected wrong cpython version") - endif() + message("Python3_EXECUTABLE: ${Python3_EXECUTABLE}") + message("Python3_INTERPRETER_ID: ${Python3_INTERPRETER_ID}") + message("Python3_VERSION: ${Python3_VERSION}") + message("Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}") + message("Python3_LIBRARIES: ${Python3_LIBRARIES}") - python3_add_library(spam2 "test_module.c") - endif() + python3_add_library(spam "test_module.c") endif() add_executable(${PROJECT_NAME} "test_package.c") -target_link_libraries(${PROJECT_NAME} PRIVATE cpython::embed) +target_link_libraries(${PROJECT_NAME} PRIVATE Python3::Python) diff --git a/recipes/cpython/all/test_package/conanfile.py b/recipes/cpython/all/test_package/conanfile.py index bca7c7fcfd3b7..9e5254b6dc6d8 100644 --- a/recipes/cpython/all/test_package/conanfile.py +++ b/recipes/cpython/all/test_package/conanfile.py @@ -25,7 +25,7 @@ def build_requirements(self): # 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]") + self.tool_requires("cmake/[>=3.16 <4]") def layout(self): cmake_layout(self) @@ -53,30 +53,13 @@ def _py_version(self): else: return Version(self.deps_cpp_info["cpython"].version) - @property - def _cmake_try_FindPythonX(self): - return not is_msvc(self) or self.settings.build_type != "Debug" - @property def _supports_modules(self): return not is_msvc(self) or self._cpython_option("shared") def generate(self): tc = CMakeToolchain(self) - version = self._py_version tc.cache_variables["BUILD_MODULE"] = self._supports_modules - tc.cache_variables["PY_VERSION_MAJOR_MINOR"] = f"{version.major}.{version.minor}" - tc.cache_variables["PY_VERSION"] = str(self._py_version) - tc.cache_variables["PY_VERSION_SUFFIX"] = "d" if self.settings.build_type == "Debug" else "" - tc.cache_variables["PYTHON_EXECUTABLE"] = self._python - tc.cache_variables["USE_FINDPYTHON_X"] = self._cmake_try_FindPythonX - tc.cache_variables["Python3_EXECUTABLE"] = self._python - tc.cache_variables["Python3_ROOT_DIR"] = self.dependencies["cpython"].package_folder - tc.cache_variables["Python3_USE_STATIC_LIBS"] = not self.dependencies["cpython"].options.shared - tc.cache_variables["Python3_FIND_FRAMEWORK"] = "NEVER" - tc.cache_variables["Python3_FIND_REGISTRY"] = "NEVER" - tc.cache_variables["Python3_FIND_IMPLEMENTATIONS"] = "CPython" - tc.cache_variables["Python3_FIND_STRATEGY"] = "LOCATION" tc.generate() deps = CMakeDeps(self) From d43821f05630abe5925f58ffd6dc9c52af0b2ea4 Mon Sep 17 00:00:00 2001 From: Ahajha Date: Sat, 6 Apr 2024 01:54:42 -0400 Subject: [PATCH 02/11] Misc cleanup --- recipes/cpython/all/conanfile.py | 4 +--- recipes/cpython/all/test_package/CMakeLists.txt | 13 ++++++------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index 64e0ffd4aba81..ec28888d493b9 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -516,7 +516,7 @@ def _exact_lib_name(self, folder): possible_extensions = ("a", "so", "dylib", "lib") for file in os.listdir(folder): for extension in possible_extensions: - if re.match(f".*\.{extension}", file): + if re.match(f".*\\.{extension}", file): return file raise ConanException(f"No library files found in {folder}") @@ -694,7 +694,6 @@ def package_info(self): "pkg_config_aliases", f"python{py_version.major}" ) self.cpp_info.components["python"].libdirs = [] - self.cpp_info.components["python"].set_property("cmake_target_name", "cpython::python") # embed component: "Embed Python into an application" self.cpp_info.components["embed"].libs = [self._lib_name] @@ -707,7 +706,6 @@ def package_info(self): "pkg_config_aliases", f"python{py_version.major}-embed" ) self.cpp_info.components["embed"].requires = ["python"] - self.cpp_info.components["embed"].set_property("cmake_target_name", "cpython::embed") # Transparent integration with CMake's FindPython(3) self.cpp_info.set_property("cmake_file_name", "Python3") diff --git a/recipes/cpython/all/test_package/CMakeLists.txt b/recipes/cpython/all/test_package/CMakeLists.txt index 04d46740d1abd..6f592b15f1d3c 100644 --- a/recipes/cpython/all/test_package/CMakeLists.txt +++ b/recipes/cpython/all/test_package/CMakeLists.txt @@ -3,15 +3,14 @@ project(test_package C) find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module Development.Embed) -option(BUILD_MODULE "Build python module") +message("Python3_EXECUTABLE: ${Python3_EXECUTABLE}") +message("Python3_INTERPRETER_ID: ${Python3_INTERPRETER_ID}") +message("Python3_VERSION: ${Python3_VERSION}") +message("Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}") +message("Python3_LIBRARIES: ${Python3_LIBRARIES}") +option(BUILD_MODULE "Build python module") if(BUILD_MODULE) - message("Python3_EXECUTABLE: ${Python3_EXECUTABLE}") - message("Python3_INTERPRETER_ID: ${Python3_INTERPRETER_ID}") - message("Python3_VERSION: ${Python3_VERSION}") - message("Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}") - message("Python3_LIBRARIES: ${Python3_LIBRARIES}") - python3_add_library(spam "test_module.c") endif() From 63fb514716b50fa3e6033430650adba24bc7cb6e Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 03:47:06 -0400 Subject: [PATCH 03/11] Add Mac install workaround --- recipes/cpython/all/conanfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index ec28888d493b9..bff522fbec26b 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -584,6 +584,9 @@ def package(self): rm(self, "vcruntime*", os.path.join(self.package_folder, "bin"), recursive=True) else: autotools = Autotools(self) + if is_apple_os(self): + # FIXME: See https://github.com/python/cpython/issues/109796, this workaround is mentioned there + autotools.make(target="sharedinstall", args=["DESTDIR="]) autotools.install(args=["DESTDIR="]) rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) rmdir(self, os.path.join(self.package_folder, "share")) From b4c08352dded2b4e4d15de000bdd28a50f654fc2 Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 03:47:28 -0400 Subject: [PATCH 04/11] Fix FindPython on Windows --- 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 bff522fbec26b..9c889c1c0c899 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -523,7 +523,9 @@ def _exact_lib_name(self, folder): @property def _cmake_module_path(self): if is_msvc(self): - return os.path.join(self._msvc_install_subprefix, "lib", "cmake") + # On Windows, `lib` is for Python modules, `libs` is for compiled objects. + # Usually CMake modules are packaged with the latter. + return os.path.join(self._msvc_install_subprefix, "libs", "cmake") else: return os.path.join("lib", "cmake") @@ -564,7 +566,7 @@ def _write_cmake_findpython_wrapper_file(self): lib_folder = os.path.join(self.package_folder, self._msvc_install_subprefix, "libs") lib_file = self._exact_lib_name(lib_folder) python_exe = "${CMAKE_CURRENT_LIST_DIR}/../../" + self._cpython_interpreter_name - python_library = "${CMAKE_CURRENT_LIST_DIR}/../../" + lib_file + python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + lib_file else: lib_folder = os.path.join(self.package_folder, "lib") lib_file = self._exact_lib_name(lib_folder) From 579268b1630bd0a39489dec920b6e632bc95bb2c Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 03:52:09 -0400 Subject: [PATCH 05/11] Small cleanup --- recipes/cpython/all/conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index 9c889c1c0c899..647ba2322d729 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -546,7 +546,7 @@ def _write_cmake_findpython_wrapper_file(self): include(${{CMAKE_ROOT}}/Modules/FindPython${{_CONAN_PYTHON_SUFFIX}}.cmake) # Sanity check: The former comes from FindPython(3), the latter comes from the injected find module - if(NOT Python${{_CONAN_PYTHON_SUFFIX}}_VERSION STREQUAL "${{Python${{_CONAN_PYTHON_SUFFIX}}_VERSION_STRING}}") + if(NOT Python${{_CONAN_PYTHON_SUFFIX}}_VERSION STREQUAL Python${{_CONAN_PYTHON_SUFFIX}}_VERSION_STRING) message(FATAL_ERROR "CMake detected wrong cpython version - this is likely a bug with the cpython Conan package") endif() From 5284dbae8e9c431630c065a67c0bd6d98aa10b5c Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 13:11:55 -0400 Subject: [PATCH 06/11] Add review suggestions --- recipes/cpython/all/conanfile.py | 57 ++++++++++++++++---------------- 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index 647ba2322d729..c3f474b2f03ea 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -512,13 +512,17 @@ def _msvc_package_copy(self): 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 _exact_lib_name(self, folder): - possible_extensions = ("a", "so", "dylib", "lib") - for file in os.listdir(folder): - for extension in possible_extensions: - if re.match(f".*\\.{extension}", file): - return file - raise ConanException(f"No library files found in {folder}") + @property + def _exact_lib_name(self): + if self.settings.os == "Windows": + extension = "lib" + elif not self.options.shared: + extension = "a" + elif is_apple_os(self): + extension = "dylib" + else: + extension = "so" + return f"{self._lib_name}.{extension}" @property def _cmake_module_path(self): @@ -536,45 +540,42 @@ def _write_cmake_findpython_wrapper_file(self): else() set(_CONAN_PYTHON_SUFFIX "") endif() - set(Python${{_CONAN_PYTHON_SUFFIX}}_EXECUTABLE {}) - set(Python${{_CONAN_PYTHON_SUFFIX}}_LIBRARY {}) + set(Python${_CONAN_PYTHON_SUFFIX}_EXECUTABLE @PYTHON_EXECUTABLE@) + set(Python${_CONAN_PYTHON_SUFFIX}_LIBRARY @PYTHON_LIBRARY@) # Fails if these are set beforehand - unset(Python${{_CONAN_PYTHON_SUFFIX}}_INCLUDE_DIRS) - unset(Python${{_CONAN_PYTHON_SUFFIX}}_INCLUDE_DIR) - - include(${{CMAKE_ROOT}}/Modules/FindPython${{_CONAN_PYTHON_SUFFIX}}.cmake) - + unset(Python${_CONAN_PYTHON_SUFFIX}_INCLUDE_DIRS) + unset(Python${_CONAN_PYTHON_SUFFIX}_INCLUDE_DIR) + + include(${CMAKE_ROOT}/Modules/FindPython${_CONAN_PYTHON_SUFFIX}.cmake) + # Sanity check: The former comes from FindPython(3), the latter comes from the injected find module - if(NOT Python${{_CONAN_PYTHON_SUFFIX}}_VERSION STREQUAL Python${{_CONAN_PYTHON_SUFFIX}}_VERSION_STRING) + if(NOT Python${_CONAN_PYTHON_SUFFIX}_VERSION STREQUAL Python${_CONAN_PYTHON_SUFFIX}_VERSION_STRING) message(FATAL_ERROR "CMake detected wrong cpython version - this is likely a bug with the cpython Conan package") endif() - if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::Module) - target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::Module INTERFACE cpython::python) + if (TARGET Python${_CONAN_PYTHON_SUFFIX}::Module) + set_target_properties(Python${_CONAN_PYTHON_SUFFIX}::Module PROPERTIES INTERFACE_LINK_LIBRARIES cpython::python) endif() - if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::SABIModule) - target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::SABIModule INTERFACE cpython::python) + if (TARGET Python${_CONAN_PYTHON_SUFFIX}::SABIModule) + set_target_properties(Python${_CONAN_PYTHON_SUFFIX}::SABIModule PROPERTIES INTERFACE_LINK_LIBRARIES cpython::python) endif() - if (TARGET Python${{_CONAN_PYTHON_SUFFIX}}::Python) - target_link_libraries(Python${{_CONAN_PYTHON_SUFFIX}}::Python INTERFACE cpython::embed) + if (TARGET Python${_CONAN_PYTHON_SUFFIX}::Python) + set_target_properties(Python${_CONAN_PYTHON_SUFFIX}::Python PROPERTIES INTERFACE_LINK_LIBRARIES cpython::embed) endif() """) # In order for the package to be relocatable, these variables must be relative to the installed CMake file if is_msvc(self): - lib_folder = os.path.join(self.package_folder, self._msvc_install_subprefix, "libs") - lib_file = self._exact_lib_name(lib_folder) python_exe = "${CMAKE_CURRENT_LIST_DIR}/../../" + self._cpython_interpreter_name - python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + lib_file + python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + self._exact_lib_name else: - lib_folder = os.path.join(self.package_folder, "lib") - lib_file = self._exact_lib_name(lib_folder) python_exe = "${CMAKE_CURRENT_LIST_DIR}/../../bin/" + self._cpython_interpreter_name - python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + lib_file + python_library = "${CMAKE_CURRENT_LIST_DIR}/../" + self._exact_lib_name cmake_file = os.path.join(self.package_folder, self._cmake_module_path, "use_conan_python.cmake") - save(self, cmake_file, template.format(python_exe, python_library)) + content = template.replace("@PYTHON_EXECUTABLE@", python_exe).replace("@PYTHON_LIBRARY@", python_library) + save(self, cmake_file, content) def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) From 7e0dfe5d0ec3b3f6c655f43cb34760c1f64c6c6b Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 13:13:29 -0400 Subject: [PATCH 07/11] Cleanup self._lib_name --- recipes/cpython/all/conanfile.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index c3f474b2f03ea..ca3d3395727c3 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -664,9 +664,7 @@ def _lib_name(self): else: lib_ext = "" else: - lib_ext = self._abi_suffix + ( - ".dll.a" if self.options.shared and self.settings.os == "Windows" else "" - ) + lib_ext = self._abi_suffix return f"python{self._version_suffix}{lib_ext}" def package_info(self): From 5ac5a41bdff5c4f13310b50e2139aac7b3618528 Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 13:13:55 -0400 Subject: [PATCH 08/11] Fix MSVC debug extension building --- recipes/cpython/all/test_package/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/recipes/cpython/all/test_package/CMakeLists.txt b/recipes/cpython/all/test_package/CMakeLists.txt index 6f592b15f1d3c..68886bdf4d074 100644 --- a/recipes/cpython/all/test_package/CMakeLists.txt +++ b/recipes/cpython/all/test_package/CMakeLists.txt @@ -12,6 +12,9 @@ message("Python3_LIBRARIES: ${Python3_LIBRARIES}") option(BUILD_MODULE "Build python module") if(BUILD_MODULE) python3_add_library(spam "test_module.c") + if(MSVC) + set_target_properties(spam PROPERTIES DEBUG_POSTFIX "_d") + endif() endif() add_executable(${PROJECT_NAME} "test_package.c") From defcf608ade08c874d89b5fd48ac226af78e1035 Mon Sep 17 00:00:00 2001 From: Alex Trotta Date: Sat, 6 Apr 2024 13:45:52 -0400 Subject: [PATCH 09/11] Fix _exact_lib_name on non-Windows --- recipes/cpython/all/conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index ca3d3395727c3..22ecd0330f979 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -514,6 +514,7 @@ def _msvc_package_copy(self): @property def _exact_lib_name(self): + prefix = "" if self.settings.os == "Windows" else "lib" if self.settings.os == "Windows": extension = "lib" elif not self.options.shared: @@ -522,7 +523,7 @@ def _exact_lib_name(self): extension = "dylib" else: extension = "so" - return f"{self._lib_name}.{extension}" + return f"{prefix}{self._lib_name}.{extension}" @property def _cmake_module_path(self): From 0fceb4c901ad52b23ec64223c469ad0ec264323e Mon Sep 17 00:00:00 2001 From: Ahajha Date: Sun, 7 Apr 2024 13:47:10 -0400 Subject: [PATCH 10/11] Fix hook warning --- recipes/cpython/all/conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/cpython/all/conanfile.py b/recipes/cpython/all/conanfile.py index 22ecd0330f979..625b37856b25d 100644 --- a/recipes/cpython/all/conanfile.py +++ b/recipes/cpython/all/conanfile.py @@ -717,6 +717,7 @@ def package_info(self): self.cpp_info.set_property("cmake_module_file_name", "Python") self.cpp_info.set_property("cmake_find_mode", "both") self.cpp_info.set_property("cmake_build_modules", [os.path.join(self._cmake_module_path, "use_conan_python.cmake")]) + self.cpp_info.builddirs = [self._cmake_module_path] if self._supports_modules: # hidden components: the C extensions of python are built as dynamically loaded shared libraries. From ef6f1408601a41e6949c6980ed24dc4782ffa822 Mon Sep 17 00:00:00 2001 From: Ahajha Date: Tue, 9 Apr 2024 12:57:33 -0400 Subject: [PATCH 11/11] Fix patch version --- recipes/cpython/all/conandata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/cpython/all/conandata.yml b/recipes/cpython/all/conandata.yml index 97a5105587069..d49b900576339 100644 --- a/recipes/cpython/all/conandata.yml +++ b/recipes/cpython/all/conandata.yml @@ -28,7 +28,7 @@ patches: - patch_file: "patches/3.12/3.12.1-0002-remove-module-deps.patch" patch_description: "Remove section of solution file forcing projects to be built that might not be used for this recipe" patch_type: "conan" - "3.11.8": + "3.11.9": - patch_file: "patches/3.9/3.9.7-0002-_msi-vcxproj.patch" patch_description: "Fix ARM/ARM64 mismatch in project file" patch_type: "bugfix"