mirror of
https://github.com/mupen64plus/mupen64plus-ui-python.git
synced 2025-04-02 10:51:53 -04:00
Merge pull request #101 from tmose1106/master
Change setup.py to Setuptools and refactor bits of code within setup.py
This commit is contained in:
commit
7d0dd4ec4e
2 changed files with 298 additions and 245 deletions
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# Directories
|
||||||
|
build/
|
||||||
|
src/m64py.egg-info/
|
||||||
|
|
||||||
|
# Files
|
||||||
|
dist/*.egg
|
537
setup.py
537
setup.py
|
@ -1,27 +1,32 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
import os
|
import fnmatch
|
||||||
import sys
|
|
||||||
import glob
|
import glob
|
||||||
import urllib
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
import zipfile
|
|
||||||
import tempfile
|
|
||||||
import subprocess
|
import subprocess
|
||||||
from os.path import join, dirname, basename, realpath
|
import sys
|
||||||
from fnmatch import fnmatch
|
import tempfile
|
||||||
from distutils.core import setup, Command
|
import urllib
|
||||||
from distutils.dep_util import newer
|
import zipfile
|
||||||
from distutils.command.build import build
|
|
||||||
from distutils.command.clean import clean
|
import distutils
|
||||||
from distutils.dir_util import copy_tree
|
import distutils.command.build as distutils_build
|
||||||
|
import distutils.command.clean as distutils_clean
|
||||||
|
import setuptools
|
||||||
|
|
||||||
sys.path.insert(0, realpath("src"))
|
|
||||||
from m64py.core.defs import FRONTEND_VERSION
|
from m64py.core.defs import FRONTEND_VERSION
|
||||||
BASE_DIR = dirname(realpath(__file__))
|
|
||||||
|
sys.path.insert(0, os.path.realpath("src"))
|
||||||
|
|
||||||
|
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
|
|
||||||
class build_qt(Command):
|
class BuildQt(setuptools.Command):
|
||||||
|
|
||||||
|
description = "Build the QT interface"
|
||||||
|
|
||||||
|
boolean_options = []
|
||||||
user_options = []
|
user_options = []
|
||||||
|
|
||||||
def initialize_options(self):
|
def initialize_options(self):
|
||||||
|
@ -30,47 +35,155 @@ class build_qt(Command):
|
||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def compile_ui(self, ui_file):
|
|
||||||
from PyQt5 import uic
|
|
||||||
py_file = os.path.splitext(ui_file)[0] + "_ui.py"
|
|
||||||
if not newer(ui_file, py_file):
|
|
||||||
return
|
|
||||||
fp = open(py_file, "w")
|
|
||||||
uic.compileUi(ui_file, fp, from_imports = True)
|
|
||||||
fp.close()
|
|
||||||
|
|
||||||
def compile_rc(self, qrc_file):
|
def compile_rc(self, qrc_file):
|
||||||
import PyQt5
|
import PyQt5
|
||||||
py_file = os.path.splitext(qrc_file)[0] + "_rc.py"
|
py_file = os.path.splitext(qrc_file)[0] + "_rc.py"
|
||||||
if not newer(qrc_file, py_file):
|
if not distutils.dep_util.newer(qrc_file, py_file):
|
||||||
return
|
return
|
||||||
origpath = os.getenv("PATH")
|
origpath = os.getenv("PATH")
|
||||||
path = origpath.split(os.pathsep)
|
path = origpath.split(os.pathsep)
|
||||||
path.append(dirname(PyQt5.__file__))
|
path.append(os.path.dirname(PyQt5.__file__))
|
||||||
os.putenv("PATH", os.pathsep.join(path))
|
os.putenv("PATH", os.pathsep.join(path))
|
||||||
if subprocess.call(["pyrcc5", qrc_file, "-o", py_file]) > 0:
|
if subprocess.call(["pyrcc5", qrc_file, "-o", py_file]) > 0:
|
||||||
self.warn("Unable to compile resource file %s" % qrc_file)
|
self.warn("Unable to compile resource file {}".format(qrc_file))
|
||||||
if not os.path.exists(py_file):
|
if not os.path.exists(py_file):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
os.putenv('PATH', origpath)
|
os.putenv("PATH", origpath)
|
||||||
|
|
||||||
|
def compile_ui(self, ui_file):
|
||||||
|
from PyQt5 import uic
|
||||||
|
py_file = os.path.splitext(ui_file)[0] + "_ui.py"
|
||||||
|
if not distutils.dep_util.newer(ui_file, py_file):
|
||||||
|
return
|
||||||
|
with open(py_file, "w") as a_file:
|
||||||
|
uic.compileUi(ui_file, a_file, from_imports=True)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
basepath = join(dirname(__file__),
|
basepath = os.path.join(os.path.dirname(__file__), "src", "m64py", "ui")
|
||||||
'src', 'm64py', 'ui')
|
for dirpath, _, filenames in os.walk(basepath):
|
||||||
for dirpath, dirs, filenames in os.walk(basepath):
|
|
||||||
for filename in filenames:
|
for filename in filenames:
|
||||||
if filename.endswith('.ui'):
|
if filename.endswith('.ui'):
|
||||||
self.compile_ui(join(dirpath, filename))
|
self.compile_ui(os.path.join(dirpath, filename))
|
||||||
elif filename.endswith('.qrc'):
|
elif filename.endswith('.qrc'):
|
||||||
self.compile_rc(join(dirpath, filename))
|
self.compile_rc(os.path.join(dirpath, filename))
|
||||||
|
|
||||||
|
|
||||||
class build_exe(Command):
|
def set_rthook():
|
||||||
"""Needs PyQt5, rarfile, PyLZMA, PyWin32, PyInstaller, Inno Setup 5"""
|
import PyInstaller
|
||||||
|
hook_file = ""
|
||||||
|
module_dir = os.path.dirname(PyInstaller.__file__)
|
||||||
|
rthook = os.path.join(module_dir, "loader", "rthooks", "pyi_rth_qt5plugins.py")
|
||||||
|
with open(rthook, "r") as hook:
|
||||||
|
data = hook.read()
|
||||||
|
if 'sys._MEIPASS, "lib"' not in data:
|
||||||
|
lines = data.split("\n")
|
||||||
|
for line in lines:
|
||||||
|
if "MEIPASS" in line:
|
||||||
|
hook_file += "d = os.path.join(sys._MEIPASS, \"lib\", d)\n"
|
||||||
|
else:
|
||||||
|
hook_file += line + "\n"
|
||||||
|
with open(rthook, "w") as hook:
|
||||||
|
hook.write(hook_file)
|
||||||
|
|
||||||
|
|
||||||
|
class BuildDmg(setuptools.Command):
|
||||||
|
|
||||||
|
description = "Generate a .dmg file for distribution"
|
||||||
|
|
||||||
user_options = []
|
user_options = []
|
||||||
|
|
||||||
|
dist_dir = os.path.join(BASE_DIR, "dist", "macosx")
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def copy_emulator(self):
|
||||||
|
src_path = os.path.join(self.dist_dir, "mupen64plus", "Contents")
|
||||||
|
dest_path = os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents")
|
||||||
|
distutils.dir_util.copy_tree(src_path, dest_path)
|
||||||
|
|
||||||
|
def copy_files(self):
|
||||||
|
dest_path = os.path.join(self.dist_dir, "dmg")
|
||||||
|
if not os.path.exists(dest_path):
|
||||||
|
os.mkdir(dest_path)
|
||||||
|
shutil.move(os.path.join(self.dist_dir, "M64Py.app"), dest_path)
|
||||||
|
for file_name in ["AUTHORS", "ChangeLog", "COPYING", "LICENSES", "README.md"]:
|
||||||
|
shutil.copy(os.path.join(BASE_DIR, file_name), dest_path)
|
||||||
|
shutil.copy(os.path.join(BASE_DIR, "test", "mupen64plus.v64"), dest_path)
|
||||||
|
|
||||||
|
def remove_files(self):
|
||||||
|
dest_path = os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents", "MacOS")
|
||||||
|
for dir_name in ["include", "lib"]:
|
||||||
|
shutil.rmtree(os.path.join(dest_path, dir_name), True)
|
||||||
|
os.remove(os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents",
|
||||||
|
"Resources", "icon-windowed.icns"))
|
||||||
|
|
||||||
|
def run_build(self):
|
||||||
|
import PyInstaller.building.build_main
|
||||||
|
work_path = os.path.join(self.dist_dir, "build")
|
||||||
|
spec_file = os.path.join(self.dist_dir, "m64py.spec")
|
||||||
|
os.environ["BASE_DIR"] = BASE_DIR
|
||||||
|
os.environ["DIST_DIR"] = self.dist_dir
|
||||||
|
opts = {"distpath": self.dist_dir,
|
||||||
|
"workpath": work_path,
|
||||||
|
"clean_build": True,
|
||||||
|
"upx_dir": None,
|
||||||
|
"debug": False}
|
||||||
|
PyInstaller.building.build_main.main(None, spec_file, True, **opts)
|
||||||
|
|
||||||
|
def run_build_dmg(self):
|
||||||
|
src_path = os.path.join(self.dist_dir, "dmg")
|
||||||
|
dst_path = os.path.join(self.dist_dir, "m64py-{}.dmg".format(FRONTEND_VERSION))
|
||||||
|
subprocess.call(["hdiutil", "create", dst_path, "-srcfolder", src_path])
|
||||||
|
|
||||||
|
def set_plist(self):
|
||||||
|
info_plist = os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents", "Info.plist")
|
||||||
|
shutil.copy(os.path.join(self.dist_dir, "m64py.icns"),
|
||||||
|
os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents", "Resources"))
|
||||||
|
shutil.copy(os.path.join(self.dist_dir, "m64py.sh"),
|
||||||
|
os.path.join(self.dist_dir, "dmg", "M64Py.app", "Contents", "MacOS"))
|
||||||
|
with open(info_plist, "r") as opts:
|
||||||
|
data = opts.read()
|
||||||
|
plist_file = ""
|
||||||
|
lines = data.split("\n")
|
||||||
|
for line in lines:
|
||||||
|
if "0.0.0" in line:
|
||||||
|
line = line.replace("0.0.0", FRONTEND_VERSION)
|
||||||
|
elif "icon-windowed.icns" in line:
|
||||||
|
line = line.replace("icon-windowed.icns", "m64py.icns")
|
||||||
|
elif "MacOS/m64py" in line:
|
||||||
|
line = line.replace("MacOS/m64py", "m64py.sh")
|
||||||
|
plist_file += line + "\n"
|
||||||
|
with open(info_plist, "w") as opts:
|
||||||
|
opts.write(plist_file)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.run_command("build_qt")
|
||||||
|
self.run_build()
|
||||||
|
self.copy_files()
|
||||||
|
self.copy_emulator()
|
||||||
|
self.remove_files()
|
||||||
|
self.set_plist()
|
||||||
|
self.run_build_dmg()
|
||||||
|
|
||||||
|
|
||||||
|
class BuildExe(setuptools.Command):
|
||||||
|
"""
|
||||||
|
Requires PyQt5, rarfile, PyLZMA, PyWin32, PyInstaller and Inno
|
||||||
|
Setup 5.
|
||||||
|
"""
|
||||||
|
|
||||||
|
description = "Generate a .exe file for distribution"
|
||||||
|
|
||||||
|
boolean_options = []
|
||||||
|
user_options = []
|
||||||
|
|
||||||
arch = "i686-w64-mingw32.static"
|
arch = "i686-w64-mingw32.static"
|
||||||
url = "https://bitbucket.org/ecsv/mupen64plus-mxe-daily/get/master.zip"
|
url = "https://bitbucket.org/ecsv/mupen64plus-mxe-daily/get/master.zip"
|
||||||
dist_dir = join(BASE_DIR, "dist", "windows")
|
dist_dir = os.path.join(BASE_DIR, "dist", "windows")
|
||||||
|
|
||||||
def initialize_options(self):
|
def initialize_options(self):
|
||||||
pass
|
pass
|
||||||
|
@ -80,96 +193,105 @@ class build_exe(Command):
|
||||||
|
|
||||||
def copy_emulator(self):
|
def copy_emulator(self):
|
||||||
tempdir = tempfile.mkdtemp()
|
tempdir = tempfile.mkdtemp()
|
||||||
zippath = join(tempdir, basename(self.url))
|
zippath = os.path.join(tempdir, os.path.basename(self.url))
|
||||||
urllib.request.urlretrieve(self.url, zippath)
|
urllib.request.urlretrieve(self.url, zippath)
|
||||||
zf = zipfile.ZipFile(zippath)
|
zip_file = zipfile.ZipFile(zippath)
|
||||||
for name in zf.namelist():
|
for name in zip_file.namelist():
|
||||||
if self.arch in name:
|
if self.arch in name:
|
||||||
dirn = basename(dirname(name))
|
dirn = os.path.basename(os.path.dirname(name))
|
||||||
filen = basename(name)
|
filen = os.path.basename(name)
|
||||||
if not filen: continue
|
if not filen:
|
||||||
dest_path = join(self.dist_dir, "m64py")
|
continue
|
||||||
|
dest_path = os.path.join(self.dist_dir, "m64py")
|
||||||
if dirn == self.arch:
|
if dirn == self.arch:
|
||||||
fullpath = join(dest_path, filen)
|
fullpath = os.path.join(dest_path, filen)
|
||||||
else:
|
else:
|
||||||
fullpath = join(dest_path, dirn, filen)
|
fullpath = os.path.join(dest_path, dirn, filen)
|
||||||
if not os.path.exists(join(dest_path, dirn)):
|
if not os.path.exists(os.path.join(dest_path, dirn)):
|
||||||
os.makedirs(join(dest_path, dirn))
|
os.makedirs(os.path.join(dest_path, dirn))
|
||||||
unpacked = open(fullpath, "wb")
|
unpacked = open(fullpath, "wb")
|
||||||
unpacked.write(zf.read(name))
|
unpacked.write(zip_file.read(name))
|
||||||
unpacked.close()
|
unpacked.close()
|
||||||
zf.close()
|
zip_file.close()
|
||||||
shutil.rmtree(tempdir)
|
shutil.rmtree(tempdir)
|
||||||
|
|
||||||
def move_files(self):
|
|
||||||
dest_path = join(self.dist_dir, "m64py", "lib")
|
|
||||||
plugins_path = join(self.dist_dir, "m64py", "qt5_plugins")
|
|
||||||
shutil.copytree(plugins_path, join(dest_path, "qt5_plugins"))
|
|
||||||
shutil.rmtree(plugins_path)
|
|
||||||
|
|
||||||
for file_name in glob.glob(join(self.dist_dir, "m64py", "*.pyd")):
|
|
||||||
if "PyQt5" not in file_name:
|
|
||||||
shutil.move(file_name, dest_path)
|
|
||||||
|
|
||||||
for file_name in glob.glob(join(self.dist_dir, "m64py", "api*.dll")):
|
|
||||||
shutil.move(file_name, dest_path)
|
|
||||||
|
|
||||||
for file_name in glob.glob(join(self.dist_dir, "m64py", "*.dll")):
|
|
||||||
print(file_name)
|
|
||||||
if "python3" not in file_name and "mupen64plus" not in basename(file_name):
|
|
||||||
shutil.move(file_name, dest_path)
|
|
||||||
|
|
||||||
def copy_files(self):
|
def copy_files(self):
|
||||||
dest_path = join(self.dist_dir, "m64py")
|
dest_path = os.path.join(self.dist_dir, "m64py")
|
||||||
rar_dir = join(os.environ["ProgramFiles(x86)"], "Unrar")
|
rar_dir = os.path.join(os.environ["ProgramFiles(x86)"], "Unrar")
|
||||||
if not os.path.isfile(join(rar_dir, "UnRAR.exe")):
|
if not os.path.isfile(os.path.join(rar_dir, "UnRAR.exe")):
|
||||||
tempdir = tempfile.mkdtemp()
|
tempdir = tempfile.mkdtemp()
|
||||||
urllib.request.urlretrieve("http://www.rarlab.com/rar/unrarw32.exe", join(tempdir, "unrar.exe"))
|
urllib.request.urlretrieve("http://www.rarlab.com/rar/unrarw32.exe",
|
||||||
subprocess.call([join(tempdir, "unrar.exe"), "-s"])
|
os.path.join(tempdir, "unrar.exe"))
|
||||||
|
subprocess.call([os.path.join(tempdir, "unrar.exe"), "-s"])
|
||||||
shutil.rmtree(tempdir)
|
shutil.rmtree(tempdir)
|
||||||
shutil.copy(join(rar_dir, "UnRAR.exe"), dest_path)
|
shutil.copy(os.path.join(rar_dir, "UnRAR.exe"), dest_path)
|
||||||
shutil.copy(join(rar_dir, "license.txt"), join(dest_path, "doc", "unrar-license.txt"))
|
shutil.copy(os.path.join(rar_dir, "license.txt"),
|
||||||
|
os.path.join(dest_path, "doc", "unrar-license.txt"))
|
||||||
for file_name in ["AUTHORS", "ChangeLog", "COPYING", "LICENSES", "README.md"]:
|
for file_name in ["AUTHORS", "ChangeLog", "COPYING", "LICENSES", "README.md"]:
|
||||||
shutil.copy(join(BASE_DIR, file_name), dest_path)
|
shutil.copy(os.path.join(BASE_DIR, file_name), dest_path)
|
||||||
|
|
||||||
import PyQt5
|
import PyQt5
|
||||||
qt5_dir = dirname(PyQt5.__file__)
|
qt5_dir = os.path.dirname(PyQt5.__file__)
|
||||||
qwindows = join(qt5_dir, "Qt", "plugins", "platforms", "qwindows.dll")
|
qwindows = os.path.join(qt5_dir, "Qt", "plugins", "platforms", "qwindows.dll")
|
||||||
qwindows_dest = join(dest_path, "lib", "qt5_plugins", "platforms")
|
qwindows_dest = os.path.join(dest_path, "lib", "qt5_plugins", "platforms")
|
||||||
if not os.path.exists(qwindows_dest):
|
if not os.path.exists(qwindows_dest):
|
||||||
os.makedirs(qwindows_dest)
|
os.makedirs(qwindows_dest)
|
||||||
shutil.copy(qwindows, qwindows_dest)
|
shutil.copy(qwindows, qwindows_dest)
|
||||||
|
|
||||||
|
def move_files(self):
|
||||||
|
dest_path = os.path.join(self.dist_dir, "m64py", "lib")
|
||||||
|
plugins_path = os.path.join(self.dist_dir, "m64py", "qt5_plugins")
|
||||||
|
shutil.copytree(plugins_path, os.path.join(dest_path, "qt5_plugins"))
|
||||||
|
shutil.rmtree(plugins_path)
|
||||||
|
|
||||||
|
for file_name in glob.glob(os.path.join(self.dist_dir, "m64py", "*.pyd")):
|
||||||
|
if "PyQt5" not in file_name:
|
||||||
|
shutil.move(file_name, dest_path)
|
||||||
|
|
||||||
|
for file_name in glob.glob(os.path.join(self.dist_dir, "m64py", "api*.dll")):
|
||||||
|
shutil.move(file_name, dest_path)
|
||||||
|
|
||||||
|
for file_name in glob.glob(os.path.join(self.dist_dir, "m64py", "*.dll")):
|
||||||
|
print(file_name)
|
||||||
|
if "python3" not in file_name and "mupen64plus" not in os.path.basename(file_name):
|
||||||
|
shutil.move(file_name, dest_path)
|
||||||
|
|
||||||
def remove_files(self):
|
def remove_files(self):
|
||||||
dest_path = join(self.dist_dir, "m64py")
|
dest_path = os.path.join(self.dist_dir, "m64py")
|
||||||
for dir_name in ["api", "man6", "applications", "apps"]:
|
for dir_name in ["api", "man6", "applications", "apps"]:
|
||||||
shutil.rmtree(join(dest_path, dir_name), True)
|
shutil.rmtree(os.path.join(dest_path, dir_name), True)
|
||||||
for file_name in glob.glob(join(dest_path, "glide*.exe")):
|
for file_name in glob.glob(os.path.join(dest_path, "glide*.exe")):
|
||||||
os.remove(file_name)
|
os.remove(file_name)
|
||||||
|
|
||||||
|
def run_build(self):
|
||||||
|
import PyInstaller.building.build_main
|
||||||
|
work_path = os.path.join(self.dist_dir, "build")
|
||||||
|
spec_file = os.path.join(self.dist_dir, "m64py.spec")
|
||||||
|
os.environ["BASE_DIR"] = BASE_DIR
|
||||||
|
os.environ["DIST_DIR"] = self.dist_dir
|
||||||
|
opts = {"distpath": self.dist_dir,
|
||||||
|
"workpath": work_path,
|
||||||
|
"clean_build": True,
|
||||||
|
"upx_dir": None,
|
||||||
|
"debug": False}
|
||||||
|
PyInstaller.building.build_main.main(None, spec_file, True, **opts)
|
||||||
|
|
||||||
def run_build_installer(self):
|
def run_build_installer(self):
|
||||||
iss_file = ""
|
iss_file = ""
|
||||||
iss_in = join(self.dist_dir, "m64py.iss.in")
|
iss_in = os.path.join(self.dist_dir, "m64py.iss.in")
|
||||||
iss_out = join(self.dist_dir, "m64py.iss")
|
iss_out = os.path.join(self.dist_dir, "m64py.iss")
|
||||||
with open(iss_in, "r") as iss: data = iss.read()
|
with open(iss_in, "r") as iss:
|
||||||
|
data = iss.read()
|
||||||
lines = data.split("\n")
|
lines = data.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
line = line.replace("{ICON}", realpath(join(self.dist_dir, "m64py")))
|
line = line.replace("{ICON}", os.path.realpath(os.path.join(self.dist_dir, "m64py")))
|
||||||
line = line.replace("{VERSION}", FRONTEND_VERSION)
|
line = line.replace("{VERSION}", FRONTEND_VERSION)
|
||||||
iss_file += line + "\n"
|
iss_file += line + "\n"
|
||||||
with open(iss_out, "w") as iss: iss.write(iss_file)
|
with open(iss_out, "w") as iss:
|
||||||
iscc = join(os.environ["ProgramFiles(x86)"], "Inno Setup 5", "ISCC.exe")
|
iss.write(iss_file)
|
||||||
|
iscc = os.path.join(os.environ["ProgramFiles(x86)"], "Inno Setup 5", "ISCC.exe")
|
||||||
subprocess.call([iscc, iss_out])
|
subprocess.call([iscc, iss_out])
|
||||||
|
|
||||||
def run_build(self):
|
|
||||||
import PyInstaller.building.build_main
|
|
||||||
work_path = join(self.dist_dir, "build")
|
|
||||||
spec_file = join(self.dist_dir, "m64py.spec")
|
|
||||||
os.environ["BASE_DIR"] = BASE_DIR
|
|
||||||
os.environ["DIST_DIR"] = self.dist_dir
|
|
||||||
opts = {"distpath": self.dist_dir, "workpath": work_path, "clean_build": True, "upx_dir": None, "debug": False}
|
|
||||||
PyInstaller.building.build_main.main(None, spec_file, True, **opts)
|
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.run_command("build_qt")
|
self.run_command("build_qt")
|
||||||
set_rthook()
|
set_rthook()
|
||||||
|
@ -181,34 +303,45 @@ class build_exe(Command):
|
||||||
self.run_build_installer()
|
self.run_build_installer()
|
||||||
|
|
||||||
|
|
||||||
class build_zip(build_exe):
|
class BuildZip(BuildExe):
|
||||||
|
|
||||||
|
description = "Generate a .zip file for distribution"
|
||||||
|
|
||||||
def run_build_zip(self):
|
def run_build_zip(self):
|
||||||
os.rename(join(self.dist_dir, "m64py"), join(self.dist_dir, "m64py-%s" % FRONTEND_VERSION))
|
os.rename(os.path.join(self.dist_dir, "m64py"),
|
||||||
shutil.make_archive(join(self.dist_dir, "m64py-%s-portable" % FRONTEND_VERSION),
|
os.path.join(self.dist_dir, "m64py-{}".format(FRONTEND_VERSION)))
|
||||||
"zip", self.dist_dir, "m64py-%s" % FRONTEND_VERSION, True)
|
shutil.make_archive(os.path.join(self.dist_dir,
|
||||||
|
"m64py-{}-portable".format(FRONTEND_VERSION)),
|
||||||
|
"zip",
|
||||||
|
self.dist_dir, "m64py-{}".format(FRONTEND_VERSION),
|
||||||
|
True)
|
||||||
|
|
||||||
def set_config_path(self):
|
@staticmethod
|
||||||
|
def set_config_path():
|
||||||
core_file = ""
|
core_file = ""
|
||||||
core_path = join(BASE_DIR, "src", "m64py", "core", "core.py")
|
core_path = os.path.join(BASE_DIR, "src", "m64py", "core", "core.py")
|
||||||
with open(core_path, "r") as core: data = core.read()
|
with open(core_path, "r") as core:
|
||||||
|
data = core.read()
|
||||||
lines = data.split("\n")
|
lines = data.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if "C.c_int(CORE_API_VERSION)" in line:
|
if "C.c_int(CORE_API_VERSION)" in line:
|
||||||
line = line.replace("None", "C.c_char_p(os.getcwd().encode())")
|
line = line.replace("None", "C.c_char_p(os.getcwd().encode())")
|
||||||
core_file += line + "\n"
|
core_file += line + "\n"
|
||||||
with open(core_path, "w") as core: core.write(core_file)
|
with open(core_path, "w") as core:
|
||||||
|
core.write(core_file)
|
||||||
|
|
||||||
settings_file = ""
|
settings_file = ""
|
||||||
settings_path = join(BASE_DIR, "src", "m64py", "frontend", "settings.py")
|
settings_path = os.path.join(BASE_DIR, "src", "m64py", "frontend", "settings.py")
|
||||||
with open(settings_path, "r") as core: data = core.read()
|
with open(settings_path, "r") as core:
|
||||||
|
data = core.read()
|
||||||
lines = data.split("\n")
|
lines = data.split("\n")
|
||||||
for line in lines:
|
for line in lines:
|
||||||
if "QSettings(" in line:
|
if "QSettings(" in line:
|
||||||
line = line.replace('QSettings("m64py", "m64py")',
|
line = line.replace("QSettings(\"m64py\", \"m64py\")",
|
||||||
'QSettings(os.path.join(os.getcwd(), "m64py.ini"), QSettings.IniFormat)')
|
"QSettings(os.path.join(os.getcwd(), \"m64py.ini\"), QSettings.IniFormat)")
|
||||||
settings_file += line + "\n"
|
settings_file += line + "\n"
|
||||||
with open(settings_path, "w") as core: core.write(settings_file)
|
with open(settings_path, "w") as core:
|
||||||
|
core.write(settings_file)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
self.run_command("build_qt")
|
self.run_command("build_qt")
|
||||||
|
@ -222,97 +355,11 @@ class build_zip(build_exe):
|
||||||
self.run_build_zip()
|
self.run_build_zip()
|
||||||
|
|
||||||
|
|
||||||
class build_dmg(Command):
|
class CleanLocal(setuptools.Command):
|
||||||
user_options = []
|
|
||||||
dist_dir = join(BASE_DIR, "dist", "macosx")
|
|
||||||
|
|
||||||
def initialize_options(self):
|
description = "Clean the local project directory"
|
||||||
pass
|
|
||||||
|
|
||||||
def finalize_options(self):
|
wildcards = ['*.py[co]', '*_ui.py', '*_rc.py', '__pycache__']
|
||||||
pass
|
|
||||||
|
|
||||||
def set_plist(self):
|
|
||||||
info_plist = join(self.dist_dir, "dmg", "M64Py.app", "Contents", "Info.plist")
|
|
||||||
shutil.copy(join(self.dist_dir, "m64py.icns"),
|
|
||||||
join(self.dist_dir, "dmg", "M64Py.app", "Contents", "Resources"))
|
|
||||||
shutil.copy(join(self.dist_dir, "m64py.sh"),
|
|
||||||
join(self.dist_dir, "dmg", "M64Py.app", "Contents", "MacOS"))
|
|
||||||
with open(info_plist, "r") as opts: data = opts.read()
|
|
||||||
plist_file = ""
|
|
||||||
lines = data.split("\n")
|
|
||||||
for line in lines:
|
|
||||||
if "0.0.0" in line:
|
|
||||||
line = line.replace("0.0.0", FRONTEND_VERSION)
|
|
||||||
elif "icon-windowed.icns" in line:
|
|
||||||
line = line.replace("icon-windowed.icns", "m64py.icns")
|
|
||||||
elif "MacOS/m64py" in line:
|
|
||||||
line = line.replace("MacOS/m64py", "m64py.sh")
|
|
||||||
plist_file += line + "\n"
|
|
||||||
with open(info_plist, "w") as opts: opts.write(plist_file)
|
|
||||||
|
|
||||||
def copy_emulator(self):
|
|
||||||
src_path = join(self.dist_dir, "mupen64plus", "Contents")
|
|
||||||
dest_path = join(self.dist_dir, "dmg", "M64Py.app", "Contents")
|
|
||||||
copy_tree(src_path, dest_path)
|
|
||||||
|
|
||||||
def copy_files(self):
|
|
||||||
dest_path = join(self.dist_dir, "dmg")
|
|
||||||
if not os.path.exists(dest_path):
|
|
||||||
os.mkdir(dest_path)
|
|
||||||
shutil.move(join(self.dist_dir, "M64Py.app"), dest_path)
|
|
||||||
for file_name in ["AUTHORS", "ChangeLog", "COPYING", "LICENSES", "README.md"]:
|
|
||||||
shutil.copy(join(BASE_DIR, file_name), dest_path)
|
|
||||||
shutil.copy(join(BASE_DIR, "test", "mupen64plus.v64"), dest_path)
|
|
||||||
|
|
||||||
def remove_files(self):
|
|
||||||
dest_path = join(self.dist_dir, "dmg", "M64Py.app", "Contents", "MacOS")
|
|
||||||
for dir_name in ["include", "lib"]:
|
|
||||||
shutil.rmtree(join(dest_path, dir_name), True)
|
|
||||||
os.remove(join(self.dist_dir, "dmg", "M64Py.app", "Contents", "Resources", "icon-windowed.icns"))
|
|
||||||
|
|
||||||
def run_build_dmg(self):
|
|
||||||
src_path = join(self.dist_dir, "dmg")
|
|
||||||
dst_path = join(self.dist_dir, "m64py-%s.dmg" % FRONTEND_VERSION)
|
|
||||||
subprocess.call(["hdiutil", "create", dst_path, "-srcfolder", src_path])
|
|
||||||
|
|
||||||
def run_build(self):
|
|
||||||
import PyInstaller.building.build_main
|
|
||||||
work_path = join(self.dist_dir, "build")
|
|
||||||
spec_file = join(self.dist_dir, "m64py.spec")
|
|
||||||
os.environ["BASE_DIR"] = BASE_DIR
|
|
||||||
os.environ["DIST_DIR"] = self.dist_dir
|
|
||||||
opts = {"distpath": self.dist_dir, "workpath": work_path, "clean_build": True, "upx_dir": None, "debug": False}
|
|
||||||
PyInstaller.building.build_main.main(None, spec_file, True, **opts)
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
self.run_command("build_qt")
|
|
||||||
self.run_build()
|
|
||||||
self.copy_files()
|
|
||||||
self.copy_emulator()
|
|
||||||
self.remove_files()
|
|
||||||
self.set_plist()
|
|
||||||
self.run_build_dmg()
|
|
||||||
|
|
||||||
|
|
||||||
def set_rthook():
|
|
||||||
import PyInstaller
|
|
||||||
hook_file = ""
|
|
||||||
module_dir = dirname(PyInstaller.__file__)
|
|
||||||
rthook = join(module_dir, "loader", "rthooks", "pyi_rth_qt5plugins.py")
|
|
||||||
with open(rthook, "r") as hook: data = hook.read()
|
|
||||||
if 'sys._MEIPASS, "lib"' not in data:
|
|
||||||
lines = data.split("\n")
|
|
||||||
for line in lines:
|
|
||||||
if "MEIPASS" in line:
|
|
||||||
hook_file += "d = os.path.join(sys._MEIPASS, \"lib\", d)\n"
|
|
||||||
else:
|
|
||||||
hook_file += line + "\n"
|
|
||||||
with open(rthook, "w") as hook: hook.write(hook_file)
|
|
||||||
|
|
||||||
|
|
||||||
class clean_local(Command):
|
|
||||||
pats = ['*.py[co]', '*_ui.py', '*_rc.py', '__pycache__']
|
|
||||||
excludedirs = ['.git', 'build', 'dist']
|
excludedirs = ['.git', 'build', 'dist']
|
||||||
user_options = []
|
user_options = []
|
||||||
|
|
||||||
|
@ -322,65 +369,65 @@ class clean_local(Command):
|
||||||
def finalize_options(self):
|
def finalize_options(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def run(self):
|
|
||||||
for e in self._walkpaths('.'):
|
|
||||||
if os.path.isdir(e):
|
|
||||||
shutil.rmtree(e)
|
|
||||||
else:
|
|
||||||
os.remove(e)
|
|
||||||
|
|
||||||
def _walkpaths(self, path):
|
def _walkpaths(self, path):
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
if any(root == join(path, e) or root.startswith(
|
for excluded_dir in self.excludedirs:
|
||||||
join(path, e, '')) for e in self.excludedirs):
|
abs_excluded_dir = os.path.join(path, excluded_dir)
|
||||||
continue
|
if root == abs_excluded_dir or root.startswith(abs_excluded_dir + os.sep):
|
||||||
for d in dirs:
|
continue
|
||||||
fpath = join(root, d)
|
for a_dir in dirs:
|
||||||
if any(fnmatch(d, p) for p in self.pats):
|
file_path = os.path.join(root, a_dir)
|
||||||
yield fpath
|
if any(fnmatch.fnmatch(a_dir, pattern) for pattern in self.wildcards):
|
||||||
for e in files:
|
yield file_path
|
||||||
fpath = join(root, e)
|
for a_file in files:
|
||||||
if any(fnmatch(fpath, p) for p in self.pats):
|
file_path = os.path.join(root, a_file)
|
||||||
yield fpath
|
if any(fnmatch.fnmatch(file_path, pattern) for pattern in self.wildcards):
|
||||||
|
yield file_path
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
for a_path in self._walkpaths('.'):
|
||||||
|
if os.path.isdir(a_path):
|
||||||
|
shutil.rmtree(a_path)
|
||||||
|
else:
|
||||||
|
os.remove(a_path)
|
||||||
|
|
||||||
|
|
||||||
class mybuild(build):
|
class MyBuild(distutils_build.build):
|
||||||
def run(self):
|
def run(self):
|
||||||
self.run_command("build_qt")
|
self.run_command("build_qt")
|
||||||
build.run(self)
|
distutils_build.build.run(self)
|
||||||
|
|
||||||
|
|
||||||
class myclean(clean):
|
class MyClean(distutils_clean.clean):
|
||||||
def run(self):
|
def run(self):
|
||||||
self.run_command("clean_local")
|
self.run_command("clean_local")
|
||||||
clean.run(self)
|
distutils_clean.clean.run(self)
|
||||||
|
|
||||||
cmdclass = {
|
|
||||||
'build': mybuild,
|
|
||||||
'build_qt': build_qt,
|
|
||||||
'build_exe': build_exe,
|
|
||||||
'build_zip': build_zip,
|
|
||||||
'build_dmg': build_dmg,
|
|
||||||
'clean': myclean,
|
|
||||||
'clean_local': clean_local
|
|
||||||
}
|
|
||||||
|
|
||||||
setup(
|
setuptools.setup(
|
||||||
name = "m64py",
|
name="m64py",
|
||||||
version = FRONTEND_VERSION,
|
version=FRONTEND_VERSION,
|
||||||
description = "M64Py - A frontend for Mupen64Plus",
|
description="A frontend for Mupen64Plus",
|
||||||
long_description = "M64Py is a Qt5 front-end (GUI) for Mupen64Plus, a cross-platform plugin-based Nintendo 64 emulator.",
|
long_description="A Qt5 front-end (GUI) for Mupen64Plus, a cross-platform plugin-based Nintendo 64 emulator.",
|
||||||
author = "Milan Nikolic",
|
author="Milan Nikolic",
|
||||||
author_email = "gen2brain@gmail.com",
|
author_email="gen2brain@gmail.com",
|
||||||
license = "GNU GPLv3",
|
license="GNU GPLv3",
|
||||||
url = "http://m64py.sourceforge.net",
|
url="http://m64py.sourceforge.net",
|
||||||
packages = ["m64py", "m64py.core", "m64py.frontend", "m64py.ui"],
|
packages=["m64py", "m64py.core", "m64py.frontend", "m64py.ui"],
|
||||||
package_dir = {"": "src"},
|
package_dir={'': "src"},
|
||||||
scripts = ["m64py"],
|
scripts=["m64py"],
|
||||||
requires = ["PyQt5", "PySDL2"],
|
requires=["PyQt5", "PySDL2"],
|
||||||
platforms = ["Linux", "Windows", "Darwin"],
|
platforms=["Linux", "Windows", "Darwin"],
|
||||||
cmdclass = cmdclass,
|
cmdclass={
|
||||||
data_files = [
|
'build': MyBuild,
|
||||||
|
'build_dmg': BuildDmg,
|
||||||
|
'build_exe': BuildExe,
|
||||||
|
'build_qt': BuildQt,
|
||||||
|
'build_zip': BuildZip,
|
||||||
|
'clean': MyClean,
|
||||||
|
'clean_local': CleanLocal
|
||||||
|
},
|
||||||
|
data_files=[
|
||||||
("share/pixmaps", ["xdg/m64py.png"]),
|
("share/pixmaps", ["xdg/m64py.png"]),
|
||||||
("share/applications", ["xdg/m64py.desktop"]),
|
("share/applications", ["xdg/m64py.desktop"]),
|
||||||
]
|
]
|
||||||
|
|
Loading…
Add table
Reference in a new issue