Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cpython: avoid invalid configurations #25500

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 31 additions & 12 deletions recipes/cpython/all/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.apple import is_apple_os, fix_apple_shared_install_name
from conan.tools.build import cross_building, can_run
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.microsoft import MSBuildDeps, MSBuildToolchain, MSBuild, is_msvc, is_msvc_static_runtime, msvc_runtime_flag, msvs_toolset, unix_path
from conan.tools.scm import Version

required_conan_version = ">=1.58.0"
Expand Down Expand Up @@ -65,7 +66,7 @@ class CPythonConan(ConanFile):

@property
def _supports_modules(self):
return not is_msvc(self) or self.options.shared
return not is_msvc(self) or self.options.get_safe("shared", default=True)

@property
def _version_suffix(self):
Expand All @@ -86,6 +87,10 @@ def config_options(self):
del self.options.with_curses
del self.options.with_gdbm
del self.options.with_nis
if is_apple_os(self) and cross_building(self):
# FIXME: The corresponding recipes currently don't support cross building
self.options.with_tkinter = False
self.options.with_curses = False

self.settings.compiler.rm_safe("libcxx")
self.settings.compiler.rm_safe("cppstd")
Expand All @@ -98,13 +103,21 @@ def configure(self):
self.options.rm_safe("with_sqlite3")
self.options.rm_safe("with_tkinter")
self.options.rm_safe("with_lzma")
if is_msvc 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)
# Disabling static MSVC builds (>=3.10) due to "AttributeError: module 'sys' has no attribute 'winver'"
self.package_type = "shared-library"
del self.options.shared

def layout(self):
basic_layout(self, src_folder="src")

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")
if not can_run(self) and not is_msvc(self):
self.build_requires(f"cpython/{self.version}")

def requirements(self):
self.requires("zlib/[>=1.2.11 <2]")
Expand Down Expand Up @@ -148,7 +161,7 @@ def package_id(self):
del self.info.options.env_vars

def validate(self):
if self.options.shared:
if self.options.get_safe("shared", default=True):
if is_msvc_static_runtime(self):
raise ConanInvalidConfiguration(
"cpython does not support MT(d) runtime when building a shared cpython library"
Expand All @@ -170,10 +183,6 @@ def validate(self):
)
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")
Expand Down Expand Up @@ -231,6 +240,16 @@ def _generate_autotools(self):
if not is_apple_os(self):
tc.extra_ldflags.append('-Wl,--as-needed')

if not can_run(self):
build_python = unix_path(self, os.path.join(self.dependencies.build["cpython"].package_folder, "bin", "python"))
tc.configure_args.append(f"--with-build-python={build_python}")
# The following are required only when cross-building, but set for all cases for consistency
tc.configure_args.append("--enable-ipv6") # enabled by default, but skip the check
dev_ptmx_exists = os.path.exists("/dev/ptmx")
dev_ptc_exists = os.path.exists("/dev/ptc")
tc.configure_args.append(f"ac_cv_file__dev_ptmx={yes_no(dev_ptmx_exists)}")
tc.configure_args.append(f"ac_cv_file__dev_ptc={yes_no(dev_ptc_exists)}")

tc.generate()

deps = AutotoolsDeps(self)
Expand Down Expand Up @@ -436,7 +455,7 @@ def _patch_sources(self):
"$(RUNSHARED) CC='$(CC) $(CONFIGURE_CFLAGS) $(CONFIGURE_CPPFLAGS)' LDSHARED='$(BLDSHARED)' OPT='$(OPT)'")

# Enable static MSVC cpython
if not self.options.shared:
if not self.options.get_safe("shared", default=True):
replace_in_file(self, os.path.join(self.source_folder, "PCbuild", "pythoncore.vcxproj"),
"<PreprocessorDefinitions>",
"<PreprocessorDefinitions>Py_NO_BUILD_SHARED;")
Expand Down Expand Up @@ -473,7 +492,7 @@ def _patch_sources(self):

@property
def _solution_projects(self):
if self.options.shared:
if self.options.get_safe("shared", default=True):
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()))

Expand Down Expand Up @@ -653,7 +672,7 @@ 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:
elif not self.options.get_safe("shared", default=True):
extension = "a"
elif is_apple_os(self):
extension = "dylib"
Expand Down Expand Up @@ -717,7 +736,7 @@ def _write_cmake_findpython_wrapper_file(self):
def package(self):
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
if is_msvc(self):
if self.options.shared:
if self.options.get_safe("shared", default=True):
self._msvc_package_layout()
else:
self._msvc_package_copy()
Expand Down Expand Up @@ -815,7 +834,7 @@ def package_info(self):
os.path.join("include", f"python{self._version_suffix}{self._abi_suffix}")
)
libdir = "lib"
if self.options.shared:
if self.options.get_safe("shared", default=True):
self.cpp_info.components["python"].defines.append("Py_ENABLE_SHARED")
else:
self.cpp_info.components["python"].defines.append("Py_NO_ENABLE_SHARED")
Expand Down
10 changes: 7 additions & 3 deletions recipes/cpython/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
cmake_minimum_required(VERSION 3.15)
project(test_package C)

find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module Development.Embed)
find_package(Python3 REQUIRED COMPONENTS Development.Module Development.Embed)

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(CAN_RUN)
find_package(Python3 REQUIRED COMPONENTS Interpreter)
message("Python3_EXECUTABLE: ${Python3_EXECUTABLE}")
message("Python3_INTERPRETER_ID: ${Python3_INTERPRETER_ID}")
endif()

option(BUILD_MODULE "Build python module")
if(BUILD_MODULE)
python3_add_library(spam "test_module.c")
Expand Down
2 changes: 2 additions & 0 deletions recipes/cpython/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def _supports_modules(self):
def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["BUILD_MODULE"] = self._supports_modules
tc.cache_variables["CAN_RUN"] = can_run(self)
tc.generate()

deps = CMakeDeps(self)
Expand All @@ -80,6 +81,7 @@ def generate(self):

# The build also needs access to the run environment to run the python executable
VirtualRunEnv(self).generate(scope="run")
# Required for find_package() work with shared=True
VirtualRunEnv(self).generate(scope="build")

if self._test_setuptools:
Expand Down
Loading