Added alternative packaging method for windows
This commit is contained in:
@@ -174,15 +174,12 @@ def freezePackage(buildWindowed, oneFile, makeSetup, hostOS):
|
|||||||
# Make Simple Package
|
# Make Simple Package
|
||||||
# =============================================================================================== #
|
# =============================================================================================== #
|
||||||
|
|
||||||
def simplePackage(hostOS):
|
def makeWindowsPackage():
|
||||||
"""Run zipapp to freeze the packages. This assumes zipapp and pip
|
"""Run zipapp to freeze the packages. This assumes zipapp and pip
|
||||||
are already installed.
|
are already installed.
|
||||||
"""
|
"""
|
||||||
# import zipapp
|
import urllib.request
|
||||||
|
import zipfile
|
||||||
from nw import __version__
|
|
||||||
|
|
||||||
exName = f"novelwriter-{__version__}-zipapp"
|
|
||||||
|
|
||||||
# Set Up Folder
|
# Set Up Folder
|
||||||
# =============
|
# =============
|
||||||
@@ -190,7 +187,7 @@ def simplePackage(hostOS):
|
|||||||
if not os.path.isdir("dist"):
|
if not os.path.isdir("dist"):
|
||||||
os.mkdir("dist")
|
os.mkdir("dist")
|
||||||
|
|
||||||
outDir = os.path.join("dist", exName)
|
outDir = os.path.join("dist", "novelWriter")
|
||||||
libDir = os.path.join(outDir, "lib")
|
libDir = os.path.join(outDir, "lib")
|
||||||
if os.path.isdir(outDir):
|
if os.path.isdir(outDir):
|
||||||
shutil.rmtree(outDir)
|
shutil.rmtree(outDir)
|
||||||
@@ -198,22 +195,63 @@ def simplePackage(hostOS):
|
|||||||
os.mkdir(outDir)
|
os.mkdir(outDir)
|
||||||
os.mkdir(libDir)
|
os.mkdir(libDir)
|
||||||
|
|
||||||
|
# Download Python Embeddable
|
||||||
|
# ==========================
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("# Downloading Python Embeddable")
|
||||||
|
print("# =============================")
|
||||||
|
print("")
|
||||||
|
|
||||||
|
pyUrl = "https://www.python.org/ftp/python/3.8.7/python-3.8.7-embed-amd64.zip"
|
||||||
|
pyZip = os.path.join(outDir, "python_embed.zip")
|
||||||
|
print("URL: %s" % pyUrl)
|
||||||
|
|
||||||
|
urllib.request.urlretrieve(pyUrl, pyZip)
|
||||||
|
|
||||||
|
print("Extracting ...")
|
||||||
|
with zipfile.ZipFile(pyZip, "r") as inFile:
|
||||||
|
inFile.extractall(outDir)
|
||||||
|
|
||||||
|
os.unlink(pyZip)
|
||||||
|
print("")
|
||||||
|
|
||||||
|
# Make sample.zip
|
||||||
|
# ===============
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.call([sys.executable, "setup.py", "sample"])
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed with error:")
|
||||||
|
print(str(e))
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
# Copy Package Files
|
# Copy Package Files
|
||||||
# ==================
|
# ==================
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("# Copying Package Files")
|
||||||
|
print("# =====================")
|
||||||
|
print("")
|
||||||
|
|
||||||
copyList = ["CHANGELOG.md", "LICENSE.md", "requirements.txt"]
|
copyList = ["CHANGELOG.md", "LICENSE.md", "requirements.txt"]
|
||||||
iconList = ["novelwriter.ico", "x-novelwriter-project.ico"]
|
iconList = ["novelwriter.ico", "x-novelwriter-project.ico"]
|
||||||
cpIgnore = shutil.ignore_patterns("__pycache__")
|
cpIgnore = shutil.ignore_patterns("__pycache__")
|
||||||
|
|
||||||
|
print("Copying: nw")
|
||||||
shutil.copytree("nw", os.path.join(outDir, "nw"), ignore=cpIgnore)
|
shutil.copytree("nw", os.path.join(outDir, "nw"), ignore=cpIgnore)
|
||||||
for copyFile in copyList:
|
for copyFile in copyList:
|
||||||
|
print("Copying: %s" % copyFile)
|
||||||
shutil.copy2(copyFile, os.path.join(outDir, copyFile))
|
shutil.copy2(copyFile, os.path.join(outDir, copyFile))
|
||||||
for iconFile in iconList:
|
for iconFile in iconList:
|
||||||
|
print("Copying: %s" % iconFile)
|
||||||
shutil.copy2(os.path.join("setup", "icons", iconFile), os.path.join(outDir, iconFile))
|
shutil.copy2(os.path.join("setup", "icons", iconFile), os.path.join(outDir, iconFile))
|
||||||
|
|
||||||
with open(os.path.join(outDir, "__main__.py"), mode="w") as outFile:
|
print("Writing: novelWriter.pyw")
|
||||||
|
with open(os.path.join(outDir, "novelWriter.pyw"), mode="w") as outFile:
|
||||||
outFile.write(
|
outFile.write(
|
||||||
"#!/usr/bin/env python3\n"
|
"#!\"pythonw.exe\"\n"
|
||||||
|
"\n"
|
||||||
"import os\n"
|
"import os\n"
|
||||||
"import sys\n"
|
"import sys\n"
|
||||||
"\n"
|
"\n"
|
||||||
@@ -224,10 +262,16 @@ def simplePackage(hostOS):
|
|||||||
" import nw\n"
|
" import nw\n"
|
||||||
" nw.main()\n"
|
" nw.main()\n"
|
||||||
)
|
)
|
||||||
|
print("")
|
||||||
|
|
||||||
# Install Dependencies
|
# Install Dependencies
|
||||||
# ====================
|
# ====================
|
||||||
|
|
||||||
|
print("")
|
||||||
|
print("# Installing Dependencies")
|
||||||
|
print("# =======================")
|
||||||
|
print("")
|
||||||
|
|
||||||
sysCmd = [sys.executable]
|
sysCmd = [sys.executable]
|
||||||
sysCmd += "-m pip install -r requirements.txt --target".split()
|
sysCmd += "-m pip install -r requirements.txt --target".split()
|
||||||
sysCmd += [libDir]
|
sysCmd += [libDir]
|
||||||
@@ -243,39 +287,37 @@ def simplePackage(hostOS):
|
|||||||
if os.path.isdir(chkDir) and chkDir.endswith(".dist-info"):
|
if os.path.isdir(chkDir) and chkDir.endswith(".dist-info"):
|
||||||
shutil.rmtree(chkDir)
|
shutil.rmtree(chkDir)
|
||||||
|
|
||||||
|
print("")
|
||||||
|
|
||||||
# Remove Unneeded Library Files
|
# Remove Unneeded Library Files
|
||||||
# =============================
|
# =============================
|
||||||
|
|
||||||
delQtLibs = [
|
delQtLibs = [
|
||||||
"Qt5DBus",
|
"opengl32sw.dll",
|
||||||
"Qt5Network",
|
"Qt5DBus.dll",
|
||||||
"Qt5Qml",
|
"Qt5Designer.dll",
|
||||||
"Qt5QmlModels",
|
"Qt5Network.dll",
|
||||||
"Qt5QmlWorkerScript",
|
"Qt5OpenGL.dll",
|
||||||
"Qt5Quick",
|
"Qt5Qml.dll",
|
||||||
"Qt5Quick3D",
|
"Qt5QmlModels.dll",
|
||||||
"Qt5Quick3DAssetImport",
|
"Qt5QmlWorkerScript.dll",
|
||||||
"Qt5Quick3DRender",
|
"Qt5Quick.dll",
|
||||||
"Qt5Quick3DRuntimeRender",
|
"Qt5Quick3D.dll",
|
||||||
"Qt5Quick3DUtils",
|
"Qt5Quick3DAssetImport.dll",
|
||||||
"Qt5QuickControls2",
|
"Qt5Quick3DRender.dll",
|
||||||
"Qt5QuickParticles",
|
"Qt5Quick3DRuntimeRender.dll",
|
||||||
"Qt5QuickShapes",
|
"Qt5Quick3DUtils.dll",
|
||||||
"Qt5QuickTemplates2",
|
"Qt5QuickControls2.dll",
|
||||||
"Qt5QuickTest",
|
"Qt5QuickParticles.dll",
|
||||||
"Qt5QuickWidgets",
|
"Qt5QuickShapes.dll",
|
||||||
"Qt5Sql",
|
"Qt5QuickTemplates2.dll",
|
||||||
|
"Qt5QuickTest.dll",
|
||||||
|
"Qt5QuickWidgets.dll",
|
||||||
|
"Qt5Sql.dll",
|
||||||
]
|
]
|
||||||
qtLibDir = os.path.join(libDir, "PyQt5", "Qt", "lib")
|
qtLibDir = os.path.join(libDir, "PyQt5", "Qt", "bin")
|
||||||
for libName in delQtLibs:
|
for libName in delQtLibs:
|
||||||
if hostOS == OS_WIN:
|
delFile = os.path.join(qtLibDir, libName)
|
||||||
libFile = f"{libName}.dll"
|
|
||||||
elif hostOS == OS_LINUX:
|
|
||||||
libFile = f"lib{libName}.so.5"
|
|
||||||
else:
|
|
||||||
continue
|
|
||||||
|
|
||||||
delFile = os.path.join(qtLibDir, libFile)
|
|
||||||
if os.path.isfile(delFile):
|
if os.path.isfile(delFile):
|
||||||
print("Deleting: %s" % delFile)
|
print("Deleting: %s" % delFile)
|
||||||
os.unlink(delFile)
|
os.unlink(delFile)
|
||||||
@@ -284,11 +326,9 @@ def simplePackage(hostOS):
|
|||||||
if os.path.isdir(qmlDir):
|
if os.path.isdir(qmlDir):
|
||||||
shutil.rmtree(qmlDir)
|
shutil.rmtree(qmlDir)
|
||||||
|
|
||||||
# zipapp.create_archive(
|
print("")
|
||||||
# outDir,
|
print("Done!")
|
||||||
# target=os.path.join("dist", f"{exName}.pyz"),
|
print("")
|
||||||
# interpreter="/usr/bin/env python3"
|
|
||||||
# )
|
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -387,7 +427,7 @@ if __name__ == "__main__":
|
|||||||
oneFile = False
|
oneFile = False
|
||||||
makeSetup = False
|
makeSetup = False
|
||||||
doFreeze = False
|
doFreeze = False
|
||||||
simPack = False
|
winPack = False
|
||||||
|
|
||||||
helpMsg = (
|
helpMsg = (
|
||||||
"\n"
|
"\n"
|
||||||
@@ -438,9 +478,9 @@ if __name__ == "__main__":
|
|||||||
doFreeze = True
|
doFreeze = True
|
||||||
oneFile = True
|
oneFile = True
|
||||||
|
|
||||||
if "package" in sys.argv:
|
if "winpack" in sys.argv:
|
||||||
sys.argv.remove("package")
|
sys.argv.remove("winpack")
|
||||||
simPack = True
|
winPack = True
|
||||||
|
|
||||||
if "setup" in sys.argv:
|
if "setup" in sys.argv:
|
||||||
sys.argv.remove("setup")
|
sys.argv.remove("setup")
|
||||||
@@ -451,8 +491,8 @@ if __name__ == "__main__":
|
|||||||
print("Error: Argument 'setup' for Inno Setup is Windows only.")
|
print("Error: Argument 'setup' for Inno Setup is Windows only.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
if simPack:
|
if winPack:
|
||||||
simplePackage(hostOS)
|
makeWindowsPackage()
|
||||||
|
|
||||||
if doFreeze:
|
if doFreeze:
|
||||||
freezePackage(buildWindowed, oneFile, makeSetup, hostOS)
|
freezePackage(buildWindowed, oneFile, makeSetup, hostOS)
|
||||||
|
|||||||
+7
-8
@@ -6,7 +6,7 @@
|
|||||||
#define nwAppVersion "%%version%%"
|
#define nwAppVersion "%%version%%"
|
||||||
#define nwAppPublisher "novelWriter"
|
#define nwAppPublisher "novelWriter"
|
||||||
#define nwAppURL "http://novelWriter.io"
|
#define nwAppURL "http://novelWriter.io"
|
||||||
#define nwAppExeName "novelWriter.exe"
|
#define nwAppExeName "novelWriter.pyw"
|
||||||
|
|
||||||
[Setup]
|
[Setup]
|
||||||
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
@@ -45,16 +45,15 @@ Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescrip
|
|||||||
Source: "{#nwAppDir}\novelWriter\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
Source: "{#nwAppDir}\novelWriter\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
|
||||||
[Icons]
|
[Icons]
|
||||||
Name: "{autoprograms}\{#nwAppName}"; Filename: "{app}\{#nwAppExeName}"
|
Name: "{autoprograms}\{#nwAppName}"; Filename: "{app}\pythonw.exe"; Parameters: "{#nwAppExeName}"; IconFilename: "{app}\novelwriter.ico"
|
||||||
Name: "{autodesktop}\{#nwAppName}"; Filename: "{app}\{#nwAppExeName}"; Tasks: desktopicon
|
Name: "{autodesktop}\{#nwAppName}"; Filename: "{app}\pythonw.exe"; Parameters: "{#nwAppExeName}"; IconFilename: "{app}\novelwriter.ico"; Tasks: desktopicon;
|
||||||
Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\{#nwAppName}"; Filename: "{app}\{#nwAppExeName}"; Tasks: quicklaunchicon
|
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "{app}\{#nwAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(nwAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
Filename: "{app}\pythonw.exe"; Parameters: "{#nwAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(nwAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
[Registry]
|
[Registry]
|
||||||
Root: HKA; Subkey: "Software\Classes\.nwx\OpenWithProgids"; ValueType: string; ValueName: "novelWriterProject.nwx"; ValueData: ""; Flags: uninsdeletevalue
|
Root: HKA; Subkey: "Software\Classes\.nwx\OpenWithProgids"; ValueType: string; ValueName: "novelWriterProject.nwx"; ValueData: ""; Flags: uninsdeletevalue
|
||||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx"; ValueType: string; ValueName: ""; ValueData: "novelWriter Project File"; Flags: uninsdeletekey
|
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx"; ValueType: string; ValueName: ""; ValueData: "novelWriter Project File"; Flags: uninsdeletekey
|
||||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\assets\icons\x-novelwriter-project.ico"
|
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\nw\assets\icons\x-novelwriter-project.ico"
|
||||||
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\novelWriter.exe"" ""%1"""
|
Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\pythonw.exe"" ""{app}\{#nwAppExeName}"" ""%1"""
|
||||||
Root: HKA; Subkey: "Software\Classes\Applications\novelWriter.exe\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: ""
|
Root: HKA; Subkey: "Software\Classes\Applications\{#nwAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: ""
|
||||||
|
|||||||
Reference in New Issue
Block a user