python now compiles for all arch \o/

This commit is contained in:
Mathieu Virbel 2015-02-03 18:42:17 +01:00
parent d4c1ac88d7
commit bfd8532e0e
5 changed files with 101 additions and 36 deletions

1
.gitignore vendored
View file

@ -4,6 +4,7 @@
*.swp
freetype-*
build/*
dist/*
src/SDL/Xcode-iPhoneOS/SDL/build/
src/SDL/Xcode-iOS/SDL/build/
tmp/*

View file

@ -13,10 +13,10 @@ class HostpythonRecipe(Recipe):
def download(self):
super(HostpythonRecipe, self).download()
self.ctx.hostpython = join(
self.ctx.build_dir, "i386", self.archive_root,
self.ctx.build_dir, self.name, "i386", self.archive_root,
"hostpython")
self.ctx.hostpgen = join(
self.ctx.build_dir, "i386", self.archive_root,
self.ctx.build_dir, self.name, "i386", self.archive_root,
"Parser", "hostpgen")
print("Global: hostpython located at {}".format(self.ctx.hostpython))
print("Global: hostpgen located at {}".format(self.ctx.hostpgen))

View file

@ -26,23 +26,25 @@ class LibffiRecipe(Recipe):
"-target", "libffi-iOS",
"-configuration", "Release")
def assemble_to(self, filename):
def make_lipo(self, filename):
shutil.copy(join(
self.get_build_dir("armv7"),
"build/Release-iphoneos/libffi.a"),
filename)
def install(self):
for sdkarch, arch in (
("iphoneos-arm64", "arm64"),
("iphoneos-armv7", "armv7"),
("iphonesimulator-i386", "i386"),
("iphonesimulator-x86_64", "x86_64")):
dest_dir = join(self.ctx.dist_dir, "include", arch, "ffi")
dest_dir = join(self.ctx.dist_dir, "include", arch)
if exists(dest_dir):
continue
shutil.copytree(join(
self.get_build_dir("armv7"),
"build_{}/include".format(sdkarch)),
join(self.ctx.dist_dir, "include", arch, "ffi"))
dest_dir)
recipe = LibffiRecipe()

View file

@ -7,6 +7,7 @@ class PythonRecipe(Recipe):
version = "2.7.1"
url = "https://www.python.org/ftp/python/{version}/Python-{version}.tar.bz2"
depends = ["hostpython", "libffi", ]
library = "libpython2.7.a"
def prebuild_arch(self, arch):
# common to all archs
@ -24,24 +25,7 @@ class PythonRecipe(Recipe):
self.set_marker("patched")
def build_arch(self, arch):
build_env = self.ctx.env.copy()
build_env["CC"] = sh.xcrun("-find", "-sdk", arch.sdk, "clang").strip()
build_env["AR"] = sh.xcrun("-find", "-sdk", arch.sdk, "ar").strip()
build_env["LD"] = sh.xcrun("-find", "-sdk", arch.sdk, "ld").strip()
build_env["CFLAGS"] = " ".join([
"-arch", arch.arch,
"-pipe", "-no-cpp-precomp",
"-isysroot", arch.sysroot,
"-O3",
"-miphoneos-version-min={}".format(arch.version_min)])
build_env["LDFLAGS"] = " ".join([
"-arch", arch.arch,
"-undefined dynamic_lookup",
"-Lextralibs/",
"-lsqlite3",
"-isysroot", arch.sysroot])
build_env = arch.get_env()
configure = sh.Command(join(self.build_dir, "configure"))
shprint(configure,
"CC={}".format(build_env["CC"]),
@ -54,7 +38,8 @@ class PythonRecipe(Recipe):
"--prefix=/python",
"--without-doc-strings",
_env=build_env)
self.apply_patch("pyconfig.patch")
self._patch_pyconfig()
self.apply_patch("ctypes_duplicate.patch")
shprint(sh.make, "-j4",
@ -62,5 +47,40 @@ class PythonRecipe(Recipe):
"HOSTPYTHON={}".format(self.ctx.hostpython),
"HOSTPGEN={}".format(self.ctx.hostpgen))
def _patch_pyconfig(self):
# patch pyconfig to remove some functionnalities
# (to have uniform build accross all platfors)
# this was before in a patch itself, but because the different
# architecture can lead to different pyconfig.h, we would need one patch
# per arch. Instead, express here the line we don't want / we want.
pyconfig = join(self.build_dir, "pyconfig.h")
def _remove_line(lines, pattern):
for line in lines[:]:
if pattern in line:
lines.remove(line)
with open(pyconfig) as fd:
lines = fd.readlines()
_remove_line(lines, "#define HAVE_BIND_TEXTDOMAIN_CODESET 1")
_remove_line(lines, "#define HAVE_FINITE 1")
_remove_line(lines, "#define HAVE_FSEEK64 1")
_remove_line(lines, "#define HAVE_FTELL64 1")
_remove_line(lines, "#define HAVE_GAMMA 1")
_remove_line(lines, "#define HAVE_GETHOSTBYNAME_R 1")
_remove_line(lines, "#define HAVE_GETHOSTBYNAME_R_6_ARG 1")
_remove_line(lines, "#define HAVE_GETRESGID 1")
_remove_line(lines, "#define HAVE_GETRESUID 1")
_remove_line(lines, "#define HAVE_GETSPENT 1")
_remove_line(lines, "#define HAVE_GETSPNAM 1")
_remove_line(lines, "#define HAVE_MREMAP 1")
_remove_line(lines, "#define HAVE_PLOCK 1")
_remove_line(lines, "#define HAVE_SEM_TIMEDWAIT 1")
_remove_line(lines, "#define HAVE_SETRESGID 1")
_remove_line(lines, "#define HAVE_SETRESUID 1")
_remove_line(lines, "#define HAVE_TMPNAM_R 1")
_remove_line(lines, "#define HAVE__GETPTY 1")
lines.append("#define HAVE_GETHOSTBYNAME 1\n")
with open(pyconfig, "wb") as fd:
fd.writelines(lines)
recipe = PythonRecipe()

View file

@ -38,14 +38,40 @@ urlretrieve = ChromeDownloader().retrieve
class Arch(object):
pass
def __init__(self, ctx):
super(Arch, self).__init__()
self.ctx = ctx
def get_env(self):
env = {}
env["CC"] = sh.xcrun("-find", "-sdk", self.sdk, "clang").strip()
env["AR"] = sh.xcrun("-find", "-sdk", self.sdk, "ar").strip()
env["LD"] = sh.xcrun("-find", "-sdk", self.sdk, "ld").strip()
env["CFLAGS"] = " ".join([
"-arch", self.arch,
"-pipe", "-no-cpp-precomp",
"--sysroot={}".format(self.sysroot),
"-I{}/include/{}".format(self.ctx.dist_dir, self.arch),
"-O3",
self.version_min
])
env["LDFLAGS"] = " ".join([
"-arch", self.arch,
"--sysroot={}".format(self.sysroot),
"-L{}/{}".format(self.ctx.dist_dir, "lib"),
"-lsqlite3",
"-undefined", "dynamic_lookup",
self.version_min
])
return env
class ArchSimulator(Arch):
sdk = "iphonesimulator"
arch = "i386"
triple = "i386-apple-darwin11"
version_min = "-miphoneos-version-min=5.1.1"
version_min = "-miphoneos-version-min=6.0.0"
sysroot = sh.xcrun("--sdk", "iphonesimulator", "--show-sdk-path").strip()
@ -61,7 +87,7 @@ class ArchIOS(Arch):
sdk = "iphoneos"
arch = "armv7"
triple = "arm-apple-darwin11"
version_min = "-miphoneos-version-min=5.1.1"
version_min = "-miphoneos-version-min=6.0.0"
sysroot = sh.xcrun("--sdk", "iphoneos", "--show-sdk-path").strip()
@ -167,7 +193,11 @@ class Context(object):
self.cache_dir = "{}/.cache".format(self.root_dir)
self.dist_dir = "{}/dist".format(self.root_dir)
self.install_dir = "{}/dist/root".format(self.root_dir)
self.archs = (ArchSimulator, Arch64Simulator, ArchIOS, Arch64IOS)
self.archs = (
ArchSimulator(self),
Arch64Simulator(self),
ArchIOS(self),
Arch64IOS(self))
# path to some tools
self.ccache = sh.which("ccache")
@ -210,6 +240,7 @@ class Recipe(object):
url = None
archs = []
depends = []
library = None
# API available for recipes
def download_file(self, url, filename, cwd=None):
@ -332,7 +363,7 @@ class Recipe(object):
yield arch
def get_build_dir(self, arch):
return join(self.ctx.build_dir, arch, self.archive_root)
return join(self.ctx.build_dir, self.name, arch, self.archive_root)
# Public Recipe API to be subclassed if needed
@ -360,7 +391,7 @@ class Recipe(object):
self.extract_arch(arch.arch)
def extract_arch(self, arch):
build_dir = join(self.ctx.build_dir, arch)
build_dir = join(self.ctx.build_dir, self.name, arch)
if exists(join(build_dir, self.archive_root)):
return
ensure_dir(build_dir)
@ -372,7 +403,7 @@ class Recipe(object):
self.name,
", ".join([x.arch for x in filtered_archs])))
for arch in self.filtered_archs:
self.build_dir = join(self.ctx.build_dir, arch.arch, self.archive_root)
self.build_dir = self.get_build_dir(arch.arch)
if self.has_marker("building"):
print("Warning: {} build for {} has been incomplete".format(
self.name, arch.arch))
@ -381,7 +412,7 @@ class Recipe(object):
self.extract_arch(arch.arch)
if self.has_marker("build_done"):
print("Build already done.")
print("Build python for {} already done.".format(arch.arch))
continue
self.set_marker("building")
@ -401,8 +432,9 @@ class Recipe(object):
name = "lib{}".format(name)
static_fn = join(self.ctx.dist_dir, "lib", "{}.a".format(name))
ensure_dir(dirname(static_fn))
print("Assemble {} to {}".format(self.name, static_fn))
self.assemble_to(static_fn)
print("Lipo {} to {}".format(self.name, static_fn))
self.make_lipo(static_fn)
print("Install {}".format(self.name))
def prebuild_arch(self, arch):
prebuild = "prebuild_{}".format(arch.arch)
@ -419,8 +451,18 @@ class Recipe(object):
if hasattr(self, postbuild):
getattr(self, postbuild)()
def assemble_to(self, filename):
return
def make_lipo(self, filename):
if not self.library:
return
args = []
for arch in self.filtered_archs:
args += [
"-arch", arch.arch,
join(self.get_build_dir(arch.arch), self.library)]
shprint(sh.lipo, "-create", "-output", filename, *args)
def install(self):
pass
@classmethod
def list_recipes(cls):