/[ascend]/trunk/SConstruct
ViewVC logotype

Diff of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 549 by johnpye, Fri Apr 28 10:01:39 2006 UTC revision 800 by johnpye, Tue Aug 1 12:22:09 2006 UTC
# Line 1  Line 1 
1  import os, commands, platform, distutils.sysconfig, os.path  import os, commands, platform, distutils.sysconfig, os.path, re
2    
3  version = "0.svn"  version = "0.9.5.96"
4    
5  #------------------------------------------------------  #------------------------------------------------------
6  # OPTIONS  # OPTIONS
# Line 12  opts = Options(['options.cache', 'config Line 12  opts = Options(['options.cache', 'config
12  #print "PLATFORM = ",platform.system()  #print "PLATFORM = ",platform.system()
13    
14  if platform.system()=="Windows":  if platform.system()=="Windows":
15      default_tcl_lib = "tcl83"      default_tcl_lib = "tcl84"
16      default_tk_lib = "tk83"      default_tk_lib = "tk84"
17      default_tktable_lib = "Tktable28"      default_tktable_lib = "Tktable28"
18      default_install_assets = "glade/"      default_install_assets = "glade/"
19      icon_extension = '.png'      icon_extension = '.png'
20      default_tcl = "c:\\Tcl"      default_tcl = "c:\\Tcl"
21      default_tcl_libpath = "$TCL\\bin"      if os.environ.get('MSYSTEM')=="MINGW32":
22            default_tcl_libpath="$TCL\\bin"
23        else:
24            default_tcl_libpath="$TCL\\lib"
25        default_rel_distdir = '.'
26        default_absolute_paths = False
27        
28        default_ida_prefix = "c:\\MinGW"
29        if not os.path.exists(default_ida_prefix):
30            default_ida_prefix = None
31    
32        default_conopt_prefix = "c:\\Program Files\\CONOPT"
33        default_conopt_libpath="$CONOPT_PREFIX"
34        default_conopt_cpppath="$CONOPT_PREFIX"
35        default_conopt_lib="conopt3"
36        default_conopt_envvar="CONOPT_PATH"
37        
38        if not os.path.exists(default_conopt_prefix):
39            default_conopt_prefix = None
40            
41        need_libm = False
42        python_exe = "c:\\Python24\\python.exe"
43  else:  else:
44      default_tcl_lib = "tcl8.3"      default_tcl_lib = "tcl8.4"
45      default_tk_lib = "tk8.3"      default_tk_lib = "tk8.4"
46      default_tktable_lib = "Tktable2.8"      default_tktable_lib = "Tktable2.8"
47      default_install_assets = "$INSTALL_DATA/ascend/glade/"      default_install_assets = "$INSTALL_ASCDATA/glade/"
48      icon_extension = '.svg'      icon_extension = '.svg'
49      default_tcl = os.path.expanduser("~/activetcl")      default_tcl = '/usr'
50      default_tcl_libpath = "$TCL/lib"          default_tcl_libpath = "$TCL/lib"    
51        default_rel_distdir = '../share/ascend'
52        default_absolute_paths = True
53        default_ida_prefix="/usr/local"
54        default_conopt_prefix="/usr"
55        default_conopt_libpath="$CONOPT_PREFIX/lib"
56        default_conopt_cpppath="$CONOPT_PREFIX/include"
57        default_conopt_lib="consub3"
58        default_conopt_envvar="LD_LIBRARY_PATH"
59    
60        need_libm = True
61        if not os.path.isdir(default_tcl):
62            default_tcl = '/usr'
63        python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
64    
65    opts.Add(
66        'CC'
67        ,'C Compiler command'
68        ,None
69    )
70    
71    opts.Add(
72        'CXX'
73        ,'C++ Compiler command'
74        ,None
75    )
76    
77    opts.Add(BoolOption(
78        'GCOV'
79        , 'Whether to enable coverage testing in object code'
80        , False
81    ))
82    
83  # Package linking option  # Package linking option
84  opts.Add(EnumOption(  opts.Add(EnumOption(
# Line 45  opts.Add(BoolOption( Line 97  opts.Add(BoolOption(
97  # You can turn off building of Tcl/Tk interface  # You can turn off building of Tcl/Tk interface
98  opts.Add(BoolOption(  opts.Add(BoolOption(
99      'WITH_TCLTK'      'WITH_TCLTK'
100      ,"Set to True if you don't want to build the original Tcl/Tk GUI."      ,"Set to False if you don't want to build the original Tcl/Tk GUI."
101      , True      , True
102  ))  ))
103    
104  # You can turn off the building of the Python interface  # You can turn off the building of the Python interface
105  opts.Add(BoolOption(  opts.Add(BoolOption(
106      'WITH_PYTHON'      'WITH_PYTHON'
107      ,"Set to True if you don't want to build Python wrappers."      ,"Set to False if you don't want to build Python wrappers."
108      , True      , True
109  ))  ))
110    
# Line 61  opts.Add(ListOption( Line 113  opts.Add(ListOption(
113      'WITH_SOLVERS'      'WITH_SOLVERS'
114      ,"List of the solvers you want to build. The default is the minimum that"        ,"List of the solvers you want to build. The default is the minimum that"  
115          +" works."          +" works."
116      ,["QRSLV","CMSLV"]      ,["QRSLV","CMSLV","LSOD","IDA","CONOPT","LRSLV"]
117      ,['QRSLV','MPS','SLV','OPTSQP'      ,['QRSLV','MPS','SLV','OPTSQP'
118          ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'          ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
119          ,'LSOD','OPTSQP'          ,'LSOD','OPTSQP',"IDA"
120       ]       ]
121  ))  ))
122    
# Line 89  opts.Add( Line 141  opts.Add(
141      'DEFAULT_ASCENDLIBRARY'      'DEFAULT_ASCENDLIBRARY'
142      ,"Set the default value of the ASCENDLIBRARY -- the location where"      ,"Set the default value of the ASCENDLIBRARY -- the location where"
143          +" ASCEND will look for models when running ASCEND"          +" ASCEND will look for models when running ASCEND"
144      ,"$INSTALL_DATA/models"      ,"$INSTALL_ASCDATA/models"
145  )  )
146    
147  # Where is SWIG?  # Where is SWIG?
# Line 102  opts.Add( Line 154  opts.Add(
154    
155  # Build the test suite?  # Build the test suite?
156  opts.Add(BoolOption(  opts.Add(BoolOption(
157      'WITH_CUNIT_TESTS'      'WITH_CUNIT'
158      ,"Whether to build the CUnit tests. Default is off. If set to on,"      ,"You can disable CUnit tests with this option. This will basically stop"
159          +" you must have CUnit installed somewhere that SCons can"          +" SCons from parsing the SConscript files relating to the 'test'"
160          +" find it, or else use the CUNIT_* options to specify."          +" target, which just might make things marginally faster. Probably"
161      ,False          +" you can just ignore this option though. SCons will sniff for Cunit"
162            +" but build the tests only if you specify the 'test' target."
163        ,True
164  ))  ))
165    
166  # Where are the CUnit includes?  # Where are the CUnit includes?
# Line 123  opts.Add(PackageOption( Line 177  opts.Add(PackageOption(
177      ,'off'      ,'off'
178  ))  ))
179    
180    opts.Add(PackageOption(
181        "IDA_PREFIX"
182        ,"Prefix for your IDA install (IDA ./configure --prefix)"
183        ,default_ida_prefix
184    ))
185    
186    opts.Add(
187        "IDA_LIB"
188        ,"Libraries linked to for IDA"
189        ,['sundials_ida','sundials_nvecserial','m']
190    )
191    
192    opts.Add(
193        'IDA_CPPPATH'
194        ,"Where is your ida.h?"
195        ,"$IDA_PREFIX/include"
196    )
197    
198    opts.Add(
199        'IDA_LIBPATH'
200        ,"Where are your SUNDIALS libraries installed?"
201        ,"$IDA_PREFIX/lib"
202    )
203    
204    # conopt
205    
206    opts.Add(PackageOption(
207        "CONOPT_PREFIX"
208        ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
209        ,default_conopt_prefix
210    ))
211    
212    opts.Add(
213        "CONOPT_LIB"
214        ,"Library linked to for CONOPT"
215        ,default_conopt_lib
216    )
217    
218    opts.Add(
219        'CONOPT_CPPPATH'
220        ,"Where is your conopt.h?"
221        ,default_conopt_cpppath
222    )
223    
224    opts.Add(
225        'CONOPT_LIBPATH'
226        ,"Where is your CONOPT libraries installed?"
227        ,default_conopt_libpath
228    )
229    
230    opts.Add(
231        'CONOPT_ENVVAR'
232        ,"What environment variable should be used at runtime to override the default search location for CONOPT DLL/SO?"
233        ,default_conopt_envvar
234    )
235    
236    opts.Add(
237        "F2C_LIB"
238        ,"F2C library (eg. g2c, gfortran, f2c)"
239        ,"g2c"
240    )
241    
242    opts.Add(PackageOption(
243        "F2C_LIBPATH"
244        ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
245        ,"off"
246    ))
247    
248  opts.Add(  opts.Add(
249      'TCL'      'TCL'
# Line 147  opts.Add( Line 268  opts.Add(
268  # What is the name of the Tcl lib?  # What is the name of the Tcl lib?
269  opts.Add(  opts.Add(
270      'TCL_LIB'      'TCL_LIB'
271      ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library"      ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
272      ,default_tcl_lib      ,default_tcl_lib
273  )  )
274    
# Line 176  opts.Add( Line 297  opts.Add(
297    
298  opts.Add(BoolOption(  opts.Add(BoolOption(
299      'STATIC_TCLTK'      'STATIC_TCLTK'
300      ,'Set true for static linking for Tcl/Tk and TkTable'      ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
301      ,False      ,False
302  ))  ))
303    
# Line 200  opts.Add( Line 321  opts.Add(
321    
322  opts.Add(  opts.Add(
323      'X11'      'X11'
324      ,'Base X11 directory'      ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
325      ,'/usr/X11R6'      ,'/usr/X11R6'
326  )  )
327    
328  opts.Add(  opts.Add(
329      'X11_LIBPATH'      'X11_LIBPATH'
330      ,'Location of X11 lib'      ,'Location of X11 lib. EXPERIMENTAL'
331      ,'$X11/lib'      ,'$X11/lib'
332  )  )
333    
334  opts.Add(  opts.Add(
335      'X11_CPPPATH'      'X11_CPPPATH'
336      ,'Location of X11 includes'      ,'Location of X11 includes. EXPERIMENTAL'
337      ,'$X11/include'      ,'$X11/include'
338  )  )
339    
340  opts.Add(  opts.Add(
341      'X11_LIB'      'X11_LIB'
342      ,'Name of X11 lib'      ,'Name of X11 lib. EXPERIMENTAL'
343      ,'X11'      ,'X11'
344  )  )
345    
# Line 236  opts.Add( Line 357  opts.Add(
357    
358  opts.Add(  opts.Add(
359      'INSTALL_LIB'      'INSTALL_LIB'
360      ,'Location to put binaries during installation'      ,'Location to put libraries during installation'
361      ,"$INSTALL_PREFIX/lib"      ,"$INSTALL_PREFIX/lib"
362  )  )
363    
364  opts.Add(  opts.Add(
365      'INSTALL_DATA'      'INSTALL_SHARE'
366      ,'Location to put data files during installation'      ,'Common shared-file location on this system'
367      ,"$INSTALL_PREFIX/share"      ,"$INSTALL_PREFIX/share"
368  )  )
369    
370    
371    opts.Add(
372        'INSTALL_ASCDATA'
373        ,"Location of ASCEND shared data (TK, python, models etc)"
374        ,"$INSTALL_SHARE/ascend"
375    )
376    
377  opts.Add(  opts.Add(
378      'INSTALL_INCLUDE'      'INSTALL_INCLUDE'
379      ,'Location to put header files during installation'      ,'Location to put header files during installation'
# Line 264  opts.Add(BoolOption( Line 392  opts.Add(BoolOption(
392      ,False      ,False
393  ))  ))
394    
395    opts.Add(BoolOption(
396        'MALLOC_DEBUG'
397        ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
398        ,False
399    ))
400    
401  opts.Add(  opts.Add(
402      'INSTALL_ROOT'      'INSTALL_ROOT'
403      ,'For use by RPM only: location of %{buildroot} during rpmbuild'      ,'For use by RPM only: location of %{buildroot} during rpmbuild'
404      ,""      ,""
405  )  )
406    
407    opts.Add(
408        'DISTTAR_NAME'
409        ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
410        ,"ascend-"+version
411    )
412    
413    opts.Add(
414        'RELEASE'
415        ,"Release number for use in RPM spec file. This should always start with a zero for releases made by the ASCEND group, in order that third parties can make 'patch' releases of higher version numbers."
416        ,"0"
417    )
418    
419    opts.Add(BoolOption(
420        'ABSOLUTE_PATHS'
421        ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
422        ,default_absolute_paths
423    ))
424    
425    opts.Add(
426        'WIN_INSTALLER_NAME'
427        ,"Name of the installer .exe to create under Windows (minus the '.exe')"
428        ,"ascend-"+version
429    )
430    
431    opts.Add(BoolOption(
432        'WITH_XTERM_COLORS'
433        ,"Set to 0 if you don't want xterm colour codes in the console output"
434        ,True
435    ))
436    
437    opts.Add(BoolOption(
438        'WITH_EXTFNS'
439        ,"Set to 0 if you don't want to attempt to build external modules bundled"
440            + " with ASCEND."
441        ,True
442    ))
443    
444  if platform.system()!="Windows":  if platform.system()!="Windows":
445      opts.Add(BoolOption(      opts.Add(BoolOption(
446          'WITH_GCCVISIBILITY'          'WITH_GCCVISIBILITY'
# Line 277  if platform.system()!="Windows": Line 448  if platform.system()!="Windows":
448          , True          , True
449      ))      ))
450    
 if platform.system()=="Windows":  
     opts.Add(BoolOption(  
         'WITH_INSTALLER'  
         ,'Build the Windows Installer (setup program) using NSIS'  
         ,False  
     ))  
   
