diff --git a/SConstruct b/SConstruct
index 5179bba..2dcdbe1 100644
--- a/SConstruct
+++ b/SConstruct
@@ -21,11 +21,17 @@ SCons construction environment can be customized in sconscript.local script.
 """
 
 import os
+from os.path import join as pjoin
 import platform
 
 def subdictionary(d, keyset):
     return dict(kv for kv in d.items() if kv[0] in keyset)
 
+def getsyspaths(*names):
+    pall = sum((os.environ.get(n, '').split(os.pathsep) for n in names), [])
+    rv = [p for p in pall if os.path.exists(p)]
+    return rv
+
 # copy system environment variables related to compilation
 DefaultEnvironment(ENV=subdictionary(os.environ, '''
     PATH CPATH CPLUS_INCLUDE_PATH LIBRARY_PATH LD_RUN_PATH
@@ -43,26 +49,71 @@ env.EnsureSConsVersion(0, 98, 1)
 # Customizable compile variables
 vars = Variables('sconsvars.py')
 
-vars.Add(PathVariable(
-    'prefix',
-    'installation prefix directory',
-    '/usr/local'))
-vars.Update(env)
-vars.Add(PathVariable(
-    'libdir',
-    'installation directory for compiled library [prefix/lib]',
-    env['prefix'] + '/lib',
-    PathVariable.PathAccept))
-vars.Add(PathVariable(
-    'includedir',
-    'installation directory for C++ header files [prefix/include]',
-    env['prefix'] + '/include',
-    PathVariable.PathAccept))
-vars.Add(PathVariable(
-    'datadir',
-    'installation directory for architecture independent data [prefix/share]',
-    env['prefix'] + '/share',
-    PathVariable.PathAccept))
+if 'PREFIX' in os.environ:
+    vars.Add(PathVariable(
+        'prefix',
+        'installation prefix directory',
+        os.environ['prefix']))
+    vars.Update(env)
+elif 'CONDA_PREFIX' in os.environ:
+    vars.Add(PathVariable(
+        'prefix',
+        'installation prefix directory',
+        os.environ['CONDA_PREFIX']))
+    vars.Update(env)
+else:
+    vars.Add(PathVariable(
+        'prefix',
+        'installation prefix directory',
+        '/usr/local'))
+    vars.Update(env)
+
+if platform.system().lower() == 'windows':
+    vars.Add(PathVariable(
+        'libdir',
+        'installation directory for compiled programs [prefix/Library/lib]',
+        pjoin(env['prefix'], 'Library', 'Lib'),
+        PathVariable.PathAccept))
+    vars.Add(PathVariable(
+        'includedir',
+        'installation directory for C++ header files [prefix/Library/include]',
+        pjoin(env['prefix'], 'Library', 'include'),
+        PathVariable.PathAccept))
+    vars.Add(PathVariable(
+        'datadir',
+        'installation directory for architecture independent data [prefix/share]',
+        pjoin(env['prefix'], 'Library', 'share'),
+        PathVariable.PathAccept))
+    
+    env['ENV']['TMP'] = os.environ['TMP']
+    env.Append(CPPPATH=[pjoin(env['prefix'], 'Library', 'include')])
+    env.Append(LIBPATH=pjoin(env['prefix'], 'Library', 'lib'))
+
+    env.Append(CPPDEFINES=['_USE_MATH_DEFINES'])
+
+else:
+    # Installation paths
+    vars.Add(PathVariable(
+        'libdir',
+        'installation directory for compiled library [prefix/lib]',
+        pjoin(env['prefix'], 'lib'),
+        PathVariable.PathAccept))
+    vars.Add(PathVariable(
+        'includedir',
+        'installation directory for C++ header files [prefix/include]',
+        pjoin(env['prefix'], 'include'),
+        PathVariable.PathAccept))
+    vars.Add(PathVariable(
+        'datadir',
+        'installation directory for architecture independent data [prefix/share]',
+        pjoin(env['prefix'], 'share'),
+        PathVariable.PathAccept))
+
+    env.Append(CPPPATH=[pjoin(env['prefix'], 'include')])
+    env.Append(LIBPATH=[pjoin(env['prefix'], 'lib')])
+    
+
+
 vars.Add(EnumVariable(
     'build',
     'compiler settings',
@@ -83,9 +134,13 @@ vars.Add(
 vars.Add(BoolVariable(
     'test_installed',
     'build tests using the installed library.', False))
+
 vars.Update(env)
 env.Help(MY_SCONS_HELP % vars.GenerateHelpText(env))
 
+env.PrependUnique(LIBPATH=getsyspaths('LIBRARY_PATH'))
+env.AppendUnique(CPPDEFINES='BOOST_ALL_NO_LIB')
+
 env['has_objcryst'] = None
 btags = [env['build'], platform.machine()]
 if env['profile']:  btags.append('profile')
diff --git a/src/SConscript b/src/SConscript
index fce570e..3bc82da 100644
--- a/src/SConscript
+++ b/src/SConscript
@@ -1,4 +1,5 @@
 import os
+import platform
 
 Import('env')
 
@@ -21,8 +22,6 @@ fast_linkflags = ['-s']
 
 # Specify minimum C++ standard.  Allow later standard from sconscript.local.
 # In case of multiple `-std` options the last option holds.
-env.PrependUnique(CXXFLAGS='-std=c++11', delete_existing=1)
-
 # Platform specific intricacies.
 if env['PLATFORM'] == 'darwin':
     env.AppendUnique(CXXFLAGS='-ftemplate-depth-256')
@@ -31,31 +30,39 @@ if env['PLATFORM'] == 'darwin':
     fast_linkflags[:] = []
 
 # Compiler specific options
-if icpc:
-    # options for Intel C++ compiler on hpc dev-intel07
-    env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise'])
-    env.PrependUnique(LIBS=['imf'])
-    fast_optimflags = ['-fast', '-no-ipo']
-else:
-    # g++ options
-    env.PrependUnique(CCFLAGS=['-Wall'])
-    fast_optimflags = ['-ffast-math']
-
-# Configure build variants
-if env['build'] == 'debug':
-    env.Append(CCFLAGS='-g')
-elif env['build'] == 'coverage':
-    env.CacheDir(None)
-    env.Append(CCFLAGS=['-g', '--coverage', '-O0'])
-    env.Append(LINKFLAGS='--coverage')
-elif env['build'] == 'fast':
-    env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags)
-    env.AppendUnique(CPPDEFINES={'NDEBUG' : None})
-    env.AppendUnique(LINKFLAGS=fast_linkflags)
-
-if env['profile']:
-    env.AppendUnique(CCFLAGS='-pg')
-    env.AppendUnique(LINKFLAGS='-pg')
+if platform.system().lower() == "windows":
+    # Visual c++
+    env.PrependUnique(CCFLAGS=['/Ox', '/EHsc', '/MD', '/std:c++14', '/Wall'])
+    env.AppendUnique(CPPDEFINES={'NDEBUG': None})
+    env.AppendUnique(LINKFLAGS=['/OPT:NOREF', '/OPT:NOICF', '/WHOLEARCHIVE:diffpy.lib'])
+    # env.AppendUnique(LINKFLAGS='/EXPORT')
+else: 
+    env.PrependUnique(CXXFLAGS='-std=c++11')
+    if icpc:
+        # options for Intel C++ compiler on hpc dev-intel07
+        env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise'])
+        env.PrependUnique(LIBS=['imf'])
+        fast_optimflags = ['-fast', '-no-ipo']
+    else:
+        # g++ options
+        env.PrependUnique(CCFLAGS=['-Wall'])
+        fast_optimflags = ['-ffast-math']
+
+    # Configure build variants
+    if env['build'] == 'debug':
+        env.Append(CCFLAGS='-g')
+    elif env['build'] == 'coverage':
+        env.CacheDir(None)
+        env.Append(CCFLAGS=['-g', '--coverage', '-O0'])
+        env.Append(LINKFLAGS='--coverage')
+    elif env['build'] == 'fast':
+        env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags)
+        env.AppendUnique(CPPDEFINES={'NDEBUG' : None})
+        env.AppendUnique(LINKFLAGS=fast_linkflags)
+
+    if env['profile']:
+        env.AppendUnique(CCFLAGS='-pg')
+        env.AppendUnique(LINKFLAGS='-pg')
 
 
 # configure boost and ObjCryst libraries unless non-relevant.
@@ -117,11 +124,15 @@ if 'sdist' in COMMAND_LINE_TARGETS:
 # use new environment with extra libraries needed for libdiffpy.
 env_lib = env.Clone()
 # Setup GSL, the GNU Scientific library.
-env_lib.ParseConfig("gsl-config --cflags --libs")
 # The dladdr call in runtimepath.cpp requires the dl library.
-env_lib.AppendUnique(LIBS=['dl'])
+env_lib.AppendUnique(LIBS=['dl', 'gsl', 'gslcblas'])
+
+if platform.system().lower() == "windows":
+    # Use a static library (does not require __declspec(dllexport) all over the code)
+    libdiffpy = env_lib.StaticLibrary('diffpy', env['lib_sources'])
+else:
+    libdiffpy = env_lib.SharedLibrary('diffpy', env['lib_sources'])
 
-libdiffpy = env_lib.SharedLibrary('diffpy', env['lib_sources'])
 # Clean up .gcda and .gcno files from coverage analysis.
 env_lib.Clean(libdiffpy, Glob('diffpy/*.gc??'))
 env_lib.Clean(libdiffpy, Glob('diffpy/srreal/*.gc??'))
diff --git a/src/SConscript.configure b/src/SConscript.configure
index 0892b10..d796bb5 100644
--- a/src/SConscript.configure
+++ b/src/SConscript.configure
@@ -19,6 +19,16 @@ def CheckBoostVersion(context, version):
     context.Result(rv)
     return rv
 
+def CheckBoostSerialization(context):
+    context.Message('Checking for boost_serialization... ')
+    test_code = '''
+        #include <boost/serialization/serialization.hpp>
+        int main() { return 0; }
+    '''
+    rv = context.TryCompile(test_code, '.cpp')
+    context.Result(rv)
+    return rv
+
 # Helper functions -----------------------------------------------------------
 
 boostlibtags = ['', '-mt']
@@ -40,10 +50,12 @@ def configure_boost_library(libname):
     print('This program requires %r library' % libname)
     Exit(1)
 
+
 # Start configuration --------------------------------------------------------
 
 conf = Configure(env, custom_tests={
     'CheckBoostVersion' : CheckBoostVersion,
+    'CheckBoostSerialization': CheckBoostSerialization
     })
 
 # serialization of unordered_map requires boost 1.56.0
@@ -52,8 +64,9 @@ if not conf.CheckBoostVersion(boost_required):
     print('This software requires Boost %s or later.' % boost_required)
     Exit(1)
 
-# boost_serialization
-configure_boost_library('boost_serialization')
+if not conf.CheckBoostSerialization():
+    print('Boost.Serialization library not found!')
+    Exit(1)
 
 # ObjCryst - assume a no-objcryst fallback configuration.
 conf.env['has_objcryst'] = False
diff --git a/src/diffpy/SConscript b/src/diffpy/SConscript
index 8e3c07d..c08a605 100644
--- a/src/diffpy/SConscript
+++ b/src/diffpy/SConscript
@@ -1,4 +1,5 @@
 import os
+import platform
 
 Import('env', 'GlobSources')
 
@@ -7,6 +8,9 @@ env['lib_sources'] += [f for f in GlobSources('*.cpp')
         if str(f) != 'runtimepath.cpp']
 
 rtrp = os.path.relpath(env['runtimepath'], env['libdir'])
+if platform.system().lower() == 'windows':
+        rtrp = rtrp.replace('\\', '/')
+
 env_rt = env.Clone()
 env_rt.AppendUnique(CPPDEFINES=dict(DIFFPYRUNTIMERELPATH=rtrp))
 rtso = env_rt.SharedObject('runtimepath', 'runtimepath.cpp')
diff --git a/src/diffpy/boost_throw_exception.cpp b/src/diffpy/boost_throw_exception.cpp
new file mode 100644
index 0000000..96f9fcf
--- /dev/null
+++ b/src/diffpy/boost_throw_exception.cpp
@@ -0,0 +1,10 @@
+#include <stdexcept>
+#include <boost/throw_exception.hpp>
+
+namespace boost {
+    void throw_exception(std::exception const & e)
+    {
+        // You can also customize the behavior here if needed.
+        throw e;
+    }
+}
diff --git a/src/diffpy/mathutils.ipp b/src/diffpy/mathutils.ipp
index acf4d24..2c60d83 100644
--- a/src/diffpy/mathutils.ipp
+++ b/src/diffpy/mathutils.ipp
@@ -34,12 +34,6 @@ inline double remainder(double x, double y)
         fmod(x, y) : (fmod(x, y) + y);
 }
 
-
-inline double log2(double x)
-{
-    return log(x) / log(2.0);
-}
-
 #endif  // _MSC_VER
 
 namespace diffpy {
diff --git a/src/diffpy/runtimepath.cpp b/src/diffpy/runtimepath.cpp
index 0957e74..0f7299e 100644
--- a/src/diffpy/runtimepath.cpp
+++ b/src/diffpy/runtimepath.cpp
@@ -23,8 +23,57 @@
 #include <sstream>
 #include <stdexcept>
 #include <sys/stat.h>
-#include <dlfcn.h>
+#include <dlfcn.h> // not available on Windows, conda install dlfcn-win32
+
+// libgen.h is not available on Windows
+#ifdef _WIN32
+#include <string>
+#include <algorithm>
+
+// A simple replacement for dirname() on Windows.
+inline std::string win_dirname(const std::string& path)
+{
+    // Find the last occurrence of either '\' or '/'
+    size_t pos = path.find_last_of("\\/");
+    if (pos == std::string::npos)
+        return ".";  // No directory found, return current directory
+    return path.substr(0, pos);
+}
+
+// Overload to match the expected C-style interface if needed:
+inline char* dirname(char* path)
+{
+    static std::string dir;
+    dir = win_dirname(std::string(path));
+    return const_cast<char*>(dir.c_str());
+}
+#else
 #include <libgen.h>
+#endif
+
+// S_ISDIR, PATH_MAX, realpath, etc.
+#ifdef _WIN32
+#include <windows.h>
+#include <stdlib.h>    // for _fullpath
+#include <sys/stat.h>  // for _stat
+#include <direct.h>    // for _getcwd, etc.
+
+// Define S_ISDIR using the Windows _S_IFDIR flag from sys/stat.h.
+#ifndef S_ISDIR
+#define S_ISDIR(mode) (((mode) & _S_IFDIR) == _S_IFDIR)
+#endif
+
+// Use MAX_PATH from <windows.h> as PATH_MAX if not defined.
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+
+// Define realpath in terms of _fullpath.
+// _fullpath returns a pointer to the resolved path in the buffer you provide.
+// The usage should be nearly equivalent.
+#define realpath(N, R) _fullpath((R), (N), PATH_MAX)
+#endif
+
 
 #include <diffpy/version.hpp>
 #include <diffpy/runtimepath.hpp>
diff --git a/src/diffpy/srreal/StructureAdapter.hpp b/src/diffpy/srreal/StructureAdapter.hpp
index 1ff4218..7ebe5e7 100644
--- a/src/diffpy/srreal/StructureAdapter.hpp
+++ b/src/diffpy/srreal/StructureAdapter.hpp
@@ -32,6 +32,12 @@
 #include <diffpy/srreal/R3linalg.hpp>
 #include <diffpy/srreal/BaseBondGenerator.hpp>
 
+#ifdef _MSC_VER
+  #define DEPRECATED __declspec(deprecated)
+#else
+  #define DEPRECATED __attribute__((deprecated))
+#endif
+
 namespace diffpy {
 namespace srreal {
 
@@ -89,9 +95,7 @@ class StructureAdapter :
 
         /// this method allows custom special configuration for a concrete
         /// pair of StructureAdapter and PairQuantity objects.
-        virtual void customPQConfig(PairQuantity* pq) const
-            __attribute__ ((deprecated))
-        { }
+        virtual DEPRECATED void customPQConfig(PairQuantity* pq) const { }
 
         /// Return difference from the other StructureAdapter
         virtual StructureDifference diff(StructureAdapterConstPtr) const;