/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 591 - (hide annotations) (download)
Fri May 12 08:25:16 2006 UTC (14 years, 2 months ago) by johnpye
File size: 27583 byte(s)
Added GCOV=1 option to SCons build, working on integrating LCOV tool with Buildbot.
1 johnpye 393 import os, commands, platform, distutils.sysconfig, os.path
2 johnpye 385
3 johnpye 577 version = "0.9.5.91"
4 johnpye 439
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 johnpye 464 #print "PLATFORM = ",platform.system()
13 johnpye 385
14 johnpye 464 if platform.system()=="Windows":
15     default_tcl_lib = "tcl83"
16     default_tk_lib = "tk83"
17     default_tktable_lib = "Tktable28"
18 johnpye 499 default_install_assets = "glade/"
19     icon_extension = '.png'
20 johnpye 521 default_tcl = "c:\\Tcl"
21 johnpye 541 default_tcl_libpath = "$TCL\\bin"
22 johnpye 464 else:
23 johnpye 521 default_tcl_lib = "tcl8.3"
24     default_tk_lib = "tk8.3"
25 johnpye 464 default_tktable_lib = "Tktable2.8"
26 johnpye 499 default_install_assets = "$INSTALL_DATA/ascend/glade/"
27     icon_extension = '.svg'
28 johnpye 521 default_tcl = os.path.expanduser("~/activetcl")
29 johnpye 541 default_tcl_libpath = "$TCL/lib"
30 johnpye 463
31 johnpye 551 if not os.path.isdir(default_tcl):
32     default_tcl = '/usr'
33    
34 johnpye 562 opts.Add(
35     'CC'
36     ,'C Compiler command'
37     ,None
38     )
39    
40     opts.Add(
41     'CXX'
42     ,'C++ Compiler command'
43     ,None
44     )
45    
46 johnpye 591 opts.Add(BoolOption(
47     'GCOV'
48     'Whether to enable coverage testing in object code'
49     ,False
50     ))
51    
52 johnpye 385 # Package linking option
53 johnpye 386 opts.Add(EnumOption(
54     'PACKAGE_LINKING'
55 johnpye 385 , 'Style of linking for external libraries'
56     , 'DYNAMIC_PACKAGES'
57 johnpye 386 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
58     ))
59 johnpye 385
60 johnpye 526 opts.Add(BoolOption(
61     'WITH_GCCVISIBILITY'
62     ,"Whether to use GCC Visibility features (only applicable if available)"
63     ,True
64     ))
65    
66 johnpye 392 # You can turn off building of Tcl/Tk interface
67 johnpye 386 opts.Add(BoolOption(
68 johnpye 542 'WITH_TCLTK'
69 johnpye 386 ,"Set to True if you don't want to build the original Tcl/Tk GUI."
70 johnpye 542 , True
71 johnpye 386 ))
72    
73 johnpye 392 # You can turn off the building of the Python interface
74 johnpye 387 opts.Add(BoolOption(
75 johnpye 542 'WITH_PYTHON'
76 johnpye 387 ,"Set to True if you don't want to build Python wrappers."
77 johnpye 542 , True
78 johnpye 387 ))
79    
80 johnpye 392 # Which solvers will we allow?
81     opts.Add(ListOption(
82     'WITH_SOLVERS'
83 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
84     +" works."
85 johnpye 392 ,["QRSLV","CMSLV"]
86     ,['QRSLV','MPS','SLV','OPTSQP'
87     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
88     ,'LSOD','OPTSQP'
89     ]
90     ))
91    
92 johnpye 393 # Where will the local copy of the help files be kept?
93     opts.Add(PackageOption(
94     'WITH_LOCAL_HELP'
95     , "Directory containing the local copy of the help files (optional)"
96     , "no"
97     ))
98    
99     # Will bintoken support be enabled?
100     opts.Add(BoolOption(
101     'WITH_BINTOKEN'
102     ,"Enable bintoken support? This means compiling models as C-code before"
103     +" running them, to increase solving speed for large models."
104     ,False
105     ))
106    
107 johnpye 398 # What should the default ASCENDLIBRARY path be?
108     # Note: users can change it by editing their ~/.ascend.ini
109 johnpye 393 opts.Add(
110     'DEFAULT_ASCENDLIBRARY'
111     ,"Set the default value of the ASCENDLIBRARY -- the location where"
112     +" ASCEND will look for models when running ASCEND"
113 johnpye 579 ,"$INSTALL_DATA/ascend/models"
114 johnpye 393 )
115    
116 johnpye 398 # Where is SWIG?
117     opts.Add(
118     'SWIG'
119     ,"SWIG location, probably only required for MinGW and MSVC users."
120     +" Enter the location as a Windows-style path, for example"
121 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
122 johnpye 398 )
123    
124 johnpye 400 # Build the test suite?
125     opts.Add(BoolOption(
126     'WITH_CUNIT_TESTS'
127     ,"Whether to build the CUnit tests. Default is off. If set to on,"
128     +" you must have CUnit installed somewhere that SCons can"
129 johnpye 463 +" find it, or else use the CUNIT_* options to specify."
130 johnpye 400 ,False
131     ))
132 johnpye 393
133 johnpye 400 # Where are the CUnit includes?
134     opts.Add(PackageOption(
135     'CUNIT_CPPPATH'
136     ,"Where are your CUnit include files?"
137 johnpye 459 ,'off'
138 johnpye 400 ))
139 johnpye 392
140 johnpye 404 # Where are the CUnit libraries?
141 johnpye 400 opts.Add(PackageOption(
142     'CUNIT_LIBPATH'
143 johnpye 404 ,"Where are your CUnit libraries?"
144 johnpye 459 ,'off'
145 johnpye 400 ))
146    
147 johnpye 521
148 johnpye 534 opts.Add(
149 johnpye 521 'TCL'
150     ,'Base of Tcl distribution'
151     ,default_tcl
152 johnpye 534 )
153 johnpye 521
154 johnpye 404 # Where are the Tcl includes?
155 johnpye 534 opts.Add(
156 johnpye 404 'TCL_CPPPATH'
157     ,"Where are your Tcl include files?"
158 johnpye 521 ,"$TCL/include"
159 johnpye 534 )
160 johnpye 404
161     # Where are the Tcl libs?
162 johnpye 534 opts.Add(
163 johnpye 404 'TCL_LIBPATH'
164     ,"Where are your Tcl libraries?"
165 johnpye 541 ,default_tcl_libpath
166 johnpye 534 )
167 johnpye 404
168 johnpye 428 # What is the name of the Tcl lib?
169     opts.Add(
170     'TCL_LIB'
171 johnpye 561 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
172 johnpye 464 ,default_tcl_lib
173 johnpye 428 )
174    
175 johnpye 405 # Where are the Tk includes?
176 johnpye 534 opts.Add(
177 johnpye 405 'TK_CPPPATH'
178     ,"Where are your Tk include files?"
179 johnpye 464 ,'$TCL_CPPPATH'
180 johnpye 534 )
181 johnpye 404
182 johnpye 405 # Where are the Tk libs?
183 johnpye 534 opts.Add(
184 johnpye 405 'TK_LIBPATH'
185     ,"Where are your Tk libraries?"
186 johnpye 464 ,'$TCL_LIBPATH'
187 johnpye 534 )
188 johnpye 405
189 johnpye 428 # What is the name of the Tk lib?
190     opts.Add(
191     'TK_LIB'
192 johnpye 521 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
193 johnpye 464 ,default_tk_lib
194 johnpye 435 )
195    
196 johnpye 460 # Static linking to TkTable
197    
198     opts.Add(BoolOption(
199 johnpye 521 'STATIC_TCLTK'
200 johnpye 554 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
201 johnpye 460 ,False
202     ))
203    
204 johnpye 464 opts.Add(
205 johnpye 460 'TKTABLE_LIBPATH'
206     ,'Location of TkTable static library'
207 johnpye 464 ,'$TCL_LIBPATH/Tktable2.8'
208     )
209 johnpye 460
210 johnpye 435 opts.Add(
211 johnpye 460 'TKTABLE_LIB'
212 johnpye 521 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
213 johnpye 464 ,default_tktable_lib
214 johnpye 460 )
215    
216     opts.Add(
217 johnpye 521 'TKTABLE_CPPPATH'
218     ,'Location of TkTable header file'
219     ,'$TCL_CPPPATH'
220     )
221    
222     opts.Add(
223     'X11'
224 johnpye 554 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
225 johnpye 521 ,'/usr/X11R6'
226     )
227    
228     opts.Add(
229     'X11_LIBPATH'
230 johnpye 554 ,'Location of X11 lib. EXPERIMENTAL'
231 johnpye 521 ,'$X11/lib'
232     )
233    
234     opts.Add(
235     'X11_CPPPATH'
236 johnpye 554 ,'Location of X11 includes. EXPERIMENTAL'
237 johnpye 521 ,'$X11/include'
238     )
239    
240     opts.Add(
241     'X11_LIB'
242 johnpye 554 ,'Name of X11 lib. EXPERIMENTAL'
243 johnpye 521 ,'X11'
244     )
245    
246     opts.Add(
247 johnpye 435 'INSTALL_PREFIX'
248     ,'Root location for installed files'
249 johnpye 449 ,'/usr/local'
250 johnpye 428 )
251    
252 johnpye 435 opts.Add(
253     'INSTALL_BIN'
254     ,'Location to put binaries during installation'
255     ,"$INSTALL_PREFIX/bin"
256     )
257    
258     opts.Add(
259 johnpye 463 'INSTALL_LIB'
260     ,'Location to put binaries during installation'
261     ,"$INSTALL_PREFIX/lib"
262     )
263    
264     opts.Add(
265 johnpye 435 'INSTALL_DATA'
266     ,'Location to put data files during installation'
267     ,"$INSTALL_PREFIX/share"
268     )
269    
270     opts.Add(
271     'INSTALL_INCLUDE'
272     ,'Location to put header files during installation'
273     ,"$INSTALL_PREFIX/include"
274     )
275    
276 johnpye 448 opts.Add(
277 johnpye 455 'PYGTK_ASSETS'
278 johnpye 532 ,'Default location for Glade assets (placed in pygtk/config.py)'
279 johnpye 455 ,default_install_assets
280     )
281    
282 johnpye 508 opts.Add(BoolOption(
283     'DEBUG'
284     ,"Compile source with debugger symbols, eg for use with 'gdb'"
285     ,False
286     ))
287    
288 johnpye 455 opts.Add(
289 johnpye 448 'INSTALL_ROOT'
290     ,'For use by RPM only: location of %{buildroot} during rpmbuild'
291     ,""
292     )
293    
294 johnpye 563 opts.Add(
295     'DISTTAR_NAME'
296     ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
297     ,"ascend-"+version
298     )
299    
300 johnpye 578 opts.Add(
301     'WIN_INSTALLER_NAME'
302     ,"Name of the installer .exe to create under Windows (minus the '.exe')"
303     ,"ascend-"+version
304     )
305    
306 johnpye 546 if platform.system()!="Windows":
307     opts.Add(BoolOption(
308     'WITH_GCCVISIBILITY'
309     , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
310     , True
311     ))
312    
313 johnpye 466 if platform.system()=="Windows":
314     opts.Add(BoolOption(
315     'WITH_INSTALLER'
316     ,'Build the Windows Installer (setup program) using NSIS'
317     ,False
318     ))
319    
320 johnpye 392 # TODO: OTHER OPTIONS?
321     # TODO: flags for optimisation
322 johnpye 393 # TODO: turning on/off bintoken functionality
323 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
324 johnpye 393
325 johnpye 498 # Import the outside environment
326    
327 johnpye 569 if os.environ.get('OSTYPE')=='msys':
328 johnpye 552 env = Environment(
329     ENV=os.environ
330 johnpye 578 , tools=['mingw','lex','yacc','fortran','swig','disttar','nsis']
331 johnpye 552 , toolpath=['scons']
332     )
333 johnpye 529 env['IS_MINGW']=True
334 johnpye 498 else:
335 johnpye 552 env = Environment(
336     ENV=os.environ
337 johnpye 578 ,tools=['default','lex','yacc','fortran','swig','disttar','nsis']
338 johnpye 552 , toolpath=['scons']
339     )
340 johnpye 498
341     if platform.system()=='Windows' and env.has_key('MSVS'):
342     print "INCLUDE =",env['ENV']['INCLUDE']
343     print "LIB =",env['ENV']['LIB']
344 johnpye 506 print "PATH =",env['ENV']['PATH']
345 johnpye 498 env.Append(CPPPATH=env['ENV']['INCLUDE'])
346     env.Append(LIBPATH=env['ENV']['LIB'])
347    
348 johnpye 385 opts.Update(env)
349     opts.Save('options.cache',env)
350    
351     Help(opts.GenerateHelpText(env))
352    
353 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
354 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
355 johnpye 386
356 johnpye 551 with_python = env.get('WITH_PYTHON')
357 johnpye 427 without_python_reason = "disabled by options/config.py"
358 johnpye 387
359 johnpye 551 with_cunit_tests = env.get('WITH_CUNIT_TESTS')
360 johnpye 427 without_cunit_reason = "not requested"
361 johnpye 400
362 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
363     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
364     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
365 johnpye 393
366 johnpye 463 can_install = True
367     if platform.system()=='Windows':
368     can_install = False
369    
370     env['CAN_INSTALL']=can_install
371    
372 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
373     print "TCL_LIBPATH =",env['TCL_LIBPATH']
374     print "TCL_LIB =",env['TCL_LIB']
375 johnpye 562 print "CC =",env['CC']
376     print "CXX =",env['CXX']
377 johnpye 393
378 johnpye 385 #------------------------------------------------------
379 johnpye 398 # SPECIAL CONFIGURATION TESTS
380    
381 johnpye 463 need_fortran = False
382    
383 johnpye 400 #----------------
384     # SWIG
385    
386 johnpye 398 import os,re
387    
388 johnpye 413 def get_swig_version(env):
389 johnpye 403 cmd = env['SWIG']+' -version'
390 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
391 johnpye 403 output = coutcerr.read()
392 johnpye 398
393 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
394     expr = re.compile(restr,re.M);
395 johnpye 398 m = expr.search(output);
396     if not m:
397 johnpye 413 return None
398 johnpye 398 maj = int(m.group('maj'))
399     min = int(m.group('min'))
400     pat = int(m.group('pat'))
401 johnpye 413
402     return (maj,min,pat)
403 johnpye 398
404 johnpye 413
405     def CheckSwigVersion(context):
406    
407     try:
408     context.Message("Checking version of SWIG... ")
409     maj,min,pat = get_swig_version(context.env)
410     except:
411     context.Result("Failed to detect version, or failed to run SWIG")
412     return 0;
413    
414 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
415    
416 johnpye 398 if maj == 1 and (
417 johnpye 400 min > 3
418     or (min == 3 and pat >= 24)
419 johnpye 398 ):
420     context.Result("ok, %d.%d.%d" % (maj,min,pat))
421     return 1;
422 johnpye 401 else:
423     context.Result("too old, %d.%d.%d" % (maj,min,pat))
424     return 0;
425 johnpye 398
426 johnpye 400 #----------------
427     # General purpose library-and-header test
428    
429 johnpye 404 class KeepContext:
430 johnpye 521 def __init__(self,context,varprefix,static=False):
431 johnpye 404 self.keep = {}
432 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
433 johnpye 404 if context.env.has_key(k):
434     self.keep[k] = context.env[k]
435 johnpye 463 else:
436     self.keep[k] = None
437 johnpye 404
438     if context.env.has_key(varprefix+'_CPPPATH'):
439 johnpye 521 context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])
440 johnpye 428 #print "Adding '"+str(cpppath_add)+"' to cpp path"
441    
442 johnpye 521 if static:
443     staticlib=env[varprefix+'_LIB']
444     #print "STATIC LIB = ",staticlib
445     context.env.Append(
446     LINKFLAGS=[staticlib]
447     )
448     else:
449     if context.env.has_key(varprefix+'_LIBPATH'):
450     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
451     #print "Adding '"+str(libpath_add)+"' to lib path"
452 johnpye 428
453 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
454     context.env.Append(LIBS=[env[varprefix+'_LIB']])
455     #print "Adding '"+str(libs_add)+"' to libs"
456 johnpye 404
457     def restore(self,context):
458 johnpye 464 #print "RESTORING CONTEXT"
459     #print self.keep
460     #print "..."
461 johnpye 404 for k in self.keep:
462 johnpye 463 if self.keep[k]==None:
463 johnpye 521 if context.env.has_key(k):
464     #print "Clearing "+str(k)
465     del context.env[k];
466 johnpye 463 else:
467 johnpye 464 #print "Restoring "+str(k)+" to '"+self.keep[k]+"'"
468 johnpye 463 context.env[k]=self.keep[k];
469 johnpye 404
470 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
471 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
472     and LIBNAME_CPPPATH and try to compile and link the
473     file with the provided text, linking with the
474     library libname."""
475    
476 johnpye 521 if static:
477     context.Message( 'Checking for static '+libname+'... ' )
478     else:
479     context.Message( 'Checking for '+libname+'... ' )
480    
481 johnpye 400 if varprefix==None:
482     varprefix = libname.upper()
483    
484 johnpye 521 keep = KeepContext(context,varprefix,static)
485 johnpye 400
486 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
487 johnpye 463 # if varprefix_LIB were in env, KeepContext would
488     # have appended it already
489 johnpye 451 context.env.Append(LIBS=libname)
490 johnpye 428
491 johnpye 404 is_ok = context.TryLink(text,ext)
492 johnpye 428
493 johnpye 521 #print "Link success? ",(is_ok != 0)
494 johnpye 400
495 johnpye 405 keep.restore(context)
496 johnpye 400
497 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
498     # print "Restored LIBS="+libname
499     # print "Restored LIBPATH="+str(context.env['LIBPATH'])
500    
501 johnpye 404 context.Result(is_ok)
502     return is_ok
503    
504     #----------------
505 johnpye 502 # GCC
506    
507     gcc_test_text = """
508     #ifndef __GNUC__
509     # error "Not using GCC"
510     #endif
511    
512     int main(void){
513     return __GNUC__;
514     }
515     """
516    
517     def CheckGcc(context):
518     context.Message("Checking for GCC... ")
519     is_ok = context.TryCompile(gcc_test_text,".c")
520     context.Result(is_ok)
521     return is_ok
522    
523     #----------------
524 johnpye 500 # GCC VISIBILITY feature
525    
526     gccvisibility_test_text = """
527     #if __GNUC__ < 4
528     # error "Require GCC version 4 or newer"
529     #endif
530    
531     __attribute__ ((visibility("default"))) int x;
532    
533     int main(void){
534     extern int x;
535     x = 4;
536     }
537     """
538    
539     def CheckGccVisibility(context):
540     context.Message("Checking for GCC 'visibility' capability... ")
541 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
542     context.Result("disabled")
543     return 0
544 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
545     context.Result(is_ok)
546     return is_ok
547 johnpye 502
548 johnpye 500 #----------------
549 johnpye 502 # YACC
550    
551     yacc_test_text = """
552     %start ROOT
553     %token MSG
554     %%
555    
556     ROOT:
557     MSG { print("HELLO"); }
558     ;
559     """
560    
561     def CheckYacc(context):
562     context.Message("Checking for Yacc... ")
563     is_ok = context.TryCompile(yacc_test_text,".y")
564     context.Result(is_ok)
565     return is_ok
566    
567     #----------------
568 johnpye 404 # CUnit test
569    
570 johnpye 400 cunit_test_text = """
571 johnpye 451 #include <CUnit/CUnit.h>
572 johnpye 400 int maxi(int i1, int i2){
573     return (i1 > i2) ? i1 : i2;
574     }
575    
576     void test_maxi(void){
577     CU_ASSERT(maxi(0,2) == 2);
578     CU_ASSERT(maxi(0,-2) == 0);
579     CU_ASSERT(maxi(2,2) == 2);
580    
581     }
582     int main(void){
583     /* CU_initialize_registry() */
584 johnpye 404 return 0;
585 johnpye 400 }
586     """
587    
588     def CheckCUnit(context):
589 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
590 johnpye 400
591 johnpye 404 #----------------
592 johnpye 405 # Tcl test
593 johnpye 404
594 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
595     tcltk_minor_newest_acceptable = 4
596     tcltk_major_required = 8
597    
598 johnpye 404 tcl_check_text = r"""
599     #include <tcl.h>
600     #include <stdio.h>
601     int main(void){
602     printf("%s",TCL_PATCH_LEVEL);
603     return 0;
604     }
605     """
606    
607     def CheckTcl(context):
608 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
609 johnpye 405
610     def CheckTclVersion(context):
611 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
612 johnpye 405 context.Message("Checking Tcl version... ")
613     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
614 johnpye 404 keep.restore(context)
615     if not is_ok:
616 johnpye 405 context.Result("failed to run check")
617 johnpye 404 return 0
618 johnpye 405
619 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
620 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
621 johnpye 428 context.Result(output+" (bad version)")
622 johnpye 405 # bad version
623     return 0
624    
625     # good version
626 johnpye 552 context.Result(output+", good")
627 johnpye 404 return 1
628    
629 johnpye 405 #----------------
630 johnpye 463 # Tk test
631 johnpye 405
632     tk_check_text = r"""
633     #include <tk.h>
634     #include <stdio.h>
635     int main(void){
636     printf("%s",TK_PATCH_LEVEL);
637     return 0;
638     }
639     """
640     def CheckTk(context):
641 johnpye 521 return CheckExtLib(context,'tk',tcl_check_text,static=env['STATIC_TCLTK'])
642 johnpye 405
643 johnpye 428
644 johnpye 405 def CheckTkVersion(context):
645 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
646 johnpye 405 context.Message("Checking Tk version... ")
647 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
648 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
649 johnpye 404 keep.restore(context)
650     if not is_ok:
651     context.Result("failed to run check")
652     return 0
653    
654 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
655 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
656 johnpye 404 # bad version
657 johnpye 561 context.Result(output+" (bad version)")
658 johnpye 404 return 0
659 johnpye 400
660 johnpye 404 # good version
661 johnpye 561 context.Result(output+" (good)")
662 johnpye 404 return 1
663 johnpye 485
664     #----------------
665 johnpye 521 # Tktable test
666    
667     tktable_check_text = r"""
668     #include <tkTable.h>
669     #include <stdio.h>
670     int main(void){
671     Table mytable;
672     return 0;
673     }
674     """
675    
676     def CheckTkTable(context):
677     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
678    
679     #---------------
680     # X11 test
681    
682     x11_check_text = r"""
683     #include <X11/Xlib.h>
684     #include <X11/IntrinsicP.h>
685     #include <X11/Intrinsic.h>
686     #include <X11/ObjectP.h>
687     #include <X11/Object.h>
688     int main(void){
689     Object mything;
690     return 0;
691     }
692     """
693    
694     def CheckX11(context):
695     return CheckExtLib(context,'X11',x11_check_text)
696    
697     #----------------
698 johnpye 485 # GCC Version sniffing
699    
700     # TODO FIXME
701    
702     gcc_version4 = False
703    
704 johnpye 398 #------------------------------------------------------
705 johnpye 385 # CONFIGURATION
706    
707     conf = Configure(env
708     , custom_tests = {
709 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
710 johnpye 400 , 'CheckCUnit' : CheckCUnit
711 johnpye 404 , 'CheckTcl' : CheckTcl
712     , 'CheckTclVersion' : CheckTclVersion
713 johnpye 405 , 'CheckTk' : CheckTk
714     , 'CheckTkVersion' : CheckTkVersion
715 johnpye 502 , 'CheckGcc' : CheckGcc
716 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
717 johnpye 502 , 'CheckYacc' : CheckYacc
718 johnpye 521 , 'CheckTkTable' : CheckTkTable
719     , 'CheckX11' : CheckX11
720 johnpye 400 # , 'CheckIsNan' : CheckIsNan
721     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
722 johnpye 385 }
723 johnpye 459 # , config_h = "config.h"
724 johnpye 385 )
725    
726 johnpye 398
727 johnpye 385 # Math library
728    
729 johnpye 427 #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
730     # print 'Did not find math library, exiting!'
731     # Exit(1)
732    
733 johnpye 385 # Where is 'isnan'?
734    
735     if not conf.CheckFunc('isnan'):
736     print "Didn't find isnan"
737 johnpye 414 # Exit(1)
738 johnpye 385
739 johnpye 500 # GCC visibility
740    
741 johnpye 502 if conf.CheckGcc():
742     conf.env['HAVE_GCC']=True;
743 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
744 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
745     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
746     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
747 johnpye 500
748 johnpye 502 # YACC
749    
750 johnpye 506 if not conf.CheckYacc():
751     print "YACC NOT FOUND OR NOT WORKING"
752     else:
753 johnpye 502 conf.env['HAVE_YACC']=True
754    
755     conf.env['HAVE_LEX']=True
756    
757 johnpye 387 # Tcl/Tk
758 johnpye 386
759 johnpye 586 if with_tcltk:
760     if conf.CheckTcl():
761     if conf.CheckTclVersion():
762     if conf.CheckTk():
763     if with_tcltk and conf.CheckTkVersion():
764     if env['STATIC_TCLTK']:
765     if conf.CheckTkTable():
766     pass
767     else:
768     without_tcltk_reason = "TkTable not found"
769     with_tcltk = False
770     else:
771     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
772     with_tcltk = False
773 johnpye 521 else:
774 johnpye 586 without_tcltk_reason = "Tk not found."
775 johnpye 551 with_tcltk = False
776 johnpye 428 else:
777 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
778 johnpye 551 with_tcltk = False
779 johnpye 586
780 johnpye 428 else:
781 johnpye 586 without_tcltk_reason = "Tcl not found."
782 johnpye 551 with_tcltk = False
783 johnpye 386
784 johnpye 521 if env['STATIC_TCLTK']:
785     conf.CheckX11()
786    
787 johnpye 395 # Python... obviously we're already running python, so we just need to
788     # check that we can link to the python library OK:
789    
790 johnpye 391 if platform.system()=="Windows":
791 johnpye 395 python_lib='python24'
792 johnpye 391 else:
793 johnpye 395 python_lib='python2.4'
794 johnpye 391
795 johnpye 395 # SWIG version
796    
797 johnpye 413 if not conf.CheckSwigVersion():
798     without_python_reason = 'SWIG >= 1.3.24 is required'
799     with_python = False
800    
801 johnpye 400 # CUnit
802    
803     if with_cunit_tests:
804 johnpye 404 if not conf.CheckCUnit():
805 johnpye 427 without_cunit_reason = 'CUnit not found'
806    
807     # BLAS
808    
809 johnpye 459 need_blas=False
810 johnpye 551 if with_tcltk:
811 johnpye 459 need_blas=True
812     if need_blas:
813     if conf.CheckLib('blas'):
814     with_local_blas = False
815     without_local_blas_reason = "Found BLAS installed on system"
816     else:
817     with_local_blas = True
818     need_fortran = True
819 johnpye 427
820     # FORTRAN
821    
822     if need_fortran:
823     conf.env.Tool('f77')
824     detect_fortran = conf.env.Detect(['g77','f77'])
825     if detect_fortran:
826     # For some reason, g77 doesn't get detected properly on MinGW
827     if not env.has_key('F77'):
828     conf.env.Replace(F77=detect_fortran)
829     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
830     conf.env.Replace(F77FLAGS='')
831 johnpye 428 #print "F77:",conf.env['F77']
832     #print "F77COM:",conf.env['F77COM']
833     #print "F77FLAGS:",conf.env['F77FLAGS']
834 johnpye 427 fortran_builder = Builder(
835     action='$F77COM'
836     , suffix='.o'
837     , src_suffix='.f'
838     )
839     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
840     else:
841     print "FORTRAN-77 required but not found"
842 johnpye 404 Exit(1)
843 johnpye 464 #else:
844     # print "FORTRAN not required"
845 johnpye 400
846 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
847    
848     # TODO: check size of void*
849    
850 johnpye 393 # TODO: detect if dynamic libraries are possible or not
851    
852 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
853     if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
854     print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
855     +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
856     env['PACKAGE_LINKING']='STATIC_PACKAGES'
857    
858 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
859 johnpye 427 with_python = 0;
860     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
861    
862     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
863    
864 johnpye 395 conf.Finish()
865    
866     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
867     env.Append(PYTHON_LIB=[python_lib])
868     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
869    
870 johnpye 507 #---------------------------------------
871     # SUBSTITUTION DICTIONARY for .in files
872    
873     subst_dict = {
874     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
875     , '@GLADE_FILE@':'ascend.glade'
876     , '@HELP_ROOT@':''
877     , '@ICON_EXTENSION@':icon_extension
878     , '@INSTALL_DATA@':env['INSTALL_DATA']
879     , '@INSTALL_BIN@':env['INSTALL_BIN']
880     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
881     , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
882     , '@VERSION@':version
883 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
884 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
885 johnpye 508 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
886     , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
887 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
888     , '@ASC_DISTDIR_REL_BIN@' : '../share/ascend'
889 johnpye 507 }
890    
891     if env['WITH_LOCAL_HELP']:
892     print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
893     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
894    
895     if with_python:
896     subst_dict['@ASCXX_USE_PYTHON@']="1"
897    
898     if env.has_key('HAVE_GCCVISIBILITY'):
899     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
900    
901     env.Append(SUBST_DICT=subst_dict)
902    
903 johnpye 385 #------------------------------------------------------
904 johnpye 558 # RECIPE: SWIG scanner
905    
906     import SCons.Script
907    
908     SWIGScanner = SCons.Scanner.ClassicCPP(
909     "SWIGScan"
910     , ".i"
911     , "CPPPATH"
912     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
913     )
914    
915     env.Append(SCANNERS=[SWIGScanner])
916    
917     #------------------------------------------------------
918 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
919    
920     import re
921 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
922 johnpye 393
923 johnpye 395 def TOOL_SUBST(env):
924     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
925     from the source to the target.
926     The values of SUBST_DICT first have any construction variables expanded
927     (its keys are not expanded).
928     If a value of SUBST_DICT is a python callable function, it is called and
929     the result is expanded as the value.
930     If there's more than one source and more than one target, each target gets
931     substituted from the corresponding source.
932 johnpye 393 """
933 johnpye 395 env.Append(TOOLS = 'SUBST')
934     def do_subst_in_file(targetfile, sourcefile, dict):
935     """Replace all instances of the keys of dict with their values.
936     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
937     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
938     """
939     try:
940     f = open(sourcefile, 'rb')
941     contents = f.read()
942     f.close()
943     except:
944     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
945     for (k,v) in dict.items():
946     contents = re.sub(k, v, contents)
947     try:
948     f = open(targetfile, 'wb')
949     f.write(contents)
950     f.close()
951     except:
952     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
953     return 0 # success
954 johnpye 393
955 johnpye 395 def subst_in_file(target, source, env):
956     if not env.has_key('SUBST_DICT'):
957     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
958     d = dict(env['SUBST_DICT']) # copy it
959     for (k,v) in d.items():
960     if callable(v):
961     d[k] = env.subst(v())
962     elif SCons.Util.is_String(v):
963     d[k]=env.subst(v)
964     else:
965     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
966     for (t,s) in zip(target, source):
967     return do_subst_in_file(str(t), str(s), d)
968 johnpye 393
969 johnpye 395 def subst_in_file_string(target, source, env):
970     """This is what gets printed on the console."""
971     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
972     for (t,s) in zip(target, source)])
973 johnpye 393
974 johnpye 395 def subst_emitter(target, source, env):
975     """Add dependency from substituted SUBST_DICT to target.
976     Returns original target, source tuple unchanged.
977     """
978     d = env['SUBST_DICT'].copy() # copy it
979     for (k,v) in d.items():
980     if callable(v):
981     d[k] = env.subst(v())
982     elif SCons.Util.is_String(v):
983     d[k]=env.subst(v)
984     Depends(target, SCons.Node.Python.Value(d))
985     return target, source
986 johnpye 393
987 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
988     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
989    
990     TOOL_SUBST(env)
991    
992 johnpye 393 #------------------------------------------------------
993 johnpye 463 # Recipe for 'CHMOD' ACTION
994 johnpye 439
995     import SCons
996     from SCons.Script.SConscript import SConsEnvironment
997     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
998     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
999    
1000     def InstallPerm(env, dest, files, perm):
1001     obj = env.Install(dest, files)
1002     for i in obj:
1003     env.AddPostAction(i, env.Chmod(str(i), perm))
1004    
1005     SConsEnvironment.InstallPerm = InstallPerm
1006    
1007     # define wrappers
1008     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1009 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1010 johnpye 463
1011 johnpye 439 #------------------------------------------------------
1012 johnpye 463 # BUILD...
1013 johnpye 385
1014 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
1015     env.Append(CPPPATH=['#base/generic'])
1016 johnpye 385
1017 johnpye 485 if gcc_version4:
1018     env.Append(CCFLAGS=['-fvisibility=hidden'])
1019    
1020 johnpye 508 if env['DEBUG']:
1021     env.Append(CCFLAGS=['-g'])
1022    
1023 johnpye 591 if env['GCOV']:
1024     env.Append(
1025     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1026     , LIBS=['gcov']
1027     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1028     )
1029    
1030 johnpye 463 #-------------
1031     # TCL/TK GUI
1032 johnpye 385
1033 johnpye 551 if with_tcltk:
1034 johnpye 463 if with_local_blas:
1035     env.SConscript(['blas/SConscript'],'env')
1036     else:
1037     print "Skipping... BLAS won't be build:", without_local_blas_reason
1038 johnpye 385
1039 johnpye 463 env.SConscript(['lsod/SConscript'],'env')
1040 johnpye 385
1041 johnpye 463 env.SConscript(['linpack/SConscript'],'env')
1042 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1043 johnpye 391 else:
1044 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1045 johnpye 386
1046 johnpye 463 #-------------
1047     # PYTHON INTERFACE
1048    
1049 johnpye 387 if with_python:
1050 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
1051 johnpye 391 else:
1052 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
1053 johnpye 400
1054 johnpye 463 #------------
1055     # BASE/GENERIC SUBDIRECTORIES
1056    
1057     dirs = ['general','utilities','compiler','solver','packages']
1058    
1059     srcs = []
1060     for d in dirs:
1061     heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1062     srcs += heresrcs
1063    
1064     #-------------
1065     # LIBASCEND -- all base/generic functionality
1066    
1067     libascend = env.SharedLibrary('ascend',srcs)
1068    
1069     #-------------
1070     # UNIT TESTS
1071    
1072 johnpye 400 if with_cunit_tests:
1073     testdirs = ['general','solver','utilities']
1074     for testdir in testdirs:
1075     path = 'base/generic/'+testdir+'/test/'
1076     env.SConscript([path+'SConscript'],'env')
1077     env.SConscript(['test/SConscript'],'env')
1078     env.SConscript(['base/generic/test/SConscript'],'env')
1079    
1080    
1081     else:
1082 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1083 johnpye 400
1084 johnpye 427
1085 johnpye 463 #------------------------------------------------------
1086     # INSTALLATION
1087 johnpye 427
1088 johnpye 552 if env.get('CAN_INSTALL'):
1089 johnpye 463 # the models directory only needs to be processed for installation, no other processing required.
1090     env.SConscript(['models/SConscript'],'env')
1091 johnpye 427
1092 johnpye 463 dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']
1093     install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1094 johnpye 449
1095 johnpye 463 # TODO: add install options
1096     env.Alias('install',install_dirs)
1097 johnpye 400
1098 johnpye 463 env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1099 johnpye 435
1100 johnpye 438 #------------------------------------------------------
1101     # CREATE the SPEC file for generation of RPM packages
1102    
1103 johnpye 463 if platform.system()=="Linux":
1104     env.SubstInFile('ascend.spec.in')
1105 johnpye 552
1106     #------------------------------------------------------
1107     # DISTRIBUTION TAR FILE
1108    
1109 johnpye 554 env['DISTTAR_FORMAT']='bz2'
1110 johnpye 556 env.Append(
1111 johnpye 566 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1112 johnpye 561 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1113 johnpye 556 )
1114 johnpye 554
1115 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1116 johnpye 556 , [env.Dir('#')]
1117 johnpye 554 )
1118    
1119     #------------------------------------------------------
1120     # RPM BUILD
1121    
1122     #if platform.system()=="Linux":
1123     # pass
1124    
1125     #------------------------------------------------------
1126     # DEFAULT TARGETS
1127    
1128 johnpye 569 env.Default(['pygtk','tcltk'])
1129 johnpye 554

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