451  # TODO: OTHER OPTIONS?  # TODO: OTHER OPTIONS?
452  # TODO: flags for optimisation  # TODO: flags for optimisation
453  # TODO: turning on/off bintoken functionality  # TODO: turning on/off bintoken functionality
# Line 291  if platform.system()=="Windows": Line 455  if platform.system()=="Windows":
455    
456  # Import the outside environment  # Import the outside environment
457    
458  if os.environ.has_key('OSTYPE') and os.environ['OSTYPE']=='msys':  def c_escape(str):
459      env = Environment(ENV=os.environ, tools=['mingw','swig','lex','yacc'])          return re.sub("\\\\","/",str)
460      env['IS_MINGW']=True  
461    envadditional={}
462    if os.environ.get('OSTYPE')=='msys':
463        envenv = os.environ;
464        tools = ['mingw','lex','yacc','fortran','swig','disttar','nsis','doxygen']
465        envadditional['IS_MINGW']=True
466    
467    elif platform.system()=="Windows":
468        envenv = {
469            'PATH':os.environ['PATH']
470            ,'INCLUDE':os.environ['INCLUDE']
471            ,'LIB':os.environ['LIB']
472            ,'MSVS_IGNORE_IDE_PATHS':1
473        }
474        tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']  
475        envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
476  else:  else:
477      env = Environment(ENV=os.environ)      envenv = os.environ
478      Tool('lex')(env)      tools=['default','lex','yacc','fortran','swig','disttar','nsis','doxygen']
479      Tool('yacc')(env)      
480      Tool('fortran')(env)  env = Environment(
481      Tool('swig')(env)      ENV=envenv
482        , toolpath=['scons']
483  if platform.system()=='Windows' and env.has_key('MSVS'):      , tools=tools
484      print "INCLUDE =",env['ENV']['INCLUDE']      , **envadditional
485      print "LIB =",env['ENV']['LIB']  )
     print "PATH =",env['ENV']['PATH']  
     env.Append(CPPPATH=env['ENV']['INCLUDE'])  
     env.Append(LIBPATH=env['ENV']['LIB'])  
