Browse Source

Add setup wizard

$ python3 deployment/windows/buildwin32.py
...
$

Fire ISS up, build installer. Result is in Output directory.
Should be around ~4 MB
Marian Beermann 9 years ago
parent
commit
82bcb039cb
4 changed files with 170 additions and 120 deletions
  1. 1 0
      borg/helpers.py
  2. 4 0
      deployment/windows/borg-shell.bat
  3. 120 120
      deployment/windows/buildwin32.py
  4. 45 0
      deployment/windows/installer.iss

+ 1 - 0
borg/helpers.py

@@ -8,6 +8,7 @@ if sys.platform != 'win32':
     import pwd
 else:
     import posixpath
+    import encodings.idna
 import hashlib
 from itertools import islice
 import os

+ 4 - 0
deployment/windows/borg-shell.bat

@@ -0,0 +1,4 @@
+SET PATH=%~dp0bin;%PATH%
+SET PYTHONPATH=%~dp0bin
+CD /D %USERPROFILE%
+CMD /K

+ 120 - 120
buildwin32.py → deployment/windows/buildwin32.py

@@ -1,120 +1,120 @@
-import shutil
-import os
-import subprocess
-from modulefinder import ModuleFinder
-
-# Creates standalone Windows executable
-# First build by following instructions from installation.rst
-
-builddir = 'win32exe'
-
-if os.path.exists(builddir):
-    shutil.rmtree(builddir)
-os.mkdir(builddir)
-os.mkdir(builddir + '/bin')
-os.mkdir(builddir + '/lib')
-
-print('Compiling wrapper')
-
-gccpath = ''  # check for compiler, path needed later
-for p in os.environ['PATH'].split(';'):
-    if os.path.exists(os.path.join(p, 'gcc.exe')):
-        gccpath = p
-        break
-if gccpath == '':
-    print('gcc not found.')
-    exit(1)
-
-source = open('wrapper.c', 'w')
-source.write(
-"""
-#include <python3.5m/python.h>
-#include <windows.h>
-#include <wchar.h>
-#include "Shlwapi.h"
-
-int wmain(int argc , wchar_t *argv[] )
-{
-
-    wchar_t *program = argv[0];
-    Py_SetProgramName(program);
-    Py_Initialize();
-
-    PySys_SetArgv(argc, argv);
-
-    wchar_t path[MAX_PATH];
-    GetModuleFileNameW(NULL, path, MAX_PATH);
-    PathRemoveFileSpecW(path);
-
-    FILE* file_1 = _wfopen(wcsncat(path, L"/borg/__main__.py", 17), L"r");
-    PyRun_AnyFile(file_1, "borg/__main__.py");
-
-    Py_Finalize();
-    PyMem_RawFree(program);
-    return 0;
-}
-""")
-source.close()
-subprocess.run('gcc wrapper.c -lpython3.5m -lshlwapi -municode -o ' + builddir + '/bin/borg.exe')
-os.remove('wrapper.c')
-
-print('Searching modules')
-
-modulepath = os.path.abspath(os.path.join(gccpath, '../lib/python3.5/'))
-
-shutil.copytree(os.path.join(modulepath, 'encodings'), os.path.join(builddir, 'lib/python3.5/encodings'))
-
-finder = ModuleFinder()
-finder.run_script('borg/__main__.py')
-extramodules = [os.path.join(modulepath, 'site.py')]
-
-for module in extramodules:
-    finder.run_script(module)
-
-print('Copying files')
-
-
-def finddlls(exe):
-    re = []
-    output = subprocess.check_output(['ntldd', '-R', exe])
-    for line in output.decode('utf-8').split('\n'):
-        if 'not found' in line:
-            continue
-        if 'windows' in line.lower():
-            continue
-        words = line.split()
-        if len(words) < 3:
-            if len(words) == 2:
-                re.append(words[0])
-            continue
-        dll = words[2]
-        re.append(dll)
-    return re
-
-items = finder.modules.items()
-for name, mod in items:
-    file = mod.__file__
-    if file is None:
-        continue
-    lib = file.find('lib')
-    if lib == -1:
-        relpath = os.path.relpath(file)
-        os.makedirs(os.path.join(builddir, 'bin', os.path.split(relpath)[0]), exist_ok=True)
-        shutil.copyfile(file, os.path.join(builddir, 'bin', relpath))
-        continue
-    relativepath = file[file.find('lib')+4:]
-    os.makedirs(os.path.join(builddir, 'lib', os.path.split(relativepath)[0]), exist_ok=True)
-    shutil.copyfile(file, os.path.join(builddir, 'lib', relativepath))
-    if file[-4:] == '.dll' or file[-4:] == '.DLL':
-        for dll in finddlls(file):
-            if builddir not in dll:
-                shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
-for dll in finddlls(os.path.join(builddir, "bin/borg.exe")):
-    if builddir not in dll:
-        shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
-shutil.copyfile('borg/__main__.py', os.path.join(builddir, 'bin/borg/__main__.py'))
-
-for extmodule in ['borg/chunker-cpython-35m.dll', 'borg/compress-cpython-35m.dll', 'borg/crypto-cpython-35m.dll', 'borg/hashindex-cpython-35m.dll']:
-    for dll in finddlls(extmodule):
-        if builddir not in dll:
-            shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
+import shutil
+import os
+import subprocess
+from modulefinder import ModuleFinder
+
+# Creates standalone Windows executable
+# First build by following instructions from installation.rst
+
+builddir = 'win32exe'
+
+if os.path.exists(builddir):
+    shutil.rmtree(builddir)
+os.mkdir(builddir)
+os.mkdir(builddir + '/bin')
+os.mkdir(builddir + '/lib')
+
+print('Compiling wrapper')
+
+gccpath = ''  # check for compiler, path needed later
+for p in os.environ['PATH'].split(';'):
+    if os.path.exists(os.path.join(p, 'gcc.exe')):
+        gccpath = p
+        break
+if gccpath == '':
+    print('gcc not found.')
+    exit(1)
+
+source = open('wrapper.c', 'w')
+source.write(
+"""
+#include <python3.5m/python.h>
+#include <windows.h>
+#include <wchar.h>
+#include "Shlwapi.h"
+
+int wmain(int argc , wchar_t *argv[] )
+{
+
+    wchar_t *program = argv[0];
+    Py_SetProgramName(program);
+    Py_Initialize();
+
+    PySys_SetArgv(argc, argv);
+
+    wchar_t path[MAX_PATH];
+    GetModuleFileNameW(NULL, path, MAX_PATH);
+    PathRemoveFileSpecW(path);
+
+    FILE* file_1 = _wfopen(wcsncat(path, L"/borg/__main__.py", 17), L"r");
+    PyRun_AnyFile(file_1, "borg/__main__.py");
+
+    Py_Finalize();
+    PyMem_RawFree(program);
+    return 0;
+}
+""")
+source.close()
+subprocess.run('gcc wrapper.c -lpython3.5m -lshlwapi -municode -o ' + builddir + '/bin/borg.exe')
+os.remove('wrapper.c')
+
+print('Searching modules')
+
+modulepath = os.path.abspath(os.path.join(gccpath, '../lib/python3.5/'))
+
+shutil.copytree(os.path.join(modulepath, 'encodings'), os.path.join(builddir, 'lib/python3.5/encodings'))
+
+finder = ModuleFinder()
+finder.run_script('borg/__main__.py')
+extramodules = [os.path.join(modulepath, 'site.py')]
+
+for module in extramodules:
+    finder.run_script(module)
+
+print('Copying files')
+
+
+def finddlls(exe):
+    re = []
+    output = subprocess.check_output(['ntldd', '-R', exe])
+    for line in output.decode('utf-8').split('\n'):
+        if 'not found' in line:
+            continue
+        if 'windows' in line.lower():
+            continue
+        words = line.split()
+        if len(words) < 3:
+            if len(words) == 2:
+                re.append(words[0])
+            continue
+        dll = words[2]
+        re.append(dll)
+    return re
+
+items = finder.modules.items()
+for name, mod in items:
+    file = mod.__file__
+    if file is None:
+        continue
+    lib = file.find('lib')
+    if lib == -1:
+        relpath = os.path.relpath(file)
+        os.makedirs(os.path.join(builddir, 'bin', os.path.split(relpath)[0]), exist_ok=True)
+        shutil.copyfile(file, os.path.join(builddir, 'bin', relpath))
+        continue
+    relativepath = file[file.find('lib')+4:]
+    os.makedirs(os.path.join(builddir, 'lib', os.path.split(relativepath)[0]), exist_ok=True)
+    shutil.copyfile(file, os.path.join(builddir, 'lib', relativepath))
+    if file[-4:] == '.dll' or file[-4:] == '.DLL':
+        for dll in finddlls(file):
+            if builddir not in dll:
+                shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
+for dll in finddlls(os.path.join(builddir, "bin/borg.exe")):
+    if builddir not in dll:
+        shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
+shutil.copyfile('borg/__main__.py', os.path.join(builddir, 'bin/borg/__main__.py'))
+
+for extmodule in ['borg/chunker-cpython-35m.dll', 'borg/compress-cpython-35m.dll', 'borg/crypto-cpython-35m.dll', 'borg/hashindex-cpython-35m.dll']:
+    for dll in finddlls(extmodule):
+        if builddir not in dll:
+            shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))

