~njansson/dolfin/hpc

2359 by Johannes Ring
The BIG commit!
1
# -*- coding: utf-8 -*-
2
3
import os, os.path, sys
4
from distutils import sysconfig
5
6
# Make sure that we have a good scons-version
7
EnsureSConsVersion(0, 96)
8
2361 by johannr@communalis.simula.no
Changed SConstruct to use scons/simula-scons if simula-scons is not found on the system.
9
# Import the local 'scons'
10
try:
11
  import simula_scons as scons
12
except ImportError:
13
  # Add simula-scons to sys.path and PYTHONPATH
14
  os.environ["PYTHONPATH"] = \
15
      os.pathsep.join([os.environ.get("PYTHONPATH",""),
16
                       os.path.join(os.getcwd(),"scons","simula-scons")])
17
  sys.path.insert(0, os.path.join(os.getcwd(),"scons","simula-scons"))
18
  import simula_scons as scons
19
 
2359 by Johannes Ring
The BIG commit!
20
# Import local exceptions
21
from simula_scons.Errors import PkgconfigError, PkgconfigMissing
22
23
# Create a SCons Environment based on the main os environment
24
env = Environment(ENV=os.environ)
25
26
# Set a projectname. Used in some places, like pkg-config generator
27
env["projectname"] = "dolfin"
28
2367 by Asmund Odegard
Writing info about the used simula-scons in log
29
scons.setDefaultEnv(env)
30
2359 by Johannes Ring
The BIG commit!
31
# Specify a file where SCons store file signatures, used to figure out what is
32
# changed. We store it in the 'scons' subdirectory to avoid mixing signatures
33
# with the files in dolfin. 
34
dolfin_sconsignfile = os.path.join(os.getcwd(), "scons", ".sconsign")
35
env.SConsignFile(dolfin_sconsignfile)
36
37
# -----------------------------------------------------------------------------
38
# Command line option handling
39
# -----------------------------------------------------------------------------
40
41
DefaultPackages = ""
42
43
# Build the commandline options for SCons:
44
options = [
45
    # configurable options for installation:
46
    scons.PathOption("prefix", "Installation prefix", "/usr/local"),
47
    scons.PathOption("libDir", "Library installation directory", "$prefix/lib"),
48
    scons.PathOption("includeDir", "C/C++ header installation directory", "$prefix/include"),
49
    scons.PathOption("pythonModuleDir", "Python module installation directory", 
50
                     scons.defaultPythonLib(prefix="$prefix")),
51
    scons.PathOption("pythonExtDir", "Python extension module installation directory", 
52
                     scons.defaultPythonLib(prefix="$prefix", plat_specific=True)),
53
    # configurable options for how we want to build:
54
    BoolOption("enableDebug", "Build with debug information", 1),
55
    BoolOption("enableDebugUblas", "Add some extra Ublas debug information", 0),
56
    BoolOption("enableOptimize", "Compile with optimization", 0),
57
    BoolOption("enableDocs", "Build documentation", 0),
58
    BoolOption("enableDemos", "Build demos", 0),
59
    # Enable or disable external packages.
60
    # These will also be listed in scons.cfg files, but if they are 
61
    # disabled here, that will override scons.cfg. Remark that unless the
62
    # module is listed as OptDependencies in scons.cfg, the whole module
63
    # will be turned off.
2368 by Johannes Ring
All packages are now enabled by default (no need for, e.g.,
64
    BoolOption("enablePetsc", "Compile with support for PETSc linear algebra", "yes"),
65
    BoolOption("enableSlepc", "Compile with support for SLEPc", "yes"),
66
    BoolOption("enableScotch", "Compile with support for Scotch", "yes"),
67
    BoolOption("enableGts", "Compile with support for GTS", "yes"),
68
    BoolOption("enableUmfpack", "Compile with support for UMFPACK", "yes"),
2359 by Johannes Ring
The BIG commit!
69
    BoolOption("enablePydolfin", "Compile the python wrappers of Dolfin", "yes"),
70
    # some of the above may need extra options (like petscDir), should we
71
    # try to get that from pkg-config?
72
    #
73
    # a few more options originally from PyCC:
74
    #BoolOption("autoFetch", "Automatically fetch datafiles from (password protected) SSH repository", 0),
75
    BoolOption("cacheOptions", "Cache command-line options for later invocations", 1),
76
    BoolOption("veryClean", "Remove the sconsign file during clean, must be set during regular build", 0),
77
    # maybe we should do this more cleverly. The default in dolfin now is
78
    # to use mpicxx if that is available...:
79
    ("CXX", "Set C++ compiler",scons.defaultCxxCompiler()),
80
    #("FORTRAN", "Set FORTRAN compiler",scons.defaultFortranCompiler()),
81
    ("customCxxFlags", "Customize compilation of C++ code", ""),
82
    #("data", "Parameter to the 'fetch' target: comma-delimited list of directories/files to fetch, \
83
    #        relative to the `data' directory. An empty value means that everything will be fetched.", ""),
84
    #("sshUser", "Specify the user for the SSH connection used to retrieve data files", ""),
85
    #('usePackages','Override or add dependency packages, separate with comma', ""),
86
    #('customDefaultPackages','Override the default set of packages (%r), separate package names with commas' % (DefaultPackages,)),
87
    ("SSLOG", "Set Simula scons log file", os.path.join(os.getcwd(),"scons","simula_scons.log")),
88
    ]
89
2367 by Asmund Odegard
Writing info about the used simula-scons in log
90
2359 by Johannes Ring
The BIG commit!
91
# This Configure class handles both command-line options (which are merged into 
92
# the environment) and autoconf-style tests. A special feature is that it
93
# remembers configuration parameters (options and results from tests) between
94
# invocations so that they are re-used when cleaning after a previous build.
95
configure = scons.Configure(env, ARGUMENTS, options)
96
97
# Open log file for writing
98
scons.logOpen(env)
99
scons.log("=================== %s log ===================" % env["projectname"])
100
scons.logDate()
101
2367 by Asmund Odegard
Writing info about the used simula-scons in log
102
# Writing the simula_scons used to the log:
103
scons.log("Using simula_scons from: %s" % scons.__file__)
104
105
2359 by Johannes Ring
The BIG commit!
106
# If we are in very-clean mode, remove the sconsign file. 
107
if env.GetOption("clean"):
108
  if env["veryClean"]:
109
    os.unlink("%s.dblite" % (dolfin_sconsignfile))
110
    # FIXME: should we also remove the file scons/options.cache?
111
    
112
# Default CXX and FORTRAN flags
113
env["CXXFLAGS"] = "-Wall -pipe -ansi" # -Werror"
114
#env["SHFORTRANFLAGS"] = "-Wall -pipe -fPIC"
115
116
# If Debug is enabled, add -g:
117
if env["enableDebugUblas"]:
118
  env.Append(CXXFLAGS=" -DDEBUG -g -Werror")
119
elif env["enableDebug"]:
120
  env.Append(CXXFLAGS=" -DDEBUG -g -Werror -DNDEBUG")
121
122
# if Optimization is requested, use -O3
123
if env["enableOptimize"]:
124
  env.Append(CXXFLAGS=" -O3")
125
else:
126
  env.Append(CXXFLAGS=" -O2")
127
128
# Not sure we need this - but lets leave it for completeness sake - if people
129
# use if for PyCC, and know that dolfin use the same system, they will expect
130
# it to be here. We should probably discuss whether that is a good argument or
131
# not. 
132
# Append whatever custom flags given
133
if env["customCxxFlags"]:
134
  env.Append(CXXFLAGS=" " + env["customCxxFlags"])
135
136
# process list of packages to be included in allowed Dependencies.
137
# Do we need this any more? I think we rather pick up (external) packages from
138
# the scons.cfg files. Actually, I doubt usePackages is ever used?
139
#env["usePackages"] = scons.resolvePackages(env["usePackages"].split(','),\
140
#        env.get("customDefaultPackages", DefaultPackages).split(","))
141
142
# Figure out if we should fetch datafiles, and set an option in env. 
143
#doFetch = "fetch" in COMMAND_LINE_TARGETS or (env["autoFetch"]) and not env.GetOption("clean")
144
#env["doFetch"] = doFetch
145
146
# -----------------------------------------------------------------------------
147
# Call the main SConscript in the 'src' directory
148
# -----------------------------------------------------------------------------
149
try:
150
  # Invoke the SConscript as if it was situated in the build directory, this
151
  # tells SCons to build beneath this
152
  buildDataHash = env.SConscript(os.path.join("dolfin", "SConscript"), exports=["env", "configure"])
153
except PkgconfigError, err:
154
  sys.stderr.write("%s\n" % err)
155
  Exit(1)
156
157
# -----------------------------------------------------------------------------
158
# Set up build targets
159
# -----------------------------------------------------------------------------
160
161
# default build-targets: shared libs, extension modules, programs, demos, and
162
# documentation.
163
for n in buildDataHash["shlibs"] + buildDataHash["extModules"] + \
164
        buildDataHash["progs"] + buildDataHash["demos"], buildDataHash["docs"]:
165
  env.Default(n)
166
167
# -----------------------------------------------------------------------------
168
# Set up installation targets
169
# -----------------------------------------------------------------------------
170
171
# shared libraries goes into our libDir:
172
for l in buildDataHash["shlibs"]:
173
  env.Install(env["libDir"], l)
174
175
# install header files in the same structure as in the source tree, within
176
# includeDir/dolfin:
177
for h in buildDataHash["headers"]:
178
  # Get the module path relative to the "src" directory
179
  dpath = os.path.dirname(h.srcnode().path).split(os.path.sep, 1)[1]
180
  env.Install(os.path.join(env["includeDir"], "dolfin", dpath), h)
181
# Also, we want the special 'dolfin.h' file to be installed directly in the
182
# toplevel includeDir. 
183
if buildDataHash.has_key("main_header") and buildDataHash["main_header"] != "":
184
  env.Install(env["includeDir"], buildDataHash["main_header"])
185
186
## install python scripts in the bin directory
187
#for s in buildDataHash["pythonScripts"]:
188
#  env.Install(env["binDir"], s)
189
190
# install python modules, usually in site-packages/dolfin
191
for m in buildDataHash["pythonModules"]:
192
  env.Install(os.path.join(env["pythonModuleDir"], "dolfin"), m)
193
194
# install extension modules, usually in site-packages
195
for e in buildDataHash["extModules"]:
196
  env.Install(os.path.join(env["pythonExtDir"], "dolfin"), e)
197
198
# install created pkg-config files in prefix/lib/pkgconfig
199
#
200
for p in buildDataHash["pkgconfig"]:
201
  env.Install(os.path.join(env["libDir"], "pkgconfig"), p)
202
203
# grab prefix from the environment, substitute all scons construction variables
204
# (those prefixed with $...), and create a normalized path:
205
prefix = os.path.normpath(env.subst(env["prefix"]))
206
# add '/' (or similar) at the end of prefix if missing:
207
if not prefix[-1] == os.path.sep:
208
  prefix += os.path.sep
209
210
# not sure we need common.py for pydolfin.
211
#commonfile=os.path.join("site-packages", "pycc", "common.py")
212
213
installfiles = scons.buildFileList(
214
    buildDataHash["pythonPackageDirs"])
215
216
for f in installfiles:
217
  #installpath=os.path.sep.join(os.path.dirname(f).split(os.path.sep)[1:])
218
  env.Install(os.path.join(env["pythonModuleDir"],"dolfin"), f)
219
220
#env = scons.installCommonFile(env, commonfile, prefix)
221
222
# No data for dolfin?
223
_targetdir=os.path.join(prefix, "share", "dolfin", "data")
224
if 'install' in COMMAND_LINE_TARGETS and not os.path.isdir(_targetdir):
225
  os.makedirs(_targetdir)
226
env = scons.addInstallTargets(env, sourcefiles=buildDataHash["data"],
227
                              targetdir=_targetdir)
228
229
## No tests to install for dolfin?
230
## Not sure tests should be installed, have to check that.
231
#_targetdir=os.path.join(prefix, "share", "pycc", "tests")
232
#if 'install' in COMMAND_LINE_TARGETS and not os.path.isdir(_targetdir):
233
#  os.makedirs(_targetdir)
234
#env = scons.addInstallTargets(env, sourcefiles=buildDataHash["tests"],
235
#                              targetdir=_targetdir)
236
237
### I am not sure there are any docs to install with dolfin.
238
_targetdir=os.path.join(prefix, "share", "doc", "dolfin")
239
if 'install' in COMMAND_LINE_TARGETS and not os.path.isdir(_targetdir):
240
  os.makedirs(_targetdir)
241
env = scons.addInstallTargets(env, sourcefiles=buildDataHash["docs"],
242
                              targetdir=_targetdir)
243
244
# Instruct scons what to do when user requests 'install'
245
env.Alias("install", [env["libDir"], env["includeDir"],
246
                      env["pythonModuleDir"], env["pythonExtDir"]])
247
248
# _runTests used to use the global 'ret' (now buildDataHash). Therefore, we
249
# need to wrap _runTests in a closure, now that the functions is moved into
250
# 'scons'
251
_runTests = scons.gen_runTests(buildDataHash)
252
253
env.Command("runtests", buildDataHash["shlibs"] + buildDataHash["extModules"],
254
            Action(_runTests, scons._strRuntests))
255
2372.1.1 by Garth N. Wells
Create dolfin.conf file like with old build system.
256
# Create helper file for setting environment variables
257
pyversion=".".join([str(s) for s in sys.version_info[0:2]])
2380 by Garth N. Wells
Clean up some debugging output.
258
f = open('dolfin.conf', 'w')
2372.1.1 by Garth N. Wells
Create dolfin.conf file like with old build system.
259
f.write('export PATH="'            + prefix + 'bin:$PATH"\n')
260
f.write('export LD_LIBRARY_PATH="' + prefix + 'lib:$LD_LIBRARY_PATH"\n')
261
f.write('export PKG_CONFIG_PATH="' + prefix + 'lib/pkgconfig:$PKG_CONFIG_PATH"\n')
262
f.write('export PYTHONPATH="'      + prefix + 'lib/python'    + pyversion + '/site-packages:$PYTHONPATH"\n')
263
f.close()
264
2359 by Johannes Ring
The BIG commit!
265
# Close log file
266
scons.logClose()
267
268
# vim:ft=python ts=2 sw=2