486    
487  opts.Update(env)  opts.Update(env)
488  opts.Save('options.cache',env)  opts.Save('options.cache',env)
489    
490  Help(opts.GenerateHelpText(env))  Help(opts.GenerateHelpText(env))
491    
492  with_tcltk_gui = (env['WITH_TCLTK']==True)  with_tcltk = env.get('WITH_TCLTK')
493  without_tcltk_reason = "disabled by options/config.py"  without_tcltk_reason = "disabled by options/config.py"
494    
495  with_python = (env['WITH_PYTHON']==True)  with_python = env.get('WITH_PYTHON')
496  without_python_reason = "disabled by options/config.py"  without_python_reason = "disabled by options/config.py"
497    
498  with_cunit_tests = env['WITH_CUNIT_TESTS']  with_cunit = env.get('WITH_CUNIT')
499  without_cunit_reason = "not requested"  without_cunit_reason = "not requested"
500    
501    with_extfns = env.get('WITH_EXTFNS')
502    without_extfn_reason = "disabled by options/config.py"
503    
504    if platform.system()=="Windows":
505        with_installer=1
506    else:
507        with_installer=0
508        without_installer_reason = "only possible under Windows"
509    
510    if 'LSOD' in env['WITH_SOLVERS']:
511        with_lsode=True
512    else:
513        with_lsode=False
514        without_lsode_reason = "not requested (WITH_SOLVERS)"
515        
516    if 'IDA' in env['WITH_SOLVERS']:
517        with_ida=True
518    else:
519        with_ida=False
520        without_ida_reason = "not requested (WITH_SOLVERS)"
521    
522    
523    if 'CONOPT' in env['WITH_SOLVERS']:
524        with_conopt=True
525    else:
526        with_conopt=False
527        without_conopt_reason = "not requested (WITH_SOLVERS)"
528    
529    
530  #print "SOLVERS:",env['WITH_SOLVERS']  #print "SOLVERS:",env['WITH_SOLVERS']
531  #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']  #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
532  #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']  #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
# Line 332  if platform.system()=='Windows': Line 537  if platform.system()=='Windows':
537    
538  env['CAN_INSTALL']=can_install  env['CAN_INSTALL']=can_install
539    
540    env['INSTALL_MODELS']=env['INSTALL_ASCDATA']+"/models/"
541    
542  print "TCL_CPPPATH =",env['TCL_CPPPATH']  print "TCL_CPPPATH =",env['TCL_CPPPATH']
543  print "TCL_LIBPATH =",env['TCL_LIBPATH']  print "TCL_LIBPATH =",env['TCL_LIBPATH']
544  print "TCL_LIB =",env['TCL_LIB']  print "TCL_LIB =",env['TCL_LIB']
545    print "CC =",env['CC']
546    print "CXX =",env['CXX']
547    print "FORTRAN=",env.get('FORTRAN')
548    
549    print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
550  #------------------------------------------------------  #------------------------------------------------------
551  # SPECIAL CONFIGURATION TESTS  # SPECIAL CONFIGURATION TESTS
552    
# Line 391  class KeepContext: Line 602  class KeepContext:
602      def __init__(self,context,varprefix,static=False):      def __init__(self,context,varprefix,static=False):
603          self.keep = {}          self.keep = {}
604          for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:          for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
605              if context.env.has_key(k):              #print "Keeping env %s = %s" % (k,context.env.get(k))
606                  self.keep[k] = context.env[k]              self.keep[k]=context.env.get(k)
             else:  
                 self.keep[k] = None  
