/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


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

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