317 lines
8.3 KiB
Python
Executable File
317 lines
8.3 KiB
Python
Executable File
#!/home/tom/ab/renpy/lib/py3-linux-x86_64/python
|
|
|
|
# Builds a distribution of Ren'Py.
|
|
from __future__ import division, absolute_import, with_statement, print_function, unicode_literals
|
|
|
|
import future.standard_library
|
|
import future.utils
|
|
PY2 = future.utils.PY2
|
|
|
|
import sys
|
|
import os
|
|
import compileall
|
|
import shutil
|
|
import subprocess
|
|
import argparse
|
|
import time
|
|
import collections
|
|
|
|
try:
|
|
from importlib import reload
|
|
except ImportError:
|
|
pass
|
|
|
|
|
|
ROOT = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
|
def zip_rapt_symbols(destination):
|
|
"""
|
|
Zips up the rapt symbols.
|
|
"""
|
|
|
|
import zipfile
|
|
|
|
if PY2:
|
|
zf = zipfile.ZipFile(destination + "/android-native-symbols.zip", "w", zipfile.ZIP_DEFLATED)
|
|
else:
|
|
zf = zipfile.ZipFile(destination + "/android-native-symbols.zip", "w", zipfile.ZIP_DEFLATED, compresslevel=3)
|
|
|
|
for dn, dirs, files in os.walk("rapt/symbols"):
|
|
for fn in dirs + files:
|
|
fn = os.path.join(dn, fn)
|
|
arcname = os.path.relpath(fn, "rapt/symbols")
|
|
zf.write(fn, arcname)
|
|
|
|
zf.close()
|
|
|
|
def copy_tutorial_file(src, dest):
|
|
"""
|
|
Copies a file from src to dst. Lines between "# tutorial-only" and
|
|
"# end-tutorial-only" comments are omitted from the copy.
|
|
"""
|
|
|
|
# True if we want to copy the line.
|
|
copy = True
|
|
|
|
with open(src, "r") as sf, open(dest, "w") as df:
|
|
for l in sf:
|
|
if "# tutorial-only" in l:
|
|
copy = False
|
|
elif "# end-tutorial-only" in l:
|
|
copy = True
|
|
else:
|
|
if copy:
|
|
df.write(l)
|
|
|
|
def link_directory(dirname):
|
|
dn = os.path.join(ROOT, dirname)
|
|
|
|
if os.path.exists(dn):
|
|
os.unlink(dn)
|
|
|
|
if PY2:
|
|
source = dn + "2"
|
|
else:
|
|
source = dn + "3"
|
|
|
|
if os.path.exists(source):
|
|
os.symlink(source, dn)
|
|
|
|
def main():
|
|
|
|
start = time.time()
|
|
|
|
ap = argparse.ArgumentParser()
|
|
ap.add_argument("version", nargs="?")
|
|
ap.add_argument("--fast", action="store_true")
|
|
ap.add_argument("--pygame", action="store", default=None)
|
|
ap.add_argument("--no-rapt", action="store_true")
|
|
ap.add_argument("--variant", action="store")
|
|
ap.add_argument("--sign", action="store_true", default=True)
|
|
ap.add_argument("--nosign", action="store_false", dest="sign")
|
|
ap.add_argument("--notarized", action="store_true", dest="notarized")
|
|
ap.add_argument("--vc-version-only", action="store_true")
|
|
ap.add_argument("--link-directories", action="store_true")
|
|
ap.add_argument("--append-version", action="store_true")
|
|
ap.add_argument("--nightly", action="store_true")
|
|
ap.add_argument("--print-version", action="store_true")
|
|
|
|
args = ap.parse_args()
|
|
|
|
link_directory("rapt")
|
|
link_directory("renios")
|
|
link_directory("web")
|
|
|
|
import renpy.versions
|
|
renpy.versions.generate_vc_version(nightly=args.nightly)
|
|
|
|
if args.link_directories or args.vc_version_only:
|
|
return
|
|
|
|
if not os.path.abspath(sys.executable).startswith(ROOT + "/lib"):
|
|
raise Exception("Distribute must be run with the python in lib/.")
|
|
|
|
if args.sign:
|
|
os.environ["RENPY_MAC_IDENTITY"] = "Developer ID Application: Tom Rothamel (XHTE5H7Z79)"
|
|
|
|
if PY2 and not sys.flags.optimize:
|
|
raise Exception("Not running with python optimization.")
|
|
|
|
try:
|
|
vc_version_base = os.path.splitext(renpy.vc_version.__file__)[0]
|
|
|
|
# Delete the .pyc and .pyo files, as reload can choose one of them instead
|
|
# of the new .py file.
|
|
for fn in [ vc_version_base + ".pyc", vc_version_base + ".pyo" ]:
|
|
if os.path.exists(fn):
|
|
os.unlink(fn)
|
|
|
|
reload(renpy.vc_version)
|
|
except Exception:
|
|
import renpy.vc_version
|
|
|
|
# A normal reload is fine, as renpy/__init__.py won't change.
|
|
reload(renpy)
|
|
|
|
if args.print_version:
|
|
print(renpy.version_only)
|
|
return
|
|
|
|
if args.version is None:
|
|
if args.nightly:
|
|
args.version = renpy.version_only
|
|
else:
|
|
args.version = ".".join(str(i) for i in renpy.version_tuple[:-1])
|
|
|
|
if args.append_version:
|
|
args.version += "-" + renpy.version_only
|
|
|
|
# Check that the versions match.
|
|
full_version = renpy.version_only # @UndefinedVariable
|
|
|
|
if "-" not in args.version \
|
|
and not full_version.startswith(args.version):
|
|
raise Exception("The command-line and Ren'Py versions do not match.")
|
|
|
|
os.environ['RENPY_BUILD_VERSION'] = args.version
|
|
|
|
# The destination directory.
|
|
destination = os.path.join("dl", args.version)
|
|
|
|
if args.variant:
|
|
destination += "-" + args.variant
|
|
|
|
if os.path.exists(os.path.join(destination, "checksums.txt")):
|
|
raise Exception("The checksums.txt file exists.")
|
|
|
|
print("Version {} ({})".format(args.version, full_version))
|
|
|
|
if sys.version_info[0] >= 3:
|
|
renpy_sh = "./renpy3.sh"
|
|
else:
|
|
renpy_sh = "./renpy2.sh"
|
|
|
|
# Compile all the python files.
|
|
compileall.compile_dir("renpy/", ddir="renpy/", force=True, quiet=1)
|
|
|
|
# Compile the various games.
|
|
if not args.fast:
|
|
for i in [ 'tutorial', 'launcher', 'the_question' ]:
|
|
print("Compiling", i)
|
|
subprocess.check_call([renpy_sh, i, "compile" ])
|
|
|
|
# Kick off the rapt build.
|
|
if not args.fast:
|
|
|
|
print("Cleaning RAPT.")
|
|
|
|
sys.path.insert(0, os.path.join(ROOT, "rapt", "buildlib"))
|
|
|
|
import rapt.interface # type: ignore
|
|
import rapt.build # type: ignore
|
|
|
|
interface = rapt.interface.Interface()
|
|
rapt.build.distclean(interface)
|
|
|
|
print("Compiling RAPT and renios.")
|
|
|
|
compileall.compile_dir("rapt/buildlib/", ddir="rapt/buildlib/", quiet=1)
|
|
compileall.compile_dir("renios/buildlib/", ddir="renios/buildlib/", quiet=1)
|
|
|
|
if not os.path.exists(destination):
|
|
os.makedirs(destination)
|
|
|
|
zip_rapt_symbols(destination)
|
|
|
|
if args.fast:
|
|
|
|
cmd = [
|
|
renpy_sh,
|
|
"launcher",
|
|
"distribute",
|
|
"launcher",
|
|
"--package",
|
|
"sdk",
|
|
"--destination",
|
|
destination,
|
|
"--no-update",
|
|
]
|
|
|
|
else:
|
|
cmd = [
|
|
renpy_sh,
|
|
"launcher",
|
|
"distribute",
|
|
"launcher",
|
|
"--destination",
|
|
destination,
|
|
]
|
|
|
|
if args.notarized:
|
|
cmd.extend([
|
|
"--macapp",
|
|
"notarized/out",
|
|
])
|
|
|
|
print()
|
|
subprocess.check_call(cmd)
|
|
|
|
# Sign the update.
|
|
if not args.fast:
|
|
subprocess.check_call([
|
|
"scripts/sign_update.py",
|
|
"/home/tom/ab/keys/renpy_private.pem",
|
|
os.path.join(destination, "updates.json"),
|
|
])
|
|
|
|
# Package pygame_sdl2.
|
|
if not args.fast:
|
|
subprocess.check_call([
|
|
"pygame_sdl2/setup.py",
|
|
"-q",
|
|
"egg_info",
|
|
"--tag-build",
|
|
"+renpy" + args.version.replace("+", "-"),
|
|
"sdist",
|
|
"-d",
|
|
os.path.abspath(destination)
|
|
])
|
|
|
|
# Write 7z.exe.
|
|
sdk = "renpy-{}-sdk".format(args.version)
|
|
|
|
if not args.fast:
|
|
|
|
# shutil.copy("renpy-ppc.zip", os.path.join(destination, "renpy-ppc.zip"))
|
|
|
|
with open("7z.sfx", "rb") as f:
|
|
sfx = f.read()
|
|
|
|
os.chdir(destination)
|
|
|
|
if os.path.exists(sdk):
|
|
shutil.rmtree(sdk)
|
|
|
|
subprocess.check_call([ "unzip", "-q", sdk + ".zip" ])
|
|
|
|
if os.path.exists(sdk + ".7z"):
|
|
os.unlink(sdk + ".7z")
|
|
|
|
sys.stdout.write("Creating -sdk.7z")
|
|
|
|
p = subprocess.Popen([ "7z", "a", sdk + ".7z", sdk], stdout=subprocess.PIPE)
|
|
for i, _l in enumerate(p.stdout): # type: ignore
|
|
if i % 10 != 0:
|
|
continue
|
|
|
|
sys.stdout.write(".")
|
|
sys.stdout.flush()
|
|
|
|
if p.wait() != 0:
|
|
raise Exception("7z failed")
|
|
|
|
with open(sdk + ".7z", "rb") as f:
|
|
data = f.read()
|
|
|
|
with open(sdk + ".7z.exe", "wb") as f:
|
|
f.write(sfx)
|
|
f.write(data)
|
|
|
|
os.unlink(sdk + ".7z")
|
|
shutil.rmtree(sdk)
|
|
|
|
else:
|
|
os.chdir(destination)
|
|
|
|
if os.path.exists(sdk + ".7z.exe"):
|
|
os.unlink(sdk + ".7z.exe")
|
|
|
|
print()
|
|
|
|
print("Distribute took {:.0f} seconds.".format(time.time() - start))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|