From 67c8966a21c21ea3496aec4ccc1017047a12f238 Mon Sep 17 00:00:00 2001
From: Peter Surda <surda@economicsofbitcoin.com>
Date: Sun, 19 Feb 2017 14:48:53 +0100
Subject: [PATCH] Windows compatibility fixes

- spec file for pyinstaller detects architecture (32 or 64bit)
- spec file uses os.path.join
- spec file creates and adds the list of messagetypes
- added MinGW/MSyS support in Makefile
- separate Makefile.msvc for MCVC
- bitmsghash.cpp minor adjustments to build also on MSVC/MinGW
- if frozen mode, messagetypes loads the list of files from a text file
  generated during archive building rather than from a directory
---
 packages/pyinstaller/bitmessagemain.spec | 47 ++++++++++++++++++------
 src/bitmsghash/Makefile                  |  9 ++++-
 src/bitmsghash/Makefile.msvc             |  2 +
 src/bitmsghash/bitmsghash.cpp            |  8 ++++
 src/messagetypes/__init__.py             | 12 +++++-
 5 files changed, 63 insertions(+), 15 deletions(-)
 create mode 100644 src/bitmsghash/Makefile.msvc

diff --git a/packages/pyinstaller/bitmessagemain.spec b/packages/pyinstaller/bitmessagemain.spec
index 0b41bb00..bb16b911 100644
--- a/packages/pyinstaller/bitmessagemain.spec
+++ b/packages/pyinstaller/bitmessagemain.spec
@@ -1,15 +1,30 @@
+import ctypes
+import os
+
 srcPath = "C:\\src\\PyBitmessage\\src\\"
-qtPath = "C:\\Qt\\4.8.6\\"
-openSSLPath = "C:\\OpenSSL-1.0.2e\\"
-outPath = "C:\\src\\PyInstaller\\bitmessagemain"
+qtPath = "C:\\Qt-4.8.7\\"
+openSSLPath = "C:\\OpenSSL-1.0.2j\\"
+outPath = "C:\\src\\PyInstaller-3.2.1\\bitmessagemain"
 
 # -*- mode: python -*-
 a = Analysis([srcPath + 'bitmessagemain.py'],
              pathex=[outPath],
-             hiddenimports=[],
+             hiddenimports=['messagetypes'],
              hookspath=None,
              runtime_hooks=None)
-			 
+
+# manually add messagetypes directory and its listing
+with open(os.path.join(srcPath, 'messagetypes.txt'), 'wt') as f:
+	for mt in os.listdir(os.path.join(srcPath, 'messagetypes')):
+		if mt == "__init__.py":
+			continue
+		splitted = os.path.splitext(mt)
+		if splitted[1] != ".py":
+			continue
+		f.write(mt + "\n")
+		a.scripts.append((os.path.join('messagetypes', mt), os.path.join(srcPath, 'messagetypes', mt), 'PYMODULE'))
+a.datas.append(('messagetypes.txt', os.path.join(srcPath, 'messagetypes.txt'), 'DATA'))
+
 # fix duplicates
 for d in a.datas:
     if 'pyconfig' in d[0]: 
@@ -22,11 +37,11 @@ def addTranslations():
     for file in os.listdir(srcPath + 'translations'):
         if file[-3:] != ".qm":
             continue
-        extraDatas.append(('translations\\'+file, srcPath + 'translations\\' + file, 'DATA'))
+        extraDatas.append((os.path.join('translations', file), os.path.join(srcPath, 'translations', file) 'DATA'))
     for file in os.listdir(qtPath + 'translations'):
         if file[0:3] != "qt_" or file[5:8] != ".qm":
             continue
-        extraDatas.append(('translations\\'+file, qtPath + 'translations\\' + file, 'DATA'))
+        extraDatas.append((os.path.join('translations', file), os.path.join(qtPath, 'translations', file), 'DATA'))
     return extraDatas
 
 def addUIs():
@@ -35,14 +50,24 @@ def addUIs():
     for file in os.listdir(srcPath + 'bitmessageqt'):
         if file[-3:] != ".ui":
             continue
-        extraDatas.append(('ui\\'+file, srcPath + 'bitmessageqt\\' + file, 'DATA'))
+        extraDatas.append((os.path.join('ui', file), os.path.join(srcPath, 'bitmessageqt', file), 'DATA'))
     return extraDatas
 
 # append the translations directory
 a.datas += addTranslations()
 a.datas += addUIs()
 
