Skip to content

Commit 4192120

Browse files
authored
Merge pull request #36 from Tieqiong/windows
fix: add windows support
2 parents b2b8d90 + 28c0622 commit 4192120

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+475
-218
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,10 @@ tags
3030

3131
# source distribution tarball
3232
libdiffpy-*.tar.gz
33+
34+
35+
.vs/*
36+
.exp
37+
.lib
38+
.dll
39+
.vscode/*

SConstruct

Lines changed: 50 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ SCons construction environment can be customized in sconscript.local script.
2121
"""
2222

2323
import os
24-
import platform
24+
from os.path import join as pjoin
25+
from SCons.Script import *
2526

2627
def subdictionary(d, keyset):
2728
return dict(kv for kv in d.items() if kv[0] in keyset)
@@ -37,40 +38,71 @@ DefaultEnvironment(ENV=subdictionary(os.environ, '''
3738
# Create construction environment
3839
env = DefaultEnvironment().Clone()
3940

40-
# Variables definitions below work only with 0.98.1 or later.
41+
# Variables definitions below work only with 0.98.1 or later
4142
env.EnsureSConsVersion(0, 98, 1)
4243

4344
# Customizable compile variables
4445
vars = Variables('sconsvars.py')
4546

46-
vars.Add(PathVariable(
47-
'prefix',
48-
'installation prefix directory',
49-
'/usr/local'))
50-
vars.Update(env)
47+
# Set PATHs
48+
if 'PREFIX' in os.environ:
49+
vars.Add(PathVariable(
50+
'prefix',
51+
'installation prefix directory',
52+
os.environ['prefix']))
53+
vars.Update(env)
54+
elif 'CONDA_PREFIX' in os.environ:
55+
vars.Add(PathVariable(
56+
'prefix',
57+
'installation prefix directory',
58+
os.environ['CONDA_PREFIX']))
59+
vars.Update(env)
60+
else:
61+
vars.Add(PathVariable(
62+
'prefix',
63+
'installation prefix directory',
64+
'/usr/local'))
65+
vars.Update(env)
66+
67+
if env['PLATFORM'] == "win32":
68+
include_path = pjoin(env['prefix'], 'Library', 'include')
69+
lib_path = pjoin(env['prefix'], 'Library', 'lib')
70+
shared_path = pjoin(env['prefix'], 'Library', 'share')
71+
72+
env['ENV']['TMP'] = os.environ['TMP']
73+
else:
74+
include_path = pjoin(env['prefix'], 'include')
75+
lib_path = pjoin(env['prefix'], 'lib')
76+
shared_path = pjoin(env['prefix'], 'share')
77+
5178
vars.Add(PathVariable(
5279
'libdir',
53-
'installation directory for compiled library [prefix/lib]',
54-
env['prefix'] + '/lib',
80+
'installation directory for compiled programs',
81+
lib_path,
5582
PathVariable.PathAccept))
5683
vars.Add(PathVariable(
5784
'includedir',
58-
'installation directory for C++ header files [prefix/include]',
59-
env['prefix'] + '/include',
85+
'installation directory for C++ header files',
86+
include_path,
6087
PathVariable.PathAccept))
6188
vars.Add(PathVariable(
6289
'datadir',
63-
'installation directory for architecture independent data [prefix/share]',
64-
env['prefix'] + '/share',
90+
'installation directory for architecture independent data',
91+
shared_path,
6592
PathVariable.PathAccept))
93+
94+
env.AppendUnique(CPPPATH=[include_path])
95+
env.AppendUnique(LIBPATH=[lib_path])
96+
97+
# Customizable build variables
6698
vars.Add(EnumVariable(
6799
'build',
68100
'compiler settings',
69101
'fast', allowed_values=('fast', 'debug', 'coverage')))
70102
vars.Add(EnumVariable(
71103
'tool',
72104
'C++ compiler toolkit to be used',
73-
'default', allowed_values=('default', 'intelc')))
105+
'default', allowed_values=('default', 'clang', 'gcc', 'intelc')))
74106
vars.Add(BoolVariable(
75107
'enable_objcryst',
76108
'enable objcryst support, when installed', None))
@@ -83,11 +115,14 @@ vars.Add(
83115
vars.Add(BoolVariable(
84116
'test_installed',
85117
'build tests using the installed library.', False))
118+
86119
vars.Update(env)
120+
87121
env.Help(MY_SCONS_HELP % vars.GenerateHelpText(env))
88122

89123
env['has_objcryst'] = None
90-
btags = [env['build'], platform.machine()]
124+
125+
btags = [env['build'], env['PLATFORM']]
91126
if env['profile']: btags.append('profile')
92127
builddir = env.Dir('build/' + '-'.join(btags))
93128

src/SConscript

Lines changed: 111 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,104 @@
11
import os
2+
from SCons.Script import *
3+
from os.path import join as pjoin
24

35
Import('env')
46

57
# Build environment configuration --------------------------------------------
68

7-
# Insert LIBRARY_PATH explicitly because some compilers
8-
# ignore it in the system environment.
9-
env.PrependUnique(LIBPATH=env['ENV'].get('LIBRARY_PATH', '').split(':'))
10-
11-
# Use Intel C++ compiler if requested by the user.
12-
icpc = None
9+
# Use C++ compiler specified by the 'tool' option.
10+
# Intel C++ compiler
1311
if env['tool'] == 'intelc':
1412
icpc = env.WhereIs('icpc')
1513
if not icpc:
1614
print("Cannot find the Intel C/C++ compiler 'icpc'.")
1715
Exit(1)
1816
env.Tool('intelc', topdir=icpc[:icpc.rfind('/bin')])
17+
env=env.Clone()
1918

20-
fast_linkflags = ['-s']
19+
# Clang++ compiler
20+
if env['tool'] == 'clang':
21+
llvm = env.WhereIs('clang++')
22+
if not llvm:
23+
print("Cannot find the clang++ compiler.")
24+
Exit(1)
25+
env=env.Clone(tools=['clangxx'])
2126

22-
# Specify minimum C++ standard. Allow later standard from sconscript.local.
23-
# In case of multiple `-std` options the last option holds.
24-
env.PrependUnique(CXXFLAGS='-std=c++11', delete_existing=1)
27+
# g++ compiler
28+
if env['tool'] == 'gcc':
29+
gcc = env.WhereIs('g++')
30+
if not gcc:
31+
print("Cannot find the g++ compiler.")
32+
Exit(1)
33+
env=env.Clone(tools=['mingw'])
34+
35+
# Default use scons auto found compiler
2536

2637
# Platform specific intricacies.
38+
fast_linkflags = ['-s']
39+
40+
# macOS specific options
2741
if env['PLATFORM'] == 'darwin':
2842
env.AppendUnique(CXXFLAGS='-ftemplate-depth-256')
29-
env.Append(SHLINKFLAGS=['-install_name', '$TARGET.abspath'])
43+
env.AppendUnique(SHLINKFLAGS=['-install_name', '$TARGET.abspath'])
3044
env.AppendUnique(SHLINKFLAGS='-headerpad_max_install_names')
3145
fast_linkflags[:] = []
3246

3347
# Compiler specific options
34-
if icpc:
35-
# options for Intel C++ compiler on hpc dev-intel07
36-
env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise'])
37-
env.PrependUnique(LIBS=['imf'])
38-
fast_optimflags = ['-fast', '-no-ipo']
39-
else:
40-
# g++ options
41-
env.PrependUnique(CCFLAGS=['-Wall'])
42-
fast_optimflags = ['-ffast-math']
43-
44-
# Configure build variants
45-
if env['build'] == 'debug':
46-
env.Append(CCFLAGS='-g')
47-
elif env['build'] == 'coverage':
48-
env.CacheDir(None)
49-
env.Append(CCFLAGS=['-g', '--coverage', '-O0'])
50-
env.Append(LINKFLAGS='--coverage')
51-
elif env['build'] == 'fast':
52-
env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags)
53-
env.AppendUnique(CPPDEFINES={'NDEBUG' : None})
54-
env.AppendUnique(LINKFLAGS=fast_linkflags)
55-
56-
if env['profile']:
57-
env.AppendUnique(CCFLAGS='-pg')
58-
env.AppendUnique(LINKFLAGS='-pg')
48+
if env['PLATFORM'] == "win32":
49+
if env['tool'] == 'clang':
50+
# clang++ on Windows
51+
env['CC'] = 'clang'
52+
env['CCFLAGS'] = ['-O3', '-ffast-math', '-std=c++14', '-m64', '-DBUILD_DLL']
53+
env.PrependUnique(CPPDEFINES='_USE_MATH_DEFINES')
54+
env['LINKFLAGS']= ['-fuse-ld=lld-link', '-m64', '-lstdc++']
55+
56+
elif env['tool'] == 'gcc':
57+
# MinGW
58+
env.PrependUnique(CCFLAGS=['-O3', '-std=c++14', '-m64', '-DBUILD_DLL'])
59+
env.PrependUnique(CPPDEFINES='_USE_MATH_DEFINES')
60+
env.AppendUnique(LINKFLAGS='-m64')
61+
62+
else:
63+
# Visual c++
64+
env.PrependUnique(CCFLAGS=['/Ox', '/EHsc', '/MD', '/std:c++14', '/Wall', '/DBUILD_DLL'])
65+
env.AppendUnique(CPPDEFINES=[{'NDEBUG': None}, '_USE_MATH_DEFINES'])
66+
env.AppendUnique(LINKFLAGS=['/OPT:NOREF', '/OPT:NOICF'])
67+
68+
else:
69+
env.PrependUnique(CXXFLAGS='-std=c++11')
70+
if env['tool'] == 'intelc':
71+
# options for Intel C++ compiler on hpc dev-intel07
72+
env.PrependUnique(CCFLAGS=['-w1', '-fp-model', 'precise'])
73+
env.PrependUnique(LIBS=['imf'])
74+
fast_optimflags = ['-fast', '-no-ipo']
75+
else:
76+
# g++ options
77+
env.PrependUnique(CCFLAGS=['-Wall'])
78+
fast_optimflags = ['-ffast-math']
79+
80+
# Configure build variants
81+
if env['build'] == 'debug':
82+
env.Append(CCFLAGS='-g')
83+
elif env['build'] == 'coverage':
84+
env.CacheDir(None)
85+
env.Append(CCFLAGS=['-g', '--coverage', '-O0'])
86+
env.Append(LINKFLAGS='--coverage')
87+
elif env['build'] == 'fast':
88+
env.AppendUnique(CCFLAGS=['-O3'] + fast_optimflags)
89+
env.AppendUnique(CPPDEFINES={'NDEBUG' : None})
90+
env.AppendUnique(LINKFLAGS=fast_linkflags)
91+
92+
if env['profile']:
93+
env.AppendUnique(CCFLAGS='-pg')
94+
env.AppendUnique(LINKFLAGS='-pg')
5995

6096

6197
# configure boost and ObjCryst libraries unless non-relevant.
6298
skip_configure = (GetOption('clean') or GetOption('help') or
6399
(['sdist'] == list(COMMAND_LINE_TARGETS)))
100+
101+
# Check dependencies
64102
if not skip_configure:
65103
SConscript('SConscript.configure')
66104

@@ -117,11 +155,15 @@ if 'sdist' in COMMAND_LINE_TARGETS:
117155
# use new environment with extra libraries needed for libdiffpy.
118156
env_lib = env.Clone()
119157
# Setup GSL, the GNU Scientific library.
120-
env_lib.ParseConfig("gsl-config --cflags --libs")
121-
# The dladdr call in runtimepath.cpp requires the dl library.
122-
env_lib.AppendUnique(LIBS=['dl'])
158+
# The dladdr call in runtimepath.cpp requires the dl library for Windows.
159+
if env['has_objcryst'] == True:
160+
env_lib.AppendUnique(LIBS=['dl', 'gsl', 'gslcblas','boost_serialization', 'libobjcryst'])
161+
else:
162+
env_lib.AppendUnique(LIBS=['dl', 'gsl', 'gslcblas','boost_serialization'])
163+
123164

124165
libdiffpy = env_lib.SharedLibrary('diffpy', env['lib_sources'])
166+
125167
# Clean up .gcda and .gcno files from coverage analysis.
126168
env_lib.Clean(libdiffpy, Glob('diffpy/*.gc??'))
127169
env_lib.Clean(libdiffpy, Glob('diffpy/srreal/*.gc??'))
@@ -141,17 +183,36 @@ if targets_that_test.intersection(COMMAND_LINE_TARGETS):
141183
prefix = env['prefix']
142184

143185
# install-lib
144-
install_lib = env.Install(env['libdir'], libdiffpy)
145-
if env['PLATFORM'] == 'darwin':
146-
# DARWIN_INSTALL_NAME can be pre-set in sconscript.local
147-
env.SetDefault(DARWIN_INSTALL_NAME='$TARGET.abspath')
148-
env.AddPostAction(install_lib,
149-
'install_name_tool -id $DARWIN_INSTALL_NAME $TARGET')
150-
if env['PLATFORM'] == 'posix' and WhereIs('ldconfig'):
151-
opts = '' if os.getuid() == 0 else '-n'
152-
env.AddPostAction(install_lib,
153-
'ldconfig %s $TARGET.dir' % opts)
154-
Alias('install-lib', install_lib)
186+
if env['PLATFORM'] in ['darwin', 'posix']:
187+
install_lib = env.Install(env['libdir'], libdiffpy)
188+
if env['PLATFORM'] == 'darwin':
189+
# DARWIN_INSTALL_NAME can be pre-set in sconscript.local
190+
env.SetDefault(DARWIN_INSTALL_NAME='$TARGET.abspath')
191+
env.AddPostAction(install_lib,
192+
'install_name_tool -id $DARWIN_INSTALL_NAME $TARGET')
193+
if env['PLATFORM'] == 'posix' and WhereIs('ldconfig'):
194+
opts = '' if os.getuid() == 0 else '-n'
195+
env.AddPostAction(install_lib,
196+
'ldconfig %s $TARGET.dir' % opts)
197+
Alias('install-lib', install_lib)
198+
199+
if env['PLATFORM'] == 'win32':
200+
bindir = pjoin(prefix, 'Library', 'bin')
201+
for node in libdiffpy:
202+
ext = os.path.splitext(str(node))[1].lower()
203+
if ext == '.dll':
204+
dll_node = node
205+
elif ext == '.lib':
206+
lib_node = node
207+
208+
if dll_node is None:
209+
print("Warning: DLL file not found in build outputs.")
210+
if lib_node is None:
211+
print("Warning: LIB file not found in build outputs.")
212+
213+
install_dll = env.Install(bindir, dll_node)
214+
install_lib = env.Install(env['libdir'], lib_node)
215+
Alias('install-lib', [install_dll, install_lib])
155216

156217
# install-include
157218
ninc = len(Dir('.').path) + 1

0 commit comments

Comments
 (0)