607                    
608          if context.env.has_key(varprefix+'_CPPPATH'):          if context.env.has_key(varprefix+'_CPPPATH'):
609              context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])              context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
610              #print "Adding '"+str(cpppath_add)+"' to cpp path"              #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
611    
612          if static:          if static:
613              staticlib=env[varprefix+'_LIB']              staticlib=env[varprefix+'_LIB']
# Line 409  class KeepContext: Line 618  class KeepContext:
618          else:          else:
619              if context.env.has_key(varprefix+'_LIBPATH'):              if context.env.has_key(varprefix+'_LIBPATH'):
620                  context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])                  context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
621                  #print "Adding '"+str(libpath_add)+"' to lib path"                  #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
622    
623              if context.env.has_key(varprefix+'_LIB'):              if context.env.has_key(varprefix+'_LIB'):
624                  context.env.Append(LIBS=[env[varprefix+'_LIB']])                  context.env.Append(LIBS=[env[varprefix+'_LIB']])
625                  #print "Adding '"+str(libs_add)+"' to libs"                  #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"    
626    
627      def restore(self,context):      def restore(self,context):
628          #print "RESTORING CONTEXT"          #print "RESTORING CONTEXT"
# Line 425  class KeepContext: Line 634  class KeepContext:
634                      #print "Clearing "+str(k)                      #print "Clearing "+str(k)
635                      del context.env[k];                      del context.env[k];
636              else:              else:
637                  #print "Restoring "+str(k)+" to '"+self.keep[k]+"'"                              #print "Restoring %s to '%s'" %(k,self.keep.get(k))
638                  context.env[k]=self.keep[k];                  context.env[k]=self.keep[k];
639    
640  def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):  def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
# Line 442  def CheckExtLib(context,libname,text,ext Line 651  def CheckExtLib(context,libname,text,ext
651      if varprefix==None:      if varprefix==None:
652          varprefix = libname.upper()          varprefix = libname.upper()
653            
654        #print "LIBS is currently:",context.env.get('LIBS')
655      keep = KeepContext(context,varprefix,static)      keep = KeepContext(context,varprefix,static)
656    
657      if not context.env.has_key(varprefix+'_LIB'):      if not context.env.has_key(varprefix+'_LIB'):
658          # if varprefix_LIB were in env, KeepContext would          # if varprefix_LIB were in env, KeepContext would
659          # have appended it already          # have appended it already
660          context.env.Append(LIBS=libname)          context.env.Append(LIBS=[libname])
661    
662      is_ok = context.TryLink(text,ext)      is_ok = context.TryLink(text,ext)
663            
# Line 456  def CheckExtLib(context,libname,text,ext Line 666  def CheckExtLib(context,libname,text,ext
666      keep.restore(context)      keep.restore(context)
667    
668  #   print "Restored CPPPATH="+str(context.env['CPPPATH'])  #   print "Restored CPPPATH="+str(context.env['CPPPATH'])
669  #   print "Restored LIBS="+libname  #   print "Restored LIBS="+str(context.env['LIBS'])
670  #   print "Restored LIBPATH="+str(context.env['LIBPATH'])  #   print "Restored LIBPATH="+str(context.env['LIBPATH'])
671    
672      context.Result(is_ok)      context.Result(is_ok)
# Line 510  def CheckGccVisibility(context): Line 720  def CheckGccVisibility(context):
720  # YACC  # YACC
721    
722  yacc_test_text = """  yacc_test_text = """
723  %start ROOT  %{
724     %token MSG  #include <stdio.h>
    %%  
725    
726     ROOT:  /* MSVC++ needs this before it can swallow Bison output */
727       MSG { print("HELLO"); }  #ifdef _MSC_VER
728     ;  # define __STDC__
729    #endif
730    %}
731    %token MSG
732    %start ROOT
733    %%
734    ROOT:
735        MSG { printf("HELLO"); }
736        ;
737    %%
738  """  """
739    
740  def CheckYacc(context):  def CheckYacc(context):
741      context.Message("Checking for Yacc... ")      context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
742      is_ok = context.TryCompile(yacc_test_text,".y")      is_ok = context.TryCompile(yacc_test_text,".y")
743      context.Result(is_ok)      context.Result(is_ok)
744      return is_ok      return is_ok
# Line 550  def CheckCUnit(context): Line 768  def CheckCUnit(context):
768      return CheckExtLib(context,'cunit',cunit_test_text)      return CheckExtLib(context,'cunit',cunit_test_text)
769    
770  #----------------  #----------------
771    # MATH test
772    
773    math_test_text = """
774    #ifndef _ALL_SOURCE
775    # define _ALL_SOURCE
776    #endif
777    #ifndef _XOPEN_SOURCE
778    # define _XOPEN_SOURCE
779    #endif
780    #ifndef _XOPEN_SOURCE_EXTENDED
781    # define _XOPEN_SOURCE_EXTENDED 1
782    #endif
783    #include <math.h>
784    int main(void){
785        double x = 1.0; double y = 1.0; int i = 1;
786        acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
787        j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
788        y0(x); y1(x); yn(i,x);
789    #ifdef _THREAD_SAFE
790        gamma_r(x,&i);
791        lgamma_r(x,&i);
792    #else
793    gamma(x);
794        lgamma(x);
795    #endif
796        hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
797        return 0;
798    }
799    """
800    
801    def CheckMath(context):
802        context.Message('Checking for IEE math library... ')
803        libsave=context.env.get('LIBS');
804        context.env.AppendUnique(LIBS=['m'])
805        is_ok=context.TryLink(math_test_text,".c")
806        context.Result(is_ok)
807        if not is_ok:
808            context.env['LIBS']=libsave
809        return is_ok
810    
811    #----------------
812    # IDA test
813    
814    ida_test_text = """
815    #include <ida/ida.h>
816    #include <nvector/nvector_serial.h>
817    #include <ida/ida_spgmr.h>
818    int main(){
819        void *ida_mem;
820        ida_mem = IDACreate();
821        return 0;
822    }
823    """
824    
825    def CheckIDA(context):
826        context.Message( 'Checking for IDA (SUNDIALS)... ' )
827    
828        keep = KeepContext(context,"IDA")
829        
830        is_ok = context.TryLink(ida_test_text,".c")
831        context.Result(is_ok)
832        
833        keep.restore(context)
834            
835        return is_ok
836    
837    #----------------
838    # CONOPT test
839    
840    conopt_test_text = """
841    #ifndef __MINGW32__
842    # error "where is mingw?"
843    #endif
844    
845    #if !defined(_WIN32)
846    # define FNAME_LCASE_DECOR
847    #endif
848    
849    #include <conopt.h>
850    #include <stdlib.h>
851    int main(){
852        int s, *v, e;
853        s = COIDEF_Size();
854        v = (int *)malloc(s*sizeof(int));
855        e = COIDEF_Ini(v);
856        return e;
857    }
858    """
859    
860    def CheckCONOPT(context):
861        context.Message( 'Checking for CONOPT... ' )
862    
863        keep = KeepContext(context,"CONOPT")
864        
865        is_ok = context.TryLink(conopt_test_text,".c")
866        context.Result(is_ok)
867        
868        keep.restore(context)
869            
870        return is_ok
871    
872    #----------------
873  # Tcl test  # Tcl test
874    
875    # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
876    tcltk_minor_newest_acceptable = 4
877    tcltk_major_required = 8
878    
879  tcl_check_text = r"""  tcl_check_text = r"""
880  #include <tcl.h>  #include <tcl.h>
881  #include <stdio.h>  #include <stdio.h>
# Line 574  def CheckTclVersion(context): Line 898  def CheckTclVersion(context):
898          return 0          return 0
899    
900      major,minor,patch = tuple([int(i) for i in output.split(".")])      major,minor,patch = tuple([int(i) for i in output.split(".")])
901      if major != 8 or minor > 3:      if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
902          context.Result(output+" (bad version)")          context.Result(output+" (bad version)")
903          # bad version          # bad version
904          return 0          return 0
905                    
906      # good version      # good version
907      context.Result(output+" (good)")      context.Result(output+", good")
908      return 1      return 1
909    
910  #----------------  #----------------
# Line 595  int main(void){ Line 919  int main(void){
919  }  }
920  """  """
921  def CheckTk(context):  def CheckTk(context):
922      return CheckExtLib(context,'tk',tcl_check_text,static=env['STATIC_TCLTK'])      return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
923    
924    
925  def CheckTkVersion(context):  def CheckTkVersion(context):
# Line 607  def CheckTkVersion(context): Line 931  def CheckTkVersion(context):
931      if not is_ok:      if not is_ok:
932          context.Result("failed to run check")          context.Result("failed to run check")
933          return 0          return 0
     context.Result(output)  
