/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 597 - (hide annotations) (download)
Fri May 12 12:29:45 2006 UTC (13 years, 6 months ago) by johnpye
File size: 28154 byte(s)
Still working on a way to add options to config.h.in such that it doesn't break
autotools.
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 johnpye 593 , 'Whether to enable coverage testing in object code'
49     , False
50 johnpye 591 ))
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 johnpye 593 'WITH_CUNIT'
127 johnpye 400 ,"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 597 opts.Add(BoolOption(
289     'MALLOC_DEBUG'
290     ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
291     ,False
292     ))
293    
294 johnpye 455 opts.Add(
295 johnpye 448 'INSTALL_ROOT'
296     ,'For use by RPM only: location of %{buildroot} during rpmbuild'
297     ,""
298     )
299    
300 johnpye 563 opts.Add(
301     'DISTTAR_NAME'
302     ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
303     ,"ascend-"+version
304     )
305    
306 johnpye 578 opts.Add(
307     'WIN_INSTALLER_NAME'
308     ,"Name of the installer .exe to create under Windows (minus the '.exe')"
309     ,"ascend-"+version
310     )
311    
312 johnpye 594 opts.Add(BoolOption(
313     'WITH_XTERM_COLORS'
314     ,"Set to 0 if you don't want xterm colour codes in the console output"
315     ,True
316     ))
317    
318 johnpye 546 if platform.system()!="Windows":
319     opts.Add(BoolOption(
320     'WITH_GCCVISIBILITY'
321     , 'Whether to use GCC Visibility extensions when building with GCC 4.0'
322     , True
323     ))
324    
325 johnpye 466 if platform.system()=="Windows":
326     opts.Add(BoolOption(
327     'WITH_INSTALLER'
328     ,'Build the Windows Installer (setup program) using NSIS'
329     ,False
330     ))
331    
332 johnpye 392 # TODO: OTHER OPTIONS?
333     # TODO: flags for optimisation
334 johnpye 393 # TODO: turning on/off bintoken functionality
335 johnpye 427 # TODO: Where will the 'Makefile.bt' file be installed?
336 johnpye 393
337 johnpye 498 # Import the outside environment
338    
339 johnpye 569 if os.environ.get('OSTYPE')=='msys':
340 johnpye 552 env = Environment(
341     ENV=os.environ
342 johnpye 578 , tools=['mingw','lex','yacc','fortran','swig','disttar','nsis']
343 johnpye 552 , toolpath=['scons']
344     )
345 johnpye 529 env['IS_MINGW']=True
346 johnpye 498 else:
347 johnpye 552 env = Environment(
348     ENV=os.environ
349 johnpye 578 ,tools=['default','lex','yacc','fortran','swig','disttar','nsis']
350 johnpye 552 , toolpath=['scons']
351     )
352 johnpye 498
353     if platform.system()=='Windows' and env.has_key('MSVS'):
354     print "INCLUDE =",env['ENV']['INCLUDE']
355     print "LIB =",env['ENV']['LIB']
356 johnpye 506 print "PATH =",env['ENV']['PATH']
357 johnpye 498 env.Append(CPPPATH=env['ENV']['INCLUDE'])
358     env.Append(LIBPATH=env['ENV']['LIB'])
359    
360 johnpye 385 opts.Update(env)
361     opts.Save('options.cache',env)
362    
363     Help(opts.GenerateHelpText(env))
364    
365 johnpye 551 with_tcltk = env.get('WITH_TCLTK')
366 johnpye 427 without_tcltk_reason = "disabled by options/config.py"
367 johnpye 386
368 johnpye 551 with_python = env.get('WITH_PYTHON')
369 johnpye 427 without_python_reason = "disabled by options/config.py"
370 johnpye 387
371 johnpye 593 with_cunit = env.get('WITH_CUNIT')
372 johnpye 427 without_cunit_reason = "not requested"
373 johnpye 400
374 johnpye 464 #print "SOLVERS:",env['WITH_SOLVERS']
375     #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
376     #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
377 johnpye 393
378 johnpye 463 can_install = True
379     if platform.system()=='Windows':
380     can_install = False
381    
382     env['CAN_INSTALL']=can_install
383    
384 johnpye 521 print "TCL_CPPPATH =",env['TCL_CPPPATH']
385     print "TCL_LIBPATH =",env['TCL_LIBPATH']
386     print "TCL_LIB =",env['TCL_LIB']
387 johnpye 562 print "CC =",env['CC']
388     print "CXX =",env['CXX']
389 johnpye 393
390 johnpye 385 #------------------------------------------------------
391 johnpye 398 # SPECIAL CONFIGURATION TESTS
392    
393 johnpye 463 need_fortran = False
394    
395 johnpye 400 #----------------
396     # SWIG
397    
398 johnpye 398 import os,re
399    
400 johnpye 413 def get_swig_version(env):
401 johnpye 403 cmd = env['SWIG']+' -version'
402 johnpye 427 (cin,coutcerr) = os.popen4(cmd)
403 johnpye 403 output = coutcerr.read()
404 johnpye 398
405 johnpye 403 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
406     expr = re.compile(restr,re.M);
407 johnpye 398 m = expr.search(output);
408     if not m:
409 johnpye 413 return None
410 johnpye 398 maj = int(m.group('maj'))
411     min = int(m.group('min'))
412     pat = int(m.group('pat'))
413 johnpye 413
414     return (maj,min,pat)
415 johnpye 398
416 johnpye 413
417     def CheckSwigVersion(context):
418    
419     try:
420     context.Message("Checking version of SWIG... ")
421     maj,min,pat = get_swig_version(context.env)
422     except:
423     context.Result("Failed to detect version, or failed to run SWIG")
424     return 0;
425    
426 johnpye 478 context.env['SWIGVERSION']=tuple([maj,min,pat])
427    
428 johnpye 398 if maj == 1 and (
429 johnpye 400 min > 3
430     or (min == 3 and pat >= 24)
431 johnpye 398 ):
432     context.Result("ok, %d.%d.%d" % (maj,min,pat))
433     return 1;
434 johnpye 401 else:
435     context.Result("too old, %d.%d.%d" % (maj,min,pat))
436     return 0;
437 johnpye 398
438 johnpye 400 #----------------
439     # General purpose library-and-header test
440    
441 johnpye 404 class KeepContext:
442 johnpye 521 def __init__(self,context,varprefix,static=False):
443 johnpye 404 self.keep = {}
444 johnpye 521 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
445 johnpye 404 if context.env.has_key(k):
446     self.keep[k] = context.env[k]
447 johnpye 463 else:
448     self.keep[k] = None
449 johnpye 404
450     if context.env.has_key(varprefix+'_CPPPATH'):
451 johnpye 521 context.env.Append(CPPPATH=[env[varprefix+'_CPPPATH']])
452 johnpye 428 #print "Adding '"+str(cpppath_add)+"' to cpp path"
453    
454 johnpye 521 if static:
455     staticlib=env[varprefix+'_LIB']
456     #print "STATIC LIB = ",staticlib
457     context.env.Append(
458     LINKFLAGS=[staticlib]
459     )
460     else:
461     if context.env.has_key(varprefix+'_LIBPATH'):
462     context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
463     #print "Adding '"+str(libpath_add)+"' to lib path"
464 johnpye 428
465 johnpye 521 if context.env.has_key(varprefix+'_LIB'):
466     context.env.Append(LIBS=[env[varprefix+'_LIB']])
467     #print "Adding '"+str(libs_add)+"' to libs"
468 johnpye 404
469     def restore(self,context):
470 johnpye 464 #print "RESTORING CONTEXT"
471     #print self.keep
472     #print "..."
473 johnpye 404 for k in self.keep:
474 johnpye 463 if self.keep[k]==None:
475 johnpye 521 if context.env.has_key(k):
476     #print "Clearing "+str(k)
477     del context.env[k];
478 johnpye 463 else:
479 johnpye 464 #print "Restoring "+str(k)+" to '"+self.keep[k]+"'"
480 johnpye 463 context.env[k]=self.keep[k];
481 johnpye 404
482 johnpye 521 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False):
483 johnpye 400 """This method will check for variables LIBNAME_LIBPATH
484     and LIBNAME_CPPPATH and try to compile and link the
485     file with the provided text, linking with the
486     library libname."""
487    
488 johnpye 521 if static:
489     context.Message( 'Checking for static '+libname+'... ' )
490     else:
491     context.Message( 'Checking for '+libname+'... ' )
492    
493 johnpye 400 if varprefix==None:
494     varprefix = libname.upper()
495    
496 johnpye 521 keep = KeepContext(context,varprefix,static)
497 johnpye 400
498 johnpye 428 if not context.env.has_key(varprefix+'_LIB'):
499 johnpye 463 # if varprefix_LIB were in env, KeepContext would
500     # have appended it already
501 johnpye 451 context.env.Append(LIBS=libname)
502 johnpye 428
503 johnpye 404 is_ok = context.TryLink(text,ext)
504 johnpye 428
505 johnpye 521 #print "Link success? ",(is_ok != 0)
506 johnpye 400
507 johnpye 405 keep.restore(context)
508 johnpye 400
509 johnpye 428 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
510     # print "Restored LIBS="+libname
511     # print "Restored LIBPATH="+str(context.env['LIBPATH'])
512    
513 johnpye 404 context.Result(is_ok)
514     return is_ok
515    
516     #----------------
517 johnpye 502 # GCC
518    
519     gcc_test_text = """
520     #ifndef __GNUC__
521     # error "Not using GCC"
522     #endif
523    
524     int main(void){
525     return __GNUC__;
526     }
527     """
528    
529     def CheckGcc(context):
530     context.Message("Checking for GCC... ")
531     is_ok = context.TryCompile(gcc_test_text,".c")
532     context.Result(is_ok)
533     return is_ok
534    
535     #----------------
536 johnpye 500 # GCC VISIBILITY feature
537    
538     gccvisibility_test_text = """
539     #if __GNUC__ < 4
540     # error "Require GCC version 4 or newer"
541     #endif
542    
543     __attribute__ ((visibility("default"))) int x;
544    
545     int main(void){
546     extern int x;
547     x = 4;
548     }
549     """
550    
551     def CheckGccVisibility(context):
552     context.Message("Checking for GCC 'visibility' capability... ")
553 johnpye 546 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
554     context.Result("disabled")
555     return 0
556 johnpye 500 is_ok = context.TryCompile(gccvisibility_test_text,".c")
557     context.Result(is_ok)
558     return is_ok
559 johnpye 502
560 johnpye 500 #----------------
561 johnpye 502 # YACC
562    
563     yacc_test_text = """
564     %start ROOT
565     %token MSG
566     %%
567    
568     ROOT:
569     MSG { print("HELLO"); }
570     ;
571     """
572    
573     def CheckYacc(context):
574     context.Message("Checking for Yacc... ")
575     is_ok = context.TryCompile(yacc_test_text,".y")
576     context.Result(is_ok)
577     return is_ok
578    
579     #----------------
580 johnpye 404 # CUnit test
581    
582 johnpye 400 cunit_test_text = """
583 johnpye 451 #include <CUnit/CUnit.h>
584 johnpye 400 int maxi(int i1, int i2){
585     return (i1 > i2) ? i1 : i2;
586     }
587    
588     void test_maxi(void){
589     CU_ASSERT(maxi(0,2) == 2);
590     CU_ASSERT(maxi(0,-2) == 0);
591     CU_ASSERT(maxi(2,2) == 2);
592    
593     }
594     int main(void){
595     /* CU_initialize_registry() */
596 johnpye 404 return 0;
597 johnpye 400 }
598     """
599    
600     def CheckCUnit(context):
601 johnpye 451 return CheckExtLib(context,'cunit',cunit_test_text)
602 johnpye 400
603 johnpye 404 #----------------
604 johnpye 405 # Tcl test
605 johnpye 404
606 johnpye 561 # TCL and TK required version 8.1, 8.2, 8.3, or 8.4:
607     tcltk_minor_newest_acceptable = 4
608     tcltk_major_required = 8
609    
610 johnpye 404 tcl_check_text = r"""
611     #include <tcl.h>
612     #include <stdio.h>
613     int main(void){
614     printf("%s",TCL_PATCH_LEVEL);
615     return 0;
616     }
617     """
618    
619     def CheckTcl(context):
620 johnpye 521 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
621 johnpye 405
622     def CheckTclVersion(context):
623 johnpye 521 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
624 johnpye 405 context.Message("Checking Tcl version... ")
625     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
626 johnpye 404 keep.restore(context)
627     if not is_ok:
628 johnpye 405 context.Result("failed to run check")
629 johnpye 404 return 0
630 johnpye 405
631 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
632 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
633 johnpye 428 context.Result(output+" (bad version)")
634 johnpye 405 # bad version
635     return 0
636    
637     # good version
638 johnpye 552 context.Result(output+", good")
639 johnpye 404 return 1
640    
641 johnpye 405 #----------------
642 johnpye 463 # Tk test
643 johnpye 405
644     tk_check_text = r"""
645     #include <tk.h>
646     #include <stdio.h>
647     int main(void){
648     printf("%s",TK_PATCH_LEVEL);
649     return 0;
650     }
651     """
652     def CheckTk(context):
653 johnpye 521 return CheckExtLib(context,'tk',tcl_check_text,static=env['STATIC_TCLTK'])
654 johnpye 405
655 johnpye 428
656 johnpye 405 def CheckTkVersion(context):
657 johnpye 521 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
658 johnpye 405 context.Message("Checking Tk version... ")
659 johnpye 521 #print "LINKFLAGS =",context.env['LINKFLAGS']
660 johnpye 405 (is_ok,output) = context.TryRun(tk_check_text,'.c')
661 johnpye 404 keep.restore(context)
662     if not is_ok:
663     context.Result("failed to run check")
664     return 0
665    
666 wangym 511 major,minor,patch = tuple([int(i) for i in output.split(".")])
667 johnpye 561 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
668 johnpye 404 # bad version
669 johnpye 561 context.Result(output+" (bad version)")
670 johnpye 404 return 0
671 johnpye 400
672 johnpye 404 # good version
673 johnpye 561 context.Result(output+" (good)")
674 johnpye 404 return 1
675 johnpye 485
676     #----------------
677 johnpye 521 # Tktable test
678    
679     tktable_check_text = r"""
680     #include <tkTable.h>
681     #include <stdio.h>
682     int main(void){
683     Table mytable;
684     return 0;
685     }
686     """
687    
688     def CheckTkTable(context):
689     return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
690    
691     #---------------
692     # X11 test
693    
694     x11_check_text = r"""
695     #include <X11/Xlib.h>
696     #include <X11/IntrinsicP.h>
697     #include <X11/Intrinsic.h>
698     #include <X11/ObjectP.h>
699     #include <X11/Object.h>
700     int main(void){
701     Object mything;
702     return 0;
703     }
704     """
705    
706     def CheckX11(context):
707     return CheckExtLib(context,'X11',x11_check_text)
708    
709     #----------------
710 johnpye 485 # GCC Version sniffing
711    
712     # TODO FIXME
713    
714     gcc_version4 = False
715    
716 johnpye 398 #------------------------------------------------------
717 johnpye 385 # CONFIGURATION
718    
719     conf = Configure(env
720     , custom_tests = {
721 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
722 johnpye 400 , 'CheckCUnit' : CheckCUnit
723 johnpye 404 , 'CheckTcl' : CheckTcl
724     , 'CheckTclVersion' : CheckTclVersion
725 johnpye 405 , 'CheckTk' : CheckTk
726     , 'CheckTkVersion' : CheckTkVersion
727 johnpye 502 , 'CheckGcc' : CheckGcc
728 johnpye 500 , 'CheckGccVisibility' : CheckGccVisibility
729 johnpye 502 , 'CheckYacc' : CheckYacc
730 johnpye 521 , 'CheckTkTable' : CheckTkTable
731     , 'CheckX11' : CheckX11
732 johnpye 400 # , 'CheckIsNan' : CheckIsNan
733     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
734 johnpye 385 }
735 johnpye 459 # , config_h = "config.h"
736 johnpye 385 )
737    
738 johnpye 398
739 johnpye 385 # Math library
740    
741 johnpye 427 #if not conf.CheckFunc('sinh') and not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
742     # print 'Did not find math library, exiting!'
743     # Exit(1)
744    
745 johnpye 385 # Where is 'isnan'?
746    
747     if not conf.CheckFunc('isnan'):
748     print "Didn't find isnan"
749 johnpye 414 # Exit(1)
750 johnpye 385
751 johnpye 500 # GCC visibility
752    
753 johnpye 502 if conf.CheckGcc():
754     conf.env['HAVE_GCC']=True;
755 johnpye 526 if env['WITH_GCCVISIBILITY'] and conf.CheckGccVisibility():
756 johnpye 509 conf.env['HAVE_GCCVISIBILITY']=True;
757     conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
758     conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
759 johnpye 500
760 johnpye 502 # YACC
761    
762 johnpye 506 if not conf.CheckYacc():
763     print "YACC NOT FOUND OR NOT WORKING"
764     else:
765 johnpye 502 conf.env['HAVE_YACC']=True
766    
767     conf.env['HAVE_LEX']=True
768    
769 johnpye 387 # Tcl/Tk
770 johnpye 386
771 johnpye 586 if with_tcltk:
772     if conf.CheckTcl():
773     if conf.CheckTclVersion():
774     if conf.CheckTk():
775     if with_tcltk and conf.CheckTkVersion():
776     if env['STATIC_TCLTK']:
777     if conf.CheckTkTable():
778     pass
779     else:
780     without_tcltk_reason = "TkTable not found"
781     with_tcltk = False
782     else:
783     without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
784     with_tcltk = False
785 johnpye 521 else:
786 johnpye 586 without_tcltk_reason = "Tk not found."
787 johnpye 551 with_tcltk = False
788 johnpye 428 else:
789 johnpye 586 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
790 johnpye 551 with_tcltk = False
791 johnpye 586
792 johnpye 428 else:
793 johnpye 586 without_tcltk_reason = "Tcl not found."
794 johnpye 551 with_tcltk = False
795 johnpye 386
796 johnpye 521 if env['STATIC_TCLTK']:
797     conf.CheckX11()
798    
799 johnpye 395 # Python... obviously we're already running python, so we just need to
800     # check that we can link to the python library OK:
801    
802 johnpye 391 if platform.system()=="Windows":
803 johnpye 395 python_lib='python24'
804 johnpye 391 else:
805 johnpye 395 python_lib='python2.4'
806 johnpye 391
807 johnpye 395 # SWIG version
808    
809 johnpye 413 if not conf.CheckSwigVersion():
810     without_python_reason = 'SWIG >= 1.3.24 is required'
811     with_python = False
812    
813 johnpye 400 # CUnit
814    
815 johnpye 593 if with_cunit:
816 johnpye 404 if not conf.CheckCUnit():
817 johnpye 427 without_cunit_reason = 'CUnit not found'
818    
819     # BLAS
820    
821 johnpye 459 need_blas=False
822 johnpye 551 if with_tcltk:
823 johnpye 459 need_blas=True
824     if need_blas:
825     if conf.CheckLib('blas'):
826     with_local_blas = False
827     without_local_blas_reason = "Found BLAS installed on system"
828     else:
829     with_local_blas = True
830     need_fortran = True
831 johnpye 427
832     # FORTRAN
833    
834     if need_fortran:
835     conf.env.Tool('f77')
836     detect_fortran = conf.env.Detect(['g77','f77'])
837     if detect_fortran:
838     # For some reason, g77 doesn't get detected properly on MinGW
839     if not env.has_key('F77'):
840     conf.env.Replace(F77=detect_fortran)
841     conf.env.Replace(F77COM='$F77 $F77FLAGS -c -o $TARGET $SOURCE')
842     conf.env.Replace(F77FLAGS='')
843 johnpye 428 #print "F77:",conf.env['F77']
844     #print "F77COM:",conf.env['F77COM']
845     #print "F77FLAGS:",conf.env['F77FLAGS']
846 johnpye 427 fortran_builder = Builder(
847     action='$F77COM'
848     , suffix='.o'
849     , src_suffix='.f'
850     )
851     conf.env.Append(BUILDERS={'Fortran':fortran_builder})
852     else:
853     print "FORTRAN-77 required but not found"
854 johnpye 404 Exit(1)
855 johnpye 464 #else:
856     # print "FORTRAN not required"
857 johnpye 400
858 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
859    
860     # TODO: check size of void*
861    
862 johnpye 393 # TODO: detect if dynamic libraries are possible or not
863    
864 johnpye 427 if platform.system()=="Windows" and env.has_key('MSVS'):
865     if not conf.CheckHeader('windows.h') and env['PACKAGE_LINKING']=='DYNAMIC_PACKAGES':
866     print "Reverting to STATIC_PACKAGES since windows.h is not available. Probably you "\
867     +"need to install the Microsoft Windows Server 2003 Platform SDK, or similar."
868     env['PACKAGE_LINKING']='STATIC_PACKAGES'
869    
870 johnpye 534 if with_python and not conf.CheckHeader(['basetsd.h','BaseTsd.h']):
871 johnpye 427 with_python = 0;
872     without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
873    
874     conf.env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
875    
876 johnpye 395 conf.Finish()
877    
878     env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
879     env.Append(PYTHON_LIB=[python_lib])
880     env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
881    
882 johnpye 507 #---------------------------------------
883     # SUBSTITUTION DICTIONARY for .in files
884    
885     subst_dict = {
886     '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
887     , '@GLADE_FILE@':'ascend.glade'
888     , '@HELP_ROOT@':''
889     , '@ICON_EXTENSION@':icon_extension
890     , '@INSTALL_DATA@':env['INSTALL_DATA']
891     , '@INSTALL_BIN@':env['INSTALL_BIN']
892     , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
893     , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
894     , '@VERSION@':version
895 johnpye 563 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
896 johnpye 507 , '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
897 johnpye 508 , '@ASC_SHLIBSUFFIX@':env['SHLIBSUFFIX']
898     , '@ASC_SHLIBPREFIX@':env['SHLIBPREFIX']
899 johnpye 589 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
900     , '@ASC_DISTDIR_REL_BIN@' : '../share/ascend'
901 johnpye 507 }
902    
903 johnpye 594 if env.get('WITH_LOCAL_HELP'):
904 johnpye 507 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
905     subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
906    
907 johnpye 597 # bool options...
908     for k,v in {'WITH_XTERM_COLORS':'ASC_XTERM_COLORS', 'MALLOC_DEBUG':'MALLOC_DEBUG'}.iteritems():
909     if env.get(k):
910     subst_dict['ifdef '+v]="if 1"
911 johnpye 594
912 johnpye 507 if with_python:
913     subst_dict['@ASCXX_USE_PYTHON@']="1"
914    
915     if env.has_key('HAVE_GCCVISIBILITY'):
916     subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
917    
918     env.Append(SUBST_DICT=subst_dict)
919    
920 johnpye 385 #------------------------------------------------------
921 johnpye 558 # RECIPE: SWIG scanner
922    
923     import SCons.Script
924    
925     SWIGScanner = SCons.Scanner.ClassicCPP(
926     "SWIGScan"
927     , ".i"
928     , "CPPPATH"
929     , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
930     )
931    
932     env.Append(SCANNERS=[SWIGScanner])
933    
934     #------------------------------------------------------
935 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
936    
937     import re
938 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
939 johnpye 393
940 johnpye 395 def TOOL_SUBST(env):
941     """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
942     from the source to the target.
943     The values of SUBST_DICT first have any construction variables expanded
944     (its keys are not expanded).
945     If a value of SUBST_DICT is a python callable function, it is called and
946     the result is expanded as the value.
947     If there's more than one source and more than one target, each target gets
948     substituted from the corresponding source.
949 johnpye 393 """
950 johnpye 395 env.Append(TOOLS = 'SUBST')
951     def do_subst_in_file(targetfile, sourcefile, dict):
952     """Replace all instances of the keys of dict with their values.
953     For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
954     then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
955     """
956     try:
957     f = open(sourcefile, 'rb')
958     contents = f.read()
959     f.close()
960     except:
961     raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
962     for (k,v) in dict.items():
963     contents = re.sub(k, v, contents)
964     try:
965     f = open(targetfile, 'wb')
966     f.write(contents)
967     f.close()
968     except:
969     raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
970     return 0 # success
971 johnpye 393
972 johnpye 395 def subst_in_file(target, source, env):
973     if not env.has_key('SUBST_DICT'):
974     raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
975     d = dict(env['SUBST_DICT']) # copy it
976     for (k,v) in d.items():
977     if callable(v):
978     d[k] = env.subst(v())
979     elif SCons.Util.is_String(v):
980     d[k]=env.subst(v)
981     else:
982     raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
983     for (t,s) in zip(target, source):
984     return do_subst_in_file(str(t), str(s), d)
985 johnpye 393
986 johnpye 395 def subst_in_file_string(target, source, env):
987     """This is what gets printed on the console."""
988     return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
989     for (t,s) in zip(target, source)])
990 johnpye 393
991 johnpye 395 def subst_emitter(target, source, env):
992     """Add dependency from substituted SUBST_DICT to target.
993     Returns original target, source tuple unchanged.
994     """
995     d = env['SUBST_DICT'].copy() # copy it
996     for (k,v) in d.items():
997     if callable(v):
998     d[k] = env.subst(v())
999     elif SCons.Util.is_String(v):
1000     d[k]=env.subst(v)
1001     Depends(target, SCons.Node.Python.Value(d))
1002     return target, source
1003 johnpye 393
1004 johnpye 395 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
1005     env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
1006    
1007     TOOL_SUBST(env)
1008    
1009 johnpye 393 #------------------------------------------------------
1010 johnpye 463 # Recipe for 'CHMOD' ACTION
1011 johnpye 439
1012     import SCons
1013     from SCons.Script.SConscript import SConsEnvironment
1014     SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
1015     lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
1016    
1017     def InstallPerm(env, dest, files, perm):
1018     obj = env.Install(dest, files)
1019     for i in obj:
1020     env.AddPostAction(i, env.Chmod(str(i), perm))
1021    
1022     SConsEnvironment.InstallPerm = InstallPerm
1023    
1024     # define wrappers
1025     SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
1026 johnpye 578 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
1027 johnpye 463
1028 johnpye 439 #------------------------------------------------------
1029 johnpye 463 # BUILD...
1030 johnpye 385
1031 johnpye 463 # so that #include <modulename/headername.h> works across all modules...
1032     env.Append(CPPPATH=['#base/generic'])
1033 johnpye 385
1034 johnpye 485 if gcc_version4:
1035     env.Append(CCFLAGS=['-fvisibility=hidden'])
1036    
1037 johnpye 508 if env['DEBUG']:
1038     env.Append(CCFLAGS=['-g'])
1039    
1040 johnpye 591 if env['GCOV']:
1041     env.Append(
1042     CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
1043     , LIBS=['gcov']
1044     , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
1045     )
1046    
1047 johnpye 463 #-------------
1048     # TCL/TK GUI
1049 johnpye 385
1050 johnpye 551 if with_tcltk:
1051 johnpye 463 if with_local_blas:
1052     env.SConscript(['blas/SConscript'],'env')
1053     else:
1054     print "Skipping... BLAS won't be build:", without_local_blas_reason
1055 johnpye 385
1056 johnpye 463 env.SConscript(['lsod/SConscript'],'env')
1057 johnpye 385
1058 johnpye 463 env.SConscript(['linpack/SConscript'],'env')
1059 johnpye 569 env.SConscript(['tcltk/generic/interface/SConscript'],'env')
1060 johnpye 391 else:
1061 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
1062 johnpye 386
1063 johnpye 463 #-------------
1064     # PYTHON INTERFACE
1065    
1066 johnpye 387 if with_python:
1067 johnpye 532 env.SConscript(['pygtk/SConscript'],'env')
1068 johnpye 391 else:
1069 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
1070 johnpye 400
1071 johnpye 463 #------------
1072     # BASE/GENERIC SUBDIRECTORIES
1073    
1074     dirs = ['general','utilities','compiler','solver','packages']
1075    
1076     srcs = []
1077     for d in dirs:
1078     heresrcs = env.SConscript('base/generic/'+d+'/SConscript','env')
1079     srcs += heresrcs
1080    
1081     #-------------
1082     # LIBASCEND -- all base/generic functionality
1083    
1084     libascend = env.SharedLibrary('ascend',srcs)
1085    
1086     #-------------
1087     # UNIT TESTS
1088    
1089 johnpye 593 if with_cunit:
1090 johnpye 400 testdirs = ['general','solver','utilities']
1091 johnpye 593 testsrcs = []
1092 johnpye 400 for testdir in testdirs:
1093     path = 'base/generic/'+testdir+'/test/'
1094     env.SConscript([path+'SConscript'],'env')
1095 johnpye 593 testsrcs += [i.path for i in env['TESTSRCS_'+testdir.upper()]]
1096    
1097     #print "TESTSRCS =",testsrcs
1098    
1099 johnpye 400 env.SConscript(['test/SConscript'],'env')
1100     env.SConscript(['base/generic/test/SConscript'],'env')
1101 johnpye 593
1102     env.Alias('test',[env.Dir('test'),env.Dir('base/generic/test')])
1103 johnpye 400
1104     else:
1105 johnpye 427 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
1106 johnpye 400
1107 johnpye 427
1108 johnpye 463 #------------------------------------------------------
1109     # INSTALLATION
1110 johnpye 427
1111 johnpye 552 if env.get('CAN_INSTALL'):
1112 johnpye 463 # the models directory only needs to be processed for installation, no other processing required.
1113     env.SConscript(['models/SConscript'],'env')
1114 johnpye 427
1115 johnpye 463 dirs = ['INSTALL_BIN','INSTALL_DATA','INSTALL_LIB']
1116     install_dirs = [env['INSTALL_ROOT']+env[d] for d in dirs]
1117 johnpye 449
1118 johnpye 463 # TODO: add install options
1119     env.Alias('install',install_dirs)
1120 johnpye 400
1121 johnpye 463 env.Install(env['INSTALL_ROOT']+env['INSTALL_LIB'],libascend)
1122 johnpye 435
1123 johnpye 438 #------------------------------------------------------
1124     # CREATE the SPEC file for generation of RPM packages
1125    
1126 johnpye 463 if platform.system()=="Linux":
1127     env.SubstInFile('ascend.spec.in')
1128 johnpye 552
1129     #------------------------------------------------------
1130     # DISTRIBUTION TAR FILE
1131    
1132 johnpye 554 env['DISTTAR_FORMAT']='bz2'
1133 johnpye 556 env.Append(
1134 johnpye 566 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.cc','.cache','.pyc','.cvsignore','.dblite','.log','.pl']
1135 johnpye 561 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist']
1136 johnpye 556 )
1137 johnpye 554
1138 johnpye 563 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
1139 johnpye 556 , [env.Dir('#')]
1140 johnpye 554 )
1141    
1142     #------------------------------------------------------
1143     # RPM BUILD
1144    
1145     #if platform.system()=="Linux":
1146     # pass
1147    
1148     #------------------------------------------------------
1149     # DEFAULT TARGETS
1150    
1151 johnpye 569 env.Default(['pygtk','tcltk'])
1152 johnpye 554

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