Changeset 317


Ignore:
Timestamp:
Jun 30, 2011 9:22:43 AM (10 years ago)
Author:
toby
Message:

more work

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/fsource/SConstruct

    r316 r317  
    55import subprocess
    66#==========================================================================================
     7def is_exe(fpath):
     8    return os.path.exists(fpath) and os.access(fpath, os.X_OK)
    79def which_path(program):
    810    "emulates Unix which: finds a program in path, but returns the path"
    911    import os, sys
    10     def is_exe(fpath):
    11         return os.path.exists(fpath) and os.access(fpath, os.X_OK)
    1212    if sys.platform == "win32" and os.path.splitext(program)[1].lower() != '.exe':
    1313        program = program + '.exe'
     
    2424#==========================================================================================
    2525# misc initializations
     26# need command-line options for fortran command and fortran options
    2627F2PYflags = '' # compiler options for f2py command
    27 F2PYpath = which_path('f2py')       # default path to f2py & python
    28 FORTpath = which_path('gfortran')   # default path to compiler
    29 ENVvars = {}
    30 SCONSvars = {}
     28F2PYpath = which_path('f2py')       # default path to f2py
     29GFORTpath = which_path('gfortran')   # path to compiler
     30FCompiler='gfortran'
     31G77path = which_path('g77')     # path to compiler
     32FORTpath = ""
     33FORTflags = ""
    3134liblist = []
    3235#==========================================================================================
     
    3437if sys.platform == "win32":
    3538    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'
     39    FCompiler='g77'
    3940elif sys.platform == "darwin":
    40     ENVvars['LDFLAGS'] = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
    41     F2PYflags = '--fcompiler=gnu95 --f77exec=gfortran --f77flags="-fno-range-check"'
     41    LDFLAGS = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
    4242    #F2PYpath = '/Library/Frameworks/Python.framework/Versions/6.2/bin/'     # path to f2py (python 6.2)
    4343    #F2PYpath = '/Library/Frameworks/Python.framework/Versions/current/bin/' # path to f2py
     
    4545    F2PYsuffix = '.so'
    4646elif sys.platform == "linux2":
    47     #ENVvars['LDFLAGS'] = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
     47    #LDFLAGS = '-undefined dynamic_lookup -bundle -static-libgfortran -static-libgcc'
    4848    #F2PYflags = '--fcompiler=gnu95 --f77exec=gfortran --f77flags="-fno-range-check"'
    4949    F2PYsuffix = '.so'
     
    5252    sys.exit()
    5353#==========================================================================================
     54# help
     55if 'help' in COMMAND_LINE_TARGETS:
     56    print """Building Fortran routines for use with GSAS-II
     57----------------------------------------------
     58
     59To build the compiled modules files needed to run GSAS-II, invoke this script:
     60    scons [options]
     61where the following options are defined (all are optional):
     62
     63-Q      -- produces less output from scons
     64
     65-n      -- causes scons to show but not execute the commands it will perform
     66
     67-c      -- clean: causes scons to delete previously created files (don't use
     68   with install)
     69
     70help    -- causes this message to be displayed (no compiling is done)
     71
     72install -- causes the module files to be placed in an installation directory
     73   (../bin<X>NNv.v) rather than ../bin (<X> is mac, win or linux; NN is 64
     74   or blank; v.v is the python version (2.6 or 2.7,...). Normally used only
     75   by Brian or Bob for distribution of compiled software.
     76
     77The following options override defaults set in the scons script:
     78
     79FCompiler=<path>   -- define the name of the fortran compiler; default is to use
     80   g77 on Windows and gfortran elsewhere. If you use something other than g77 or
     81   gfortran, you must also specify F2PYflags
     82
     83FORTpath=<path>    -- define a path to the fortran program; default is to use
     84   first gfortran (g77 for Windows) found in path
     85
     86FORTflags='string' -- string of options to be used for Fortran
     87   during library build step
     88
     89F2PYpath=<path>    -- define a path to the f2py program; default is to use
     90   first f2py found in path
     91
     92F2PYflags='string' -- defines optional flags to be supplied to f2py:
     93   Typically these option define which fortran compiler to use.
     94
     95F2PYsuffix='.xxx'  -- extension for output module files (default: win: '.pyd',
     96   mac/linux: '.so')
     97
     98LDFLAGS='string'   -- string of options to be used for f2py during link step
     99
     100Note that at present, only 32-bit python is supported and python 3.x is
     101not supported.
     102
     103examples:
     104    scons -Q
     105       (builds into ../bin for current platform using default options)
     106    scons -Q install
     107       (builds into ../bin<platform> for module distribution)
     108    scons -Q install F2PYpath=/Library/Frameworks/Python.framework/Versions/6.2/bin/
     109       (builds with a non-default [e.g. older] version of python)
     110    """
     111    sys.exit()
     112#==========================================================================================
    54113# override from command-line options
    55 for var in ['F2PYflags','F2PYpath','FORTpath','F2PYsuffix']:
     114for var in ['F2PYflags','F2PYpath','F2PYsuffix','FCompiler','FORTpath','FORTflags','LDFLAGS']:
    56115    if ARGUMENTS.get(var, None) is not None:
    57116        print 'Setting',var,'to',ARGUMENTS.get(var),'based on command line'
    58117        exec(var + "= ARGUMENTS.get('" + var +"')")
    59 var = 'LDFLAGS'
    60 if 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)
    63 var = 'FORTRANFLAGS'
    64 if 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 
     118#==========================================================================================
     119# use the compiler choice to set compiler options, but don't change anything
     120# specified on the command line
     121if FCompiler == 'gfortran':
     122    if FORTpath == "": FORTpath = GFORTpath
     123    if F2PYflags == "": F2PYflags = '--fcompiler=gnu95 --f77exec=gfortran --f77flags="-fno-range-check"'
     124elif FCompiler == 'g77':
     125    if FORTpath == "": FORTpath = G77path
     126    if F2PYflags == "": F2PYflags = '--fcompiler=gnu --f77exec=g77 --f77flags="-fno-range-check"'
     127    if sys.platform == "win32":
     128        if FORTflags == "": FORTflags = ' -w -O2 -fno-automatic -finit-local-zero -malign-double -mwindows'
     129else:
     130    if FORTpath == "": print 'Likely error, FORTpath is not specified'
     131    if F2PYflags == "":
     132        print 'Error: specify a F2PYflags value'
     133        sys.exit()
     134
     135#==========================================================================================
    69136# get the python version number from the python image in the f2py directory
    70 p = subprocess.Popen([os.path.join(F2PYpath,'python')], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
    71 p.stdin.write("import sys;print str(sys.version_info[0]);print str(sys.version_info[1]);sys.exit()")
     137#  find the python location. Note that on Windows it may be in the parent of the f2py location
     138# then run it to get info about the verision and the number of bits
     139for program in ['python','../python']:
     140    if sys.platform == "win32" and os.path.splitext(program)[1].lower() != '.exe':
     141        program = program + '.exe'
     142    pythonprogram = os.path.normpath(os.path.join(F2PYpath,program))
     143    if is_exe(pythonprogram): break
     144else:
     145    print 'python not found'
     146    sys.exit()
     147p = subprocess.Popen(pythonprogram, stdout=subprocess.PIPE, stdin=subprocess.PIPE)
     148p.stdin.write("import sys,platform;print str(sys.version_info[0]);print str(sys.version_info[1]);print platform.architecture()[0];sys.exit()")
    72149p.stdin.close()
    73150p.wait()
    74151versions = p.stdout.readlines()
    75152version = str(int(versions[0])) + '.' + str(int(versions[1]))
     153PlatformBits = versions[2][:-1]
    76154#
    77155
     
    81159    Default(InstallLoc)
    82160elif 'install' in COMMAND_LINE_TARGETS:
    83     if platform.architecture()[0] == '64bit':
     161    if PlatformBits == '64bit':
    84162        bits = '64'
    85163    else:
     
    93171    InstallLoc = '../' + prefix + bits + version
    94172    Alias('install',InstallLoc)
    95 if 'help' in COMMAND_LINE_TARGETS:
    96     print """
    97 Building Fortran routines for use with GSAS-II
    98 ----------------------------------------------
    99 
    100 To build the compiled modules files needed to run GSAS-II, invoke this script:
    101     scons [options]
    102 where 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 
    111 help    -- causes this message to be displayed (no compiling is done)
    112 
    113 install -- 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 
    118 The following options override defaults set in the scons script:
    119 
    120 F2PYflags='string' -- defines optional flags to be supplied to f2py:
    121    Typically these option define which fortran compiler to use.
    122 
    123 F2PYpath=<path>    -- define a path to the f2py program; default is to use
    124    first f2py found in path
    125 
    126 FORTpath=<path>    -- define a path to the f2py program; default is to use
    127    first gfortran (g77 for Windows) found in path
    128 
    129 F2PYsuffix='.xxx'  -- extension for output module files (default: win: '.pyd',
    130    mac/linux: '.so')
    131 
    132 LDFLAGS='string'   -- string of options to be used for f2py during link step
    133 
    134 FORTRANFLAGS='string'  -- string of options to be used for Fortran
    135    during library build step
    136 
    137 Note that at present, only 32-bit python is supported and python 3.x is
    138 not supported.
    139 
    140 examples:
    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
     173
     174# Setup build Environment
     175env = Environment()
     176# Define a builder to run f2py
    151177def generate_f2py(source, target, env, for_signature):
    152178    module = os.path.splitext(str(source[0]))[0]
     
    156182    return os.path.join(F2PYpath,'f2py')  + ' -c $SOURCE -m ' + module + ' ' + F2PYflags
    157183f2py = Builder(generator = generate_f2py)
    158 env = Environment(BUILDERS = {'f2py' : f2py},)
     184env.Append(BUILDERS = {'f2py' : f2py},)
     185
     186if ARGUMENTS.get('FCompiler', None) is not None or env.get('FORTRAN') is None:
     187    # create a builder for the fortran compiler for library compilation, if needed
     188    def generate_obj(source, target, env, for_signature):
     189        dir = os.path.split(str(source[0]))[0]
     190        obj = os.path.splitext(str(source[0]))[0]+'.o'
     191        return os.path.join(FORTpath,FCompiler)  + ' -c $SOURCE ' + FORTflags + ' -I' + dir + ' -o' + obj
     192    fort = Builder(generator = generate_obj, suffix = '.o',
     193                   src_suffix = '.for')
     194    env.Append(BUILDERS = {'fort' : fort},)
     195    FortranCompile = env.fort
     196    print 'Defining a FORTRAN builder'
     197else:
     198    FortranCompile = Object
     199    env['FORTRANFLAGS'] = FORTflags
     200
    159201# Setup build Environment
    160202if FORTpath != "":  env.PrependENVPath('PATH', FORTpath)
    161 #for path in PATH:
    162 #    env.PrependENVPath('PATH', path)
    163 for var in ENVvars:
    164     env['ENV'][var] = ENVvars[var]
    165 for 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 
     203var = 'LDFLAGS'
     204env['ENV'][var] = eval(var)
    175205
    176206# find libraries to build (subdirectories named *subs)
    177207for sub in glob.glob('*subs'):
    178     lib = Library(sub, Glob(os.path.join(sub,'*.for'))) # register library to be created
     208    filelist = []
     209    for file in glob.glob(os.path.join(sub,'*.for')):
     210        #target = os.path.splitext(file)[0]+'.o'
     211        target = FortranCompile(file) # connect .o files to .for files
     212        #print 'Compile: ',file, target
     213        filelist.append(target)
     214    #lib = Library(sub, Glob(os.path.join(sub,'*.for'))) # register library to be created
     215    lib = Library(sub, filelist) # register library to be created
    179216    liblist.append(lib[0].name)
    180217    filename = str(lib[0])
     
    183220modlist = []
    184221for src in glob.glob('*.for'):
    185     target = os.path.splitext(src)[0] + '.so'
     222    target = os.path.splitext(src)[0] + F2PYsuffix
    186223    out = env.f2py(target,src)
    187224    Depends(target, liblist) # make sure libraries are rebuilt if old
    188225    modlist.append(out[0].name)
    189226    env.Install(InstallLoc, out[0].name)
     227    break # bail out early for testing
    190228print 80*'='
    191 for var in ['F2PYflags','F2PYpath','FORTpath','F2PYsuffix']:
     229for var in ['FCompiler','FORTpath','FORTflags','F2PYflags','F2PYpath','F2PYsuffix','LDFLAGS']:
    192230    print 'Variable ',var,'is',eval(var)
    193231print 'Required fortran libraries:',
     
    197235for mod in modlist: print " " + mod,
    198236print ""
    199 print 'Python/f2py version =',version
     237print 'Using python at', pythonprogram
     238print 'Python/f2py version =',version,PlatformBits
    200239print 'Install directory is',InstallLoc
    201240print 80*'='
     241#print env.Dump()
Note: See TracChangeset for help on using the changeset viewer.