forked from usnistgov/OOF2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
oof2-build
executable file
·276 lines (234 loc) · 9.95 KB
/
oof2-build
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
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
#!/usr/bin/env python
# This script builds the various oof2 versions used by the developers.
# It shouldn't be necessary for anyone else to use it.
# Run "oof2-build <version> to build the version named <version>.
# Valid values for version are listed in the build_types tuple below.
# Optional arguments can appear after the version name. Any arguments
# beginning with '--' will be inserted into the setup.py 'build'
# argument list.
# The stow directory name is constructed from the build version, the
# git branch name (if any) and the local directory name. This allows
# multiple built versions to coexist, even if they're on the same git
# branch. If the local directory names begins with 'OOF2', only the
# part after 'OOF2' is used.
# In addition, the 'pg' argument turns on profiling in the C++ code.
# It won't work unless you're using a python that was built with -pg.
# 'gperf' turns on the google profiling tools.
# Set the following environment variables:
# OOFINSTALL determines where the installation goes. If it's not
# defined, your home directory will be used.
# Set your PATH to include $OOFINSTALL/bin.
# Set your PYTHONPATH to include
# $OOFINSTALL/lib/python2.7/site-packages
# Change 2.7 to 2.6 (or whatever) as appropriate. You can do that like this:
# setenv PYTHONPATH {$OOFINSTALL}/lib/python`python -c 'import sys; print "%d.%d"%sys.version_info[:2]'`/site-packages
# Set your LD_LIBRARY_PATH to include $OOFINSTALL/lib. This isn't
# necessary on OS X.
def dashjoin(*args):
return '-'.join(x for x in args if x)
## TODO: The oof2 and oof3d versions of this script have diverged a
## bit... Ideally they should be identical except for the next line.
## Perhaps that line should be in a separate local config file that is
## imported here. The --3D flag and other dimension-specific data
## should be in that file too. Then we wouldn't need separate build
## targets for 2d and 3d -- running "oof2-build debug" in an oof2
## directory would build oof2, and running it in a oof3d directory
## would build oof3d.
oofname = "oof2"
import sys, string, os, subprocess, glob
pyversion = string.join(map(str, sys.version_info[:2]),".")
# Pop the first two arguments, which are the program name and the
# build type.
# Is this oof2-build or oof2-clean?
progname = sys.argv.pop(0)
cleaning = "clean" in progname
# First argument must be a build type:
# dist
# devel (must be followed by an integer devel level)
# debug
build_types = ('dist', 'devel', 'debug', 'profile')
if len(sys.argv) < 1:
print "You must provide a build type"
sys.exit()
build_type = sys.argv.pop(0)
if build_type not in build_types:
print "Unrecognized build type:", build_type
sys.exit()
# To make it possible to build OOF2 on different git branches, the
# output for the branches needs to go into distinct directories. We
# derive the directory names from the git branch name.
proc = subprocess.Popen(['git', 'symbolic-ref', '--short', 'HEAD'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutdata, stderrdata = proc.communicate()
if stderrdata:
print "*** Failed to get git branch name!", stderrdata.strip()
branchtag = ""
else:
branchtag = stdoutdata.strip()
# To make it possible to build different versions of the *same* branch
# of OOF2 (for example, one that is up-to-date with git and one that
# is locally modified), the stow directory name also includes the name
# of the local directory'.
localdir = os.path.split(os.getcwd())[1]
if localdir.startswith(oofname) or localdir.startswith(oofname.upper()):
localdir = localdir[len(oofname):]
build_args = []
mp = ""
# Use GCC to build OOF on both Linux and OS X.
# The main reason of doing this is because gcc supports OpenMP while
# clang has not supported yet.
# TODO: If clang starts to supports OpenMP in the future, the
# following two lines can be deleted.
# Uncomment the following lines to use gcc
#os.environ["CC"] = "gcc-mp-4.9"
#os.environ["CXX"] = "g++-mp-4.9"
if build_type == 'devel':
## TODO: Calling argv.pop here is ugly. We're assuming that no
## arguments other than the build type will be processed before
## this point. We really should do proper argument processing,
## parse them all with getopt, and make the build type a normal
## argument. (eg, oof2-build --debug, oof2-build --dist,
## oof2-build --devel=2, etc.)
build_args.append("--enable-devel="+sys.argv.pop(0))
elif build_type == 'debug':
build_args.append("--debug")
elif build_type == 'profile':
build_args.append("--debug")
os.putenv('CFLAGS', '-g -fno-inline')
build_args.append("--debug")
if sys.platform[:6] == 'netbsd':
build_args.append('--library-dirs=/usr/pkg/lib')
while sys.argv:
arg = sys.argv.pop(0)
if arg.startswith("--"):
build_args.append(arg)
if arg=='--enable-openmp': # ugly, but not worth doing right
mp = True
elif arg == 'seg':
build_args.append('--enable-segmentation')
elif arg == 'mp':
build_args.append('--enable-openmp')
mp = "mp"
elif arg == 'pg':
os.putenv('CFLAGS', '-pg')
elif arg == 'efence':
build_args.append('--library-dirs=/opt/local/lib')
build_args.append('--libraries=efence')
elif arg == 'gperf':
# Google performance tools (profiler)
# os.putenv('CFLAGS', '-I/users/lnz5/loc/include')
# TODO: Why use putenv?
os.putenv('LDFLAGS', '-lprofiler')
#build_args.append('--libraries=profiler')
# Are we using x11 or cocoa?
cocoa = ""
if sys.platform == 'darwin':
# Cocoa mode is controlled by which versions of the dependencies
# are currently installed by MacPorts, and isn't explicitly
# referenced in the build process. But since it's necessary to
# rebuild oof2 when switching between x11 and cocoa modes, it's
# convenient to keep the builds separate.
proc = subprocess.Popen(['port', 'installed', 'py27-pygtk'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
stdoutdata, stderrdata = proc.communicate()
if proc.returncode != 0:
print "oof2-build: couldn't find py27-pygtk variant, assuming x11"
print " ", stderrdata
else:
if "quartz" in stdoutdata:
cocoa = "cocoa" # will be in stowdir and builddir names
# Where to put everything?
installdir = os.getenv("OOFINSTALL")
if not installdir:
installdir = os.getenv("HOME")
stowdir = os.path.join(installdir, 'stow')
builddir = dashjoin("builddir", branchtag, cocoa, build_type, mp)
stowsubdir = dashjoin(
"oof2", branchtag, localdir, cocoa, build_type, pyversion, mp)
laststowfile = os.path.join(stowdir, '.last_oof_install')
try:
lsf = file(laststowfile, "r")
laststow = lsf.readline().rstrip()
lsf.close()
except IOError:
laststow = None
startdir = os.getcwd()
if not cleaning:
# Move builddir to build
try:
print "oof2-build: Using build directory", builddir
os.rename(builddir, 'build')
except OSError:
print "Directory %s not found, creating new build directory." % builddir
os.mkdir('build')
# On OS X, prevent the build directory from being backed up. This
# attribute is attached to the directory, not its path, and sticks
# to it when the directory is moved.
if sys.platform == 'darwin':
subprocess.check_call(['tmutil', 'addexclusion',
os.path.abspath('build')])
try:
# Hack. Remove the oof2 or oof3d script from the build/script*
# directory, if it exists. setup.py will rebuild it trivally if
# it's missing. It has to be rebuilt if the python version has
# changed, but the setup.py script won't notice that.
fnames = glob.glob(os.path.join('build', 'script*', oofname))
if len(fnames) > 1:
print "Expected to find one script named", oofname, "but found",\
len(fnames), "!"
sys.exit()
elif len(fnames) == 1:
print "Removing", fnames[0]
os.remove(fnames[0])
build_cmd = "python setup.py build %s install --prefix=%s" \
% (string.join(build_args),
os.path.join(stowdir, stowsubdir))
print build_cmd
result = os.system(build_cmd)
if not result: # successful
os.chdir(stowdir)
if not laststow:
print "Stowing", stowsubdir
stowcmd = "stow " + stowsubdir
os.system(stowcmd)
lsf = file(laststowfile, "w")
print >> lsf, stowsubdir
lsf.close()
elif laststow != stowsubdir:
print "Unstowing", laststow, "and stowing", stowsubdir
unstowcmd = "stow -D " + laststow
os.system(unstowcmd)
stowcmd = "stow " + stowsubdir
os.system(stowcmd)
lsf = file(laststowfile, "w")
print >> lsf, stowsubdir
lsf.close()
else:
print "Restowing", stowsubdir
stowcmd = "stow -R " + stowsubdir
os.system(stowcmd)
finally:
os.chdir(startdir)
os.rename('build', builddir)
else:
# Cleaning
# Clean out the stow directory
os.chdir(stowdir)
try:
if laststow == stowsubdir:
print "Unstowing", stowsubdir, "from", stowdir
os.system('stow -D %s' % stowsubdir)
os.remove(laststowfile)
print "Emptying", os.path.join(stowdir, stowsubdir)
os.system('rm -rf %s' % stowsubdir)
finally:
os.chdir(startdir)
os.rename(builddir, 'build')
os.system('python setup.py clean --most --swig')
if os.path.exists('build'):
os.rename('build', builddir)
else:
os.mkdir(builddir)
if sys.platform == 'darwin':
subprocess.check_call(['tmutil', 'addexclusion',
os.path.abspath(builddir)])