/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 463 - (hide annotations) (download)
Sun Apr 16 10:18:16 2006 UTC (13 years, 8 months ago) by johnpye
File size: 21423 byte(s)
Converting to the new shared-object configuration (on email discussion with Ben)
First stage: PyGTK interface on windows. More to come.
1 johnpye 393 import os, commands, platform, distutils.sysconfig, os.path
2 johnpye 385
3 johnpye 439 version = "0.9.6rc0"
4    
5 johnpye 385 #------------------------------------------------------
6     # OPTIONS
7 johnpye 392 #
8     # Note that if you set the options via the command line, they will be
9     # remembered in the file 'options.cache'. It's a feature ;-)
10 johnpye 385
11     opts = Options(['options.cache', 'config.py'])
12     print "PLATFORM = ",platform.system()
13    
14 johnpye 392 # Import the outside environment
15     env = Environment(ENV=os.environ)
16 johnpye 463
17 johnpye 415 if platform.system()=='Windows' and env.has_key('MSVS'):
18 johnpye 414 print "INCLUDE =",env['ENV']['INCLUDE']
19 johnpye 416 print "LIB =",env['ENV']['LIB']
20     print "LINK =",env['LINK']
21     print "LINKCOM =",env['LINKCOM']
22     print "AR =",env['AR']
23     print "ARCOM =",env['ARCOM']
24 johnpye 427 #env['AR']='link /lib'
25 johnpye 414 env.Append(CPPPATH=env['ENV']['INCLUDE'])
26     env.Append(LIBPATH=env['ENV']['LIB'])
27 johnpye 427 env.Append(CPPDEFINES=['_CRT_SECURE_NO_DEPRECATED','_CRT_SECURE_NO_DEPRECATE'])
28 johnpye 414
29 johnpye 463
30    
31 johnpye 385 # Package linking option
32 johnpye 386 opts.Add(EnumOption(
33     'PACKAGE_LINKING'
34 johnpye 385 , 'Style of linking for external libraries'
35     , 'DYNAMIC_PACKAGES'
36 johnpye 386 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
37     ))
38 johnpye 385
39 johnpye 392 # You can turn off building of Tcl/Tk interface
40 johnpye 386 opts.Add(BoolOption(
41     'WITHOUT_TCLTK_GUI'
42     ,"Set to True if you don't want to build the original Tcl/Tk GUI."
43     , False
44     ))
45    
46 johnpye 392 # You can turn off the building of the Python interface
47 johnpye 387 opts.Add(BoolOption(
48     'WITHOUT_PYTHON'
49     ,"Set to True if you don't want to build Python wrappers."
50     , False
51     ))
52    
53 johnpye 392 # Which solvers will we allow?
54     opts.Add(ListOption(
55     'WITH_SOLVERS'
56 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
57     +" works."
58 johnpye 392 ,["QRSLV","CMSLV"]
59     ,['QRSLV','MPS','SLV','OPTSQP'
60     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
61     ,'LSOD','OPTSQP'
62     ]
63     ))
64    
65 johnpye 393 # Where will the local copy of the help files be kept?
66     opts.Add(PackageOption(
67     'WITH_LOCAL_HELP'
68     , "Directory containing the local copy of the help files (optional)"
69     , "no"
70     ))
71    
72     # Will bintoken support be enabled?
73     opts.Add(BoolOption(
74     'WITH_BINTOKEN'
75     ,"Enable bintoken support? This means compiling models as C-code before"
76     +" running them, to increase solving speed for large models."
77     ,False
78     ))
79    
80 johnpye 398 # What should the default ASCENDLIBRARY path be?
81     # Note: users can change it by editing their ~/.ascend.ini
82 johnpye 393 opts.Add(
83     'DEFAULT_ASCENDLIBRARY'
84     ,"Set the default value of the ASCENDLIBRARY -- the location where"
85     +" ASCEND will look for models when running ASCEND"
86 johnpye 459 ,"$INSTALL_DATA/models"
87 johnpye 393 )
88    
89 johnpye 398 # Where is SWIG?
90     opts.Add(
91     'SWIG'
92     ,"SWIG location, probably only required for MinGW and MSVC users."
93     +" Enter the location as a Windows-style path, for example"
94 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
95 johnpye 398 )
96    
97 johnpye 400 # Build the test suite?
98     opts.Add(BoolOption(
99     'WITH_CUNIT_TESTS'
100     ,"Whether to build the CUnit tests. Default is off. If set to on,"
101     +" you must have CUnit installed somewhere that SCons can"
102 johnpye 463 +" find it, or else use the CUNIT_* options to specify."
103 johnpye 400 ,False
104     ))
105 johnpye 393
106 johnpye 400 # Where are the CUnit includes?
107     opts.Add(PackageOption(
108     'CUNIT_CPPPATH'
109     ,"Where are your CUnit include files?"
110 johnpye 459 ,'off'
111 johnpye 400 ))
112 johnpye 392
113 johnpye 404 # Where are the CUnit libraries?
114 johnpye 400 opts.Add(PackageOption(
115     'CUNIT_LIBPATH'
116 johnpye 404 ,"Where are your CUnit libraries?"
117 johnpye 459 ,'off'
118 johnpye 400 ))
119    
120 johnpye 404 # Where are the Tcl includes?
121     opts.Add(PackageOption(
122     'TCL_CPPPATH'
123     ,"Where are your Tcl include files?"
124 johnpye 463 ,"disable"
125 johnpye 404 ))
126    
127     # Where are the Tcl libs?
128     opts.Add(PackageOption(
129     'TCL_LIBPATH'
130     ,"Where are your Tcl libraries?"
131 johnpye 459 ,'off'
132 johnpye 404 ))
133    
134 johnpye 428 # What is the name of the Tcl lib?
135     opts.Add(
136     'TCL_LIB'
137     ,"Name of Tcl lib (eg 'tcl' or 'tcl83')"
138     ,'tcl'
139     )
140    
141 johnpye 405 # Where are the Tk includes?
142     opts.Add(PackageOption(
143     'TK_CPPPATH'
144     ,"Where are your Tk include files?"
145 johnpye 459 ,'off'
146 johnpye 405 ))
147 johnpye 404
148 johnpye 405 # Where are the Tk libs?
149     opts.Add(PackageOption(
150     'TK_LIBPATH'
151     ,"Where are your Tk libraries?"
152 johnpye 459 ,'off'
153 johnpye 405 ))
154    
155 johnpye 428 # What is the name of the Tk lib?
156     opts.Add(
157     'TK_LIB'
158     ,"Name of Tk lib (eg 'tk' or 'tk83')"
159     ,'tk'
160 johnpye 435 )
161    
162 johnpye 460 # Static linking to TkTable
163    
164     opts.Add(BoolOption(
165     'STATIC_TKTABLE'
166     ,'Use static linking to TkTable or not'
167     ,False
168     ))
169    
170     opts.Add(PackageOption(
171     'TKTABLE_LIBPATH'
172     ,'Location of TkTable static library'
173     ,'off'
174     ))
175    
176 johnpye 435 opts.Add(
177 johnpye 460 'TKTABLE_LIB'
178     ,'Name of TkTable static library (excluding suffix/prefix, eg libtktable2.8.so -> tktable2.8)'
179     ,'Tktable2.8'
180     )
181    
182     opts.Add(
183 johnpye 435 'INSTALL_PREFIX'
184     ,'Root location for installed files'
185 johnpye 449 ,'/usr/local'
186 johnpye 428 )
187    
188 johnpye 435 opts.Add(
189     'INSTALL_BIN'
190     ,'Location to put binaries during installation'
191     ,"$INSTALL_PREFIX/bin"
192     )
193    
194     opts.Add(
195 johnpye 463 'INSTALL_LIB'
196     ,'Location to put binaries during installation'
197     ,"$INSTALL_PREFIX/lib"
198     )
199    
200     opts.Add(
201 johnpye 435 'INSTALL_DATA'
202     ,'Location to put data files during installation'
203     ,"$INSTALL_PREFIX/share"
204     )
205    
206     opts.Add(
207     'INSTALL_INCLUDE'
208     ,'Location to put header files during installation'
209     ,"$INSTALL_PREFIX/include"
210     )
211    
212 johnpye 455 if platform.system()=="Windows":
213     default_install_assets = "glade/"
214     icon_extension = '.png'
215     else:
216     default_install_assets = "$INSTALL_DATA/ascend/glade/"
217     icon_extension = '.svg'
218    
219 johnpye 448 opts.Add(
220 johnpye 455 'PYGTK_ASSETS'
221     ,'Default location for Glade assets (placed in pygtk/interface/config.py)'
222     ,default_install_assets
223     )
224    
225     opts.Add(
226 johnpye 448 'INSTALL_ROOT'
227     ,'For use by RPM only: location of %{buildroot} during rpmbuild'
228     ,""
229     )
230    
231 johnpye 392 # TODO: OTHER OPTIONS?
232     # TODO: flags for optimisation
233 johnpye 393 # TODO: turning on/off bintoken functionality
234 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
235 johnpye 393
236 johnpye 385 opts.Update(env)
237     opts.Save('options.cache',env)
238    
239     Help(opts.GenerateHelpText(env))
240    
241 johnpye 386 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
242 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
243 johnpye 386
244 johnpye 387 with_python = (env['WITHOUT_PYTHON']==False)
245 johnpye 427 without_python_reason = "disabled by options/config.py"
246 johnpye 387
247 johnpye 400 with_cunit_tests = env['WITH_CUNIT_TESTS']
248 johnpye 427 without_cunit_reason = "not requested"
249 johnpye 400
250 johnpye 392 print "SOLVERS:",env['WITH_SOLVERS']
251 johnpye 393 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
252     print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
253     print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
254    
255     subst_dict = {
256     '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
257 johnpye 436 , '@GLADE_FILE@':'ascend.glade'
258 johnpye 393 , '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
259 johnpye 455 , '@ICON_EXTENSION@':icon_extension
260 johnpye 393 , '@HELP_ROOT@':''
261 johnpye 436 , '@INSTALL_DATA@':env['INSTALL_DATA']
262     , '@INSTALL_BIN@':env['INSTALL_BIN']
263     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
264 johnpye 455 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
265 johnpye 439 , '@VERSION@':version
266 johnpye 393 }
267    
268     if env['WITH_LOCAL_HELP']:
269     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
270 johnpye 463
271     can_install = True
272     if platform.system()=='Windows':
273     can_install = False
274    
275     env['CAN_INSTALL']=can_install
276    
277 johnpye 393 env.Append(SUBST_DICT=subst_dict)
278    
279 johnpye 385 #------------------------------------------------------
280 johnpye 398 # SPECIAL CONFIGURATION TESTS
281    
282 johnpye 463 need_fortran = False
283    
284 johnpye 400 #----------------
285     # SWIG
286    
287 johnpye 398 import os,re
288    
289 johnpye 413 def get_swig_version(env):
290 johnpye 403 cmd = env['SWIG']+' -version'
291 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
292 johnpye 403 output = coutcerr.read()
293 johnpye 398
294 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
295     expr = re.compile(restr,re.M);
296 johnpye 398 m = expr.search(output);
297     if not m:
298 johnpye 413 return None
299 johnpye 398 maj = int(m.group('maj'))
300     min = int(m.group('min'))
301     pat = int(m.group('pat'))
302 johnpye 413
303     return (maj,min,pat)
304 johnpye 398
305 johnpye 413
306     def CheckSwigVersion(context):
307    
308     try:
309     context.Message("Checking version of SWIG... ")
310     maj,min,pat = get_swig_version(context.env)
311     except:
312     context.Result("Failed to detect version, or failed to run SWIG")
313     return 0;
314    
315 johnpye 398 if maj == 1 and (
316 johnpye 400 min > 3
317     or (min == 3 and pat >= 24)
318 johnpye 398 ):
319     context.Result("ok, %d.%d.%d" % (maj,min,pat))
320     return 1;
321 johnpye 401 else:
322     context.Result("too old, %d.%d.%d" % (maj,min,pat))
323     return 0;
324 johnpye 398
325 johnpye 400 #----------------
326     # General purpose library-and-header test
327    
328 johnpye 404 class KeepContext:
329     def __init__(self,context,varprefix):
330     self.keep = {}
331     for k in ['LIBS','LIBPATH','CPPPATH']:
332     if context.env.has_key(k):
333     self.keep[k] = context.env[k]
334 johnpye 463 else:
335     self.keep[k] = None
336 johnpye 404
337     libpath_add = []
338     if context.env.has_key(varprefix+'_LIBPATH'):
339     libpath_add = [env[varprefix+'_LIBPATH']]
340 johnpye 428 #print "Adding '"+str(libpath_add)+"' to lib path"
341 johnpye 400
342 johnpye 404 cpppath_add = []
343     if context.env.has_key(varprefix+'_CPPPATH'):
344     cpppath_add = [env[varprefix+'_CPPPATH']]
345 johnpye 428 #print "Adding '"+str(cpppath_add)+"' to cpp path"
346    
347     libs_add = []
348     if context.env.has_key(varprefix+'_LIB'):
349     libs_add = [env[varprefix+'_LIB']]
350 johnpye 463 print "Adding '"+str(libs_add)+"' to libs"
351 johnpye 428
352 johnpye 405 context.env.Append(
353     LIBPATH = libpath_add
354     , CPPPATH = cpppath_add
355 johnpye 428 , LIBS = libs_add
356 johnpye 405 )
357 johnpye 404
358     def restore(self,context):
359 johnpye 463 print "RESTORING CONTEXT"
360     print self.keep
361     print "..."
362 johnpye 404 for k in self.keep:
363 johnpye 463 if self.keep[k]==None:
364     print "Clearing "+str(k)
365     del context.env[k];
366     else:
367     print "Restoring "+str(k)+" to '"+self.keep[k]+"'"
368     context.env[k]=self.keep[k];
369 johnpye 404
370 johnpye 400 def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
371     """This method will check for variables LIBNAME_LIBPATH
372     and LIBNAME_CPPPATH and try to compile and link the
373     file with the provided text, linking with the
374     library libname."""
375    
376 johnpye 405 context.Message( 'Checking for '+libname+'... ' )
377 johnpye 400
378     if varprefix==None:
379     varprefix = libname.upper()
380    
381 johnpye 404 keep = KeepContext(context,varprefix)
382 johnpye 400
383 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
384 johnpye 463 # if varprefix_LIB were in env, KeepContext would
385     # have appended it already
386 johnpye 451 context.env.Append(LIBS=libname)
387 johnpye 428
388 johnpye 404 is_ok = context.TryLink(text,ext)
389 johnpye 428
390     # print "Link success? ",(is_ok != 0)
391 johnpye 400
392 johnpye 405 keep.restore(context)
393 johnpye 400
394 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
395     # print "Restored LIBS="+libname
396     # print "Restored LIBPATH="+str(context.env['LIBPATH'])
397    
398 johnpye 404 context.Result(is_ok)
399     return is_ok
400    
401     #----------------
402     # CUnit test
403    
404 johnpye 400 cunit_test_text = """
405 johnpye 451 #include <CUnit/CUnit.h>
406 johnpye 400 int maxi(int i1, int i2){
407     return (i1 > i2) ? i1 : i2;
408     }
409    
410     void test_maxi(void){
411     CU_ASSERT(maxi(0,2) == 2);
412     CU_ASSERT(maxi(0,-2) == 0);
413     CU_ASSERT(maxi(2,2) == 2);
414    
415     }
416     int main(void){
417     /* CU_initialize_registry() */
418 johnpye 404 return 0;
419 johnpye 400 }
420     """
421    
422     def CheckCUnit(context):
423 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
424 johnpye 400
425 johnpye 404 #----------------
426 johnpye 405 # Tcl test
427 johnpye 404
428     tcl_check_text = r"""
429     #include <tcl.h>
430     #include <stdio.h>
431     int main(void){
432     printf("%s",TCL_PATCH_LEVEL);
433     return 0;
434     }
435     """
436    
437     def CheckTcl(context):
438 johnpye 405 return CheckExtLib(context,'tcl',tcl_check_text)
439    
440     def CheckTclVersion(context):
441 johnpye 404 keep = KeepContext(context,'TCL')
442 johnpye 405 context.Message("Checking Tcl version... ")
443     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
444 johnpye 404 keep.restore(context)
445     if not is_ok:
446 johnpye 405 context.Result("failed to run check")
447 johnpye 404 return 0
448 johnpye 405
449     major,minor,patch = tuple(int(i) for i in output.split("."))
450     if major != 8 or minor > 3:
451 johnpye 428 context.Result(output+" (bad version)")
452 johnpye 405 # bad version
453     return 0
454    
455     # good version
456 johnpye 428 context.Result(output+" (good)")
457 johnpye 404 return 1
458    
459 johnpye 405 #----------------
460 johnpye 463 # Tk test
461 johnpye 405
462     tk_check_text = r"""
463     #include <tk.h>
464     #include <stdio.h>
465     int main(void){
466     printf("%s",TK_PATCH_LEVEL);
467     return 0;
468     }
469     """
470     def CheckTk(context):
471 johnpye 428 return CheckExtLib(context,'tk',tcl_check_text)
472 johnpye 405
473 johnpye 428
474 johnpye 405 def CheckTkVersion(context):
475     keep = KeepContext(context,'TK')
476     context.Message("Checking Tk version... ")
477     (is_ok,output) = context.TryRun(tk_check_text,'.c')
478 johnpye 404 keep.restore(context)
479     if not is_ok:
480     context.Result("failed to run check")
481     return 0
482     context.Result(output)
483    
484     major,minor,patch = tuple(int(i) for i in output.split("."))
485     if major != 8 or minor > 3:
486     # bad version
487     return 0
488 johnpye 400
489 johnpye 404 # good version
490     return 1
491    
492 johnpye 398 #------------------------------------------------------
493 johnpye 385 # CONFIGURATION
494    
495     conf = Configure(env
496     , custom_tests = {
497 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
498 johnpye 400 , 'CheckCUnit' : CheckCUnit
499 johnpye 404 , 'CheckTcl' : CheckTcl
500     , 'CheckTclVersion' : CheckTclVersion
501 johnpye 405 , 'CheckTk' : CheckTk
502     , 'CheckTkVersion' : CheckTkVersion
503 johnpye 400 # , 'CheckIsNan' : CheckIsNan
504     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
505 johnpye 385 }
506 johnpye 459 # , config_h = "config.h"
507 johnpye 385 )
508    
509 johnpye 398
510 johnpye 385 # Math library
511    
512 johnpye 427 #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
513     # print 'Did not find math library, exiting!'
514     # Exit(1)
515    
516 johnpye 385 # Where is 'isnan'?
517    
518     if not conf.CheckFunc('isnan'):
519     print "Didn't find isnan"
520 johnpye 414 # Exit(1)
521 johnpye 385
522 johnpye 387 # Tcl/Tk
523 johnpye 386
524 johnpye 428 if conf.CheckTcl():
525     if with_tcltk_gui and conf.CheckTclVersion():
526     if conf.CheckTk():
527     if with_tcltk_gui and not conf.CheckTkVersion():
528     without_tcltk_reason = "Require Tk version <= 8.3. See 'scons -h'"
529     with_tcltk_gui = False
530     else:
531     without_tcltk_reason = "Tk not found."
532     with_tcltk_gui = False
533     else:
534 johnpye 405 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
535 johnpye 404 with_tcltk_gui = False
536 johnpye 386
537 johnpye 405 else:
538 johnpye 428 without_tcltk_reason = "Tcl not found."
539 johnpye 412 with_tcltk_gui = False
540    
541 johnpye 395 # Python... obviously we're already running python, so we just need to
542     # check that we can link to the python library OK:
543    
544 johnpye 391 if platform.system()=="Windows":
545 johnpye 395 python_lib='python24'
546 johnpye 391 else:
547 johnpye 395 python_lib='python2.4'
548 johnpye 391
549 johnpye 395 # SWIG version
550    
551 johnpye 396 if platform.system()=="Windows":
552     env['ENV']['SWIGFEATURES']='-O'
553     else:
554     env['ENV']['SWIGFEATURES']='-O'
555 johnpye 395
556 johnpye 413
557     if not conf.CheckSwigVersion():
558     without_python_reason = 'SWIG >= 1.3.24 is required'
559     with_python = False
560    
561 johnpye 400 # CUnit
562    
563     if with_cunit_tests:
564 johnpye 404 if not conf.CheckCUnit():
565 johnpye 427 without_cunit_reason = 'CUnit not found'
566    
567     # BLAS
568    
569 johnpye 459 need_blas=False
570     if with_tcltk_gui:
571     need_blas=True
572     if need_blas:
573     if conf.CheckLib('blas'):
574     print "FOUND BLAS"
575     with_local_blas = False
576     without_local_blas_reason = "Found BLAS installed on system"
577     else:
578     print "DIDN'T FIND BLAS"
579     with_local_blas = True
580     need_fortran = True
581 johnpye 427
582     # FORTRAN
583    
584     if need_fortran:
585     conf.env.Tool('f77')
586     detect_fortran = conf.env.Detect(['g77','f77'])
587     if detect_fortran:
588     # For some reason, g77 doesn't get detected properly on MinGW
589     if not env.has_key('F77'):
590     conf.env.Replace(F77=detect_fortran)
591     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
592     conf.env.Replace(F77FLAGS='')
593 johnpye 428 #print "F77:",conf.env['F77']
594     #print "F77COM:",conf.env['F77COM']
595     #print "F77FLAGS:",conf.env['F77FLAGS']
596 johnpye 427 fortran_builder = Builder(
597     action='$F77COM'
598     , suffix='.o'
599     , src_suffix='.f'
600     )
601     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
602     else:
603     print "FORTRAN-77 required but not found"
604 johnpye 404 Exit(1)
605 johnpye 427 else:
606     print "FORTRAN not required"
607 johnpye 400
608 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
609    
610     # TODO: check size of void*
611    
612 johnpye 393 # TODO: detect if dynamic libraries are possible or not
613    
614 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
615     if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
616     print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
617     +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
618     env['PACKAGE_LINKING']='STATIC_PACKAGES'
619    
620     if with_python and not conf.CheckHeader('basetsd.h'):
621     with_python = 0;
622     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
623    
624     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
625    
626 johnpye 395 conf.Finish()
627    
628     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
629     env.Append(PYTHON_LIB=[python_lib])
630     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
631    
632 johnpye 385 #------------------------------------------------------
633 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
634    
635     import re
636 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
637 johnpye 393
638 johnpye 395 def TOOL_SUBST(env):
639     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
640     from the source to the target.
641     The values of SUBST_DICT first have any construction variables expanded
642     (its keys are not expanded).
643     If a value of SUBST_DICT is a python callable function, it is called and
644     the result is expanded as the value.
645     If there's more than one source and more than one target, each target gets
646     substituted from the corresponding source.
647 johnpye 393 """
648 johnpye 395 env.Append(TOOLS = 'SUBST')
649     def do_subst_in_file(targetfile, sourcefile, dict):
650     """Replace all instances of the keys of dict with their values.
651     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
652     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
653     """
654     try:
655     f = open(sourcefile, 'rb')
656     contents = f.read()
657     f.close()
658     except:
659     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
660     for (k,v) in dict.items():
661     contents = re.sub(k, v, contents)
662     try:
663     f = open(targetfile, 'wb')
664     f.write(contents)
665     f.close()
666     except:
667     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
668     return 0 # success
669 johnpye 393
670 johnpye 395 def subst_in_file(target, source, env):
671     if not env.has_key('SUBST_DICT'):
672     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
673     d = dict(env['SUBST_DICT']) # copy it
674     for (k,v) in d.items():
675     if callable(v):
676     d[k] = env.subst(v())
677     elif SCons.Util.is_String(v):
678     d[k]=env.subst(v)
679     else:
680     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
681     for (t,s) in zip(target, source):
682     return do_subst_in_file(str(t), str(s), d)
683 johnpye 393
684 johnpye 395 def subst_in_file_string(target, source, env):
685     """This is what gets printed on the console."""
686     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
687     for (t,s) in zip(target, source)])
688 johnpye 393
689 johnpye 395 def subst_emitter(target, source, env):
690     """Add dependency from substituted SUBST_DICT to target.
691     Returns original target, source tuple unchanged.
692     """
693     d = env['SUBST_DICT'].copy() # copy it
694     for (k,v) in d.items():
695     if callable(v):
696     d[k] = env.subst(v())
697     elif SCons.Util.is_String(v):
698     d[k]=env.subst(v)
699     Depends(target, SCons.Node.Python.Value(d))
700     return target, source
701 johnpye 393
702 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
703     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
704    
705     TOOL_SUBST(env)
706    
707 johnpye 393 #------------------------------------------------------
708 johnpye 463 # Recipe for 'CHMOD' ACTION
709 johnpye 439
710     import SCons
711     from SCons.Script.SConscript import SConsEnvironment
712     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
713     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
714    
715     def InstallPerm(env, dest, files, perm):
716     obj = env.Install(dest, files)
717     for i in obj:
718     env.AddPostAction(i, env.Chmod(str(i), perm))
719    
720     SConsEnvironment.InstallPerm = InstallPerm
721    
722     # define wrappers
723     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
724     SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
725 johnpye 463
726 johnpye 439 #------------------------------------------------------
727 johnpye 463 # Recipe for NSIS build
728 johnpye 385
729 johnpye 463 #import re
730     #
731     #nsis_re = re.compile(r'^\s*OutFile\s+(\S+)\s*$', re.M)
732     #
733     #def nsis_scan(node, env):
734     # print dict(node[0])
735     # f = file(node,'r');
736     # contents = f.read()
737     # f.close()
738     # return nsis_re.findall(contents)
739     #
740     #env.Append(SCANNERS=nsis_scan)
741     #
742     #def nsis_modify_targets(target, source, env):
743     # scan = nsis_scan(source, env)
744     # print "SCAN NSIS:",scan
745     # target.append(scan)
746     # return target, source
747     #
748     #nsis_builder = Builder(
749     # action='$NSIS /X\"OutFile $TARGET\" $NSISFLAGS $SOURCE'
750     # , emitter=nsis_modify_targets
751     #)
752     #env.Append(BUILDERS={'Nsis':nsis_builder})
753 johnpye 393
754 johnpye 463 #------------------------------------------------------
755     # BUILD...
756 johnpye 385
757 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
758     env.Append(CPPPATH=['#base/generic'])
759 johnpye 385
760 johnpye 463 #-------------
761     # TCL/TK GUI
762 johnpye 385
763 johnpye 463 if with_tcltk_gui:
764     if with_local_blas:
765     env.SConscript(['blas/SConscript'],'env')
766     else:
767     print "Skipping... BLAS won't be build:", without_local_blas_reason
768 johnpye 385
769 johnpye 463 env.SConscript(['lsod/SConscript'],'env')
770 johnpye 385
771 johnpye 463 env.SConscript(['linpack/SConscript'],'env')
772 johnpye 386 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
773 johnpye 391 else:
774 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
775 johnpye 386
776 johnpye 463 #-------------
777     # PYTHON INTERFACE
778    
779 johnpye 387 if with_python:
780     env.SConscript(['pygtk/interface/SConscript'],'env')
781 johnpye 391 else:
782 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
783 johnpye 400
784 johnpye 463 #------------
785     # BASE/GENERIC SUBDIRECTORIES
786    
787     dirs = ['general','utilities','compiler','solver','packages']
788    
789     srcs = []
790     for d in dirs:
791     heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
792     srcs += heresrcs
793    
794     #-------------
795     # LIBASCEND -- all base/generic functionality
796    
797     libascend = env.SharedLibrary('ascend',srcs)
798    
799     #-------------
800     # UNIT TESTS
801    
802 johnpye 400 if with_cunit_tests:
803     testdirs = ['general','solver','utilities']
804     for testdir in testdirs:
805     path = 'base/generic/'+testdir+'/test/'
806     env.SConscript([path+'SConscript'],'env')
807     env.SConscript(['test/SConscript'],'env')
808     env.SConscript(['base/generic/test/SConscript'],'env')
809    
810    
811     else:
812 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
813 johnpye 400
814 johnpye 427
815 johnpye 463 #------------------------------------------------------
816     # INSTALLATION
817 johnpye 427
818 johnpye 463 if env.has_key('CAN_INSTALL') and env['CAN_INSTALL']:
819     # the models directory only needs to be processed for installation, no other processing required.
820     env.SConscript(['models/SConscript'],'env')
821 johnpye 427
822 johnpye 463 dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']
823     install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
824 johnpye 449
825 johnpye 463 # TODO: add install options
826     env.Alias('install',install_dirs)
827 johnpye 400
828 johnpye 463 env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
829 johnpye 435
830 johnpye 438 #------------------------------------------------------
831     # CREATE the SPEC file for generation of RPM packages
832    
833 johnpye 463 if platform.system()=="Linux":
834     env.SubstInFile('ascend.spec.in')
835    
836     #if platform.system()=="Windows":
837     # env.Nsis("create.nsi")

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