934    
935      major,minor,patch = tuple([int(i) for i in output.split(".")])      major,minor,patch = tuple([int(i) for i in output.split(".")])
936      if major != 8 or minor > 3:      if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
937          # bad version          # bad version
938            context.Result(output+" (bad version)")
939          return 0          return 0
940                    
941      # good version      # good version
942        context.Result(output+" (good)")
943      return 1      return 1
944    
945  #----------------  #----------------
# Line 662  gcc_version4 = False Line 987  gcc_version4 = False
987    
988  conf = Configure(env  conf = Configure(env
989      , custom_tests = {      , custom_tests = {
990          'CheckSwigVersion' : CheckSwigVersion          'CheckMath' : CheckMath
991            , 'CheckSwigVersion' : CheckSwigVersion
992          , 'CheckCUnit' : CheckCUnit          , 'CheckCUnit' : CheckCUnit
993          , 'CheckTcl' : CheckTcl          , 'CheckTcl' : CheckTcl
994          , 'CheckTclVersion' : CheckTclVersion          , 'CheckTclVersion' : CheckTclVersion
# Line 673  conf = Configure(env Line 999  conf = Configure(env
999          , 'CheckYacc' : CheckYacc          , 'CheckYacc' : CheckYacc
1000          , 'CheckTkTable' : CheckTkTable          , 'CheckTkTable' : CheckTkTable
1001          , 'CheckX11' : CheckX11          , 'CheckX11' : CheckX11
1002            , 'CheckIDA' : CheckIDA
1003            , 'CheckCONOPT' : CheckCONOPT
1004  #       , 'CheckIsNan' : CheckIsNan  #       , 'CheckIsNan' : CheckIsNan
1005  #       , 'CheckCppUnitConfig' : CheckCppUnitConfig  #       , 'CheckCppUnitConfig' : CheckCppUnitConfig
1006      }      }
1007  #   , config_h = "config.h"  #   , config_h = "config.h"
1008  )  )
1009    
1010    # stdio -- just to check that compiler is behaving
1011    
1012    if not conf.CheckHeader('stdio.h'):
1013        print "Did not find 'stdio.h'! Check your compiler configuration."
1014        Exit(1)
1015    
1016  # Math library  # Math library
1017    
1018  #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):  if need_libm:
1019  #   print 'Did not find math library, exiting!'      if not conf.CheckMath():
1020  #   Exit(1)          print 'Did not find math library, exiting!'
1021            Exit(1)
1022        #pass
1023    
1024  # Where is 'isnan'?  # Where is 'isnan'?
1025    
1026  if not conf.CheckFunc('isnan'):  if not conf.CheckFunc('isnan') and not conf.CheckFunc('_isnan'):
1027      print "Didn't find isnan"      print "Didn't find isnan"
1028  #   Exit(1)  #   Exit(1)
1029    
# Line 700  if conf.CheckGcc(): Line 1035  if conf.CheckGcc():
1035          conf.env['HAVE_GCCVISIBILITY']=True;          conf.env['HAVE_GCCVISIBILITY']=True;
1036          conf.env.Append(CCFLAGS=['-fvisibility=hidden'])          conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
1037          conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])          conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
1038        conf.env.Append(CCFLAGS=['-Wall'])
1039    
1040  # YACC  # YACC
1041    
# Line 712  conf.env['HAVE_LEX']=True Line 1048  conf.env['HAVE_LEX']=True
1048    
1049  # Tcl/Tk  # Tcl/Tk
1050    
1051  if conf.CheckTcl():  if with_tcltk:
1052      if with_tcltk_gui and conf.CheckTclVersion():      if conf.CheckTcl():
1053          if conf.CheckTk():          if conf.CheckTclVersion():
1054              if with_tcltk_gui and conf.CheckTkVersion():              if conf.CheckTk():
1055                  if conf.CheckTkTable():                  if with_tcltk and conf.CheckTkVersion():
1056                      pass                      if env['STATIC_TCLTK']:
1057                            if conf.CheckTkTable():
1058                                pass
1059                            else:
1060                                without_tcltk_reason = "TkTable not found"
1061                                with_tcltk = False
1062                  else:                  else:
1063                      without_tcltk_reason = "TkTable not found"                      without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
1064                      with_tcltk_gui = False                      with_tcltk = False
1065              else:              else:
1066                  without_tcltk_reason = "Require Tk version <= 8.3. See 'scons -h'"                  without_tcltk_reason = "Tk not found."
1067                  with_tcltk_gui = False                  with_tcltk = False
1068          else:          else:
1069              without_tcltk_reason = "Tk not found."              without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
1070              with_tcltk_gui = False              with_tcltk = False
     else:  
         without_tcltk_reason = "Require Tcl <= 8.3 Tcl."  
         with_tcltk_gui = False  
1071    
1072  else:      else:
1073      without_tcltk_reason = "Tcl not found."          without_tcltk_reason = "Tcl not found."
1074      with_tcltk_gui = False          with_tcltk = False
1075    
1076  if env['STATIC_TCLTK']:  if env['STATIC_TCLTK']:
1077      conf.CheckX11()      conf.CheckX11()
# Line 754  if not conf.CheckSwigVersion(): Line 1092  if not conf.CheckSwigVersion():
1092    
1093  # CUnit  # CUnit
1094    
1095  if with_cunit_tests:  if with_cunit:
1096      if not conf.CheckCUnit():      if not conf.CheckCUnit():
1097          without_cunit_reason = 'CUnit not found'          without_cunit_reason = 'CUnit not found'
1098            with_cunit = False
1099            #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
1100    
1101    # IDA
1102    
1103    if not with_ida:
1104        without_ida_reason = "Not selected (see config option WITH_SOLVERS)"
1105    elif not conf.CheckIDA():
1106        with_ida = False
1107        without_ida_reason = "IDA not found"
1108    
1109    # CONOPT
1110    
1111    if not with_conopt:
1112        without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
1113    elif not conf.CheckCONOPT():
1114        with_conopt = False
1115        without_conpt_reason = "CONOPT not found"
1116    
1117  # BLAS  # BLAS
1118    
1119  need_blas=False  need_blas=False
1120  if with_tcltk_gui:  
1121    if with_lsode:
1122        need_fortran = True
1123      need_blas=True      need_blas=True
1124    
1125  if need_blas:  if need_blas:
1126      if conf.CheckLib('blas'):      if conf.CheckLib('blas'):
         print "FOUND BLAS"  
1127          with_local_blas = False          with_local_blas = False
1128          without_local_blas_reason = "Found BLAS installed on system"          without_local_blas_reason = "Found BLAS installed on system"
1129      else:      else:
         print "DIDN'T FIND BLAS"  
