Browse Source

Windows: clean deployment scripts

Antti Aalto 9 years ago
parent
commit
184a1fcd88
3 changed files with 45 additions and 29 deletions
  1. 43 25
      deployment/windows/buildwin32.py
  2. 2 3
      deployment/windows/installer.iss
  3. 0 1
      src/borg/helpers.py

+ 43 - 25
deployment/windows/buildwin32.py

@@ -3,8 +3,7 @@ import os
 import subprocess
 import subprocess
 import sys
 import sys
 from modulefinder import ModuleFinder
 from modulefinder import ModuleFinder
-
-import borg
+import zipfile
 
 
 # Creates standalone Windows executable
 # Creates standalone Windows executable
 # First build by following instructions from installation.rst
 # First build by following instructions from installation.rst
@@ -15,17 +14,17 @@ if os.path.exists(builddir):
     shutil.rmtree(builddir)
     shutil.rmtree(builddir)
 os.mkdir(builddir)
 os.mkdir(builddir)
 os.mkdir(builddir + '/bin')
 os.mkdir(builddir + '/bin')
-os.mkdir(builddir + '/lib')
+library = zipfile.PyZipFile(os.path.join(builddir, 'library.zip'), mode='w')
 
 
 print('Compiling wrapper')
 print('Compiling wrapper')
 
 
 gccpath = ''  # check for compiler, path needed later
 gccpath = ''  # check for compiler, path needed later
 for p in os.environ['PATH'].split(';'):
 for p in os.environ['PATH'].split(';'):
-    if os.path.exists(os.path.join(p, 'gcc.exe')):
+    if os.path.exists(os.path.join(p, 'g++.exe')):
         gccpath = p
         gccpath = p
         break
         break
 if gccpath == '':
 if gccpath == '':
-    print('gcc not found.')
+    print('g++ not found.')
     exit(1)
     exit(1)
 
 
 source = open('wrapper.c', 'w')
 source = open('wrapper.c', 'w')
@@ -34,17 +33,23 @@ source.write(
 #include <python3.5m/python.h>
 #include <python3.5m/python.h>
 #include <windows.h>
 #include <windows.h>
 #include <wchar.h>
 #include <wchar.h>
+#include <string>
 #include "Shlwapi.h"
 #include "Shlwapi.h"
 
 
 int wmain(int argc , wchar_t *argv[] )
 int wmain(int argc , wchar_t *argv[] )
 {
 {
-
-    wchar_t *program = argv[0];
-    Py_SetProgramName(program);
+    wchar_t path[MAX_PATH];
+    GetModuleFileNameW(NULL, path, MAX_PATH);
+    PathRemoveFileSpecW(path);
+    std::wstring selfpath(path);
+    std::wstring libpath = selfpath + L"/library.zip;" + selfpath + L"/bin";
+
+    Py_SetPath(libpath.c_str());
+    Py_SetProgramName(argv[0]);
     Py_Initialize();
     Py_Initialize();
-
     PySys_SetArgv(argc, argv);
     PySys_SetArgv(argc, argv);
 
 
+    PyImport_ImportModule("encodings.idna");
     PyRun_SimpleString("from runpy import run_module\\n"
     PyRun_SimpleString("from runpy import run_module\\n"
                        "run_module('borg')");
                        "run_module('borg')");
 
 
@@ -53,18 +58,24 @@ int wmain(int argc , wchar_t *argv[] )
 }
 }
 """)
 """)
 source.close()
 source.close()
-subprocess.check_call('gcc wrapper.c -lpython3.5m -lshlwapi -municode -o ' + builddir + '/bin/borg.exe')
+subprocess.check_call('g++ wrapper.c -lpython3.5m -lshlwapi -municode -o ' + builddir + '/borg.exe')
 os.remove('wrapper.c')
 os.remove('wrapper.c')
 
 
 print('Searching modules')
 print('Searching modules')
 
 
 modulepath = os.path.abspath(os.path.join(gccpath, '../lib/python3.5/'))
 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'))
+# Bundle all encodings - In theory user may use any encoding in command prompt
+for file in os.listdir(os.path.join(modulepath, 'encodings')):
+    if os.path.isfile(os.path.join(modulepath, 'encodings', file)):
+        library.write(os.path.join(modulepath, 'encodings', file), os.path.join('encodings', file))
 
 
 finder = ModuleFinder()
 finder = ModuleFinder()
-finder.run_script(os.path.join(borg.__path__[0], '__main__.py'))
-extramodules = [os.path.join(modulepath, 'site.py')]
+finder.run_script('src/borg/__main__.py')
+
+# For some reason modulefinder does not find these, add them manually
+extramodules = [os.path.join(modulepath, 'site.py'), os.path.join(modulepath, 'encodings/idna.py'),
+    os.path.join(modulepath, 'stringprep.py')]
 
 
 for module in extramodules:
 for module in extramodules:
     finder.run_script(module)
     finder.run_script(module)