+ 45 - 0
deployment/windows/installer.iss

@@ -0,0 +1,45 @@
+#define MyAppName "Borg for Windows"
+#define MyAppVersion "1.1"
+#define MyAppPublisher "The Borg Collective"
+#define MyAppURL "https://borgbackup.rtfd.org/"
+#define MyAppExeName "borg-shell.bat"
+
+[Setup]
+AppId={{1B6E8CD4-25F2-4400-A53F-4338D6614475}
+AppName={#MyAppName}
+AppVersion={#MyAppVersion}
+;AppVerName={#MyAppName} {#MyAppVersion}
+AppPublisher={#MyAppPublisher}
+AppPublisherURL={#MyAppURL}
+AppSupportURL={#MyAppURL}
+AppUpdatesURL={#MyAppURL}
+DefaultDirName={pf}\{#MyAppName}
+DefaultGroupName={#MyAppName}
+AllowNoIcons=yes
+LicenseFile=LICENSE
+OutputBaseFilename=Borg Backup {#MyAppVersion} Setup
+Compression=lzma/normal
+SolidCompression=yes
+SourceDir=..\..
+ArchitecturesInstallIn64BitMode=x64
+ArchitecturesAllowed=x64
+
+[Languages]
+Name: "english"; MessagesFile: "compiler:Default.isl"
+
+[Tasks]
+Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
+
+[Files]
+Source: "deployment\windows\borg-shell.bat"; DestDir: "{app}"; Flags: ignoreversion
+Source: "win32exe\bin\*"; DestDir: "{app}\bin"; Flags: replacesameversion recursesubdirs
+Source: "win32exe\lib\*"; DestDir: "{app}\lib"; Flags: replacesameversion recursesubdirs
+; NOTE: Don't use "Flags: ignoreversion" on any shared system files
+
+[Icons]
+Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
+Name: "{commondesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
+
+[Run]
+Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: shellexec postinstall skipifsilent
+