add alias for hostpython/python, that point to either 2 or 3 version depending of the previous compiled state.
This allows the recipe to point on an versionless python.
This commit is contained in:
parent
9762ee754c
commit
811cbd48a7
10 changed files with 130 additions and 40 deletions
15
recipes/hostpython.py
Normal file
15
recipes/hostpython.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from toolchain import Recipe
|
||||||
|
|
||||||
|
class HostpythonAliasRecipe(Recipe):
|
||||||
|
is_alias = True
|
||||||
|
|
||||||
|
def init_after_import(self, ctx):
|
||||||
|
hostpython = ctx.state.get("hostpython")
|
||||||
|
if not hostpython:
|
||||||
|
print("WARNING: no hostpython set yet, so you need to specify")
|
||||||
|
print("WARNING: either hostpython2 or hostpython3 in your deps")
|
||||||
|
else:
|
||||||
|
self.depends = [hostpython]
|
||||||
|
|
||||||
|
recipe = HostpythonAliasRecipe()
|
|
@ -5,7 +5,7 @@ import sh
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
|
||||||
class HostpythonRecipe(Recipe):
|
class Hostpython2Recipe(Recipe):
|
||||||
version = "2.7.1"
|
version = "2.7.1"
|
||||||
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
||||||
depends = ["hostlibffi"]
|
depends = ["hostlibffi"]
|
||||||
|
@ -13,7 +13,9 @@ class HostpythonRecipe(Recipe):
|
||||||
archs = ["x86_64"]
|
archs = ["x86_64"]
|
||||||
|
|
||||||
def init_with_ctx(self, ctx):
|
def init_with_ctx(self, ctx):
|
||||||
super(HostpythonRecipe, self).init_with_ctx(ctx)
|
super(Hostpython2Recipe, self).init_with_ctx(ctx)
|
||||||
|
self.set_hostpython(self, 2.7)
|
||||||
|
self.ctx.so_suffix = ".so"
|
||||||
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython", "bin", "python")
|
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython", "bin", "python")
|
||||||
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython", "bin", "pgen")
|
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython", "bin", "pgen")
|
||||||
print("Global: hostpython located at {}".format(self.ctx.hostpython))
|
print("Global: hostpython located at {}".format(self.ctx.hostpython))
|
||||||
|
@ -110,4 +112,4 @@ class HostpythonRecipe(Recipe):
|
||||||
join(self.ctx.dist_dir, "hostpython", "bin", "pgen"))
|
join(self.ctx.dist_dir, "hostpython", "bin", "pgen"))
|
||||||
|
|
||||||
|
|
||||||
recipe = HostpythonRecipe()
|
recipe = Hostpython2Recipe()
|
||||||
|
|
|
@ -14,6 +14,8 @@ class Hostpython3Recipe(Recipe):
|
||||||
|
|
||||||
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)
|
||||||
|
self.set_hostpython(self, 3.7)
|
||||||
|
self.ctx.so_suffix = ".cpython-37m-darwin.so"
|
||||||
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython3", "bin", "python")
|
self.ctx.hostpython = join(self.ctx.dist_dir, "hostpython3", "bin", "python")
|
||||||
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython3", "bin", "pgen")
|
self.ctx.hostpgen = join(self.ctx.dist_dir, "hostpython3", "bin", "pgen")
|
||||||
print("Global: hostpython located at {}".format(self.ctx.hostpython))
|
print("Global: hostpython located at {}".format(self.ctx.hostpython))
|
||||||
|
|
|
@ -9,9 +9,8 @@ class IosRecipe(CythonRecipe):
|
||||||
pbx_frameworks = ["MessageUI", "CoreMotion", "UIKit"]
|
pbx_frameworks = ["MessageUI", "CoreMotion", "UIKit"]
|
||||||
|
|
||||||
def install(self):
|
def install(self):
|
||||||
self.install_python_package(name="ios.so", is_dir=False)
|
self.install_python_package(
|
||||||
|
name=self.so_filename("ios"), is_dir=False)
|
||||||
|
|
||||||
|
|
||||||
recipe = IosRecipe()
|
recipe = IosRecipe()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@ class KivyRecipe(CythonRecipe):
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
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 = ["python", "sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
|
depends = ["sdl2", "sdl2_image", "sdl2_mixer", "sdl2_ttf", "ios",
|
||||||
"pyobjus"]
|
"pyobjus", "python"]
|
||||||
pbx_frameworks = ["OpenGLES", "Accelerate"]
|
pbx_frameworks = ["OpenGLES", "Accelerate"]
|
||||||
pre_build_ext = True
|
pre_build_ext = True
|
||||||
|
|
||||||
|
@ -40,4 +40,3 @@ class KivyRecipe(CythonRecipe):
|
||||||
|
|
||||||
|
|
||||||
recipe = KivyRecipe()
|
recipe = KivyRecipe()
|
||||||
|
|
||||||
|
|
|
@ -18,8 +18,9 @@ class PyobjusRecipe(CythonRecipe):
|
||||||
|
|
||||||
def cythonize_build(self):
|
def cythonize_build(self):
|
||||||
# don't use the cythonize, pyobjus don't support method rewriting
|
# don't use the cythonize, pyobjus don't support method rewriting
|
||||||
|
pyver = "-{}".format(self.ctx.python_major)
|
||||||
shprint(sh.find, self.build_dir, "-iname", "*.pyx",
|
shprint(sh.find, self.build_dir, "-iname", "*.pyx",
|
||||||
"-exec", "cython", "{}", ";")
|
"-exec", "cython", pyver, "{}", ";")
|
||||||
# ffi is installed somewhere else, this include doesn't work
|
# ffi is installed somewhere else, this include doesn't work
|
||||||
# XXX ideally, we need to fix libffi installation...
|
# XXX ideally, we need to fix libffi installation...
|
||||||
shprint(sh.sed,
|
shprint(sh.sed,
|
||||||
|
@ -28,5 +29,3 @@ class PyobjusRecipe(CythonRecipe):
|
||||||
"pyobjus/pyobjus.c")
|
"pyobjus/pyobjus.c")
|
||||||
|
|
||||||
recipe = PyobjusRecipe()
|
recipe = PyobjusRecipe()
|
||||||
|
|
||||||
|
|
||||||
|
|
15
recipes/python.py
Normal file
15
recipes/python.py
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from toolchain import Recipe
|
||||||
|
|
||||||
|
class PythonAliasRecipe(Recipe):
|
||||||
|
is_alias = True
|
||||||
|
|
||||||
|
def init_after_import(self, ctx):
|
||||||
|
python = ctx.state.get("python")
|
||||||
|
if not python:
|
||||||
|
print("WARNING: no python set yet, so you need to specify")
|
||||||
|
print("WARNING: either python2 or python3 in your deps")
|
||||||
|
else:
|
||||||
|
self.depends = [python]
|
||||||
|
|
||||||
|
recipe = PythonAliasRecipe()
|
|
@ -4,21 +4,21 @@ import sh
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
|
||||||
class PythonRecipe(Recipe):
|
class Python2Recipe(Recipe):
|
||||||
version = "2.7.1"
|
version = "2.7.1"
|
||||||
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
|
||||||
depends = ["hostpython", "libffi", ]
|
depends = ["hostpython2", "libffi"]
|
||||||
optional_depends = ["openssl"]
|
optional_depends = ["openssl"]
|
||||||
library = "libpython2.7.a"
|
library = "libpython2.7.a"
|
||||||
pbx_libraries = ["libz", "libbz2", "libsqlite3"]
|
pbx_libraries = ["libz", "libbz2", "libsqlite3"]
|
||||||
|
|
||||||
def init_with_ctx(self, ctx):
|
def init_with_ctx(self, ctx):
|
||||||
super(PythonRecipe, self).init_with_ctx(ctx)
|
super(Python2Recipe, self).init_with_ctx(ctx)
|
||||||
self.ctx.python_ver_dir = "python2.7"
|
self.set_python(self, 2.7)
|
||||||
self.ctx.python_prefix = join(ctx.dist_dir, "root", "python")
|
ctx.python_ver_dir = "python2.7"
|
||||||
self.ctx.site_packages_dir = join(
|
ctx.python_prefix = join(ctx.dist_dir, "root", "python")
|
||||||
ctx.dist_dir, "root", "python", "lib", ctx.python_ver_dir,
|
ctx.site_packages_dir = join(
|
||||||
"site-packages")
|
ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages")
|
||||||
|
|
||||||
def prebuild_arch(self, arch):
|
def prebuild_arch(self, arch):
|
||||||
# common to all archs
|
# common to all archs
|
||||||
|
@ -149,4 +149,4 @@ class PythonRecipe(Recipe):
|
||||||
os.chdir(oldpwd)
|
os.chdir(oldpwd)
|
||||||
|
|
||||||
|
|
||||||
recipe = PythonRecipe()
|
recipe = Python2Recipe()
|
||||||
|
|
|
@ -15,11 +15,11 @@ class Python3Recipe(Recipe):
|
||||||
|
|
||||||
def init_with_ctx(self, ctx):
|
def init_with_ctx(self, ctx):
|
||||||
super(Python3Recipe, self).init_with_ctx(ctx)
|
super(Python3Recipe, self).init_with_ctx(ctx)
|
||||||
self.ctx.python_ver_dir = "python3.7"
|
self.set_python(self, 3.7)
|
||||||
self.ctx.python_prefix = join(ctx.dist_dir, "root", "python")
|
ctx.python_ver_dir = "python3.7"
|
||||||
self.ctx.site_packages_dir = join(
|
ctx.python_prefix = join(ctx.dist_dir, "root", "python3")
|
||||||
ctx.dist_dir, "root", "python", "lib", ctx.python_ver_dir,
|
ctx.site_packages_dir = join(
|
||||||
"site-packages")
|
ctx.python_prefix, "lib", ctx.python_ver_dir, "site-packages")
|
||||||
|
|
||||||
def prebuild_arch(self, arch):
|
def prebuild_arch(self, arch):
|
||||||
# common to all archs
|
# common to all archs
|
||||||
|
|
87
toolchain.py
87
toolchain.py
|
@ -306,6 +306,7 @@ class Context(object):
|
||||||
cython = None
|
cython = None
|
||||||
sdkver = None
|
sdkver = None
|
||||||
sdksimver = None
|
sdksimver = None
|
||||||
|
so_suffix = None # set by one of the hostpython
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super(Context, self).__init__()
|
super(Context, self).__init__()
|
||||||
|
@ -413,20 +414,30 @@ class Context(object):
|
||||||
return "IDEBuildOperationMaxNumberOfConcurrentCompileTasks={}".format(self.num_cores)
|
return "IDEBuildOperationMaxNumberOfConcurrentCompileTasks={}".format(self.num_cores)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Recipe(object):
|
class Recipe(object):
|
||||||
version = None
|
props = {
|
||||||
url = None
|
"is_alias": False,
|
||||||
archs = []
|
"version": None,
|
||||||
depends = []
|
"url": None,
|
||||||
optional_depends = []
|
"archs": [],
|
||||||
library = None
|
"depends": [],
|
||||||
libraries = []
|
"optional_depends": [],
|
||||||
include_dir = None
|
"library": None,
|
||||||
include_per_arch = False
|
"libraries": [],
|
||||||
frameworks = []
|
"include_dir": None,
|
||||||
sources = []
|
"include_per_arch": False,
|
||||||
pbx_frameworks = []
|
"frameworks": [],
|
||||||
pbx_libraries = []
|
"sources": [],
|
||||||
|
"pbx_frameworks": [],
|
||||||
|
"pbx_libraries": []
|
||||||
|
}
|
||||||
|
|
||||||
|
def __new__(cls):
|
||||||
|
for prop, value in cls.props.items():
|
||||||
|
if not hasattr(cls, prop):
|
||||||
|
setattr(cls, prop, value)
|
||||||
|
return super(Recipe, cls).__new__(cls)
|
||||||
|
|
||||||
# API available for recipes
|
# API available for recipes
|
||||||
def download_file(self, url, filename, cwd=None):
|
def download_file(self, url, filename, cwd=None):
|
||||||
|
@ -560,6 +571,12 @@ class Recipe(object):
|
||||||
"""
|
"""
|
||||||
return join(self.ctx.include_dir, "common", self.name)
|
return join(self.ctx.include_dir, "common", self.name)
|
||||||
|
|
||||||
|
def so_filename(self, name):
|
||||||
|
"""Return the filename of a library with the appropriate so suffix
|
||||||
|
(.so for Python 2.7, .cpython-37m-darwin for Python 3.7)
|
||||||
|
"""
|
||||||
|
return "{}{}".format(name, self.ctx.so_suffix)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
modname = self.__class__.__module__
|
modname = self.__class__.__module__
|
||||||
|
@ -619,6 +636,37 @@ class Recipe(object):
|
||||||
arch = self.filtered_archs[0]
|
arch = self.filtered_archs[0]
|
||||||
return arch.get_env()
|
return arch.get_env()
|
||||||
|
|
||||||
|
def set_hostpython(self, instance, version):
|
||||||
|
state = self.ctx.state
|
||||||
|
hostpython = state.get("hostpython")
|
||||||
|
if hostpython is None:
|
||||||
|
state["hostpython"] = instance.name
|
||||||
|
state.sync()
|
||||||
|
elif hostpython != instance.name:
|
||||||
|
print("ERROR: Wanted to use {}".format(instance.name))
|
||||||
|
print("ERROR: but hostpython is already provided by {}.".format(
|
||||||
|
hostpython))
|
||||||
|
print("ERROR: You can have only one hostpython version compiled")
|
||||||
|
sys.exit(1)
|
||||||
|
self.ctx.python_major = int(version)
|
||||||
|
self.ctx.hostpython_ver = version
|
||||||
|
self.ctx.hostpython_recipe = instance
|
||||||
|
|
||||||
|
def set_python(self, instance, version):
|
||||||
|
state = self.ctx.state
|
||||||
|
python = state.get("python")
|
||||||
|
if python is None:
|
||||||
|
state["python"] = instance.name
|
||||||
|
state.sync()
|
||||||
|
elif python != instance.name:
|
||||||
|
print("ERROR: Wanted to use {}".format(instance.name))
|
||||||
|
print("ERROR: but python is already provided by {}.".format(
|
||||||
|
python))
|
||||||
|
print("ERROR: You can have only one python version compiled")
|
||||||
|
sys.exit(1)
|
||||||
|
self.ctx.python_ver = version
|
||||||
|
self.ctx.python_recipe = instance
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def archive_root(self):
|
def archive_root(self):
|
||||||
key = "{}.archive_root".format(self.name)
|
key = "{}.archive_root".format(self.name)
|
||||||
|
@ -649,6 +697,12 @@ class Recipe(object):
|
||||||
raise ValueError("Invalid path passed into {}".format(envname))
|
raise ValueError("Invalid path passed into {}".format(envname))
|
||||||
return d
|
return d
|
||||||
|
|
||||||
|
def init_after_import(cls, ctx):
|
||||||
|
"""This can be used to dynamically set some variables
|
||||||
|
depending of the state
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
@cache_execution
|
@cache_execution
|
||||||
def download(self):
|
def download(self):
|
||||||
key = "{}.archive_root".format(self.name)
|
key = "{}.archive_root".format(self.name)
|
||||||
|
@ -875,6 +929,7 @@ class Recipe(object):
|
||||||
mod = importlib.import_module("recipes.{}".format(name))
|
mod = importlib.import_module("recipes.{}".format(name))
|
||||||
recipe = mod.recipe
|
recipe = mod.recipe
|
||||||
recipe.recipe_dir = join(ctx.root_dir, "recipes", name)
|
recipe.recipe_dir = join(ctx.root_dir, "recipes", name)
|
||||||
|
recipe.init_after_import(ctx)
|
||||||
|
|
||||||
if version:
|
if version:
|
||||||
recipe.version = version
|
recipe.version = version
|
||||||
|
@ -916,7 +971,7 @@ class PythonRecipe(Recipe):
|
||||||
"--prefix", iosbuild,
|
"--prefix", iosbuild,
|
||||||
_env=env)
|
_env=env)
|
||||||
dest_dir = join(self.ctx.site_packages_dir, name)
|
dest_dir = join(self.ctx.site_packages_dir, name)
|
||||||
self.remove_junk(iosbuild)
|
#self.remove_junk(iosbuild)
|
||||||
if is_dir:
|
if is_dir:
|
||||||
if exists(dest_dir):
|
if exists(dest_dir):
|
||||||
shutil.rmtree(dest_dir)
|
shutil.rmtree(dest_dir)
|
||||||
|
@ -944,6 +999,7 @@ class CythonRecipe(PythonRecipe):
|
||||||
filename = filename[len(self.build_dir) + 1:]
|
filename = filename[len(self.build_dir) + 1:]
|
||||||
print("Cythonize {}".format(filename))
|
print("Cythonize {}".format(filename))
|
||||||
cmd = sh.Command(join(self.ctx.root_dir, "tools", "cythonize.py"))
|
cmd = sh.Command(join(self.ctx.root_dir, "tools", "cythonize.py"))
|
||||||
|
hostpython = self.ctx.state.get("hostpython")
|
||||||
shprint(cmd, filename)
|
shprint(cmd, filename)
|
||||||
|
|
||||||
def cythonize_build(self):
|
def cythonize_build(self):
|
||||||
|
@ -1021,6 +1077,9 @@ def build_recipes(names, ctx):
|
||||||
build_order = list(graph.find_order())
|
build_order = list(graph.find_order())
|
||||||
print("Build order is {}".format(build_order))
|
print("Build order is {}".format(build_order))
|
||||||
recipes = [Recipe.get_recipe(name, ctx) for name in build_order]
|
recipes = [Recipe.get_recipe(name, ctx) for name in build_order]
|
||||||
|
recipes = [recipe for recipe in recipes if not recipe.is_alias]
|
||||||
|
recipes_order = [recipe.name for recipe in recipes]
|
||||||
|
print("Recipe order is {}".format(recipes_order))
|
||||||
for recipe in recipes:
|
for recipe in recipes:
|
||||||
recipe.init_with_ctx(ctx)
|
recipe.init_with_ctx(ctx)
|
||||||
for recipe in recipes:
|
for recipe in recipes:
|
||||||
|
|
Loading…
Reference in a new issue