/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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