diff --git a/.gitignore b/.gitignore index 6c3ef9113..c89ecb7d6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ *.pyc build_artifacts - -.vscode/ diff --git a/anaconda.yaml b/anaconda.yaml index c53fbf835..7a50beb1d 100644 --- a/anaconda.yaml +++ b/anaconda.yaml @@ -7,9 +7,10 @@ upstream_sources: from_pattern: ^v(\d+\.\d+\.\d+)$ to_pattern: \1 packages: + - python - libpython - libpython-static - - python + - cpython - python-freethreading - python-gil - python-jit diff --git a/recipe/build_base.bat b/recipe/build_base.bat index cd5a6d455..a3ae43509 100644 --- a/recipe/build_base.bat +++ b/recipe/build_base.bat @@ -54,7 +54,7 @@ if "%DEBUG_C%"=="yes" ( :: AP doesn't support PGO atm? set PGO= -if "%PY_GIL_DISABLED%" == "yes" ( +if "%PY_FREETHREADING%" == "yes" ( set "FREETHREADING=--disable-gil" set "THREAD=t" set "EXE_T=%VER%t" @@ -75,6 +75,13 @@ set TCLTK_MSBUILD_PROPS="/p:TclVersion=%tk%" "/p:TkVersion=%tk%" cd PCbuild +:: CF (skipped): CONDA_BUILD_CROSS_COMPILATION host-vs-build extra MSBuild. +:: AR native workers only; ARCH/BUILD_PATH above, not CF HOST_DIR/BUILD_DIR. +:: if "%CONDA_BUILD_CROSS_COMPILATION%" == "1" ( +:: set LIBRARY_PREFIX=%BUILD_PREFIX%\\Library +:: call build.bat %CONFIG% %FREETHREADING% -m -e -v -p %BUILD_PLATFORM% %TCLTK_MSBUILD_PROPS% +:: ) + :: Twice because: :: error : importlib_zipimport.h updated. You will need to rebuild pythoncore to see the changes. call build.bat %PGO% %CONFIG% %FREETHREADING% -m -e -v -p %PLATFORM% %TCLTK_MSBUILD_PROPS% diff --git a/recipe/build_base.sh b/recipe/build_base.sh index 849e82122..8af3c6a7e 100644 --- a/recipe/build_base.sh +++ b/recipe/build_base.sh @@ -9,6 +9,7 @@ cp $BUILD_PREFIX/share/libtool/build-aux/config.* . # https://docs.python.org/3.14/using/configure.html#cmdoption-enable-experimental-jit # says we want a python>=3.11 to build python. if [[ ! -d ${SRC_DIR}/python-bin ]]; then + # AR: bootstrap from main (CF uses -c conda-forge). CONDA_SUBDIR=$build_platform conda create -p ${SRC_DIR}/python-bin "python>=3.11" -c main --override-channels --yes --quiet export PATH=${SRC_DIR}/python-bin/bin:${PATH} fi @@ -35,24 +36,23 @@ _buildd_shared=build-shared _ENABLE_SHARED=--enable-shared # We *still* build a shared lib here for non-static embedded use cases _DISABLE_SHARED=--disable-shared -# Hack to allow easily comparing static vs shared interpreter performance -# .. hack because we just build it shared in both the build-static and -# build-shared directories. -# Yes this hack is a bit confusing, sorry about that. -if [[ ${PY_INTERP_LINKAGE_NATURE} == shared ]]; then - _DISABLE_SHARED=--enable-shared - _ENABLE_SHARED=--enable-shared -fi # For debugging builds, set this to no to disable profile-guided optimization -if [[ ${DEBUG_C} == yes ]]; then +if [[ ${PY_INTERP_DEBUG} == yes || ${DEBUG_C} == yes ]]; then _OPTIMIZED=no else _OPTIMIZED=yes fi +# CF (skipped): debug builds on conda-forge main must not ship; AR has no python_debug channel. +# if [[ ${PY_INTERP_DEBUG} == yes ]]; then +# if [[ "$CI" != "" && "$channel_targets" == "conda-forge main" ]]; then +# exit 1 +# fi +# fi + declare -a _dbg_opts -if [[ ${DEBUG_PY} == yes ]]; then +if [[ ${PY_INTERP_DEBUG} == yes ]]; then # This Python will not be usable with non-debug Python modules. _dbg_opts+=(--with-pydebug) DBG=d @@ -60,15 +60,16 @@ else DBG= fi -if [[ ${PY_GIL_DISABLED} == yes ]]; then +if [[ ${PY_FREETHREADING} == yes ]]; then # This Python will not be usable with non-free threading Python modules. THREAD=t else THREAD= fi -ABIFLAGS=${DBG} +ABIFLAGS=${DBG}${THREAD} VERABI=${VER}${THREAD}${DBG} +VERABI_NO_DBG=${VER}${THREAD} # Make sure the "python" value in conda_build_config.yaml is up to date. test "${PY_VER}" = "${VER}" @@ -107,6 +108,12 @@ if [[ ${_OPTIMIZED} = yes ]]; then CXXFLAGS=$(echo "${CXXFLAGS}" | sed "s/-O2/-O3/g") fi +if [[ ${PY_INTERP_DEBUG} == yes ]]; then + CPPFLAGS=$(echo "${CPPFLAGS}" | sed "s/-O2/-O0/g") + CFLAGS=$(echo "${CFLAGS}" | sed "s/-O2/-O0/g") + CXXFLAGS=$(echo "${CXXFLAGS}" | sed "s/-O2/-O0/g") +fi + if [[ "$target_platform" == linux-* ]]; then cp ${PREFIX}/include/uuid/uuid.h ${PREFIX}/include/uuid.h fi @@ -170,6 +177,7 @@ if [[ "${CONDA_BUILD_CROSS_COMPILATION}" == "1" ]]; then echo "ac_cv_file__dev_ptc=no" >> config.site echo "ac_cv_pthread=yes" >> config.site echo "ac_cv_little_endian_double=yes" >> config.site + # CF also lists linux-riscv64 here; AR does not build it. if [[ "${target_platform}" == "osx-arm64" || "${target_platform}" == "linux-ppc64le" || "${target_platform}" == "linux-aarch64" ]]; then echo "ac_cv_aligned_required=no" >> config.site echo "ac_cv_pthread_is_default=yes" >> config.site @@ -207,6 +215,7 @@ if [[ ${target_platform} == osx-64 ]]; then # TODO: check with LLVM 12 if the following hack is needed. # https://reviews.llvm.org/D76461 may have fixed the need for the following hack. echo '#!/bin/bash' > $BUILD_PREFIX/bin/$HOST-llvm-ar + # AR: versioned llvm-ar (CF uses unversioned llvm-ar → LLVM 20 Abort). echo "$BUILD_PREFIX/bin/llvm-ar-$LLVM_VER --format=darwin" '"$@"' >> $BUILD_PREFIX/bin/$HOST-llvm-ar chmod +x $BUILD_PREFIX/bin/$HOST-llvm-ar export ARCHFLAGS="-arch x86_64" @@ -253,14 +262,13 @@ _common_configure_args+=(--with-tzpath=${PREFIX}/share/zoneinfo) _common_configure_args+=(--with-computed-gotos) _common_configure_args+=(--with-system-expat) _common_configure_args+=(--enable-loadable-sqlite-extensions) -# TODO: Remove this comment in PR#256 # Dropped dead tcltk configure flags — log-confirmed unused in 3.15.0rc2: # configure: WARNING: unrecognized options: --with-tcltk-includes, --with-tcltk-libs # _tkinter already comes from pkg-config. _common_configure_args+=(--with-platlibdir=lib) _common_configure_args+=(--with-system-libmpdec=yes) -if [[ "${DEBUG_PY}" == "yes" || "${target_platform}" != *"64" || ${PY_GIL_DISABLED} == yes ]]; then +if [[ "${PY_INTERP_DEBUG}" == "yes" || "${target_platform}" != *"-64" || ${PY_FREETHREADING} == yes ]]; then _common_configure_args+=(--enable-experimental-jit=no) else _common_configure_args+=(--enable-experimental-jit=yes-off) @@ -271,7 +279,7 @@ if [[ "${target_platform}" == osx-* ]]; then _common_configure_args+=(--with-tail-call-interp) fi -if [[ ${PY_GIL_DISABLED} == yes ]]; then +if [[ ${PY_FREETHREADING} == yes ]]; then _common_configure_args+=(--disable-gil) fi @@ -337,8 +345,8 @@ pushd ${_buildd_static} popd make -j${CPU_COUNT} -C ${_buildd_static} \ - EXTRA_CFLAGS="${EXTRA_CFLAGS}" \ - ${_MAKE_TARGET} "${_PROFILE_TASK[@]}" 2>&1 | tee make-static.log + EXTRA_CFLAGS="${EXTRA_CFLAGS}" \ + ${_MAKE_TARGET} "${_PROFILE_TASK[@]}" 2>&1 | tee make-static.log if rg "Failed to build these modules" make-static.log; then echo "(static) :: Failed to build some modules, check the log" exit 1 @@ -370,7 +378,7 @@ fi # build a static library with PIC objects and without LTO/PGO make -j${CPU_COUNT} -C ${_buildd_shared} \ EXTRA_CFLAGS="${EXTRA_CFLAGS}" \ - LIBRARY=libpython${VERABI}-pic.a libpython${VERABI}-pic.a + LIBRARY=libpython${VERABI_NO_DBG}-pic.a libpython${VERABI_NO_DBG}-pic.a make -C ${_buildd_static} install @@ -389,13 +397,23 @@ if [[ ${_OPTIMIZED} == yes ]]; then _FLAGS_REPLACE+=("") done fi -# Use sysconfigdata from the shared build, as we want packages to prefer -# linking against the shared library. Issue #565. -SYSCONFIG=$(find ${_buildd_shared}/$(cat ${_buildd_shared}/pybuilddir.txt) -name "_sysconfigdata*.py" -print0) +# Use sysconfig from the shared build so extensions prefer .so (CF #565). +# Shared libpython*.so/.dylib is installed by the libpython output, not here. +BUILD_DIR=$(< ${_buildd_shared}/pybuilddir.txt) +SYSCONFIG=$(find ${_buildd_shared}/${BUILD_DIR} -name "_sysconfigdata*.py" -print0) cat ${SYSCONFIG} | ${SYS_PYTHON} "${RECIPE_DIR}"/replace-word-pairs.py \ "${_FLAGS_REPLACE[@]}" \ - > ${PREFIX}/lib/python${VERABI}/$(basename ${SYSCONFIG}) -MAKEFILE=$(find ${PREFIX}/lib/python${VERABI}/ -path "*config-*/Makefile" -print0) + > ${PREFIX}/lib/python${VERABI_NO_DBG}/$(basename ${SYSCONFIG}) +# CF copies build-details.json from the shared build (#565). Native only: +# AR does not cross-compile (CONDA_BUILD_CROSS_COMPILATION is never 1). +# if [[ "${CONDA_BUILD_CROSS_COMPILATION}" == "1" ]]; then +# # build-details.json is incorrect when cross-compiling: +# # https://github.com/python/cpython/issues/136267 +# ... +# fi +BUILD_DETAILS=${_buildd_shared}/${BUILD_DIR}/build-details.json +cp ${BUILD_DETAILS} ${PREFIX}/lib/python${VERABI_NO_DBG}/ +MAKEFILE=$(find ${PREFIX}/lib/python${VERABI_NO_DBG}/ -path "*config-*/Makefile" -print0) cp ${MAKEFILE} /tmp/Makefile-$$ cat /tmp/Makefile-$$ | ${SYS_PYTHON} "${RECIPE_DIR}"/replace-word-pairs.py \ "${_FLAGS_REPLACE[@]}" \ @@ -417,7 +435,7 @@ ln -s ${PREFIX}/bin/pydoc${VER} ${PREFIX}/bin/pydoc # Remove test data to save space # Though keep `support` as some things use that. # TODO :: Make a subpackage for this once we implement multi-level testing. -pushd ${PREFIX}/lib/python${VERABI} +pushd ${PREFIX}/lib/python${VERABI_NO_DBG} mkdir test_keep mv test/__init__.py test/support test/test_support* test/test_script_helper* test_keep/ rm -rf test */test @@ -430,7 +448,7 @@ pushd ${PREFIX} chmod +w lib/libpython${VERABI}.a ${STRIP} -S lib/libpython${VERABI}.a fi - CONFIG_LIBPYTHON=$(find lib/python${VERABI}/config-${VERABI}* -name "libpython${VERABI}.a") + CONFIG_LIBPYTHON=$(find lib/python${VERABI_NO_DBG}/config-${VERABI}* -name "libpython${VERABI}.a") if [[ -f lib/libpython${VERABI}.a ]] && [[ -f ${CONFIG_LIBPYTHON} ]]; then chmod +w ${CONFIG_LIBPYTHON} rm ${CONFIG_LIBPYTHON} @@ -440,7 +458,7 @@ popd # Copy sysconfig that gets recorded to a non-default name # using the new compilers with python will require setting _PYTHON_SYSCONFIGDATA_NAME # to the name of this file (minus the .py extension) -pushd "${PREFIX}"/lib/python${VERABI} +pushd "${PREFIX}"/lib/python${VERABI_NO_DBG} # On Python 3.5 _sysconfigdata.py was getting copied in here and compiled for some reason. # This breaks our attempt to find the right one as recorded_name. find lib-dynload -name "_sysconfigdata*.py*" -exec rm {} \; @@ -497,6 +515,7 @@ pushd "${PREFIX}"/lib/python${VERABI} popd if [[ ${HOST} =~ .*linux.* ]]; then + # AR: historical path (CF uses share/python_compiler_compat). mkdir -p ${PREFIX}/compiler_compat ln -s ${PREFIX}/bin/${HOST}-ld ${PREFIX}/compiler_compat/ld echo "Files in this folder are to enhance backwards compatibility of anaconda software with older compilers." > ${PREFIX}/compiler_compat/README @@ -505,6 +524,13 @@ fi python -c "import compileall,os;compileall.compile_dir(os.environ['PREFIX'])" rm ${PREFIX}/lib/libpython${VERABI}.a + +if [[ ${PY_INTERP_DEBUG} == yes ]]; then + rm ${PREFIX}/bin/python${VER} + ln -s ${PREFIX}/bin/python${VERABI} ${PREFIX}/bin/python${VER} + ln -s ${PREFIX}/include/python${VERABI} ${PREFIX}/include/python${VER} +fi + if [[ "$target_platform" == linux-* ]]; then rm ${PREFIX}/include/uuid.h fi @@ -522,7 +548,7 @@ fi # /lib/python3.13t/site-packages. # Note that these directories are not added to sys.path if they do not exist. SP_DIR="${PREFIX}/lib/python${PY_VER}${THREAD}/site-packages" -if [[ ${PY_GIL_DISABLED} == yes ]]; then +if [[ ${PY_FREETHREADING} == yes ]]; then echo "${PREFIX}/lib/python${PY_VER}/site-packages" >> $SP_DIR/conda-site.pth fi # Do not add ${PREFIX}/lib/python/site-packages (CF experimental ABI3/noarch diff --git a/recipe/conda_build_config.yaml b/recipe/conda_build_config.yaml index 5e998d424..fde999661 100644 --- a/recipe/conda_build_config.yaml +++ b/recipe/conda_build_config.yaml @@ -14,10 +14,16 @@ python_impl: # Override aggregate global tk 8.6 — build/test against tk 9 from pkgs/main tk: - '9.0' -gil_type: - - normal - # Will be enabled as part of https://anaconda.atlassian.net/browse/PKG-5855 - - disabled # [not (s390x or (osx and x86_64))] +# Whether to build free-threaded Python (3.13+) +freethreading: + - yes + - no + +# Debug interpreter lives on PR #258 / PKG-2624, not this CF-align PR. +# Do not zip with channel_targets (F94): all variants upload to +# ad-testing/label/py315. +build_type: + - release # Override aggregate global clang 20 on osx. CPython 3.15 JIT requires LLVM 21 # (Tools/jit/_llvm.py); mixing compiler('c')=20 with clang-21/llvm-tools-21 diff --git a/recipe/meta.yaml b/recipe/meta.yaml index 0ca4fe2a7..58978a472 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -4,65 +4,70 @@ {% set ver2 = '.'.join(version.split('.')[0:2]) %} {% set ver2nd = ''.join(version.split('.')[0:2]) %} {% set ver3nd = ''.join(version.split('.')[0:3]) %} -{% set build_number = 0 %} +{% set build_number = 1 %} + {% set channel_targets = ('abc', 'def') %} -# this is just for the initial build, to break dependencies with python -> pip -> libpython-static -{% set bootstrap = "false" %} # this makes the linter happy {% set channel_targets = channel_targets or 'conda-forge main' %} # Sanitize build system env. var tweak parameters # (passed to the build scripts via script_env). -{% set from_source_control = os.environ.get('CONDA_BUILD_FROM_SOURCE_CONTROL', '') %} -{% if from_source_control == '' or from_source_control == 'no' %} - {% set from_source_control = 'no' %} -{% else %} - {% set from_source_control = 'yes' %} -{% endif %} -{% set linkage_nature = os.environ.get('PY_INTERP_LINKAGE_NATURE', '') %} -{% if linkage_nature != '' %} - {% set linkage_nature = "_" ~ linkage_nature %} +{% if freethreading is not defined %} + {% set freethreading = "yes" %} {% endif %} -{% if linkage_nature == 'shared' %} - {% set linkage_nature_env = 'shared' %} + +{% set abi_tag = "cp" + ver2nd %} +# freethreading, set using conda_build_config.yaml +{% if freethreading == "yes" %} + {% set abi_tag = abi_tag + "t" %} {% else %} - {% set linkage_nature_env = 'static' %} + {% set build_number = build_number + 100 %} {% endif %} -{% set dbg_abi = "" %} -{% set debug = os.environ.get('PY_INTERP_DEBUG', '') %} -{% if debug != '' and debug != 'no' %} + +# build_type, set using conda_build_config.yaml +{% if build_type == "debug" %} {% set py_interp_debug = "yes" %} - {% set debug = "_dbg" %} - {% set dbg_abi = "d" %} # [win] + {% set debug = "_debug" %} {% else %} {% set py_interp_debug = "no" %} + {% set debug = "" %} {% endif %} -# no-GIL, set using conda_build_config.yaml -{% if gil_type is defined and gil_type == "disabled" %} - {% set py_gil_disabled = "yes" %} - {% set abi_suffix = "t" %} +{% if win %} + {% set site_packages_path = "lib/python/site-packages" %} +{% elif freethreading == "yes" %} + {% set site_packages_path = "lib/python" + ver2 + "t/site-packages" %} {% else %} - {% set py_gil_disabled = "no" %} - {% set abi_suffix = "" %} - {% set build_number = build_number + 100 %} + {% set site_packages_path = "lib/python" + ver2 + "/site-packages" %} +{% endif %} + +# CMake needs to be told that the debug/freethreading ABI is fine; the option takes a 4-tuple, +# Python_FIND_ABI=;;;; for details see +# https://cmake.org/cmake/help/latest/module/FindPython.html#hints +{% set cmake_test_args=" -DPython_FIND_ABI=\"" ~ ("ON" if build_type == "debug" else "OFF") ~ ";ANY;ANY;" ~ ("ON" if freethreading == "yes" else "OFF") ~ "\"" %} +{% if unix %} + # for CMake invocations during testing, we need to avoid accidentally picking up python versions from + # the image, but we don't want to use `${CMAKE_ARGS}` from the compiler activation, because that contains + # `CMAKE_FIND_ROOT_PATH_MODE_PROGRAM=NEVER`; while that's useful for building (i.e. don't look in `host:`, + # because we want to use binaries from `build:`), we want the exact opposite when running tests. + {% set cmake_test_args=cmake_test_args ~ " -DCMAKE_POLICY_DEFAULT_CMP0094=NEW -DCMAKE_FIND_ROOT_PATH_MODE_PROGRAM=ONLY -DCMAKE_FIND_ROOT_PATH=${PREFIX}" %} +{% endif %} + +# extremely noisy; only use if needing to debug how CMake finds our libraries +{% set cmake_debug = "" %} +{% if False %} + {% set cmake_debug = "--debug-find --trace --debug-output --debug-trycompile" %} {% endif %} -{% set abi_tag = "cp" + ver2nd + abi_suffix %} package: name: python-split version: {{ version }}{{ dev }} source: -{% if from_source_control == 'yes' %} - - git_url: https://github.com/python/CPython.git - git_tag: v{{ version }}{{ dev }} -{% else %} - url: https://www.python.org/ftp/python/{{ version }}/Python-{{ version }}{{ dev }}.tar.xz - # md5 from: https://www.python.org/downloads/release/python-{{ ver3nd }}/ + # sha256 from: https://www.python.org/downloads/release/python-{{ ver3nd }}{{ dev }}/ sha256: 506630aa66d5441188f34df22c0760bfe87fc92212630493ebc9ff3b3a7a1d49 -{% endif %} patches: - patches/0001-Win32-Change-FD_SETSIZE-from-512-to-2048.patch - patches/0002-Win32-Do-not-download-externals.patch @@ -94,22 +99,22 @@ source: - patches/0023-branding.patch - patches/0024-Do-not-define-pid_t-as-it-might-conflict-with-the-ac.patch - patches/0025-Unvendor-zstd.patch - - patches/0026-Set-Py_GIL_DISABLED-in-windows-to-match-unix.patch # [win and gil_type == "disabled"] +{% if freethreading == "yes" %} + - patches/0026-Set-Py_GIL_DISABLED-in-windows-to-match-unix.patch +{% endif %} - patches/0027-More-unixy-layout-for-windows.patch - patches/0028-Avoid-erroring-when-conda-site.pth-has-non-existent-.patch - patches/0029-Unvendor-zlib-ng.patch - - patches/0030-xxlimited-freethreading-stable-abi-link.patch # [win and gil_type == "disabled"] +{% if freethreading == "yes" %} + - patches/0030-xxlimited-freethreading-stable-abi-link.patch +{% endif %} build: number: {{ build_number }} requirements: build: -{% if from_source_control == 'yes' %} - - git -{% else %} - msys2-gcc-libs # [win] -{% endif %} outputs: - name: python @@ -126,8 +131,8 @@ outputs: # C++ only installed so CXX is defined for distutils/sysconfig. - {{ compiler('cxx') }} # [unix] # These two are just to get the headers needed for tk.h, but is unused - - xorg-libx11 # [linux] - - xorg-xorgproto # [linux] + - xorg-libx11 # [unix] + - xorg-xorgproto # [unix] # Disabled until verified to work correctly detect_binary_files_with_prefix: true # detect_binary_files_with_prefix: False @@ -141,30 +146,26 @@ outputs: # - lib/libpython3.dylib # [osx] # match python.org compiler standard skip: true # [win and int(float(vc)) < 14] -{% if 'conda-forge' in channel_targets %} - skip_compile_pyc: - - '*.py' # [build_platform != target_platform] -{% endif %} - string: {{ dev_ }}h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ linkage_nature }}{{ debug }}_{{ abi_tag }} + string: {{ dev_ }}h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ debug }}_{{ abi_tag }} + python_site_packages_path: {{ site_packages_path }} run_exports: noarch: - python weak: - python_abi {{ ver2 }}.* *_{{ abi_tag }} - track_features: # [gil_type == "disabled"] - - free-threading # [gil_type == "disabled"] +{% if py_interp_debug == "yes" %} + - python {{ ver2 }}.* *_debug_{{ abi_tag }} +{% endif %} +{% if freethreading == "yes" %} + track_features: + - py_freethreading +{% endif %} script_env: - - PY_INTERP_LINKAGE_NATURE={{ linkage_nature_env }} - PY_INTERP_DEBUG={{ py_interp_debug }} - - PY_GIL_DISABLED={{ py_gil_disabled }} + - PY_FREETHREADING={{ freethreading }} # Putting these here means they get emitted to build_env_setup.{sh,bat} meaning we can launch IDEs # after sourcing or calling that script without examine the contents of conda_build.{sh,bat} for # important env. vars. -{% if 'conda-forge' in channel_targets %} - - CONDA_FORGE=yes -{% else %} - - CONDA_FORGE=no -{% endif %} missing_dso_whitelist: # [win or linux] - '**/MSVCR71.dll' # [win] - '**/MSVCR80.dll' # [win] @@ -189,57 +190,50 @@ outputs: - libtool # [unix] - pkg-config # [not win] - ld_impl_{{ target_platform }} # [linux] -{% if 'conda-forge' in channel_targets %} - - binutils_impl_{{ target_platform }} # [linux] -{% endif %} - # called in build_base.sh - - sed # [unix] - - ripgrep # [not win] + # we haven't used binutils for builds of python on main + #- binutils_impl_{{ target_platform }} # [linux] # https://github.com/python/cpython/blob/main/Tools/jit/README.md#installing-llvm: # "LLVM version 21 is the officially supported version" - clang-21 # [not win] # configure script looks for llvm-ar for lto. - # llvm-tools-21 also supplies llvm-ar-21, which build_base.sh wraps as the lto archiver - # that configure picks up via $HOST-llvm-ar. + # llvm-tools-21 also supplies llvm-ar-21, which build_base.sh + # wraps as the lto archiver that configure picks up via + # $HOST-llvm-ar. - llvm-tools-21 # [not win] - clang 21.* # [win] - llvm-tools 21.* # [win] + # called in build_base.sh + - sed # [unix] + - ripgrep # [unix] host: - bzip2 {{ bzip2 }} - - sqlite {{ sqlite }} + - expat {{ expat }} + - ld_impl_{{ target_platform }} >=2.36.1 # [linux] + - libffi {{ libffi }} - xz {{ xz }} + - libmpdec-devel {{ libmpdec }} + - libuuid {{ libuuid }} # [linux] + - sqlite {{ sqlite }} + - ncurses {{ ncurses }} # [unix] + - openssl {{ openssl }} + - readline {{ readline }} # [unix] + - tk {{ tk }} + # These two are just to get the headers needed for tk.h, but is unused + - xorg-libx11 {{ xorg_libx11 }} # [unix] + - xorg-xorgproto {{ xorg_xorgproto }} # [unix] # Although we might like to use zlib-ng something else is # pulling in zlib and we get an overlinking error - zlib {{ zlib }} #- zlib-ng {{ zlib_ng }} - zstd {{ zstd }} - - openssl {{ openssl }} - - readline {{ readline }} # [not win] - - tk {{ tk }} - # These two are just to get the headers needed for tk.h, but is unused - - xorg-libx11 {{ xorg_libx11 }} # [linux] - - xorg-xorgproto {{ xorg_xorgproto }} # [linux] - - ncurses {{ ncurses }} # [unix] - - libffi {{ libffi }} - - ld_impl_{{ target_platform }} >=2.35.1 # [linux] - - libuuid {{ libuuid }} # [linux] - - libmpdec-devel {{ libmpdec }} - - expat {{ expat }} run: - - ld_impl_{{ target_platform }} >=2.35.1 # [linux] + - ld_impl_{{ target_platform }} >=2.36.1 # [linux] - tzdata - python_abi {{ ver2 }}.* *_{{ abi_tag }} -{% if 'conda-forge' in channel_targets %} - - ncurses # [unix] - run_constrained: - - python_abi {{ ver2 }}.* *_cp{{ ver2nd }} -{% endif %} test: -{% if 'conda-forge' in channel_targets %} - downstreams: - - cython - - setuptools -{% endif %} + #downstreams: + # - cython + # - setuptools requires: - ripgrep - cmake-no-system @@ -252,6 +246,8 @@ outputs: - {{ compiler('c') }} # Tried to use enable_language(C) to avoid needing this. It does not work. - {{ compiler('cxx') }} + # For tkinter, but we expect from system + - xorg-libx11 # [unix] files: - tests/cmake/* - tests/cython/* @@ -285,6 +281,19 @@ outputs: - test ! -f ${PREFIX}/lib/libpython${PKG_VERSION%.*}.so # [linux] - test ! -f ${PREFIX}/lib/libpython${PKG_VERSION%.*}.dylib # [osx] - test ! -f ${PREFIX}/lib/libpython${PKG_VERSION%.*}.nolto.a # [unix] + {% if freethreading == "yes" %} + - if not exist %PREFIX%\\lib\\python3t.lib exit 1 # [win] + - if not exist %PREFIX%\\lib\\python{{ ver2nd }}t.lib exit 1 # [win] + # libs\ kept for link-time compat (CFEP-27 section 6, conda-forge PR 918) + - if not exist %PREFIX%\\libs\\python3t.lib exit 1 # [win] + - if not exist %PREFIX%\\libs\\python{{ ver2nd }}t.lib exit 1 # [win] + {% else %} + - if not exist %PREFIX%\\lib\\python3.lib exit 1 # [win] + - if not exist %PREFIX%\\lib\\python{{ ver2nd }}.lib exit 1 # [win] + # libs\ kept for link-time compat (CFEP-27 section 6, conda-forge PR 918) + - if not exist %PREFIX%\\libs\\python3.lib exit 1 # [win] + - if not exist %PREFIX%\\libs\\python{{ ver2nd }}.lib exit 1 # [win] + {% endif %} # https://github.com/conda-forge/python-feedstock/issues/384 - if exist %PREFIX%\\Scripts\\pydoc exit 1 # [win] - if exist %PREFIX%\\Scripts\\idle exit 1 # [win] @@ -292,14 +301,10 @@ outputs: - if not exist %PREFIX%\\Scripts\\idle-script.py exit 1 # [win] - if not exist %PREFIX%\\Scripts\\idle.exe exit 1 # [win] - if not exist %PREFIX%\\Scripts\\pydoc.exe exit 1 # [win] - # 0027 unixy Win layout: getpath landmarks lib\python\os.py and include\python. - if not exist %PREFIX%\\include\\python\\pyconfig.h exit 1 # [win] - - if not exist %PREFIX%\\lib\\python{{ ver2nd }}{{ abi_suffix }}.lib exit 1 # [win] - # libs\ kept for link-time compat (CFEP-27 section 6, conda-forge PR 918) - - if not exist %PREFIX%\\libs\\python{{ ver2nd }}{{ abi_suffix }}.lib exit 1 # [win] - pushd tests - pushd cmake - - cmake -GNinja -DPY_VER={{ version }} -DEXTRA_COMPONENTS="Development.Module" --debug-find --trace --debug-output --debug-trycompile . + - cmake -GNinja {{ cmake_test_args }} -DPY_VER={{ version }} -DEXTRA_COMPONENTS="Development.Module" {{ cmake_debug }} . - popd - popd - python run_test.py @@ -321,8 +326,8 @@ outputs: - {{ compiler('cxx') }} # [unix] script_env: - PY_INTERP_DEBUG={{ py_interp_debug }} - - PY_FREETHREADING={{ py_gil_disabled }} - string: h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ linkage_nature }}{{ debug }}_{{ abi_tag }} + - PY_FREETHREADING={{ freethreading }} + string: h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ debug }}_{{ abi_tag }} run_exports: # [unix] weak: # [unix] - {{ pin_subpackage("libpython", min_pin="x.x", max_pin="x") }} # [unix] @@ -337,115 +342,139 @@ outputs: - {{ pin_subpackage('python', exact=True) }} test: files: + - tests/cmake/* - tests/prefix-replacement/* requires: - {{ stdlib('c') }} - {{ compiler('c') }} + # cmake expects a C++ compiler for some reason - {{ compiler('cxx') }} - ripgrep + - cmake-no-system + - ninja-base commands: - - VER=${PKG_VERSION%.*} # [unix] - - VERABI=${VER} # [unix] -{% if py_gil_disabled == "yes" %} - - VERABI=${VERABI}t # [unix] + - VER=${PKG_VERSION%.*} # [not win] + - VERABI=${VER} # [not win] +{% if freethreading == "yes" %} + - VERABI=${VERABI}t # [not win] {% endif %} + - VERABI_NO_DBG=${VERABI} # [not win] {% if py_interp_debug == "yes" %} - - VERABI=${VERABI}d # [unix] + - VERABI=${VERABI}d # [not win] {% endif %} - test -f ${PREFIX}/lib/libpython${VERABI}${SHLIB_EXT} # [unix] -{% if py_interp_debug == "no" %} - - test -f ${PREFIX}/lib/libpython3${SHLIB_EXT} # [unix] -{% endif %} - - pushd tests # [unix] - - pushd prefix-replacement # [unix] - - bash build-and-test.sh # [unix] - - popd # [unix] - - popd # [unix] + - test -f ${PREFIX}/lib/libpython3${SHLIB_EXT} # [unix and build_type == "release"] + - pushd tests + - pushd prefix-replacement # [unix] + - bash build-and-test.sh # [unix] + - popd # [unix] + - pushd cmake + - cmake -GNinja {{ cmake_test_args }} -DPY_VER={{ version }} -DEXTRA_COMPONENTS="Development.Embed" {{ cmake_debug }} . + - popd + - popd -{% if bootstrap != "true" %} - name: libpython-static - script: install_static.sh # [unix] + script: install_static.sh # [unix] build: number: {{ build_number }} + # hints for the CI system force_use_keys: - - gil_type + - freethreading + - build_type activate_in_script: true ignore_run_exports: - python_abi ignore_run_exports_from: # [unix] - {{ compiler('cxx') }} # [unix] - string: h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ linkage_nature }}{{ debug }}_{{ abi_tag }} script_env: - - PY_GIL_DISABLED={{ py_gil_disabled }} - PY_INTERP_DEBUG={{ py_interp_debug }} - - PY_FREETHREADING={{ py_gil_disabled }} + - PY_FREETHREADING={{ freethreading }} + string: h{{ PKG_HASH }}_{{ PKG_BUILDNUM }}{{ debug }}_{{ abi_tag }} requirements: build: - {{ stdlib('c') }} - {{ compiler('c') }} - {{ compiler('cxx') }} -{% if from_source_control == 'yes' %} - - git -{% endif %} host: - {{ pin_subpackage('python', exact=True) }} run: - {{ pin_subpackage('python', exact=True) }} test: files: + - tests/cmake/* - tests/prefix-replacement/* requires: - {{ stdlib('c') }} - {{ compiler('c') }} - # Tried to use enable_language(C) to avoid needing this. It does not work. + # cmake expects a C++ compiler for some reason - {{ compiler('cxx') }} - ripgrep - + - cmake-no-system + - ninja-base commands: - - pushd tests # [unix] - - pushd prefix-replacement # [unix] - - test -f ${PREFIX}/lib/libpython${PKG_VERSION%.*}{{ abi_suffix }}.a # [unix] - - test -f ${PREFIX}/lib/libpython${PKG_VERSION%.*}{{ abi_suffix }}.nolto.a # [unix] - - test -f ${PREFIX}/lib/python${PKG_VERSION%.*}{{ abi_suffix }}/config-${PKG_VERSION%.*}{{ abi_suffix }}-darwin/libpython${PKG_VERSION%.*}{{ abi_suffix }}.a # [osx] - - bash build-and-test.sh # [unix] - - popd # [unix] - - popd # [unix] + - VER=${PKG_VERSION%.*} # [not win] + - VERABI=${VER} # [not win] +{% if freethreading == "yes" %} + - VERABI=${VERABI}t # [not win] +{% endif %} + - VERABI_NO_DBG=${VERABI} # [not win] +{% if py_interp_debug == "yes" %} + - VERABI=${VERABI}d # [not win] {% endif %} + - test -f ${PREFIX}/lib/libpython${VERABI}.a # [unix] + - test -f ${PREFIX}/lib/libpython${VERABI_NO_DBG}.nolto.a # [unix] + - test -f ${PREFIX}/lib/python${VERABI_NO_DBG}/config-${VERABI}-darwin/libpython${VERABI}.a # [osx] + - pushd tests + - pushd prefix-replacement # [unix] + - bash build-and-test.sh # [unix] + - popd # [unix] + - pushd cmake + - cmake -GNinja {{ cmake_test_args }} -DPY_VER={{ version }} -DEXTRA_COMPONENTS="Development.Embed" {{ cmake_debug }} . + - popd + - popd + + - name: cpython + build: + noarch: generic + requirements: + run: + - python {{ version }}{{ dev }} + - python_abi * *_{{ abi_tag }} - name: python-freethreading build: noarch: generic -{% if gil_type == "normal" %} - skip: True +{% if freethreading != "yes" %} + skip: true {% endif %} requirements: run: - - python {{ version }}{{ dev }}.* + - cpython {{ version }}{{ dev }} - python_abi * *_{{ abi_tag }} - name: python-gil build: noarch: generic -{% if gil_type == "disabled" %} - skip: True +{% if freethreading == "yes" %} + skip: true {% endif %} requirements: run: - - python {{ version }}{{ dev }}.* + - cpython {{ version }}{{ dev }} - python_abi * *_{{ abi_tag }} - name: python-jit script: install_jit_activation.sh # [not win] script: install_jit_activation.bat # [win] build: -{% if gil_type == "disabled" %} - skip: True +{% if freethreading == "yes" %} + skip: true {% endif %} skip: true # [py<313] noarch: generic requirements: run: - - python {{ version }}{{ dev }} + - cpython {{ version }}{{ dev }} - __unix # [unix] - __win # [win] test: @@ -468,8 +497,29 @@ about: fewer lines of code than would be possible in languages such as C++ or Java. The language provides constructs intended to enable clear programs on both a small and large scale. - doc_url: https://www.python.org/doc/versions/ - dev_url: https://devguide.python.org/ + + We provide some meta packages for convenience. + To get a CPython flavour, use: + + conda install cpython + + To get the freethreading build (i.e. without the Global Interpreter Lock - GIL): + + conda install python-freethreading + + To get the default build (i.e. with the GIL): + + conda install python-gil + + To enable the use of the experimental JIT compiler in CPython: + + conda install python-jit + + or set the environment variable PYTHON_JIT=1. Note that the JIT support + is available for x86_64 builds only. + + doc_url: https://devguide.python.org/ + dev_url: https://github.com/python/cpython extra: feedstock-name: python @@ -486,4 +536,4 @@ extra: - xhochy skip-lints: - license_file_overspecified - - parsing_jinja_failure # gil_type / channel_targets jinja; linter cannot expand this recipe + - parsing_jinja_failure # freethreading / channel_targets jinja; linter cannot expand this recipe diff --git a/recipe/run_test_jit.py b/recipe/run_test_jit.py index ae203f783..154fc1716 100644 --- a/recipe/run_test_jit.py +++ b/recipe/run_test_jit.py @@ -12,10 +12,14 @@ sys.exit(0) else: print("JIT available but not enabled", file=sys.stderr) + sys.exit(1) else: - print("JIT not available", file=sys.stderr) + # python-jit is noarch and PBP tests it against every python variant. + # configure disables JIT for debug, freethreading, and some arches; + # the metapackage is a no-op there. + print("JIT not compiled into this interpreter; skip") + sys.exit(0) else: print(f"WARNING: cannot validate JIT using Python {sys.version}", file=sys.stderr) - print(f"WARNING: validate using Python >= 3.14", file=sys.stderr) - -sys.exit(1) + print("WARNING: validate using Python >= 3.14", file=sys.stderr) + sys.exit(1) diff --git a/recipe/tests/prefix-replacement/a.c b/recipe/tests/prefix-replacement/a.c index dacc1d63e..93922c20d 100644 --- a/recipe/tests/prefix-replacement/a.c +++ b/recipe/tests/prefix-replacement/a.c @@ -9,7 +9,8 @@ main(int argc, char *argv[]) fprintf(stderr, "Fatal error: cannot decode argv[0]\n"); exit(1); } - Py_SetProgramName(program); /* optional but recommended */ + // Removed in Python 3.13 and needs to be replaced with https://docs.python.org/3.13/c-api/init_config.html#c.PyConfig.program_name + // Py_SetProgramName(program); /* optional but recommended */ Py_Initialize(); PyRun_SimpleString("from time import time,ctime\n" "print('Today is', ctime(time()))\n");