xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-devtools/python/python3_3.10.9.bb (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593SmuzhiyunSUMMARY = "The Python Programming Language"
2*4882a593SmuzhiyunHOMEPAGE = "http://www.python.org"
3*4882a593SmuzhiyunDESCRIPTION = "Python is a programming language that lets you work more quickly and integrate your systems more effectively."
4*4882a593SmuzhiyunLICENSE = "PSF-2.0"
5*4882a593SmuzhiyunSECTION = "devel/python"
6*4882a593Smuzhiyun
7*4882a593SmuzhiyunLIC_FILES_CHKSUM = "file://LICENSE;md5=a1822df8d0f068628ca6090aedc5bfc8"
8*4882a593Smuzhiyun
9*4882a593SmuzhiyunSRC_URI = "http://www.python.org/ftp/python/${PV}/Python-${PV}.tar.xz \
10*4882a593Smuzhiyun           file://run-ptest \
11*4882a593Smuzhiyun           file://create_manifest3.py \
12*4882a593Smuzhiyun           file://get_module_deps3.py \
13*4882a593Smuzhiyun           file://python3-manifest.json \
14*4882a593Smuzhiyun           file://check_build_completeness.py \
15*4882a593Smuzhiyun           file://reformat_sysconfig.py \
16*4882a593Smuzhiyun           file://cgi_py.patch \
17*4882a593Smuzhiyun           file://0001-Do-not-add-usr-lib-termcap-to-linker-flags-to-avoid-.patch \
18*4882a593Smuzhiyun           ${@bb.utils.contains('PACKAGECONFIG', 'tk', '', 'file://avoid_warning_about_tkinter.patch', d)} \
19*4882a593Smuzhiyun           file://0001-Do-not-use-the-shell-version-of-python-config-that-w.patch \
20*4882a593Smuzhiyun           file://python-config.patch \
21*4882a593Smuzhiyun           file://0001-Makefile.pre-use-qemu-wrapper-when-gathering-profile.patch \
22*4882a593Smuzhiyun           file://0001-python3-use-cc_basename-to-replace-CC-for-checking-c.patch \
23*4882a593Smuzhiyun           file://0001-bpo-36852-proper-detection-of-mips-architecture-for-.patch \
24*4882a593Smuzhiyun           file://crosspythonpath.patch \
25*4882a593Smuzhiyun           file://0001-Use-FLAG_REF-always-for-interned-strings.patch \
26*4882a593Smuzhiyun           file://0001-test_locale.py-correct-the-test-output-format.patch \
27*4882a593Smuzhiyun           file://0017-setup.py-do-not-report-missing-dependencies-for-disa.patch \
28*4882a593Smuzhiyun           file://0001-Makefile-do-not-compile-.pyc-in-parallel.patch \
29*4882a593Smuzhiyun           file://0020-configure.ac-setup.py-do-not-add-a-curses-include-pa.patch \
30*4882a593Smuzhiyun           file://0001-Skip-failing-tests-due-to-load-variability-on-YP-AB.patch \
31*4882a593Smuzhiyun           file://0001-test_ctypes.test_find-skip-without-tools-sdk.patch \
32*4882a593Smuzhiyun           file://makerace.patch \
33*4882a593Smuzhiyun           file://0001-sysconfig.py-use-platlibdir-also-for-purelib.patch \
34*4882a593Smuzhiyun           file://0001-Lib-pty.py-handle-stdin-I-O-errors-same-way-as-maste.patch \
35*4882a593Smuzhiyun           file://0001-setup.py-Do-not-detect-multiarch-paths-when-cross-co.patch \
36*4882a593Smuzhiyun           file://deterministic_imports.patch \
37*4882a593Smuzhiyun           file://0001-Avoid-shebang-overflow-on-python-config.py.patch \
38*4882a593Smuzhiyun           file://cve-2023-24329.patch \
39*4882a593Smuzhiyun           "
40*4882a593Smuzhiyun
41*4882a593SmuzhiyunSRC_URI:append:class-native = " \
42*4882a593Smuzhiyun           file://0001-Lib-sysconfig.py-use-prefix-value-from-build-configu.patch \
43*4882a593Smuzhiyun           file://0001-distutils-sysconfig-append-STAGING_LIBDIR-python-sys.patch \
44*4882a593Smuzhiyun           file://12-distutils-prefix-is-inside-staging-area.patch \
45*4882a593Smuzhiyun           file://0001-Don-t-search-system-for-headers-libraries.patch \
46*4882a593Smuzhiyun           "
47*4882a593SmuzhiyunSRC_URI[sha256sum] = "5ae03e308260164baba39921fdb4dbf8e6d03d8235a939d4582b33f0b5e46a83"
48*4882a593Smuzhiyun
49*4882a593Smuzhiyun# exclude pre-releases for both python 2.x and 3.x
50*4882a593SmuzhiyunUPSTREAM_CHECK_REGEX = "[Pp]ython-(?P<pver>\d+(\.\d+)+).tar"
51*4882a593SmuzhiyunUPSTREAM_CHECK_URI = "https://www.python.org/downloads/source/"
52*4882a593Smuzhiyun
53*4882a593SmuzhiyunCVE_PRODUCT = "python"
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun# Upstream consider this expected behaviour
56*4882a593SmuzhiyunCVE_CHECK_IGNORE += "CVE-2007-4559"
57*4882a593Smuzhiyun# This is not exploitable when glibc has CVE-2016-10739 fixed.
58*4882a593SmuzhiyunCVE_CHECK_IGNORE += "CVE-2019-18348"
59*4882a593Smuzhiyun# These are specific to Microsoft Windows
60*4882a593SmuzhiyunCVE_CHECK_IGNORE += "CVE-2020-15523 CVE-2022-26488"
61*4882a593Smuzhiyun# The mailcap module is insecure by design, so this can't be fixed in a meaningful way.
62*4882a593Smuzhiyun# The module will be removed in the future and flaws documented.
63*4882a593SmuzhiyunCVE_CHECK_IGNORE += "CVE-2015-20107"
64*4882a593Smuzhiyun
65*4882a593SmuzhiyunPYTHON_MAJMIN = "3.10"
66*4882a593Smuzhiyun
67*4882a593SmuzhiyunS = "${WORKDIR}/Python-${PV}"
68*4882a593Smuzhiyun
69*4882a593SmuzhiyunBBCLASSEXTEND = "native nativesdk"
70*4882a593Smuzhiyun
71*4882a593Smuzhiyuninherit autotools pkgconfig qemu ptest multilib_header update-alternatives
72*4882a593Smuzhiyun
73*4882a593SmuzhiyunMULTILIB_SUFFIX = "${@d.getVar('base_libdir',1).split('/')[-1]}"
74*4882a593Smuzhiyun
75*4882a593SmuzhiyunALTERNATIVE:${PN}-dev = "python3-config"
76*4882a593SmuzhiyunALTERNATIVE_LINK_NAME[python3-config] = "${bindir}/python${PYTHON_MAJMIN}-config"
77*4882a593SmuzhiyunALTERNATIVE_TARGET[python3-config] = "${bindir}/python${PYTHON_MAJMIN}-config-${MULTILIB_SUFFIX}"
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun
80*4882a593SmuzhiyunDEPENDS = "bzip2-replacement-native libffi bzip2 openssl sqlite3 zlib virtual/libintl xz virtual/crypt util-linux-libuuid libtirpc libnsl2 autoconf-archive-native ncurses"
81*4882a593SmuzhiyunDEPENDS:append:class-target = " python3-native"
82*4882a593SmuzhiyunDEPENDS:append:class-nativesdk = " python3-native"
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun# force to use the mutex+cond implementation (https://bugs.python.org/issue41710)
85*4882a593SmuzhiyunCFLAGS += "-DHAVE_BROKEN_POSIX_SEMAPHORES"
86*4882a593Smuzhiyun
87*4882a593SmuzhiyunEXTRA_OECONF = " --without-ensurepip --enable-shared --with-platlibdir=${baselib}"
88*4882a593SmuzhiyunEXTRA_OECONF:append:class-native = " --bindir=${bindir}/${PN}"
89*4882a593Smuzhiyun
90*4882a593Smuzhiyunexport CROSSPYTHONPATH="${STAGING_LIBDIR_NATIVE}/python${PYTHON_MAJMIN}/lib-dynload/"
91*4882a593Smuzhiyun
92*4882a593SmuzhiyunEXTRANATIVEPATH += "python3-native"
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun# LTO will be enabled via packageconfig depending upong distro features
95*4882a593SmuzhiyunLTO:class-target = ""
96*4882a593Smuzhiyun
97*4882a593SmuzhiyunCACHED_CONFIGUREVARS = " \
98*4882a593Smuzhiyun                ac_cv_file__dev_ptmx=yes \
99*4882a593Smuzhiyun                ac_cv_file__dev_ptc=no \
100*4882a593Smuzhiyun                ac_cv_working_tzset=yes \
101*4882a593Smuzhiyun"
102*4882a593Smuzhiyun
103*4882a593Smuzhiyun# PGO currently causes builds to not be reproducible so disable by default, see YOCTO #13407
104*4882a593SmuzhiyunPACKAGECONFIG:class-target ??= "readline gdbm ${@bb.utils.filter('DISTRO_FEATURES', 'lto', d)}"
105*4882a593SmuzhiyunPACKAGECONFIG:class-native ??= "readline gdbm"
106*4882a593SmuzhiyunPACKAGECONFIG:class-nativesdk ??= "readline gdbm"
107*4882a593SmuzhiyunPACKAGECONFIG[readline] = ",,readline"
108*4882a593Smuzhiyun# Use profile guided optimisation by running PyBench inside qemu-user
109*4882a593SmuzhiyunPACKAGECONFIG[pgo] = "--enable-optimizations,,qemu-native"
110*4882a593SmuzhiyunPACKAGECONFIG[tk] = ",,tk"
111*4882a593SmuzhiyunPACKAGECONFIG[gdbm] = ",,gdbm"
112*4882a593SmuzhiyunPACKAGECONFIG[lto] = "--with-lto,,"
113*4882a593Smuzhiyun
114*4882a593Smuzhiyundo_configure:prepend () {
115*4882a593Smuzhiyun    mkdir -p ${B}/Modules
116*4882a593Smuzhiyun    cat > ${B}/Modules/Setup.local << EOF
117*4882a593Smuzhiyun*disabled*
118*4882a593Smuzhiyun${@bb.utils.contains('PACKAGECONFIG', 'gdbm', '', '_gdbm _dbm', d)}
119*4882a593Smuzhiyun${@bb.utils.contains('PACKAGECONFIG', 'readline', '', 'readline', d)}
120*4882a593SmuzhiyunEOF
121*4882a593Smuzhiyun}
122*4882a593Smuzhiyun
123*4882a593SmuzhiyunCPPFLAGS:append = " -I${STAGING_INCDIR}/ncursesw -I${STAGING_INCDIR}/uuid"
124*4882a593Smuzhiyun
125*4882a593SmuzhiyunEXTRA_OEMAKE = '\
126*4882a593Smuzhiyun  STAGING_LIBDIR=${STAGING_LIBDIR} \
127*4882a593Smuzhiyun  STAGING_INCDIR=${STAGING_INCDIR} \
128*4882a593Smuzhiyun  LIB=${baselib} \
129*4882a593Smuzhiyun'
130*4882a593Smuzhiyun
131*4882a593Smuzhiyundo_compile:prepend:class-target() {
132*4882a593Smuzhiyun       if ${@bb.utils.contains('PACKAGECONFIG', 'pgo', 'true', 'false', d)}; then
133*4882a593Smuzhiyun                qemu_binary="${@qemu_wrapper_cmdline(d, '${STAGING_DIR_TARGET}', ['${B}', '${STAGING_DIR_TARGET}/${base_libdir}'])}"
134*4882a593Smuzhiyun                cat >pgo-wrapper <<EOF
135*4882a593Smuzhiyun#!/bin/sh
136*4882a593Smuzhiyuncd ${B}
137*4882a593Smuzhiyun$qemu_binary "\$@"
138*4882a593SmuzhiyunEOF
139*4882a593Smuzhiyun                chmod +x pgo-wrapper
140*4882a593Smuzhiyun        fi
141*4882a593Smuzhiyun}
142*4882a593Smuzhiyun
143*4882a593Smuzhiyundo_install:prepend() {
144*4882a593Smuzhiyun        ${WORKDIR}/check_build_completeness.py ${T}/log.do_compile
145*4882a593Smuzhiyun}
146*4882a593Smuzhiyun
147*4882a593Smuzhiyundo_install:append:class-target() {
148*4882a593Smuzhiyun        oe_multilib_header python${PYTHON_MAJMIN}/pyconfig.h
149*4882a593Smuzhiyun}
150*4882a593Smuzhiyun
151*4882a593Smuzhiyundo_install:append:class-native() {
152*4882a593Smuzhiyun        # Make sure we use /usr/bin/env python
153*4882a593Smuzhiyun        for PYTHSCRIPT in `grep -rIl ${bindir}/${PN}/python ${D}${bindir}/${PN}`; do
154*4882a593Smuzhiyun                sed -i -e '1s|^#!.*|#!/usr/bin/env python3|' $PYTHSCRIPT
155*4882a593Smuzhiyun        done
156*4882a593Smuzhiyun        # Add a symlink to the native Python so that scripts can just invoke
157*4882a593Smuzhiyun        # "nativepython" and get the right one without needing absolute paths
158*4882a593Smuzhiyun        # (these often end up too long for the #! parser in the kernel as the
159*4882a593Smuzhiyun        # buffer is 128 bytes long).
160*4882a593Smuzhiyun        ln -s python3-native/python3 ${D}${bindir}/nativepython3
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun        # Remove the opt-1.pyc and opt-2.pyc files. There are over 3,000 of them
163*4882a593Smuzhiyun        # and the overhead in each recipe-sysroot-native isn't worth it, particularly
164*4882a593Smuzhiyun        # when they're only used for python called with -O or -OO.
165*4882a593Smuzhiyun        #find ${D} -name *opt-*.pyc -delete
166*4882a593Smuzhiyun        # Remove all pyc files. There are a ton of them and it is probably faster to let
167*4882a593Smuzhiyun        # python create the ones it wants at runtime rather than manage in the sstate
168*4882a593Smuzhiyun        # tarballs and sysroot creation.
169*4882a593Smuzhiyun        find ${D} -name *.pyc -delete
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun        # Nothing should be looking into ${B} for python3-native
172*4882a593Smuzhiyun        sed -i -e 's:${B}:/build/path/unavailable/:g' \
173*4882a593Smuzhiyun                ${D}/${libdir}/python${PYTHON_MAJMIN}/config-${PYTHON_MAJMIN}${PYTHON_ABI}*/Makefile
174*4882a593Smuzhiyun}
175*4882a593Smuzhiyun
176*4882a593Smuzhiyundo_install:append() {
177*4882a593Smuzhiyun        for c in ${D}/${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py; do
178*4882a593Smuzhiyun            python3 ${WORKDIR}/reformat_sysconfig.py $c
179*4882a593Smuzhiyun        done
180*4882a593Smuzhiyun        rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/__pycache__/_sysconfigdata*.cpython*
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun        mkdir -p ${D}${libdir}/python-sysconfigdata
183*4882a593Smuzhiyun        sysconfigfile=`find ${D} -name _sysconfig*.py`
184*4882a593Smuzhiyun        sed -i  \
185*4882a593Smuzhiyun                -e "s,^ 'LIBDIR'.*, 'LIBDIR': '${STAGING_LIBDIR}'\,,g" \
186*4882a593Smuzhiyun                -e "s,^ 'INCLUDEDIR'.*, 'INCLUDEDIR': '${STAGING_INCDIR}'\,,g" \
187*4882a593Smuzhiyun                -e "s,^ 'CONFINCLUDEDIR'.*, 'CONFINCLUDEDIR': '${STAGING_INCDIR}'\,,g" \
188*4882a593Smuzhiyun                -e "/^ 'INCLDIRSTOMAKE'/{N; s,/usr/include,${STAGING_INCDIR},g}" \
189*4882a593Smuzhiyun                -e "/^ 'INCLUDEPY'/s,/usr/include,${STAGING_INCDIR},g" \
190*4882a593Smuzhiyun                -e "s,${B},/build/path/unavailable/,g" \
191*4882a593Smuzhiyun                $sysconfigfile
192*4882a593Smuzhiyun        cp $sysconfigfile ${D}${libdir}/python-sysconfigdata/_sysconfigdata.py
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun
195*4882a593Smuzhiyun        # Unfortunately the following pyc files are non-deterministc due to 'frozenset'
196*4882a593Smuzhiyun        # being written without strict ordering, even with PYTHONHASHSEED = 0
197*4882a593Smuzhiyun        # Upstream is discussing ways to solve the issue properly, until then let's
198*4882a593Smuzhiyun        # just not install the problematic files.
199*4882a593Smuzhiyun        # More info: http://benno.id.au/blog/2013/01/15/python-determinism
200*4882a593Smuzhiyun        rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/test/__pycache__/test_range.cpython*
201*4882a593Smuzhiyun        rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/test/__pycache__/test_xml_etree.cpython*
202*4882a593Smuzhiyun
203*4882a593Smuzhiyun        # Similar to the above, we're getting reproducibility issues with
204*4882a593Smuzhiyun        # /usr/lib/python3.10/__pycache__/traceback.cpython-310.pyc
205*4882a593Smuzhiyun        # so remove it too
206*4882a593Smuzhiyun        rm -f ${D}${libdir}/python${PYTHON_MAJMIN}/__pycache__/traceback.cpython*
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun        # Remove the opt-1.pyc and opt-2.pyc files. They effectively waste space on embedded
209*4882a593Smuzhiyun        # style targets as they're only used when python is called with the -O or -OO options
210*4882a593Smuzhiyun        # which is rare.
211*4882a593Smuzhiyun        find ${D} -name *opt-*.pyc -delete
212*4882a593Smuzhiyun}
213*4882a593Smuzhiyun
214*4882a593Smuzhiyundo_install:append:class-nativesdk () {
215*4882a593Smuzhiyun    # Make sure we use /usr/bin/env python
216*4882a593Smuzhiyun    for PYTHSCRIPT in `grep -rIl ${bindir}/python ${D}${bindir}`; do
217*4882a593Smuzhiyun         sed -i -e '1s|^#!.*|#!/usr/bin/env python3|' $PYTHSCRIPT
218*4882a593Smuzhiyun    done
219*4882a593Smuzhiyun    create_wrapper ${D}${bindir}/python${PYTHON_MAJMIN} TERMINFO_DIRS='${sysconfdir}/terminfo:/etc/terminfo:/usr/share/terminfo:/usr/share/misc/terminfo:/lib/terminfo' PYTHONNOUSERSITE='1'
220*4882a593Smuzhiyun}
221*4882a593Smuzhiyun
222*4882a593SmuzhiyunSSTATE_SCAN_FILES += "Makefile _sysconfigdata.py"
223*4882a593SmuzhiyunSSTATE_HASHEQUIV_FILEMAP = " \
224*4882a593Smuzhiyun    populate_sysroot:*/lib*/python3*/_sysconfigdata*.py:${TMPDIR} \
225*4882a593Smuzhiyun    populate_sysroot:*/lib*/python3*/_sysconfigdata*.py:${COREBASE} \
226*4882a593Smuzhiyun    populate_sysroot:*/lib*/python3*/config-*/Makefile:${TMPDIR} \
227*4882a593Smuzhiyun    populate_sysroot:*/lib*/python3*/config-*/Makefile:${COREBASE} \
228*4882a593Smuzhiyun    populate_sysroot:*/lib*/python-sysconfigdata/_sysconfigdata.py:${TMPDIR} \
229*4882a593Smuzhiyun    populate_sysroot:*/lib*/python-sysconfigdata/_sysconfigdata.py:${COREBASE} \
230*4882a593Smuzhiyun    "
231*4882a593SmuzhiyunPACKAGE_PREPROCESS_FUNCS += "py_package_preprocess"
232*4882a593Smuzhiyun
233*4882a593Smuzhiyunpy_package_preprocess () {
234*4882a593Smuzhiyun        # Remove references to buildmachine paths in target Makefile and _sysconfigdata
235*4882a593Smuzhiyun        sed -i -e 's:--sysroot=${STAGING_DIR_TARGET}::g' -e s:'--with-libtool-sysroot=${STAGING_DIR_TARGET}'::g \
236*4882a593Smuzhiyun                -e 's|${DEBUG_PREFIX_MAP}||g' \
237*4882a593Smuzhiyun                -e 's:${HOSTTOOLS_DIR}/::g' \
238*4882a593Smuzhiyun                -e 's:${RECIPE_SYSROOT_NATIVE}::g' \
239*4882a593Smuzhiyun                -e 's:${RECIPE_SYSROOT}::g' \
240*4882a593Smuzhiyun                -e 's:${BASE_WORKDIR}/${MULTIMACH_TARGET_SYS}::g' \
241*4882a593Smuzhiyun                ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/config-${PYTHON_MAJMIN}${PYTHON_ABI}*/Makefile \
242*4882a593Smuzhiyun                ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py \
243*4882a593Smuzhiyun                ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config
244*4882a593Smuzhiyun
245*4882a593Smuzhiyun        # Reformat _sysconfigdata after modifying it so that it remains
246*4882a593Smuzhiyun        # reproducible
247*4882a593Smuzhiyun        for c in ${PKGD}/${libdir}/python${PYTHON_MAJMIN}/_sysconfigdata*.py; do
248*4882a593Smuzhiyun            python3 ${WORKDIR}/reformat_sysconfig.py $c
249*4882a593Smuzhiyun        done
250*4882a593Smuzhiyun
251*4882a593Smuzhiyun        # Recompile _sysconfigdata after modifying it
252*4882a593Smuzhiyun        cd ${PKGD}
253*4882a593Smuzhiyun        sysconfigfile=`find . -name _sysconfigdata_*.py`
254*4882a593Smuzhiyun        ${STAGING_BINDIR_NATIVE}/python3-native/python3 \
255*4882a593Smuzhiyun             -c "from py_compile import compile; compile('$sysconfigfile')"
256*4882a593Smuzhiyun        ${STAGING_BINDIR_NATIVE}/python3-native/python3 \
257*4882a593Smuzhiyun             -c "from py_compile import compile; compile('$sysconfigfile', optimize=1)"
258*4882a593Smuzhiyun        ${STAGING_BINDIR_NATIVE}/python3-native/python3 \
259*4882a593Smuzhiyun             -c "from py_compile import compile; compile('$sysconfigfile', optimize=2)"
260*4882a593Smuzhiyun        cd -
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun        mv ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config ${PKGD}/${bindir}/python${PYTHON_MAJMIN}-config-${MULTILIB_SUFFIX}
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun        #Remove the unneeded copy of target sysconfig data
265*4882a593Smuzhiyun        rm -rf ${PKGD}/${libdir}/python-sysconfigdata
266*4882a593Smuzhiyun}
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun# We want bytecode precompiled .py files (.pyc's) by default
269*4882a593Smuzhiyun# but the user may set it on their own conf
270*4882a593SmuzhiyunINCLUDE_PYCS ?= "1"
271*4882a593Smuzhiyun
272*4882a593Smuzhiyunpython(){
273*4882a593Smuzhiyun    import collections, json
274*4882a593Smuzhiyun
275*4882a593Smuzhiyun    filename = os.path.join(d.getVar('THISDIR'), 'python3', 'python3-manifest.json')
276*4882a593Smuzhiyun    # This python changes the datastore based on the contents of a file, so mark
277*4882a593Smuzhiyun    # that dependency.
278*4882a593Smuzhiyun    bb.parse.mark_dependency(d, filename)
279*4882a593Smuzhiyun
280*4882a593Smuzhiyun    with open(filename) as manifest_file:
281*4882a593Smuzhiyun        manifest_str =  manifest_file.read()
282*4882a593Smuzhiyun        json_start = manifest_str.find('# EOC') + 6
283*4882a593Smuzhiyun        manifest_file.seek(json_start)
284*4882a593Smuzhiyun        manifest_str = manifest_file.read()
285*4882a593Smuzhiyun        python_manifest = json.loads(manifest_str, object_pairs_hook=collections.OrderedDict)
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun    # First set RPROVIDES for -native case
288*4882a593Smuzhiyun    # Hardcoded since it cant be python3-native-foo, should be python3-foo-native
289*4882a593Smuzhiyun    pn = 'python3'
290*4882a593Smuzhiyun    rprovides = (d.getVar('RPROVIDES') or "").split()
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun    # ${PN}-misc-native is not in the manifest
293*4882a593Smuzhiyun    rprovides.append(pn + '-misc-native')
294*4882a593Smuzhiyun
295*4882a593Smuzhiyun    for key in python_manifest:
296*4882a593Smuzhiyun        pypackage = pn + '-' + key + '-native'
297*4882a593Smuzhiyun        if pypackage not in rprovides:
298*4882a593Smuzhiyun              rprovides.append(pypackage)
299*4882a593Smuzhiyun
300*4882a593Smuzhiyun    d.setVar('RPROVIDES:class-native', ' '.join(rprovides))
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun    # Then work on the target
303*4882a593Smuzhiyun    include_pycs = d.getVar('INCLUDE_PYCS')
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun    packages = d.getVar('PACKAGES').split()
306*4882a593Smuzhiyun    pn = d.getVar('PN')
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun    newpackages=[]
309*4882a593Smuzhiyun    for key in python_manifest:
310*4882a593Smuzhiyun        pypackage = pn + '-' + key
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun        if pypackage not in packages:
313*4882a593Smuzhiyun            # We need to prepend, otherwise python-misc gets everything
314*4882a593Smuzhiyun            # so we use a new variable
315*4882a593Smuzhiyun            newpackages.append(pypackage)
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun        # "Build" python's manifest FILES, RDEPENDS and SUMMARY
318*4882a593Smuzhiyun        d.setVar('FILES:' + pypackage, '')
319*4882a593Smuzhiyun        for value in python_manifest[key]['files']:
320*4882a593Smuzhiyun            d.appendVar('FILES:' + pypackage, ' ' + value)
321*4882a593Smuzhiyun
322*4882a593Smuzhiyun        # Add cached files
323*4882a593Smuzhiyun        if include_pycs == '1':
324*4882a593Smuzhiyun            for value in python_manifest[key]['cached']:
325*4882a593Smuzhiyun                    d.appendVar('FILES:' + pypackage, ' ' + value)
326*4882a593Smuzhiyun
327*4882a593Smuzhiyun        for value in python_manifest[key]['rdepends']:
328*4882a593Smuzhiyun            # Make it work with or without $PN
329*4882a593Smuzhiyun            if '${PN}' in value:
330*4882a593Smuzhiyun                value=value.split('-', 1)[1]
331*4882a593Smuzhiyun            d.appendVar('RDEPENDS:' + pypackage, ' ' + pn + '-' + value)
332*4882a593Smuzhiyun
333*4882a593Smuzhiyun        for value in python_manifest[key].get('rrecommends', ()):
334*4882a593Smuzhiyun            if '${PN}' in value:
335*4882a593Smuzhiyun                value=value.split('-', 1)[1]
336*4882a593Smuzhiyun            d.appendVar('RRECOMMENDS:' + pypackage, ' ' + pn + '-' + value)
337*4882a593Smuzhiyun
338*4882a593Smuzhiyun        d.setVar('SUMMARY:' + pypackage, python_manifest[key]['summary'])
339*4882a593Smuzhiyun
340*4882a593Smuzhiyun    # Prepending so to avoid python-misc getting everything
341*4882a593Smuzhiyun    packages = newpackages + packages
342*4882a593Smuzhiyun    d.setVar('PACKAGES', ' '.join(packages))
343*4882a593Smuzhiyun    d.setVar('ALLOW_EMPTY:${PN}-modules', '1')
344*4882a593Smuzhiyun    d.setVar('ALLOW_EMPTY:${PN}-pkgutil', '1')
345*4882a593Smuzhiyun
346*4882a593Smuzhiyun    if "pgo" in d.getVar("PACKAGECONFIG").split() and not bb.utils.contains('MACHINE_FEATURES', 'qemu-usermode', True, False, d):
347*4882a593Smuzhiyun        bb.fatal("pgo cannot be enabled as there is no qemu-usermode support for this architecture/machine")
348*4882a593Smuzhiyun}
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun# Files needed to create a new manifest
351*4882a593Smuzhiyun
352*4882a593Smuzhiyundo_create_manifest() {
353*4882a593Smuzhiyun    # This task should be run with every new release of Python.
354*4882a593Smuzhiyun    # We must ensure that PACKAGECONFIG enables everything when creating
355*4882a593Smuzhiyun    # a new manifest, this is to base our new manifest on a complete
356*4882a593Smuzhiyun    # native python build, containing all dependencies, otherwise the task
357*4882a593Smuzhiyun    # wont be able to find the required files.
358*4882a593Smuzhiyun    # e.g. BerkeleyDB is an optional build dependency so it may or may not
359*4882a593Smuzhiyun    # be present, we must ensure it is.
360*4882a593Smuzhiyun
361*4882a593Smuzhiyun    cd ${WORKDIR}
362*4882a593Smuzhiyun    # This needs to be executed by python-native and NOT by HOST's python
363*4882a593Smuzhiyun    nativepython3 create_manifest3.py ${PYTHON_MAJMIN}
364*4882a593Smuzhiyun    cp python3-manifest.json.new ${THISDIR}/python3/python3-manifest.json
365*4882a593Smuzhiyun}
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun# bitbake python -c create_manifest
368*4882a593Smuzhiyun# Make sure we have native python ready when we create a new manifest
369*4882a593Smuzhiyunaddtask do_create_manifest after do_patch do_prepare_recipe_sysroot
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun# manual dependency additions
372*4882a593SmuzhiyunRRECOMMENDS:${PN}-core:append:class-nativesdk = " nativesdk-python3-modules"
373*4882a593SmuzhiyunRRECOMMENDS:${PN}-crypt:append:class-target = " ${MLPREFIX}openssl ${MLPREFIX}ca-certificates"
374*4882a593SmuzhiyunRRECOMMENDS:${PN}-crypt:append:class-nativesdk = " ${MLPREFIX}openssl ${MLPREFIX}ca-certificates"
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun# For historical reasons PN is empty and provided by python3-modules
377*4882a593SmuzhiyunFILES:${PN} = ""
378*4882a593SmuzhiyunRPROVIDES:${PN}-modules = "${PN}"
379*4882a593Smuzhiyun
380*4882a593SmuzhiyunFILES:${PN}-pydoc += "${bindir}/pydoc${PYTHON_MAJMIN} ${bindir}/pydoc3"
381*4882a593SmuzhiyunFILES:${PN}-idle += "${bindir}/idle3 ${bindir}/idle${PYTHON_MAJMIN}"
382*4882a593Smuzhiyun
383*4882a593Smuzhiyun# provide python-pyvenv from python3-venv
384*4882a593SmuzhiyunRPROVIDES:${PN}-venv += "${MLPREFIX}python3-pyvenv"
385*4882a593Smuzhiyun
386*4882a593Smuzhiyun# package libpython3
387*4882a593SmuzhiyunPACKAGES =+ "libpython3 libpython3-staticdev"
388*4882a593SmuzhiyunFILES:libpython3 = "${libdir}/libpython*.so.*"
389*4882a593SmuzhiyunFILES:libpython3-staticdev += "${libdir}/python${PYTHON_MAJMIN}/config-${PYTHON_MAJMIN}-*/libpython${PYTHON_MAJMIN}.a"
390*4882a593SmuzhiyunINSANE_SKIP:${PN}-dev += "dev-elf"
391*4882a593SmuzhiyunINSANE_SKIP:${PN}-ptest = "dev-deps"
392*4882a593Smuzhiyun
393*4882a593Smuzhiyun# catch all the rest (unsorted)
394*4882a593SmuzhiyunPACKAGES += "${PN}-misc"
395*4882a593SmuzhiyunRDEPENDS:${PN}-misc += "\
396*4882a593Smuzhiyun  ${PN}-core \
397*4882a593Smuzhiyun  ${PN}-email \
398*4882a593Smuzhiyun  ${PN}-codecs \
399*4882a593Smuzhiyun  ${PN}-pydoc \
400*4882a593Smuzhiyun  ${PN}-pickle \
401*4882a593Smuzhiyun  ${PN}-audio \
402*4882a593Smuzhiyun  ${PN}-numbers \
403*4882a593Smuzhiyun"
404*4882a593SmuzhiyunRDEPENDS:${PN}-modules:append:class-target = " ${MLPREFIX}python3-misc"
405*4882a593SmuzhiyunRDEPENDS:${PN}-modules:append:class-nativesdk = " ${MLPREFIX}python3-misc"
406*4882a593SmuzhiyunFILES:${PN}-misc = "${libdir}/python${PYTHON_MAJMIN} ${libdir}/python${PYTHON_MAJMIN}/lib-dynload"
407*4882a593Smuzhiyun
408*4882a593Smuzhiyun# catch manpage
409*4882a593SmuzhiyunPACKAGES += "${PN}-man"
410*4882a593SmuzhiyunFILES:${PN}-man = "${datadir}/man"
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun# See https://bugs.python.org/issue18748 and https://bugs.python.org/issue37395
413*4882a593SmuzhiyunRDEPENDS:libpython3:append:libc-glibc = " libgcc"
414*4882a593SmuzhiyunRDEPENDS:${PN}-ctypes:append:libc-glibc = " ${MLPREFIX}ldconfig"
415*4882a593SmuzhiyunRDEPENDS:${PN}-ptest = "${PN}-modules ${PN}-tests ${PN}-dev unzip bzip2 libgcc tzdata-europe coreutils sed"
416*4882a593SmuzhiyunRDEPENDS:${PN}-ptest:append:libc-glibc = " locale-base-tr-tr.iso-8859-9"
417*4882a593SmuzhiyunRDEPENDS:${PN}-tkinter += "${@bb.utils.contains('PACKAGECONFIG', 'tk', '${MLPREFIX}tk ${MLPREFIX}tk-lib', '', d)}"
418*4882a593SmuzhiyunRDEPENDS:${PN}-idle += "${@bb.utils.contains('PACKAGECONFIG', 'tk', '${PN}-tkinter ${MLPREFIX}tcl', '', d)}"
419*4882a593SmuzhiyunRDEPENDS:${PN}-dev = ""
420*4882a593SmuzhiyunRDEPENDS:${PN}-pydoc += "${PN}-io"
421*4882a593Smuzhiyun
422*4882a593SmuzhiyunRDEPENDS:${PN}-tests:append:class-target = " ${MLPREFIX}bash"
423*4882a593SmuzhiyunRDEPENDS:${PN}-tests:append:class-nativesdk = " ${MLPREFIX}bash"
424*4882a593Smuzhiyun
425*4882a593Smuzhiyun# Python's tests contain large numbers of files we don't need in the recipe sysroots
426*4882a593SmuzhiyunSYSROOT_PREPROCESS_FUNCS += " py3_sysroot_cleanup"
427*4882a593Smuzhiyunpy3_sysroot_cleanup () {
428*4882a593Smuzhiyun	rm -rf ${SYSROOT_DESTDIR}${libdir}/python${PYTHON_MAJMIN}/test
429*4882a593Smuzhiyun}
430