diff --git a/make.py b/make.py index a699ad13..55a909fd 100755 --- a/make.py +++ b/make.py @@ -39,7 +39,7 @@ def installPackages(hostOS): print("#######################") print("") - installQueue = ["pip", "pyinstaller", "-r requirements.txt"] + installQueue = ["pip", "-r requirements.txt"] if hostOS == OS_DARWIN: installQueue.append("pyobjc") @@ -336,7 +336,7 @@ def makeWindowsPackage(): # Inno Setup Builder # =============================================================================================== # -def innoSetup(): +def innoSetup(setupType): """Run the Inno Setup tool to build a setup.exe file for Windows. """ print("") @@ -346,7 +346,7 @@ def innoSetup(): # Read the iss template issData = "" - with open(os.path.join("setup", "win_setup.iss"), mode="r") as inFile: + with open(os.path.join("setup", "win_setup_%s.iss" % setupType), mode="r") as inFile: issData = inFile.read() import nw # noqa: E402 @@ -425,7 +425,8 @@ if __name__ == "__main__": # Flags and Variables buildWindowed = True oneFile = False - makeSetup = False + makeSetupExe = False + makeSetupPyz = False doFreeze = False winPack = False @@ -433,20 +434,30 @@ if __name__ == "__main__": "\n" "novelWriter Make Tool\n" "=====================\n" - "This tool provides build commands for distibuting novelWriter as a\n" - "package. The available options are as follows:\n" "\n" - "help Print the help message.\n" - "freeze Freeze the package and produces a folder of all\n" - " dependencies using pyinstaller.\n" - "onefile Build a standalone executable with all dependencies\n" - " bundled. Implies 'freeze', cannot be used with 'setup'.\n" - "pip Run pip to install all package dependencies for\n" - " novelWriter and this build tool.\n" - "setup Build a setup.exe installer for Windows. This option\n" - " automaticall disables the 'onefile' option.\n" - "clean This will attempt to delete the 'build' and 'dist'\n" - " folders in the current folder.\n" + "This tool provides build commands for distibuting novelWriter as a package on Linux and\n" + "Windows. The available options are as follows:\n" + "\n" + "General:\n" + "\n" + " help Print the help message.\n" + " pip Install all package dependencies for novelWriter using pip.\n" + " clean Will attempt to delete the 'build' and 'dist' folders.\n" + "\n" + "Python Packaging:\n" + "\n" + " winpack Creates a pyz package in a folder with all dependencies using the zipapp\n" + " tool. This option is intended for Windows deployment.\n" + " freeze Freeze the package and produces a folder with all dependencies using the\n" + " pyinstaller tool. This option is not designed for a specific OS.\n" + " onefile Build a standalone executable with all dependencies bundled using the\n" + " pyinstaller tool. Implies 'freeze', cannot be used with 'setup_exe'.\n" + "\n" + "Windows Installers:\n" + "\n" + " setup_exe Build a Windows installer from a pyinstaller freeze package using Inno\n" + " Setup. This option automatically disables 'onefile'.\n" + " setup_pyz Build a Windows installer from a zipapp package using Inno Setup.\n" ) if "help" in sys.argv or len(sys.argv) <= 1: @@ -482,11 +493,21 @@ if __name__ == "__main__": sys.argv.remove("winpack") winPack = True - if "setup" in sys.argv: - sys.argv.remove("setup") + if "setup_exe" in sys.argv: + sys.argv.remove("setup_exe") if hostOS == OS_WIN: oneFile = False - makeSetup = True + makeSetupExe = True + makeSetupPyz = False + else: + print("Error: Argument 'setup' for Inno Setup is Windows only.") + sys.exit(1) + + if "setup_pyz" in sys.argv: + sys.argv.remove("setup_pyz") + if hostOS == OS_WIN: + makeSetupExe = False + makeSetupPyz = True else: print("Error: Argument 'setup' for Inno Setup is Windows only.") sys.exit(1) @@ -495,9 +516,12 @@ if __name__ == "__main__": makeWindowsPackage() if doFreeze: - freezePackage(buildWindowed, oneFile, makeSetup, hostOS) + freezePackage(buildWindowed, oneFile, makeSetupExe, hostOS) - if makeSetup: - innoSetup() + if makeSetupExe: + innoSetup("exe") + + if makeSetupPyz: + innoSetup("pyz") # END Main diff --git a/setup/win_setup_exe.iss b/setup/win_setup_exe.iss new file mode 100644 index 00000000..bed7c5ed --- /dev/null +++ b/setup/win_setup_exe.iss @@ -0,0 +1,59 @@ +; Script generated by the Inno Setup Script Wizard. +; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES! + +#define nwAppDir "%%dir%%\dist" +#define nwAppName "novelWriter" +#define nwAppVersion "%%version%%" +#define nwAppPublisher "novelWriter" +#define nwAppURL "http://novelWriter.io" +#define nwAppExeName "novelWriter.exe" + +[Setup] +; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. +; (To generate a new GUID, click Tools | Generate GUID inside the IDE.) +AppId={{459A75D0-951F-4932-9809-6002EC8E733E} +AppName={#nwAppName} +AppVersion={#nwAppVersion} +AppVerName={#nwAppName} {#nwAppVersion} +AppPublisher={#nwAppPublisher} +AppPublisherURL={#nwAppURL} +AppSupportURL={#nwAppURL} +AppUpdatesURL={#nwAppURL} +DefaultDirName={autopf}\{#nwAppName} +DisableProgramGroupPage=yes +; The [Icons] "quicklaunchicon" entry uses {userappdata} but its [Tasks] entry has a proper IsAdminInstallMode Check. +UsedUserAreasWarning=no +; Uncomment the following line to run in non administrative install mode (install for current user only.) +;PrivilegesRequired=lowest +PrivilegesRequiredOverridesAllowed=dialog +OutputDir={#nwAppDir} +OutputBaseFilename=novelwriter-{#nwAppVersion}-win10-amd64-setup +Compression=lzma +SolidCompression=yes +WizardStyle=modern +ArchitecturesInstallIn64BitMode=x64 +ChangesAssociations=yes + +[Languages] +Name: "english"; MessagesFile: "compiler:Default.isl" + +[Tasks] +Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked +Name: "quicklaunchicon"; Description: "{cm:CreateQuickLaunchIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked; OnlyBelowVersion: 6.1; Check: not IsAdminInstallMode + +[Files] +Source: "{#nwAppDir}\novelWriter\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs + +[Icons] +Name: "{autoprograms}\{#nwAppName}"; Filename: "{app}\{#nwAppExeName}" +Name: "{autodesktop}\{#nwAppName}"; Filename: "{app}\{#nwAppExeName}"; Tasks: desktopicon + +[Run] +Filename: "{app}\{#nwAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(nwAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent + +[Registry] +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\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\assets\icons\x-novelwriter-project.ico" +Root: HKA; Subkey: "Software\Classes\novelWriterProject.nwx\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#nwAppExeName}"" ""%1""" +Root: HKA; Subkey: "Software\Classes\Applications\{#nwAppExeName}\SupportedTypes"; ValueType: string; ValueName: ".nwx"; ValueData: "" diff --git a/setup/win_setup.iss b/setup/win_setup_pyz.iss similarity index 100% rename from setup/win_setup.iss rename to setup/win_setup_pyz.iss