Fixes building in venv

Borrowed from p4a:
https://github.com/kivy/python-for-android/pull/2159
Also refs upstream issue:
https://bugs.python.org/issue40261
Note that the fix used upstream cannot really be used directly here
because the actual system Python is impacted.
Adds venv build to CI to check for regressions.
This commit is contained in:
Andre Miras 2020-04-29 14:43:07 -07:00
parent aa1fced45a
commit d180ee0807
9 changed files with 113 additions and 34 deletions

View file

@ -48,6 +48,28 @@ jobs:
run: | run: |
.ci/test_project.sh .ci/test_project.sh
build_python3_kivy_venv:
runs-on: macos-latest
steps:
- name: Checkout kivy-ios
uses: actions/checkout@v2
- name: Set up Python 3.7.x
uses: actions/setup-python@v1
with:
python-version: 3.7.x
- name: Install requirements
run: |
python -m venv venv
. venv/bin/activate
pip install -r requirements.txt
pip install sh
brew install autoconf automake libtool pkg-config
brew link libtool
pip install Cython==0.28.1
- name: Build Python & Kivy
run: |
python toolchain.py build python3 kivy
build_updated_recipes: build_updated_recipes:
runs-on: macos-latest runs-on: macos-latest
steps: steps:

View file

@ -1,5 +1,6 @@
# Kivy for iOS # Kivy for iOS
[![kivy-ios](https://github.com/kivy/kivy-ios/workflows/kivy-ios/badge.svg)](https://github.com/kivy/kivy-ios/actions?query=workflow%3Akivy-ios)
[![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers) [![Backers on Open Collective](https://opencollective.com/kivy/backers/badge.svg)](#backers)
[![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors) [![Sponsors on Open Collective](https://opencollective.com/kivy/sponsors/badge.svg)](#sponsors)

View file

@ -1,35 +1,20 @@
from toolchain import Recipe, shprint from toolchain import Recipe, shprint, cd, cache_execution
from os.path import join
import sh import sh
import os
import shutil
class HostSetuptools3(Recipe): class HostSetuptools3(Recipe):
depends = ["openssl", "hostpython3"] depends = ["openssl", "hostpython3"]
archs = ["x86_64"] archs = ["x86_64"]
url = "setuptools" version = '40.9.0'
url = 'https://pypi.python.org/packages/source/s/setuptools/setuptools-{version}.zip'
def prebuild_arch(self, arch): @cache_execution
def install(self):
arch = self.filtered_archs[0]
build_dir = self.get_build_dir(arch.arch)
hostpython = sh.Command(self.ctx.hostpython) hostpython = sh.Command(self.ctx.hostpython)
sh.curl("-O", "https://bootstrap.pypa.io/ez_setup.py") with cd(build_dir):
shprint(hostpython, "./ez_setup.py") shprint(hostpython, "setup.py", "install")
# Extract setuptools egg and remove .pth files. Otherwise subsequent
# python package installations using setuptools will raise exceptions.
# Setuptools version 28.3.0
site_packages_path = join(
self.ctx.dist_dir, 'hostpython3',
'lib', 'python3.8', 'site-packages')
os.chdir(site_packages_path)
with open('setuptools.pth', 'r') as f:
setuptools_egg_path = f.read().strip('./').strip('\n')
print("setuptools_egg_path=", setuptools_egg_path)
unzip = sh.Command('unzip')
shprint(unzip, "-o", setuptools_egg_path)
os.remove(setuptools_egg_path)
os.remove('setuptools.pth')
os.remove('easy-install.pth')
shutil.rmtree('EGG-INFO')
recipe = HostSetuptools3() recipe = HostSetuptools3()

View file

@ -1,4 +1,4 @@
from toolchain import Recipe, shprint from toolchain import Recipe, cd, shprint
from os.path import join from os.path import join
import os import os
import sh import sh
@ -14,6 +14,7 @@ class Hostpython3Recipe(Recipe):
depends = ["hostlibffi", "hostopenssl"] depends = ["hostlibffi", "hostopenssl"]
optional_depends = [] optional_depends = []
archs = ["x86_64"] archs = ["x86_64"]
build_subdir = 'native-build'
def init_with_ctx(self, ctx): def init_with_ctx(self, ctx):
super(Hostpython3Recipe, self).init_with_ctx(ctx) super(Hostpython3Recipe, self).init_with_ctx(ctx)
@ -24,9 +25,13 @@ class Hostpython3Recipe(Recipe):
logger.info("Global: hostpython located at {}".format(self.ctx.hostpython)) logger.info("Global: hostpython located at {}".format(self.ctx.hostpython))
logger.info("Global: hostpgen located at {}".format(self.ctx.hostpgen)) logger.info("Global: hostpgen located at {}".format(self.ctx.hostpgen))
def get_build_subdir(self, arch):
return join(self.get_build_dir(arch), self.build_subdir)
def prebuild_arch(self, arch): def prebuild_arch(self, arch):
if self.has_marker("patched"): if self.has_marker("patched"):
return return
self.apply_patch("pyconfig_detection.patch")
self.copy_file("ModulesSetup", "Modules/Setup.local") self.copy_file("ModulesSetup", "Modules/Setup.local")
self.set_marker("patched") self.set_marker("patched")
@ -55,20 +60,24 @@ class Hostpython3Recipe(Recipe):
def build_x86_64(self): def build_x86_64(self):
build_env = self.get_build_env() build_env = self.get_build_env()
configure = sh.Command(join(self.build_dir, "configure")) configure = sh.Command(join(self.build_dir, "configure"))
shprint(configure, arch = self.filtered_archs[0]
"--prefix={}".format(join(self.ctx.dist_dir, "hostpython3")), build_subdir = self.get_build_subdir(arch.arch)
"--with-openssl={}".format(join(self.ctx.dist_dir, 'hostopenssl')), os.makedirs(build_subdir, exist_ok=True)
_env=build_env) with cd(build_subdir):
shprint(sh.make, "-C", self.build_dir, self.ctx.concurrent_make, shprint(configure,
"--prefix={}".format(join(self.ctx.dist_dir, "hostpython3")),
"--with-openssl={}".format(join(self.ctx.dist_dir, 'hostopenssl')),
_env=build_env)
shprint(sh.make, "-C", build_subdir, self.ctx.concurrent_make,
_env=build_env) _env=build_env)
def install(self): def install(self):
arch = list(self.filtered_archs)[0] arch = list(self.filtered_archs)[0]
build_env = self.get_build_env() build_env = self.get_build_env()
build_dir = self.get_build_dir(arch.arch) build_subdir = self.get_build_subdir(arch.arch)
build_env["PATH"] = os.environ["PATH"] build_env["PATH"] = os.environ["PATH"]
shprint(sh.make, self.ctx.concurrent_make, shprint(sh.make, self.ctx.concurrent_make,
"-C", build_dir, "-C", build_subdir,
"install", "install",
_env=build_env) _env=build_env)
shutil.copy( shutil.copy(

View file

@ -0,0 +1,25 @@
diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py
--- Python-3.8.2/Lib/site.py 2020-02-24 22:36:25.000000000 +0100
+++ Python-3.8.2-new/Lib/site.py 2020-05-01 17:10:43.000000000 +0200
@@ -458,9 +458,8 @@
env = os.environ
if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
- executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
- else:
- executable = sys.executable
+ print("Ignoring __PYVENV_LAUNCHER__")
+ executable = sys.executable
exe_dir, _ = os.path.split(os.path.abspath(executable))
site_prefix = os.path.dirname(exe_dir)
sys._home = None
@@ -487,7 +486,8 @@
if key == 'include-system-site-packages':
system_site = value.lower()
elif key == 'home':
- sys._home = value
+ # this is breaking pyconfig.h path detection with venv
+ print('Ignoring "sys._home = value" override')
sys.prefix = sys.exec_prefix = site_prefix

View file

@ -17,7 +17,7 @@ class KivyRecipe(CythonRecipe):
url = "https://github.com/kivy/kivy/archive/{version}.zip" url = "https://github.com/kivy/kivy/archive/{version}.zip"
library = "libkivy.a" library = "libkivy.a"
depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios", depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
"pyobjus", "python"] "pyobjus", "python", "host_setuptools3"]
pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"] pbx_frameworks = ["OpenGLES", "Accelerate", "CoreMedia", "CoreVideo"]
pre_build_ext = True pre_build_ext = True

View file

@ -32,6 +32,7 @@ class Python3Recipe(Recipe):
self.apply_patch("posixmodule.patch") self.apply_patch("posixmodule.patch")
self.apply_patch("dynload_shlib.patch") self.apply_patch("dynload_shlib.patch")
self.apply_patch("disable_explicit_blake2.patch") self.apply_patch("disable_explicit_blake2.patch")
self.apply_patch("pyconfig_detection.patch")
self.copy_file("ModulesSetup", "Modules/Setup.local") self.copy_file("ModulesSetup", "Modules/Setup.local")
self.append_file("ModulesSetup.mobile", "Modules/Setup.local") self.append_file("ModulesSetup.mobile", "Modules/Setup.local")
self.set_marker("patched") self.set_marker("patched")

View file

@ -0,0 +1,25 @@
diff -Nru Python-3.8.2/Lib/site.py Python-3.8.2-new/Lib/site.py
--- Python-3.8.2/Lib/site.py 2020-02-24 22:36:25.000000000 +0100
+++ Python-3.8.2-new/Lib/site.py 2020-05-01 17:10:43.000000000 +0200
@@ -458,9 +458,8 @@
env = os.environ
if sys.platform == 'darwin' and '__PYVENV_LAUNCHER__' in env:
- executable = sys._base_executable = os.environ['__PYVENV_LAUNCHER__']
- else:
- executable = sys.executable
+ print("Ignoring __PYVENV_LAUNCHER__")
+ executable = sys.executable
exe_dir, _ = os.path.split(os.path.abspath(executable))
site_prefix = os.path.dirname(exe_dir)
sys._home = None
@@ -487,7 +486,8 @@
if key == 'include-system-site-packages':
system_site = value.lower()
elif key == 'home':
- sys._home = value
+ # this is breaking pyconfig.h path detection with venv
+ print('Ignoring "sys._home = value" override')
sys.prefix = sys.exec_prefix = site_prefix

View file

@ -8,7 +8,7 @@ This tool intend to replace all the previous tools/ in shell script.
import sys import sys
from sys import stdout from sys import stdout
from os.path import join, dirname, realpath, exists, isdir, basename from os.path import join, dirname, realpath, exists, isdir, basename, expanduser
from os import listdir, unlink, makedirs, environ, chdir, getcwd, walk from os import listdir, unlink, makedirs, environ, chdir, getcwd, walk
import zipfile import zipfile
import tarfile import tarfile
@ -19,6 +19,7 @@ import shutil
import fnmatch import fnmatch
import tempfile import tempfile
import time import time
from contextlib import contextmanager
from datetime import datetime from datetime import datetime
from pprint import pformat from pprint import pformat
import logging import logging
@ -58,6 +59,16 @@ IS_PY3 = sys.version_info[0] >= 3
IS_PY2 = sys.version_info[0] == 2 IS_PY2 = sys.version_info[0] == 2
@contextmanager
def cd(newdir):
prevdir = getcwd()
chdir(expanduser(newdir))
try:
yield
finally:
chdir(prevdir)
def shprint(command, *args, **kwargs): def shprint(command, *args, **kwargs):
kwargs["_iter"] = True kwargs["_iter"] = True
kwargs["_out_bufsize"] = 1 kwargs["_out_bufsize"] = 1