Make sample.zip before pyinstaller runs, and make sure the make_windows script is windows only
This commit is contained in:
Regular → Executable
+204
-191
@@ -1,191 +1,204 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
"""
|
"""
|
||||||
This script will either build:
|
This script will either build:
|
||||||
* A single file executable named dist/novelWriter.exe. This is a quite
|
* A single file executable named dist/novelWriter.exe. This is a quite
|
||||||
slow option, and the file is fairly big. Option --onefile
|
slow option, and the file is fairly big. Option --onefile
|
||||||
* A single directory named dist/novelWriter with a novelWriter.exe, and
|
* A single directory named dist/novelWriter with a novelWriter.exe, and
|
||||||
all dependecies included. This is the default.
|
all dependecies included. This is the default.
|
||||||
* The latter can be combined with a build stage of a setup.exe file
|
* The latter can be combined with a build stage of a setup.exe file
|
||||||
named setup-novelwriter-<version>.exe. Option --setup.
|
named setup-novelwriter-<version>.exe. Option --setup.
|
||||||
|
|
||||||
In addition, providing the --pip flag will cause the script to try to
|
In addition, providing the --pip flag will cause the script to try to
|
||||||
install all dependencies needed for runing the build, and for running
|
install all dependencies needed for runing the build, and for running
|
||||||
novelWriter itself.
|
novelWriter itself.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import getopt
|
import getopt
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
# Defaults
|
if not sys.platform.startswith("win32"):
|
||||||
buildWindowed = True
|
print("ERROR: This script is intended for Windows only.")
|
||||||
runPip = False
|
sys.exit(1)
|
||||||
oneFile = False
|
|
||||||
makeSetup = False
|
# Defaults
|
||||||
innoSetup = None
|
buildWindowed = True
|
||||||
|
runPip = False
|
||||||
# Parse Options
|
oneFile = False
|
||||||
shortOpt = "hd"
|
makeSetup = False
|
||||||
longOpt = [
|
innoSetup = None
|
||||||
"help",
|
|
||||||
"debug",
|
# Parse Options
|
||||||
"pip",
|
shortOpt = "hd"
|
||||||
"onefile",
|
longOpt = [
|
||||||
"setup",
|
"help",
|
||||||
"inno=",
|
"debug",
|
||||||
]
|
"pip",
|
||||||
helpMsg = (
|
"onefile",
|
||||||
"\n"
|
"setup",
|
||||||
"novelWriter Install Script for Windows\n"
|
"inno=",
|
||||||
"\n"
|
]
|
||||||
"Usage:\n"
|
helpMsg = (
|
||||||
" -h, --help Print this message.\n"
|
"\n"
|
||||||
" --pip Install dependecies first.\n"
|
"novelWriter Install Script for Windows\n"
|
||||||
" --onefile Create a single executable file.\n"
|
"\n"
|
||||||
" --setup Make Inno Setup file.\n"
|
"Usage:\n"
|
||||||
" --inno= Path to the Inno Setup exec.\n"
|
" -h, --help Print this message.\n"
|
||||||
" -d, --debug Build novelWriter for debugging. To debug novelwriter after build,\n"
|
" --pip Install dependecies first.\n"
|
||||||
" run it from command line with the debug options. Please check the\n"
|
" --onefile Create a single executable file.\n"
|
||||||
" novelWriter --help output for details.\n"
|
" --setup Make Inno Setup file.\n"
|
||||||
)
|
" --inno= Path to the Inno Setup exec.\n"
|
||||||
|
" -d, --debug Build novelWriter for debugging. To debug novelwriter after build,\n"
|
||||||
try:
|
" run it from command line with the debug options. Please check the\n"
|
||||||
inOpts, inArgs = getopt.getopt(sys.argv[1:], shortOpt, longOpt)
|
" novelWriter --help output for details.\n"
|
||||||
except getopt.GetoptError:
|
)
|
||||||
print(helpMsg)
|
|
||||||
sys.exit(1)
|
try:
|
||||||
|
inOpts, inArgs = getopt.getopt(sys.argv[1:], shortOpt, longOpt)
|
||||||
for inOpt, inArg in inOpts:
|
except getopt.GetoptError:
|
||||||
if inOpt in ("-h", "--help"):
|
print(helpMsg)
|
||||||
print(helpMsg)
|
sys.exit(1)
|
||||||
sys.exit(0)
|
|
||||||
elif inOpt in ("-d", "--debug"):
|
for inOpt, inArg in inOpts:
|
||||||
buildWindowed = False
|
if inOpt in ("-h", "--help"):
|
||||||
elif inOpt == "--pip":
|
print(helpMsg)
|
||||||
runPip = True
|
sys.exit(0)
|
||||||
elif inOpt == "--onefile":
|
elif inOpt in ("-d", "--debug"):
|
||||||
oneFile = True
|
buildWindowed = False
|
||||||
elif inOpt == "--setup":
|
elif inOpt == "--pip":
|
||||||
makeSetup = True
|
runPip = True
|
||||||
elif inOpt == "--inno":
|
elif inOpt == "--onefile":
|
||||||
innoSetup = inArg
|
oneFile = True
|
||||||
|
elif inOpt == "--setup":
|
||||||
# Run pip
|
makeSetup = True
|
||||||
if runPip:
|
elif inOpt == "--inno":
|
||||||
print("")
|
innoSetup = inArg
|
||||||
print("###########################")
|
|
||||||
print(" Installing Dependencies")
|
# Run pip
|
||||||
print("###########################")
|
if runPip:
|
||||||
print("")
|
print("")
|
||||||
try:
|
print("###########################")
|
||||||
subprocess.call([
|
print(" Installing Dependencies")
|
||||||
sys.executable, "-m",
|
print("###########################")
|
||||||
"pip", "install", "--user", "--upgrade", "pip"
|
print("")
|
||||||
])
|
try:
|
||||||
subprocess.call([
|
subprocess.call([
|
||||||
sys.executable, "-m",
|
sys.executable, "-m",
|
||||||
"pip", "install", "--user", "--upgrade", "pyinstaller"
|
"pip", "install", "--user", "--upgrade", "pip"
|
||||||
])
|
])
|
||||||
subprocess.call([
|
subprocess.call([
|
||||||
sys.executable, "-m",
|
sys.executable, "-m",
|
||||||
"pip", "install", "--user", "--upgrade", "-r", "requirements.txt"
|
"pip", "install", "--user", "--upgrade", "pyinstaller"
|
||||||
])
|
])
|
||||||
except Exception as e:
|
subprocess.call([
|
||||||
print("Failed with error:")
|
sys.executable, "-m",
|
||||||
print(str(e))
|
"pip", "install", "--user", "--upgrade", "-r", "requirements.txt"
|
||||||
sys.exit(1)
|
])
|
||||||
|
except Exception as e:
|
||||||
# Run pyinstaller
|
print("Failed with error:")
|
||||||
print("")
|
print(str(e))
|
||||||
print("#######################")
|
sys.exit(1)
|
||||||
print(" Running PyInstaller")
|
|
||||||
print("#######################")
|
# Run pyinstaller
|
||||||
print("")
|
print("")
|
||||||
instOpt = [
|
print("#######################")
|
||||||
"--name=novelWriter",
|
print(" Running PyInstaller")
|
||||||
"--clean",
|
print("#######################")
|
||||||
"--add-data=%s;%s" % (os.path.join("nw", "assets"), "assets"),
|
print("")
|
||||||
"--icon=%s" % os.path.join("nw", "assets", "icons", "novelwriter.ico"),
|
instOpt = [
|
||||||
"--exclude-module=PyQt5.QtQml",
|
"--name=novelWriter",
|
||||||
"--exclude-module=PyQt5.QtBluetooth",
|
"--clean",
|
||||||
"--exclude-module=PyQt5.QtDBus",
|
"--add-data=%s;%s" % (os.path.join("nw", "assets"), "assets"),
|
||||||
"--exclude-module=PyQt5.QtMultimedia",
|
"--icon=%s" % os.path.join("nw", "assets", "icons", "novelwriter.ico"),
|
||||||
"--exclude-module=PyQt5.QtMultimediaWidgets",
|
"--exclude-module=PyQt5.QtQml",
|
||||||
"--exclude-module=PyQt5.QtNetwork",
|
"--exclude-module=PyQt5.QtBluetooth",
|
||||||
"--exclude-module=PyQt5.QtNetworkAuth",
|
"--exclude-module=PyQt5.QtDBus",
|
||||||
"--exclude-module=PyQt5.QtNfc",
|
"--exclude-module=PyQt5.QtMultimedia",
|
||||||
"--exclude-module=PyQt5.QtQuick",
|
"--exclude-module=PyQt5.QtMultimediaWidgets",
|
||||||
"--exclude-module=PyQt5.QtQuickWidgets",
|
"--exclude-module=PyQt5.QtNetwork",
|
||||||
"--exclude-module=PyQt5.QtRemoteObjects",
|
"--exclude-module=PyQt5.QtNetworkAuth",
|
||||||
"--exclude-module=PyQt5.QtSensors",
|
"--exclude-module=PyQt5.QtNfc",
|
||||||
"--exclude-module=PyQt5.QtSerialPort",
|
"--exclude-module=PyQt5.QtQuick",
|
||||||
"--exclude-module=PyQt5.QtSql",
|
"--exclude-module=PyQt5.QtQuickWidgets",
|
||||||
]
|
"--exclude-module=PyQt5.QtRemoteObjects",
|
||||||
|
"--exclude-module=PyQt5.QtSensors",
|
||||||
if buildWindowed:
|
"--exclude-module=PyQt5.QtSerialPort",
|
||||||
instOpt.append("--windowed")
|
"--exclude-module=PyQt5.QtSql",
|
||||||
|
]
|
||||||
if oneFile and not makeSetup:
|
|
||||||
instOpt.append("--onefile")
|
if buildWindowed:
|
||||||
else:
|
instOpt.append("--windowed")
|
||||||
instOpt.append("--onedir")
|
|
||||||
|
if oneFile and not makeSetup:
|
||||||
instOpt.append("novelWriter.py")
|
instOpt.append("--onefile")
|
||||||
|
else:
|
||||||
import PyInstaller.__main__ # noqa: E402
|
instOpt.append("--onedir")
|
||||||
PyInstaller.__main__.run(instOpt)
|
|
||||||
|
instOpt.append("novelWriter.py")
|
||||||
if not oneFile:
|
|
||||||
# These dll files are not nee3ded, and take up a fair bit of space.
|
# Make sample.zip first
|
||||||
delIfExists = [
|
print("Building sample.zip")
|
||||||
"Qt5DBus.dll", "Qt5Network.dll", "Qt5Qml.dll", "Qt5QmlModels.dll", "Qt5Quick.dll",
|
try:
|
||||||
"Qt5Quick3D.dll", "Qt5Quick3DAssetImport.dll", "Qt5Quick3DRender.dll",
|
subprocess.call([sys.executable, "setup.py" "sample"])
|
||||||
"Qt5Quick3DRuntimeRender.dll", "Qt5Quick3DUtils.dll", "Qt5Sql.dll"
|
except Exception as e:
|
||||||
]
|
print("Failed with error:")
|
||||||
distDir = os.path.join(os.getcwd(), "dist", "novelWriter")
|
print(str(e))
|
||||||
for delFile in delIfExists:
|
sys.exit(1)
|
||||||
delPath = os.path.join(distDir, delFile)
|
|
||||||
if os.path.isfile(delPath):
|
import PyInstaller.__main__ # noqa: E402
|
||||||
print("Deleting file: %s" % delPath)
|
PyInstaller.__main__.run(instOpt)
|
||||||
os.unlink(delPath)
|
|
||||||
|
if not oneFile:
|
||||||
print("")
|
# These dll files are not nee3ded, and take up a fair bit of space.
|
||||||
print("Build Finished")
|
delIfExists = [
|
||||||
print("")
|
"Qt5DBus.dll", "Qt5Network.dll", "Qt5Qml.dll", "Qt5QmlModels.dll", "Qt5Quick.dll",
|
||||||
print("If everything went well, the novelWriter executable should be in the folder named 'dist'")
|
"Qt5Quick3D.dll", "Qt5Quick3DAssetImport.dll", "Qt5Quick3DRender.dll",
|
||||||
print("")
|
"Qt5Quick3DRuntimeRender.dll", "Qt5Quick3DUtils.dll", "Qt5Sql.dll"
|
||||||
|
]
|
||||||
if makeSetup:
|
distDir = os.path.join(os.getcwd(), "dist", "novelWriter")
|
||||||
print("")
|
for delFile in delIfExists:
|
||||||
print("######################")
|
delPath = os.path.join(distDir, delFile)
|
||||||
print(" Running Inno Setup")
|
if os.path.isfile(delPath):
|
||||||
print("######################")
|
print("Deleting file: %s" % delPath)
|
||||||
print("")
|
os.unlink(delPath)
|
||||||
if innoSetup is None:
|
|
||||||
innoSetup = "C:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe"
|
print("")
|
||||||
if not os.path.isfile(innoSetup):
|
print("Build Finished")
|
||||||
print("ERROR: Cannot fine Inno Setup's ISCC.exe file.")
|
print("")
|
||||||
print(" Looked in: %s" % innoSetup)
|
print("If everything went well, the novelWriter executable should be in the folder named 'dist'")
|
||||||
print(" Please provide a path with the --inno= option.")
|
print("")
|
||||||
sys.exit(1)
|
|
||||||
|
if makeSetup:
|
||||||
# Read the iss template
|
print("")
|
||||||
issData = ""
|
print("######################")
|
||||||
with open(os.path.join("setup", "win_setup.iss"), mode="r") as inFile:
|
print(" Running Inno Setup")
|
||||||
issData = inFile.read()
|
print("######################")
|
||||||
|
print("")
|
||||||
import nw # noqa: E402
|
if innoSetup is None:
|
||||||
issData = issData.replace(r"%%version%%", nw.__version__)
|
innoSetup = "C:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe"
|
||||||
issData = issData.replace(r"%%dir%%", os.getcwd())
|
if not os.path.isfile(innoSetup):
|
||||||
|
print("ERROR: Cannot fine Inno Setup's ISCC.exe file.")
|
||||||
with open("setup.iss", mode="w+") as outFile:
|
print(" Looked in: %s" % innoSetup)
|
||||||
outFile.write(issData)
|
print(" Please provide a path with the --inno= option.")
|
||||||
|
sys.exit(1)
|
||||||
try:
|
|
||||||
subprocess.call([innoSetup, "setup.iss"])
|
# Read the iss template
|
||||||
except Exception as e:
|
issData = ""
|
||||||
print("Failed with error:")
|
with open(os.path.join("setup", "win_setup.iss"), mode="r") as inFile:
|
||||||
print(str(e))
|
issData = inFile.read()
|
||||||
sys.exit(1)
|
|
||||||
|
import nw # noqa: E402
|
||||||
|
issData = issData.replace(r"%%version%%", nw.__version__)
|
||||||
|
issData = issData.replace(r"%%dir%%", os.getcwd())
|
||||||
|
|
||||||
|
with open("setup.iss", mode="w+") as outFile:
|
||||||
|
outFile.write(issData)
|
||||||
|
|
||||||
|
try:
|
||||||
|
subprocess.call([innoSetup, "setup.iss"])
|
||||||
|
except Exception as e:
|
||||||
|
print("Failed with error:")
|
||||||
|
print(str(e))
|
||||||
|
sys.exit(1)
|
||||||
|
|||||||
Reference in New Issue
Block a user