source: trunk/fsource/SConstruct @ 316

Last change on this file since 316 was 316, checked in by toby, 10 years ago

scons fixes; copy win options from batch file

File size: 7.8 KB
Line 
1import platform
2import sys
3import os
4import glob
5import subprocess
6#==========================================================================================
7def which_path(program):
8    "emulates Unix which: finds a program in path, but returns the path"
9    import os, sys
10    def is_exe(fpath):
11        return os.path.exists(fpath) and os.access(fpath, os.X_OK)
12    if sys.platform == "win32" and os.path.splitext(program)[1].lower() != '.exe':
13        program = program + '.exe'
14    fpath, fname = os.path.split(program)
15    if fpath:
16        if is_exe(program):
17            return fpath
18    else:
19        for path in os.environ["PATH"].split(os.pathsep):
20            exe_file = os.path.join(path, program)
21            if is_exe(exe_file):
22                return path
23    return ""
24#==========================================================================================
25# misc initializations
26F2PYflags = '' # compiler options for f2py command
27F2PYpath = which_path('f2py')       # default path to f2py & python
28FORTpath = which_path('gfortran')   # default path to compiler
29ENVvars = {}
30SCONSvars = {}
31liblist = []
32#==========================================================================================
33# configure platform dependent options here:
34if sys.platform == "win32":
35    F2PYsuffix = '.pyd'
36    FORTpath = which_path('g77')   # default path to compiler
37    F2PYflags = '--compiler=mingw32 --fcompiler=gnu'
38    SCONSvars['FORTRANFLAGS'] = ' -w -O2 -fno-automatic -finit-local-zero -malign-double -mwindows'
39elif sys.platform == "darwin":
40    ENVvars['LDFLAGS'] = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
41    F2PYflags = '--fcompiler=gnu95 --f77exec=gfortran --f77flags="-fno-range-check"'
42    #F2PYpath = '/Library/Frameworks/Python.framework/Versions/6.2/bin/'     # path to f2py (python 6.2)
43    #F2PYpath = '/Library/Frameworks/Python.framework/Versions/current/bin/' # path to f2py
44    #FORTpath = '/sw/bin'                                                    # path to compilier
45    F2PYsuffix = '.so'
46elif sys.platform == "linux2":
47    #ENVvars['LDFLAGS'] = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
48    #F2PYflags = '--fcompiler=gnu95 --f77exec=gfortran --f77flags="-fno-range-check"'
49    F2PYsuffix = '.so'
50else:
51    print "Sorry, parameters for platform "+sys.platform+" are not yet defined"
52    sys.exit()
53#==========================================================================================
54# override from command-line options
55for var in ['F2PYflags','F2PYpath','FORTpath','F2PYsuffix']:
56    if ARGUMENTS.get(var, None) is not None:
57        print 'Setting',var,'to',ARGUMENTS.get(var),'based on command line'
58        exec(var + "= ARGUMENTS.get('" + var +"')")
59var = 'LDFLAGS'
60if ARGUMENTS.get(var, None) is not None:
61    print 'Setting '+var+' environment variable to',ARGUMENTS.get(var),'based on command line'
62    ENVvars[var] = ARGUMENTS.get(var)
63var = 'FORTRANFLAGS'
64if ARGUMENTS.get(var, None) is not None:
65    print 'Setting '+var+' internal variable to',ARGUMENTS.get(var),'based on command line'
66    SCONSvars[var] = ARGUMENTS.get(var)
67#==========================================================================================
68
69# get the python version number from the python image in the f2py directory
70p = subprocess.Popen([os.path.join(F2PYpath,'python')], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
71p.stdin.write("import sys;print str(sys.version_info[0]);print str(sys.version_info[1]);sys.exit()")
72p.stdin.close()
73p.wait()
74versions = p.stdout.readlines()
75version = str(int(versions[0])) + '.' + str(int(versions[1]))
76#
77
78# Install location
79InstallLoc = '../bin'
80if len(COMMAND_LINE_TARGETS) == 0:
81    Default(InstallLoc)
82elif 'install' in COMMAND_LINE_TARGETS:
83    if platform.architecture()[0] == '64bit':
84        bits = '64'
85    else:
86        bits = ''
87    if sys.platform == "win32":
88        prefix = 'binwin'
89    elif sys.platform == "darwin":
90        prefix = 'binmac'
91    elif sys.platform == "linux2":
92        prefix = 'binlinux'
93    InstallLoc = '../' + prefix + bits + version
94    Alias('install',InstallLoc)
95if 'help' in COMMAND_LINE_TARGETS:
96    print """
97Building Fortran routines for use with GSAS-II
98----------------------------------------------
99
100To build the compiled modules files needed to run GSAS-II, invoke this script:
101    scons [options]
102where the following options are defined (all are optional):
103
104-Q      -- produces less output from scons
105
106-n      -- causes scons to show but not execute the commands it will perform
107
108-c      -- clean: causes scons to delete previously created files (don't use
109   with install)
110
111help    -- causes this message to be displayed (no compiling is done)
112
113install -- causes the module files to be placed in an installation directory
114   (../bin<X>NNv.v) rather than ../bin (<X> is mac, win or linux; NN is 64
115   or blank; v.v is the python version (2.6 or 2.7,...). Normally used only
116   by Brian or Bob for distribution of compiled software.
117
118The following options override defaults set in the scons script:
119
120F2PYflags='string' -- defines optional flags to be supplied to f2py:
121   Typically these option define which fortran compiler to use.
122
123F2PYpath=<path>    -- define a path to the f2py program; default is to use
124   first f2py found in path
125
126FORTpath=<path>    -- define a path to the f2py program; default is to use
127   first gfortran (g77 for Windows) found in path
128
129F2PYsuffix='.xxx'  -- extension for output module files (default: win: '.pyd',
130   mac/linux: '.so')
131
132LDFLAGS='string'   -- string of options to be used for f2py during link step
133
134FORTRANFLAGS='string'  -- string of options to be used for Fortran
135   during library build step
136
137Note that at present, only 32-bit python is supported and python 3.x is
138not supported.
139
140examples:
141    scons -Q
142       (builds into ../bin for current platform using default options)
143    scons -Q install
144       (builds into ../bin<platform> for module distribution)
145    scons -Q install F2PYpath=/Library/Frameworks/Python.framework/Versions/6.2/bin/
146       (builds with a non-default [e.g. older] version of python)
147    """
148    sys.exit()
149
150# commands needed to run f2py
151def generate_f2py(source, target, env, for_signature):
152    module = os.path.splitext(str(source[0]))[0]
153    if len(liblist) > 0:
154        for lib in liblist:
155            module = module + ' ' + str(lib)
156    return os.path.join(F2PYpath,'f2py')  + ' -c $SOURCE -m ' + module + ' ' + F2PYflags
157f2py = Builder(generator = generate_f2py)
158env = Environment(BUILDERS = {'f2py' : f2py},)
159# Setup build Environment
160if FORTpath != "":  env.PrependENVPath('PATH', FORTpath)
161#for path in PATH:
162#    env.PrependENVPath('PATH', path)
163for var in ENVvars:
164    env['ENV'][var] = ENVvars[var]
165for var in SCONSvars:
166    env[var] = ENVvars[var]
167
168# for testing
169#out = env.f2py('fellipse.for')
170#filename = str(out[0])
171#print filename
172#print os.path.join(InstallLoc,filename)
173#Command(os.path.join(InstallLoc,filename),filename,Copy("$TARGET","$SOURCE"))
174
175
176# find libraries to build (subdirectories named *subs)
177for sub in glob.glob('*subs'):
178    lib = Library(sub, Glob(os.path.join(sub,'*.for'))) # register library to be created
179    liblist.append(lib[0].name)
180    filename = str(lib[0])
181    #Install(InstallLoc,filename)
182# find modules that need to be built
183modlist = []
184for src in glob.glob('*.for'):
185    target = os.path.splitext(src)[0] + '.so'
186    out = env.f2py(target,src)
187    Depends(target, liblist) # make sure libraries are rebuilt if old
188    modlist.append(out[0].name)
189    env.Install(InstallLoc, out[0].name)
190print 80*'='
191for var in ['F2PYflags','F2PYpath','FORTpath','F2PYsuffix']:
192    print 'Variable ',var,'is',eval(var)
193print 'Required fortran libraries:',
194for lib in liblist: print " " + lib,
195print ""
196print 'f2py modules:',
197for mod in modlist: print " " + mod,
198print ""
199print 'Python/f2py version =',version
200print 'Install directory is',InstallLoc
201print 80*'='
Note: See TracBrowser for help on using the repository browser.