1130          with_local_blas = True          with_local_blas = True
1131          need_fortran = True          need_fortran = True
1132    else:
1133        with_local_blas= False;
1134        without_local_blas_reason = "BLAS not required"
1135    
1136  # FORTRAN  # FORTRAN
1137    
1138  if need_fortran:  if need_fortran:
1139      conf.env.Tool('f77')      conf.env.Tool('fortran')
1140      detect_fortran = conf.env.Detect(['g77','f77'])      detect_fortran = conf.env.Detect(['g77','f77','gfortran'])
1141      if detect_fortran:      if detect_fortran:
1142          # For some reason, g77 doesn't get detected properly on MinGW          # For some reason, g77 doesn't get detected properly on MinGW
1143          if not env.has_key('F77'):          if not env.has_key('F77') and not env.has_key('FORTRAN'):
1144              conf.env.Replace(F77=detect_fortran)              conf.env.Replace(F77=detect_fortran)
1145              conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')              conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
1146              conf.env.Replace(F77FLAGS='')              conf.env.Replace(F77FLAGS='')
# Line 794  if need_fortran: Line 1154  if need_fortran:
1154              )              )
1155              conf.env.Append(BUILDERS={'Fortran':fortran_builder})              conf.env.Append(BUILDERS={'Fortran':fortran_builder})
1156      else:      else:
1157          print "FORTRAN-77 required but not found"          with_lsode=False;
1158          Exit(1)          without_lsode_reason="FORTRAN-77 required but not found"
1159    
1160  #else:  #else:
1161  #   print "FORTRAN not required"  #   print "FORTRAN not required"
1162    
1163    # F2C
1164    
1165    if need_fortran:
1166        if platform.system()=="Windows":
1167            conf.env.Append(LIBPATH='c:\mingw\lib')
1168    
1169    
1170  # TODO: -D_HPUX_SOURCE is needed  # TODO: -D_HPUX_SOURCE is needed
1171    
1172  # TODO: check size of void*  # TODO: check size of void*
# Line 806  if need_fortran: Line 1174  if need_fortran:
1174  # TODO: detect if dynamic libraries are possible or not  # TODO: detect if dynamic libraries are possible or not
1175    
1176  if platform.system()=="Windows" and env.has_key('MSVS'):  if platform.system()=="Windows" and env.has_key('MSVS'):
1177      if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':      _found_windows_h = conf.CheckHeader('Windows.h')
1178          print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\  
1179              +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."      if not _found_windows_h:
1180          env['PACKAGE_LINKING']='STATIC_PACKAGES'          print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
1181                    Exit(1)
1182    
1183      if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):      if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
1184          with_python = 0;          with_python = 0;
1185          without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."          without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
# Line 826  env.Append(PYTHON_CPPPATH=[distutils.sys Line 1195  env.Append(PYTHON_CPPPATH=[distutils.sys
1195  #---------------------------------------  #---------------------------------------
1196  # SUBSTITUTION DICTIONARY for .in files  # SUBSTITUTION DICTIONARY for .in files
1197    
1198    release = env.get('RELEASE')
1199    if release=="0.":
1200        release="0"
1201    
1202    #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
1203    
1204  subst_dict = {  subst_dict = {
1205      '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']      '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
1206      , '@GLADE_FILE@':'ascend.glade'      , '@GLADE_FILE@':'ascend.glade'
1207      , '@HELP_ROOT@':''      , '@HELP_ROOT@':''
1208      , '@ICON_EXTENSION@':icon_extension      , '@ICON_EXTENSION@':icon_extension
1209      , '@INSTALL_DATA@':env['INSTALL_DATA']      , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
1210      , '@INSTALL_BIN@':env['INSTALL_BIN']      , '@INSTALL_BIN@':env['INSTALL_BIN']
1211      , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']      , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
1212        , '@INSTALL_LIB@':env['INSTALL_LIB']
1213        , '@INSTALL_MODELS@':env['INSTALL_MODELS']
1214      , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']      , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
1215      , '@VERSION@':version      , '@VERSION@':version
1216        , '@RELEASE@':release
1217        , '@DISTTAR_NAME@':env['DISTTAR_NAME']
1218      , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'      , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
1219      , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']      , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
1220      , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']      , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
1221        , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
1222        , '@ASC_DISTDIR_REL_BIN@' : default_rel_distdir
1223        , '@PYTHON@' : python_exe
1224        , '@ASC_CONOPT_LIB@':env.get('CONOPT_LIB')
1225        , '@ASC_CONOPT_ENVVAR@':env.get('CONOPT_ENVVAR')
1226        , '@ASC_CONOPT_DLPATH@':c_escape(env.subst("$CONOPT_LIBPATH"))
1227  }  }
1228    
1229  if env['WITH_LOCAL_HELP']:  if env.get('WITH_LOCAL_HELP'):
1230      print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']      print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
1231      subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']      subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
1232    
1233    # bool options...
1234    for k,v in {
1235            'ABSOLUTE_PATHS' : 'ASC_ABSOLUTE_PATHS'
1236            ,'WITH_XTERM_COLORS' : 'ASC_XTERM_COLORS'
1237            ,'MALLOC_DEBUG' : 'MALLOC_DEBUG'
1238    }.iteritems():
1239        if env.get(k):
1240    #       subst_dict['@'+v+'@']='1'
1241            subst_dict["/\\* #define "+v+' @'+v+"@ \\*/"]='# define '+v+' 1 '
1242    
1243    if with_ida:
1244        subst_dict["/\\* #define ASC_WITH_IDA @ASC_WITH_IDA@ \\*/"]='#define ASC_WITH_IDA '
1245    
1246    if with_conopt:
1247        subst_dict["/\\* #define ASC_WITH_CONOPT @ASC_WITH_CONOPT@ \\*/"]='#define ASC_WITH_CONOPT '
1248    
1249    if with_lsode:
1250        subst_dict["/\\* #define ASC_WITH_LSODE @ASC_WITH_LSODE@ \\*/"]='#define ASC_WITH_LSODE '
1251    
1252  if with_python:  if with_python:
1253      subst_dict['@ASCXX_USE_PYTHON@']="1"      subst_dict['@ASCXX_USE_PYTHON@']="1"
1254        env['WITH_PYTHON']=1;
1255    
1256  if env.has_key('HAVE_GCCVISIBILITY'):  if env.has_key('HAVE_GCCVISIBILITY'):
1257      subst_dict['@HAVE_GCCVISIBILITY@'] = "1"      subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
# Line 854  if env.has_key('HAVE_GCCVISIBILITY'): Line 1259  if env.has_key('HAVE_GCCVISIBILITY'):
1259  env.Append(SUBST_DICT=subst_dict)  env.Append(SUBST_DICT=subst_dict)
1260    
1261  #------------------------------------------------------  #------------------------------------------------------
1262    # RECIPE: SWIG scanner
1263    
1264    import SCons.Script
1265    
1266    SWIGScanner = SCons.Scanner.ClassicCPP(
1267        "SWIGScan"
1268        , ".i"
1269        , "CPPPATH"
1270        , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
1271    )
1272    
1273    env.Append(SCANNERS=[SWIGScanner])
1274    
1275    #------------------------------------------------------
1276  # RECIPE: 'SubstInFile', used in pygtk SConscript  # RECIPE: 'SubstInFile', used in pygtk SConscript
1277    
1278  import re  import re
# Line 945  SConsEnvironment.InstallPerm = InstallPe Line 1364  SConsEnvironment.InstallPerm = InstallPe
1364            
1365  # define wrappers      # define wrappers    
1366  SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)    SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)  
1367  SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)      SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1368    SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
 #------------------------------------------------------  
 # NSIS Support for SCons  
   
 # Adapted version by John Pye, April 2006.  
 # from http://www.scons.org/cgi-sys/cgiwrap/scons/moin.cgi/NsisSconsTool  
 # Written by Mike Elkins, January 2004.  
   
 #This tool provides SCons support for the Nullsoft Scriptable Install System  
 #a windows installer builder available at http://nsis.sourceforge.net/home  
   
 #In addition, if you set NSISDEFINES to a dictionary, those variables will be passed  
 #to NSIS.  
   
 import SCons.Builder  
 import SCons.Util  
 import SCons.Scanner  
 import SCons.Sig  
 import os.path  
 import glob  
   
 def nsis_parse( sources, keyword, multiple ):  
   """  
   A function that knows how to read a .nsi file and figure  
   out what files are referenced, or find the 'OutFile' line.  
   
   
   sources is a list of nsi files.  
   keyword is the command ('File' or 'OutFile') to look for  
   multiple is true if you want all the args as a list, false if you  
   just want the first one.  
   """  
   stuff = []  
   for s in sources:  
     c = s.get_contents()  
     for l in c.split('\n'):  
       semi = l.find(';')  
       if (semi != -1):  
         l = l[:semi]  
       hash = l.find('#')  
       if (hash != -1):  
         l = l[:hash]  
       # Look for the keyword  
       l = l.strip()  
       spl = l.split(None,1)  
       if len(spl) > 1:  
         if spl[0].capitalize() == keyword.capitalize():  
           arg = spl[1]  
           if arg.startswith('"') and arg.endswith('"'):  
             arg = arg[1:-1]  
           if multiple:  
             stuff += [ arg ]  
           else:  
             return arg  
   return stuff  
   
   
 def nsis_path( filename, nsisdefines, rootdir ):  
   """  
   Do environment replacement, and prepend with the SCons root dir if  
   necessary  
   """  
   # We can't do variables defined by NSIS itself (like $INSTDIR),  
   # only user supplied ones (like ${FOO})  
   varPos = filename.find('${')  
   while varPos != -1:  
     endpos = filename.find('}',varPos)  
     assert endpos != -1  
     if not nsisdefines.has_key(filename[varPos+2:endpos]):  
       raise KeyError ("Could not find %s in NSISDEFINES" % filename[varPos+2:endpos])  
     val = nsisdefines[filename[varPos+2:endpos]]  
     if type(val) == list:  
       if varPos != 0 or endpos+1 != len(filename):  
         raise Exception("Can't use lists on variables that aren't complete filenames")  
       return val  
     filename = filename[0:varPos] + val + filename[endpos+1:]  
     varPos = filename.find('${')  
   return filename  
   
   
 def nsis_scanner( node, env, path ):  
   """  
   The scanner that looks through the source .nsi files and finds all lines  
   that are the 'File' command, fixes the directories etc, and returns them.  
   """  
   nodes = node.rfile()  
   if not node.exists():  
     return []  
   nodes = []  
   source_dir = node.get_dir()  
   for include in nsis_parse([node],'file',1):  
     exp = nsis_path(include,env['NSISDEFINES'],source_dir)  
     if type(exp) != list:  
       exp = [exp]  
     for p in exp:  
       for filename in glob.glob( os.path.abspath(  
         os.path.join(str(source_dir),p))):  
           # Why absolute path?  Cause it breaks mysteriously without it :(  
           nodes.append(filename)  
   return nodes  
   
   
 def nsis_emitter( source, target, env ):  
   """  
   The emitter changes the target name to match what the command actually will  
   output, which is the argument to the OutFile command.  
   """  
   nsp = nsis_parse(source,'outfile',0)  
   if not nsp:  
     return (target,source)  
   x  = (  
     nsis_path(nsp,env['NSISDEFINES'],''),  
     source)  
   return x  
   
 def quoteIfSpaced(text):  
   if ' ' in text:  
     return '"'+text+'"'  
   else:  
     return text  
   
 def toString(item,env):  
   if type(item) == list:  
     ret = ''  
     for i in item:  
       if ret:  
         ret += ' '  
       val = toString(i,env)  
       if ' ' in val:  
         val = "'"+val+"'"  
       ret += val  
     return ret  
   else:  
     # For convienence, handle #s here  
     if str(item).startswith('#'):  
       item = env.File(item).get_abspath()  
     return str(item)  
   
 def runNSIS(source,target,env,for_signature):  
   ret = env['NSIS']+" "  
   if env.has_key('NSISFLAGS'):  
     for flag in env['NSISFLAGS']:  
       ret += flag  
       ret += ' '  
   if env.has_key('NSISDEFINES'):  
     for d in env['NSISDEFINES']:  
       ret += '/D'+d  
       if env['NSISDEFINES'][d]:  
         ret +='='+quoteIfSpaced(toString(env['NSISDEFINES'][d],env))  
       ret += ' '  
   for s in source:  
     ret += quoteIfSpaced(str(s))  
   return ret  
   
 def find_nsis(env):  
   """  
   Try and figure out if NSIS is installed on this machine, and if so,  
   where.  
   """  
   if SCons.Util.can_read_reg:  
     # If we can read the registry, get the NSIS command from it  
     try:  
       k = SCons.Util.RegOpenKeyEx(SCons.Util.hkey_mod.HKEY_LOCAL_MACHINE,  
                                   'SOFTWARE\\NSIS')  
       val, tok = SCons.Util.RegQueryValueEx(k,None)  
       ret = val + os.path.sep + 'makensis.exe'  
       if os.path.exists(ret):  
         return '"' + ret + '"'  
       else:  
         return None  
     except:  
       pass # Couldn't find the key, just act like we can't read the registry  
   # Hope it's on the path  
   return env.WhereIs('makensis.exe')  
   
 def nsis_exists(env):  
   """  
   Is NSIS findable on this machine?  
   """  
   if find_nsis(env) != None:  
     return 1  
   return 0  
   
 env['BUILDERS']['Nsis'] = SCons.Builder.Builder(generator=runNSIS,  
                                  src_suffix='.nsi',  
                                  emitter=nsis_emitter)  
   
 env.Append(SCANNERS = SCons.Scanner.Scanner( function = nsis_scanner,  
              skeys = ['.nsi']))  
   
 if not env.has_key('NSISDEFINES'):  
     env['NSISDEFINES'] = {}  
 env['NSIS'] = find_nsis(env)  