@@ -98,23 +109,30 @@ for name, mod in items:
     if lib == -1:
     if lib == -1:
         # Part of the borg package
         # Part of the borg package
         relpath = os.path.relpath(file)[4:]
         relpath = os.path.relpath(file)[4:]
-        os.makedirs(os.path.join(builddir, 'lib', 'python3.5', os.path.split(relpath)[0]), exist_ok=True)
-        shutil.copyfile(file, os.path.join(builddir, 'lib', 'python3.5', 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))
+        os.makedirs(os.path.join(builddir, 'bin', os.path.split(relpath)[0]), exist_ok=True)
+        shutil.copyfile(file, os.path.join(builddir, 'bin', relpath))
+    else:
+        relativepath = file[file.find('lib')+14:]
+        if 'encodings' in file:
+            continue
+        if relativepath not in library.namelist():
+            if relativepath.startswith('site-packages'):
+                relativepath = relativepath[14:]
+            library.write(file, relativepath)
     if file[-4:] == '.dll' or file[-4:] == '.DLL':
     if file[-4:] == '.dll' or file[-4:] == '.DLL':
+        shutil.copyfile(file, os.path.join(builddir, 'bin', os.path.split(file)[1]))
         for dll in finddlls(file):
         for dll in finddlls(file):
             if builddir not in dll:
             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")):
+                shutil.copyfile(dll, os.path.join(builddir, os.path.split(dll)[1]))
+for dll in finddlls(os.path.join(builddir, "borg.exe")):
     if builddir not in dll:
     if builddir not in dll:
-        shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
+        shutil.copyfile(dll, os.path.join(builddir, os.path.split(dll)[1]))
 
 
-shutil.copyfile('src/borg/__main__.py', os.path.join(builddir, 'lib/python3.5/borg/__main__.py'))
+shutil.copyfile('src/borg/__main__.py', os.path.join(builddir, 'bin', 'borg/__main__.py'))
+library.write(os.path.join(modulepath, 'site.py'), 'site.py')
 
 
-for extmodule in ['src/borg/chunker-cpython-35m.dll', 'src/borg/compress-cpython-35m.dll', 'src/borg/crypto-cpython-35m.dll', 'src/borg/hashindex-cpython-35m.dll']:
+for extmodule in ['src/borg/chunker-cpython-35m.dll', 'src/borg/compress-cpython-35m.dll',
+    'src/borg/crypto-cpython-35m.dll', 'src/borg/hashindex-cpython-35m.dll']:
     for dll in finddlls(extmodule):
     for dll in finddlls(extmodule):
         if builddir not in dll:
         if builddir not in dll:
-            shutil.copyfile(dll, os.path.join(builddir, 'bin', os.path.split(dll)[1]))
+            shutil.copyfile(dll, os.path.join(builddir, os.path.split(dll)[1]))

+ 2 - 3
deployment/windows/installer.iss

@@ -2,7 +2,7 @@
 #define MyAppVersion "1.1"
 #define MyAppVersion "1.1"
 #define MyAppPublisher "The Borg Collective"
 #define MyAppPublisher "The Borg Collective"
 #define MyAppURL "https://borgbackup.rtfd.org/"
 #define MyAppURL "https://borgbackup.rtfd.org/"
-#define MyAppExeName "bin/borg.exe"
+#define MyAppExeName "borg.exe"
 
 
 [Setup]
 [Setup]
 AppId={{1B6E8CD4-25F2-4400-A53F-4338D6614475}
 AppId={{1B6E8CD4-25F2-4400-A53F-4338D6614475}
@@ -32,8 +32,7 @@ Name: "english"; MessagesFile: "compiler:Default.isl"
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
 
 
 [Files]
 [Files]
-Source: "win32exe\bin\*"; DestDir: "{app}\bin"; Flags: replacesameversion recursesubdirs
-Source: "win32exe\lib\*"; DestDir: "{app}\lib"; Flags: replacesameversion recursesubdirs
+Source: "win32exe\*"; DestDir: "{app}"; Flags: replacesameversion recursesubdirs
 ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 ; NOTE: Don't use "Flags: ignoreversion" on any shared system files
 
 
 [Icons]
 [Icons]

+ 0 - 1
src/borg/helpers.py

@@ -25,7 +25,6 @@ if sys.platform != 'win32':
     import pwd
     import pwd
 else:
 else:
     import posixpath
     import posixpath
-    import encodings.idna
 
 
 
 
 import msgpack
 import msgpack