From a8f7da7a2b0c71e48c6cc41446d878527254af3e Mon Sep 17 00:00:00 2001
From: Jack Williams <jacwil014@gmail.com>
Date: Thu, 27 Sep 2018 07:05:12 -0700
Subject: [PATCH] More Windows compatibility (#75)

* Attempt to make setup.py more platform independent

* Fix markdown

* Fix cmake config for pre-Windows 10 installations

* Fix Travis build
---
 pe-parser-library/cmake/peparse-config.cmake |  4 +--
 python/README.md                             | 27 ++++++++++++++
 python/setup.py                              | 37 ++++++++++++++------
 3 files changed, 56 insertions(+), 12 deletions(-)

diff --git a/pe-parser-library/cmake/peparse-config.cmake b/pe-parser-library/cmake/peparse-config.cmake
index d350f7e..940ecb7 100644
--- a/pe-parser-library/cmake/peparse-config.cmake
+++ b/pe-parser-library/cmake/peparse-config.cmake
@@ -1,5 +1,5 @@
-find_path(PEPARSE_INCLUDE_DIR "parser-library/parse.h")
-find_library(PEPARSE_LIBRARIES NAMES "libpe-parser-library")
+find_path(PEPARSE_INCLUDE_DIR $<SHELL_PATH:"parser-library/parse.h">)
+find_library(PEPARSE_LIBRARIES NAMES "libpe-parser-library" "pe-parser-library")
 
 include(FindPackageHandleStandardArgs)
 find_package_handle_standard_args(peparse DEFAULT_MSG PEPARSE_INCLUDE_DIR PEPARSE_LIBRARIES)
diff --git a/python/README.md b/python/README.md
index 8d36674..2be2c02 100644
--- a/python/README.md
+++ b/python/README.md
@@ -7,11 +7,38 @@ Building
 If you can build pe-parse and have a working python environment (headers and
 libraries) you can build pepy.
 
+Python 2.7
+----------
 1. Build pepy:
   * python setup.py build
 2. Install pepy:
   * python setup.py install
 
+**Building on Windows:** If you get a build error of 'Unable to find
+vcvarsall.bat', you must set the `VS90COMNTOOLS` environment variable prior
+to the appropriate path as per
+[this SO article](http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat):
+> While running setup.py for package installations, Python 2.7 searches for an
+> installed Visual Studio 2008. You can trick Python to use a newer Visual
+> Studio by setting the correct path in VS90COMNTOOLS environment variable
+> before calling setup.py.
+> 
+> Execute the following command based on the version of Visual Studio installed:
+> * Visual Studio 2010 (VS10): `SET VS90COMNTOOLS=%VS100COMNTOOLS%`
+> * Visual Studio 2012 (VS11): `SET VS90COMNTOOLS=%VS110COMNTOOLS%`
+> * Visual Studio 2013 (VS12): `SET VS90COMNTOOLS=%VS120COMNTOOLS%`
+> * Visual Studio 2015/2017 (VS14): `SET VS90COMNTOOLS=%VS140COMNTOOLS%`
+
+Python 3.x
+----------
+1. Build pepy:
+  * python3 setup.py build
+2. Install pepy:
+  * python3 setup.py install
+
+**Building on Windows:** Python 3.x is typically installed as _python.exe_
+**NOT** _python3.exe_.
+
 Using
 =====
 Parsed object
diff --git a/python/setup.py b/python/setup.py
index a30bac1..1e607c3 100644
--- a/python/setup.py
+++ b/python/setup.py
@@ -24,19 +24,36 @@
 # SUCH DAMAGE.
 
 from distutils.core import setup, Extension
+import os
+import sys
+import platform
 
-INCLUDE_DIRS = ['/usr/local/include',
-                '/opt/local/include',
-                '/usr/include',
-                '../pe-parser-library/include']
-LIBRARY_DIRS = ['/usr/lib',
-                '/usr/local/lib']
+here = os.path.abspath(os.path.dirname(__file__))
+
+SOURCE_FILES = [os.path.join(here, 'pepy.cpp'),
+                os.path.abspath(os.path.join(here, '..', 'pe-parser-library', 'src', 'parse.cpp')),
+                os.path.abspath(os.path.join(here, '..', 'pe-parser-library', 'src', 'buffer.cpp'))]
+
+if platform.system() == 'Windows':
+  INCLUDE_DIRS = [os.path.abspath(os.path.join(os.path.dirname(sys.executable), 'include')),
+                  os.path.abspath(os.path.join(here, '..', 'pe-parser-library', 'include')),
+                  'C:\\usr\\include']
+  LIBRARY_DIRS = [os.path.abspath(os.path.join(os.path.dirname(sys.executable), 'libs')),
+                  'C:\\usr\\lib']
+  COMPILE_ARGS = ["/EHsc"]
+else:
+  INCLUDE_DIRS = ['/usr/local/include',
+                  '/opt/local/include',
+                  '/usr/include',
+                  os.path.abspath(os.path.join(here, '..', 'pe-parser-library', 'include'))]
+  LIBRARY_DIRS = ['/usr/lib',
+                  '/usr/local/lib']
+  COMPILE_ARGS = ["-std=c++11", "-g", "-O0"] # Debug only
 
 extension_mod = Extension('pepy',
-                          sources = ['pepy.cpp',
-                                     '../pe-parser-library/src/parse.cpp',
-                                     '../pe-parser-library/src/buffer.cpp'],
-                          extra_compile_args = ["-std=c++11", "-g", "-O0"], # Debug only
+                          sources = SOURCE_FILES,
+                          extra_compile_args = COMPILE_ARGS,
+                          language='c++',
                           include_dirs = INCLUDE_DIRS,
                           library_dirs = LIBRARY_DIRS)