add the toolchain script.
This commit is contained in:
parent
18c67317fe
commit
5c4f42b1d4
1 changed files with 57 additions and 17 deletions
74
toolchain.py
74
toolchain.py
|
@ -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
|
||||||
from os import listdir, unlink, makedirs, environ
|
from os import listdir, unlink, makedirs, environ, chdir
|
||||||
import zipfile
|
import zipfile
|
||||||
import tarfile
|
import tarfile
|
||||||
import importlib
|
import importlib
|
||||||
|
@ -23,6 +23,7 @@ except ImportError:
|
||||||
def shprint(command, *args, **kwargs):
|
def shprint(command, *args, **kwargs):
|
||||||
kwargs["_iter"] = True
|
kwargs["_iter"] = True
|
||||||
kwargs["_out_bufsize"] = 1
|
kwargs["_out_bufsize"] = 1
|
||||||
|
kwargs["_err_to_out"] = True
|
||||||
#kwargs["_err_to_out"] = True
|
#kwargs["_err_to_out"] = True
|
||||||
for line in command(*args, **kwargs):
|
for line in command(*args, **kwargs):
|
||||||
stdout.write(line)
|
stdout.write(line)
|
||||||
|
@ -60,7 +61,7 @@ class Context(object):
|
||||||
print("No iphone SDK installed")
|
print("No iphone SDK installed")
|
||||||
ok = False
|
ok = False
|
||||||
else:
|
else:
|
||||||
iphoneos = iphoneos[0].split()[-1]
|
iphoneos = iphoneos[0].split()[-1].replace("iphoneos", "")
|
||||||
self.sdkver = iphoneos
|
self.sdkver = iphoneos
|
||||||
|
|
||||||
# get the latest iphonesimulator version
|
# get the latest iphonesimulator version
|
||||||
|
@ -69,7 +70,7 @@ class Context(object):
|
||||||
ok = False
|
ok = False
|
||||||
print("Error: No iphonesimulator SDK installed")
|
print("Error: No iphonesimulator SDK installed")
|
||||||
else:
|
else:
|
||||||
iphonesim = iphonesim[0].split()[-1]
|
iphonesim = iphonesim[0].split()[-1].replace("iphonesimulator", "")
|
||||||
self.sdksimver = iphonesim
|
self.sdksimver = iphonesim
|
||||||
|
|
||||||
# get the path for Developer
|
# get the path for Developer
|
||||||
|
@ -77,7 +78,7 @@ class Context(object):
|
||||||
sh.xcode_select("-print-path").strip())
|
sh.xcode_select("-print-path").strip())
|
||||||
|
|
||||||
# path to the iOS SDK
|
# path to the iOS SDK
|
||||||
self.iossdkroot = "{}/SDKs.iPhoneOS{}.sdk".format(
|
self.iossdkroot = "{}/SDKs/iPhoneOS{}.sdk".format(
|
||||||
self.devroot, self.sdkver)
|
self.devroot, self.sdkver)
|
||||||
|
|
||||||
# root of the toolchain
|
# root of the toolchain
|
||||||
|
@ -116,10 +117,18 @@ class Context(object):
|
||||||
ensure_dir(self.dist_dir)
|
ensure_dir(self.dist_dir)
|
||||||
ensure_dir(self.install_dir)
|
ensure_dir(self.install_dir)
|
||||||
|
|
||||||
|
# remove the most obvious flags that can break the compilation
|
||||||
|
self.env.pop("MACOSX_DEPLOYMENT_TARGET", None)
|
||||||
|
self.env.pop("PYTHONDONTWRITEBYTECODE", None)
|
||||||
|
self.env.pop("ARCHFLAGS", None)
|
||||||
|
self.env.pop("CFLAGS", None)
|
||||||
|
self.env.pop("LDFLAGS", None)
|
||||||
|
|
||||||
|
|
||||||
class Recipe(object):
|
class Recipe(object):
|
||||||
version = None
|
version = None
|
||||||
url = None
|
url = None
|
||||||
|
depends = []
|
||||||
|
|
||||||
# API available for recipes
|
# API available for recipes
|
||||||
def download_file(self, url, filename, cwd=None):
|
def download_file(self, url, filename, cwd=None):
|
||||||
|
@ -186,10 +195,20 @@ class Recipe(object):
|
||||||
sh.patch("-t", "-d", self.build_dir, "-p1", "-i", filename)
|
sh.patch("-t", "-d", self.build_dir, "-p1", "-i", filename)
|
||||||
|
|
||||||
def copy_file(self, filename, dest):
|
def copy_file(self, filename, dest):
|
||||||
|
print("Copy {} to {}".format(filename, dest))
|
||||||
filename = join(self.recipe_dir, filename)
|
filename = join(self.recipe_dir, filename)
|
||||||
dest = join(self.build_dir, dest)
|
dest = join(self.build_dir, dest)
|
||||||
shutil.copy(filename, dest)
|
shutil.copy(filename, dest)
|
||||||
|
|
||||||
|
def append_file(self, filename, dest):
|
||||||
|
print("Append {} to {}".format(filename, dest))
|
||||||
|
filename = join(self.recipe_dir, filename)
|
||||||
|
dest = join(self.build_dir, dest)
|
||||||
|
with open(filename, "rb") as fd:
|
||||||
|
data = fd.read()
|
||||||
|
with open(dest, "ab") as fd:
|
||||||
|
fd.write(data)
|
||||||
|
|
||||||
def has_marker(self, marker):
|
def has_marker(self, marker):
|
||||||
"""
|
"""
|
||||||
Return True if the current build directory has the marker set
|
Return True if the current build directory has the marker set
|
||||||
|
@ -203,10 +222,14 @@ class Recipe(object):
|
||||||
with open(join(self.build_dir, ".{}".format(marker)), "w") as fd:
|
with open(join(self.build_dir, ".{}".format(marker)), "w") as fd:
|
||||||
fd.write("ok")
|
fd.write("ok")
|
||||||
|
|
||||||
def marker(self, marker):
|
def delete_marker(self, marker):
|
||||||
"""
|
"""
|
||||||
Return a context that will be executed only if the marker has been set
|
Delete a specific marker
|
||||||
"""
|
"""
|
||||||
|
try:
|
||||||
|
unlink(join(self.build_dir, ".{}".format(marker)))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
|
@ -226,6 +249,9 @@ class Recipe(object):
|
||||||
|
|
||||||
# Public Recipe API to be subclassed if needed
|
# Public Recipe API to be subclassed if needed
|
||||||
|
|
||||||
|
def init_with_ctx(self, ctx):
|
||||||
|
self.ctx = ctx
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
print("Download {}".format(self.name))
|
print("Download {}".format(self.name))
|
||||||
self.download()
|
self.download()
|
||||||
|
@ -238,40 +264,54 @@ class Recipe(object):
|
||||||
fn = self.archive_fn
|
fn = self.archive_fn
|
||||||
if not exists(fn):
|
if not exists(fn):
|
||||||
self.download_file(self.url.format(version=self.version), fn)
|
self.download_file(self.url.format(version=self.version), fn)
|
||||||
|
self.archive_root = self.get_archive_rootdir(self.archive_fn)
|
||||||
|
|
||||||
def extract(self):
|
def extract(self):
|
||||||
# recipe tmp directory
|
# recipe tmp directory
|
||||||
archive_root = self.get_archive_rootdir(self.archive_fn)
|
archive_root = self.get_archive_rootdir(self.archive_fn)
|
||||||
for arch in self.ctx.archs:
|
for arch in self.ctx.archs:
|
||||||
print("Extract {} for {}".format(self.name, arch))
|
print("Extract {} for {}".format(self.name, arch))
|
||||||
build_dir = join(self.ctx.build_dir, arch)
|
self.extract_arch(arch, archive_root)
|
||||||
if exists(join(build_dir, archive_root)):
|
|
||||||
continue
|
def extract_arch(self, arch, archive_root):
|
||||||
ensure_dir(build_dir)
|
build_dir = join(self.ctx.build_dir, arch)
|
||||||
self.extract_file(self.archive_fn, build_dir)
|
if exists(join(build_dir, archive_root)):
|
||||||
|
return
|
||||||
|
ensure_dir(build_dir)
|
||||||
|
self.extract_file(self.archive_fn, build_dir)
|
||||||
|
|
||||||
def build_all(self):
|
def build_all(self):
|
||||||
archive_root = self.get_archive_rootdir(self.archive_fn)
|
archive_root = self.get_archive_rootdir(self.archive_fn)
|
||||||
for arch in self.ctx.archs:
|
for arch in self.ctx.archs:
|
||||||
self.build_dir = join(self.ctx.build_dir, arch, archive_root)
|
self.build_dir = join(self.ctx.build_dir, arch, archive_root)
|
||||||
|
if self.has_marker("building"):
|
||||||
|
print("Warning: {} build for {} has been incomplete".format(
|
||||||
|
self.name, arch))
|
||||||
|
print("Warning: deleting the build and restarting.")
|
||||||
|
shutil.rmtree(self.build_dir)
|
||||||
|
self.extract_arch(arch, archive_root)
|
||||||
|
self.set_marker("building")
|
||||||
|
|
||||||
|
chdir(self.build_dir)
|
||||||
|
print("Prebuild {} for {}".format(self.name, arch))
|
||||||
self.prebuild_arch(arch)
|
self.prebuild_arch(arch)
|
||||||
|
print("Build {} for {}".format(self.name, arch))
|
||||||
self.build_arch(arch)
|
self.build_arch(arch)
|
||||||
|
print("Postbuild {} for {}".format(self.name, arch))
|
||||||
self.postbuild_arch(arch)
|
self.postbuild_arch(arch)
|
||||||
|
self.delete_marker("building")
|
||||||
|
|
||||||
def prebuild_arch(self, arch):
|
def prebuild_arch(self, arch):
|
||||||
print("Prebuild {} for {}".format(self.name, arch))
|
|
||||||
prebuild = "prebuild_{}".format(arch)
|
prebuild = "prebuild_{}".format(arch)
|
||||||
if hasattr(self, prebuild):
|
if hasattr(self, prebuild):
|
||||||
getattr(self, prebuild)()
|
getattr(self, prebuild)()
|
||||||
|
|
||||||
def build_arch(self, arch):
|
def build_arch(self, arch):
|
||||||
print("Build {} for {}".format(self.name, arch))
|
|
||||||
build = "build_{}".format(arch)
|
build = "build_{}".format(arch)
|
||||||
if hasattr(self, build):
|
if hasattr(self, build):
|
||||||
getattr(self, build)()
|
getattr(self, build)()
|
||||||
|
|
||||||
def postbuild_arch(self, arch):
|
def postbuild_arch(self, arch):
|
||||||
print("Postbuild {} for {}".format(self.name, arch))
|
|
||||||
postbuild = "postbuild_{}".format(arch)
|
postbuild = "postbuild_{}".format(arch)
|
||||||
if hasattr(self, postbuild):
|
if hasattr(self, postbuild):
|
||||||
getattr(self, postbuild)()
|
getattr(self, postbuild)()
|
||||||
|
@ -284,11 +324,11 @@ def list_recipes():
|
||||||
if isdir(fn):
|
if isdir(fn):
|
||||||
yield name
|
yield name
|
||||||
|
|
||||||
def compile_recipe(name, ctx):
|
def build_recipe(name, ctx):
|
||||||
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.ctx = ctx
|
recipe.init_with_ctx(ctx)
|
||||||
recipe.execute()
|
recipe.execute()
|
||||||
|
|
||||||
|
|
||||||
|
@ -304,4 +344,4 @@ if __name__ == "__main__":
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
ctx = Context()
|
ctx = Context()
|
||||||
print list(list_recipes())
|
print list(list_recipes())
|
||||||
compile_recipe("hostpython", ctx)
|
build_recipe("libffi", ctx)
|
||||||
|
|
Loading…
Reference in a new issue