1369    
1370  #------------------------------------------------------  #------------------------------------------------------
1371  # BUILD...  # BUILD...
1372    
1373  # so that #include <modulename/headername.h> works across all modules...  # so that #include <modulename/headername.h> works across all modules...
1374  env.Append(CPPPATH=['#base/generic'])  env.AppendUnique(CPPPATH=['#base/generic'])
   
 if gcc_version4:  
     env.Append(CCFLAGS=['-fvisibility=hidden'])  
1375    
1376  if env['DEBUG']:  if env['DEBUG']:
1377      env.Append(CCFLAGS=['-g'])      env.Append(CCFLAGS=['-g'])
1378    
1379  #-------------  if env['GCOV']:
1380  # TCL/TK GUI      env.Append(
1381            CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1382            , LIBS=['gcov']
1383            , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1384        )
1385    
1386  if with_tcltk_gui:  if with_ida:
1387      if with_local_blas:      env.Append(WITH_IDA=1)
         env.SConscript(['blas/SConscript'],'env')  
     else:  
         print "Skipping... BLAS won't be build:", without_local_blas_reason  
1388    
1389      env.SConscript(['lsod/SConscript'],'env')        if with_conopt:
1390        env.Append(WITH_CONOPT=1)
1391    
1392      env.SConscript(['linpack/SConscript'],'env')  #-------------
1393      env.SConscript(['tcltk98/generic/interface/SConscript'],'env')  # TCL/TK GUI
1394    
1395    if with_tcltk:
1396        env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1397  else:  else:
1398      print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason      print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1399    
# Line 1179  else: Line 1408  else:
1408  #------------  #------------
1409  # BASE/GENERIC SUBDIRECTORIES  # BASE/GENERIC SUBDIRECTORIES
1410    
1411    libascend_env = env.Copy()
1412    
1413  dirs = ['general','utilities','compiler','solver','packages']  dirs = ['general','utilities','compiler','solver','packages']
1414    
1415  srcs = []  srcs = []
1416  for d in dirs:  for d in dirs:
1417      heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')      heresrcs = libascend_env.SConscript('base/generic/'+d+'/SConscript','libascend_env')
1418      srcs += heresrcs      srcs += heresrcs
1419    
1420  #-------------  #-------------
1421    # IMPORTED CODE: LSODE, BLAS, etc
1422    
1423    if with_lsode:
1424        srcs += env.SConscript(['lsod/SConscript'],'env')
1425        srcs += env.SConscript(['linpack/SConscript'],'env')
1426    else:
1427        print "Skipping... LSODE won't be built:", without_lsode_reason
1428    
1429    if with_local_blas:
1430        srcs += env.SConscript(['blas/SConscript'],'env')
1431    else:
1432        print "Skipping... BLAS won't be built:", without_local_blas_reason
1433    
1434    if not with_ida:
1435        print "Skipping... IDA won't be built:", without_ida_reason
1436    
1437    #-------------
1438  # LIBASCEND -- all base/generic functionality  # LIBASCEND -- all base/generic functionality
1439    
1440  libascend = env.SharedLibrary('ascend',srcs)  libascend = libascend_env.SharedLibrary('ascend',srcs)
1441    
1442    env.Alias('libascend',libascend)
1443    
1444  #-------------  #-------------
1445  # UNIT TESTS  # UNIT TESTS (C CODE)
1446    
1447  if with_cunit_tests:  if with_cunit:
1448      testdirs = ['general','solver','utilities']      testdirs = ['general','solver','utilities']
1449        testsrcs = []
1450      for testdir in testdirs:      for testdir in testdirs:
1451          path = 'base/generic/'+testdir+'/test/'          path = 'base/generic/'+testdir+'/test/'
1452          env.SConscript([path+'SConscript'],'env')          env.SConscript([path+'SConscript'],'env')
1453            testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1454    
1455        #print "TESTSRCS =",testsrcs
1456            
1457      env.SConscript(['test/SConscript'],'env')      env.SConscript(['test/SConscript'],'env')
1458      env.SConscript(['base/generic/test/SConscript'],'env')      env.SConscript(['base/generic/test/SConscript'],'env')
1459        
1460        env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1461            
1462  else:  else:
1463      print "Skipping... CUnit tests aren't being built:",without_cunit_reason      print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1464    
1465    #-------------
1466    # EXTERNAL FUNCTIONS
1467    
1468    extfns = []
1469    if with_extfns:
1470        testdirs = ['johnpye/extfn']
1471        for testdir in testdirs:
1472            path = 'models/'+testdir+"/SConscript"
1473            extfns += env.SConscript(path,'env')
1474    else:
1475        print "Skipping... External modules aren't being built:",without_extfns_reason
1476    
1477    env.Alias('extfns',extfns)
1478    
1479    #------------------------------------------------------
1480    # CREATE ASCEND-CONFIG scriptlet
1481    
1482    ascendconfig = env.SubstInFile('ascend-config.in')
1483    
1484  #------------------------------------------------------  #------------------------------------------------------
1485  # INSTALLATION  # INSTALLATION
1486    
1487  if env.has_key('CAN_INSTALL') and env['CAN_INSTALL']:  if env.get('CAN_INSTALL'):
1488      # the models directory only needs to be processed for installation, no other processing required.      # the models directory only needs to be processed for installation, no other processing required.
1489      env.SConscript(['models/SConscript'],'env')      env.SConscript(['models/SConscript'],'env')
1490    
1491      dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']      dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE']
1492      install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]      install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1493    
1494      # TODO: add install options      # TODO: add install options
1495      env.Alias('install',install_dirs)      env.Alias('install',install_dirs)
1496    
1497      env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)      env.InstallShared(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1498    
1499        env.InstallProgram(env['INSTALL_ROOT']+env['INSTALL_BIN'],ascendconfig)
1500    
1501    #------------------------------------------------------
1502    # WINDOWS INSTALLER
1503    # For the windows installer, please see pygtk/SConscript
1504    
1505    if with_installer:
1506        pass
1507    else:
1508        print "Skipping... Windows installer isn't being built:",without_installer_reason
1509    
1510    #------------------------------------------------------
1511    # PROJECT FILE for MSVC
1512    
1513    env.SConscript(['base/msvc/SConscript'],['env','libascend']);
1514    
1515  #------------------------------------------------------  #------------------------------------------------------
1516  # CREATE the SPEC file for generation of RPM packages  # CREATE the SPEC file for generation of RPM packages
1517    
1518  if platform.system()=="Linux":  if platform.system()=="Linux":
1519      env.SubstInFile('ascend.spec.in')      env.SubstInFile('ascend.spec.in')
1520    
1521    #------------------------------------------------------
1522    # DISTRIBUTION TAR FILE
1523    
1524    env['DISTTAR_FORMAT']='bz2'
1525    env.Append(
1526        DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1527        , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1528    )
1529    
1530    tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1531        , [env.Dir('#')]
1532    )
1533    
1534    env.Depends(tar,'ascend.spec')
1535    
1536    #------------------------------------------------------
1537    # LIBASCEND DOXYGEN DOCUMENTATION
1538    
1539    env.SConscript('base/doc/SConscript',['env'])
1540    
1541    #------------------------------------------------------
1542    # RPM BUILD
1543    
1544    # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
1545    # (check * for the version number used to create the tarball)
1546    
1547    #------------------------------------------------------
1548    # DEFAULT TARGETS
1549    
1550    default_targets =['libascend']
1551    if with_tcltk:
1552        default_targets.append('tcltk')
1553    if with_python:
1554        default_targets.append('pygtk')
1555    if with_installer:
1556        default_targets.append('installer')
1557    if with_extfns:
1558        default_targets.append('extfns')
1559    
1560    env.Default(default_targets)
1561    
1562    print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
1563    
1564    # vim: set syntax=python:
1565    

Legend:
Removed from v.549  
changed lines
  Added in v.800

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22