-a.binaries.append(('msvcr120.dll', 'C:\\WINDOWS\\system32\\msvcr120.dll', 'BINARY'))
+if ctypes.sizeof(ctypes.c_voidp) == 4:
+	arch=32
+else:
+	arch=64
+
+a.binaries += [('libeay32.dll', openSSLPath + 'libeay32.dll', 'BINARY'),
+	(os.path.join('bitmsghash', 'bitmsghash%i.dll' % (arch)), os.path.join(srcPath, 'bitmsghash', 'bitmsghash%i.dll' % (arch)), 'BINARY'),
+	(os.path.join('bitmsghash', 'bitmsghash.cl'), os.path.join(srcPath, 'bitmsghash', 'bitmsghash.cl'), 'BINARY'),
+	(os.path.join('sslkeys', 'cert.pem'), os.path.join(srcPath, 'sslkeys', 'cert.pem'), 'BINARY'),
+	(os.path.join('sslkeys', 'key.pem'), os.path.join(srcPath, 'sslkeys', 'key.pem'), 'BINARY')
+	]
 
 pyz = PYZ(a.pure)
 exe = EXE(pyz,
@@ -50,9 +75,9 @@ exe = EXE(pyz,
           a.binaries,
           a.zipfiles,
           a.datas,
-          a.binaries + [('libeay32.dll', openSSLPath + 'libeay32.dll', 'BINARY'), ('bitmsghash\\bitmsghash32.dll', srcPath + 'bitmsghash\\bitmsghash32.dll', 'BINARY'), ('bitmsghash\\bitmsghash.cl', srcPath + 'bitmsghash\\bitmsghash.cl', 'BINARY'), ('sslkeys\\cert.pem', srcPath + 'sslkeys\\cert.pem', 'BINARY'), ('sslkeys\\key.pem', srcPath + 'sslkeys\\key.pem', 'BINARY')],
+          a.binaries,
           name='Bitmessage.exe',
           debug=False,
           strip=None,
           upx=False,
-          console=False, icon= srcPath + 'images\\can-icon.ico')
+          console=False, icon= os.path.join(srcPath, 'images', 'can-icon.ico')
diff --git a/src/bitmsghash/Makefile b/src/bitmsghash/Makefile
index 88744524..3d0f5d0a 100644
--- a/src/bitmsghash/Makefile
+++ b/src/bitmsghash/Makefile
@@ -2,6 +2,11 @@ UNAME_S := $(shell uname -s)
 ifeq ($(UNAME_S),Darwin)
 	CCFLAGS += -I/usr/local/Cellar/openssl/1.0.2d_1/include
 	LDFLAGS += -L/usr/local/Cellar/openssl/1.0.2d_1/lib
+else ifeq ($(UNAME_S),MINGW32_NT-6.1)
+	CCFLAGS += -IC:\OpenSSL-1.0.2j-mingw\include -D_WIN32 -march=native
+	LDFLAGS += -static-libgcc -LC:\OpenSSL-1.0.2j-mingw\lib -lwsock32 -o bitmsghash32.dll -Wl,--out-implib,bitmsghash.a
+else
+	LDFLAGS += -lpthread -o bigmsghash.so
 endif
    	
 all: bitmsghash.so
@@ -10,11 +15,11 @@ powtest:
 	./testpow.py
 
 bitmsghash.so: bitmsghash.o
-	g++ bitmsghash.o -shared -fPIC -lpthread -lcrypto $(LDFLAGS) -o bitmsghash.so
+	g++ bitmsghash.o -shared -fPIC -lcrypto $(LDFLAGS)
 
 bitmsghash.o:
 	g++ -Wall -O3 -march=native -fPIC $(CCFLAGS) -c bitmsghash.cpp
 
 clean:
-	rm -f bitmsghash.o bitmsghash.so
+	rm -f bitmsghash.o bitmsghash.so bitmsghash*.dll
 
diff --git a/src/bitmsghash/Makefile.msvc b/src/bitmsghash/Makefile.msvc
new file mode 100644
index 00000000..63482c34
--- /dev/null
+++ b/src/bitmsghash/Makefile.msvc
@@ -0,0 +1,2 @@
+all:
+	cl /I C:\OpenSSL-1.0.2j\include /INCREMENTAL bitmsghash.cpp /MT /link /DLL /OUT:bitmsghash32.dll /LIBPATH:C:\OpenSSL-1.0.2j\lib\ libeay32.lib ws2_32.lib
diff --git a/src/bitmsghash/bitmsghash.cpp b/src/bitmsghash/bitmsghash.cpp
index 3c06b218..2d0d4b50 100644
--- a/src/bitmsghash/bitmsghash.cpp
+++ b/src/bitmsghash/bitmsghash.cpp
@@ -66,7 +66,11 @@ void * threadfunc(void* param) {
 			successval = tmpnonce;
 		}
 	}
+#ifdef _WIN32
+	return 0;
+#else
 	return NULL;
+#endif
 }
 
 void getnumthreads()
@@ -104,7 +108,11 @@ void getnumthreads()
 #endif
 	for (unsigned int i = 0; i < len * 8; i++)
 #if defined(_WIN32)
+#if defined(_MSC_VER)
 		if (dwProcessAffinity & (1i64 << i))
+#else // CYGWIN/MINGW
+		if (dwProcessAffinity & (1ULL << i))
+#endif
 #elif defined __linux__
 		if (CPU_ISSET(i, &dwProcessAffinity))
 #else
diff --git a/src/messagetypes/__init__.py b/src/messagetypes/__init__.py
index 16d97ae7..e22be925 100644
--- a/src/messagetypes/__init__.py
+++ b/src/messagetypes/__init__.py
@@ -3,7 +3,7 @@ from os import path, listdir
 from string import lower
 
 from debug import logger
-
+import paths
 
 class MsgBase(object):
     def encode(self):
@@ -28,7 +28,15 @@ def constructObject(data):
     else:
         return returnObj
 
-for mod in listdir(path.dirname(__file__)):
+mods = []
+if paths.frozen is not None:
+    with open(path.join(path.dirname(path.dirname(__file__)), 'messagetypes.txt'), 'rt') as f:
+        for m in f.readline():
+            mods.append(m.rstrip())
+else:
+    mods = listdir(path.dirname(__file__))
+
+for mod in mods:
     if mod == "__init__.py":
         continue
     splitted = path.splitext(mod)