-
Notifications
You must be signed in to change notification settings - Fork 5
/
build-env.py
224 lines (170 loc) · 6.74 KB
/
build-env.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
EnsureSConsVersion(1,2)
import os
import inspect
import platform
def get_cuda_paths():
"""Determines CUDA {bin,lib,include} paths
returns (bin_path,lib_path,inc_path)
"""
# determine defaults
if os.name == 'nt':
bin_path = 'C:/CUDA/bin'
lib_path = 'C:/CUDA/lib'
inc_path = 'C:/CUDA/include'
elif os.name == 'posix':
bin_path = '/usr/local/cuda/bin'
lib_path = '/usr/local/cuda/lib'
inc_path = '/usr/local/cuda/include'
else:
raise ValueError, 'Error: unknown OS. Where is nvcc installed?'
if platform.platform()[:6] != 'Darwin' and \
platform.machine()[-2:] == '64':
lib_path += '64'
# override with environement variables
if 'CUDA_BIN_PATH' in os.environ:
bin_path = os.path.abspath(os.environ['CUDA_BIN_PATH'])
if 'CUDA_LIB_PATH' in os.environ:
lib_path = os.path.abspath(os.environ['CUDA_LIB_PATH'])
if 'CUDA_INC_PATH' in os.environ:
inc_path = os.path.abspath(os.environ['CUDA_INC_PATH'])
return (bin_path,lib_path,inc_path)
def getTools():
result = []
if os.name == 'nt':
result = ['default', 'msvc']
elif os.name == 'posix':
result = ['default', 'gcc']
else:
result = ['default']
return result;
OldEnvironment = Environment;
# this dictionary maps the name of a compiler program to a dictionary mapping the name of
# a compiler switch of interest to the specific switch implementing the feature
gCompilerOptions = {
'gcc' : {'warn_all' : '-Wall', 'warn_errors' : '-Werror', 'optimization' : '-O2', 'debug' : '-g', 'exception_handling' : '', 'omp' : '-fopenmp'},
'g++' : {'warn_all' : '-Wall', 'warn_errors' : '-Werror', 'optimization' : '-O2', 'debug' : '-g', 'exception_handling' : '', 'omp' : '-fopenmp'},
'cl' : {'warn_all' : '/Wall', 'warn_errors' : '/WX', 'optimization' : '/Ox', 'debug' : ['/Zi', '-D_DEBUG', '/MTd'], 'exception_handling' : '/EHsc', 'omp' : '/openmp'}
}
# this dictionary maps the name of a linker program to a dictionary mapping the name of
# a linker switch of interest to the specific switch implementing the feature
gLinkerOptions = {
'gcc' : {'debug' : ''},
'g++' : {'debug' : ''},
'link' : {'debug' : '/debug' }
}
def getCFLAGS(mode, warn, warnings_as_errors, CC):
result = []
if mode == 'release':
# turn on optimization
result.append(gCompilerOptions[CC]['optimization'])
elif mode == 'debug':
# turn on debug mode
result.append(gCompilerOptions[CC]['debug'])
result.append('-DTHRUST_DEBUG')
if warn:
# turn on all warnings
result.append(gCompilerOptions[CC]['warn_all'])
if warnings_as_errors:
# treat warnings as errors
result.append(gCompilerOptions[CC]['warn_errors'])
# avoid problems specific to windows
if CC == 'cl':
# avoid min/max problems due to windows.h
result.append('/DNOMINMAX')
# suppress warnings due to "decorated name length exceeded"
result.append('/wd4503')
return result
def getCXXFLAGS(mode, warn, warnings_as_errors, CXX):
result = []
if mode == 'release':
# turn on optimization
result.append(gCompilerOptions[CXX]['optimization'])
elif mode == 'debug':
# turn on debug mode
result.append(gCompilerOptions[CXX]['debug'])
# enable exception handling
result.append(gCompilerOptions[CXX]['exception_handling'])
if warn:
# turn on all warnings
result.append(gCompilerOptions[CXX]['warn_all'])
if warnings_as_errors:
# treat warnings as errors
result.append(gCompilerOptions[CXX]['warn_errors'])
return result
def getNVCCFLAGS(mode, arch):
result = ['-arch=' + arch]
if platform.platform()[:6] == 'Darwin':
if platform.machine()[-2:] == '64':
result.append('-m64')
else:
result.append('-m32')
if mode == 'debug':
# turn on debug mode
# XXX make this work when we've debugged nvcc -G
#result.append('-G')
pass
return result
def getLINKFLAGS(mode, LINK):
result = []
if mode == 'debug':
# turn on debug mode
result.append(gLinkerOptions[LINK]['debug'])
return result
def Environment(*args, **keywords):
# allow the user discretion to choose the MSVC version
vars = Variables()
if os.name == 'nt':
vars.Add(EnumVariable('MSVC_VERSION', 'MS Visual C++ version', None, allowed_values=('8.0', '9.0', '10.0')))
# add a variable to handle RELEASE/DEBUG mode
vars.Add(EnumVariable('mode', 'Release versus debug mode', 'release',
allowed_values = ('release', 'debug')))
# add a variable to handle compute capability
vars.Add(EnumVariable('arch', 'Compute capability code generation', 'sm_10',
allowed_values = ('sm_10', 'sm_11', 'sm_12', 'sm_13', 'sm_20', 'sm_21', 'sm_30')))
# add a variable to handle warnings
if os.name == 'posix':
vars.Add(BoolVariable('Wall', 'Enable all compilation warnings', 1))
else:
vars.Add(BoolVariable('Wall', 'Enable all compilation warnings', 0))
# add a variable to treat warnings as errors
vars.Add(BoolVariable('Werror', 'Treat warnings as errors', 0))
# create an Environment
env = OldEnvironment(*args, tools = getTools(), variables = vars, **keywords)
# get the absolute path to the directory containing
# this source file
thisFile = inspect.getabsfile(Environment)
thisDir = os.path.dirname(thisFile)
# enable nvcc
env.Tool('nvcc', toolpath = [os.path.join(thisDir)])
# get C compiler switches
env.Append(CFLAGS = getCFLAGS(env['mode'], env['Wall'], env['Werror'], env.subst('$CC')))
# get CXX compiler switches
env.Append(CXXFLAGS = getCXXFLAGS(env['mode'], env['Wall'], env['Werror'], env.subst('$CXX')))
# get NVCC compiler switches
env.Append(NVCCFLAGS = getNVCCFLAGS(env['mode'], env['arch']))
# get linker switches
env.Append(LINKFLAGS = getLINKFLAGS(env['mode'], env.subst('$LINK')))
# get CUDA paths
(cuda_exe_path,cuda_lib_path,cuda_inc_path) = get_cuda_paths()
env.Append(LIBPATH = [cuda_lib_path])
env.Append(CPPPATH = [cuda_inc_path])
# link against the standard library
# we don't have to do this on Windows
if os.name == 'posix':
env.Append(LIBS = ['stdc++'])
# link against backend-specific runtimes
# XXX we shouldn't have to link against cudart unless we're using the
# cuda runtime, but cudafe inserts some dependencies when compiling .cu files
# XXX ideally this gets handled in nvcc.py if possible
env.Append(LIBS = ['cudart'])
# import the LD_LIBRARY_PATH so we can run commands which depend
# on shared libraries
# XXX we should probably just copy the entire environment
if os.name == 'posix':
if env['PLATFORM'] == "darwin":
env['ENV']['DYLD_LIBRARY_PATH'] = os.environ['DYLD_LIBRARY_PATH']
else:
env['ENV']['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
# generate help text
Help(vars.GenerateHelpText(env))
return env