/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2715 - (show annotations) (download)
Sun Sep 1 12:29:23 2013 UTC (9 years ago) by jpye
File size: 75608 byte(s)
reviewing mingw32 build.
changing detection of glade directory on windows.
1 #!/usr/bin/python invoke_using_scons
2 # This is a build script for use with SCons. Use it to compile ASCEND on
3 # Linux, Windows. It should also give some success on Mac, although this is
4 # much less tested.
5
6 # version number for this ASCEND build:
7 version = "0.9.8"
8
9 # shared library API numbering, for Linux (FIXME windows too?)
10 soname_major_int = "1"
11 soname_minor = ".0"
12
13 import sys, os, commands, platform, distutils.sysconfig, os.path, re, types
14 import subprocess
15
16 # version number for python, useful on Windows
17 pyversion = "%d.%d" % (sys.version_info[0],sys.version_info[1])
18
19 # architecture label
20 winarchtag = "-win32"
21 if platform.architecture()[0] == "64bit":
22 winarchtag="-amd64"
23
24 import SCons.Warnings
25 SCons.Warnings.suppressWarningClass(SCons.Warnings.VisualCMissingWarning)
26
27 #------------------------------------------------------
28 # PLATFORM DEFAULTS
29
30 #print "PLATFORM = ",platform.system()
31
32 soname_major = "." + soname_major_int
33 default_install_prefix = '/usr/local'
34 default_install_bin = "$INSTALL_PREFIX/bin"
35 default_install_lib = "$INSTALL_PREFIX/lib"
36 default_install_models = "$INSTALL_LIB/ascend/models"
37 default_install_solvers = "$INSTALL_LIB/ascend/solvers"
38 default_install_assets = "$INSTALL_ASCDATA/glade/"
39 default_install_ascdata = "$INSTALL_SHARE/ascend"
40 default_install_include = "$INSTALL_PREFIX/include"
41 default_install_python = distutils.sysconfig.get_python_lib(plat_specific=1)
42 default_install_python_ascend = "$INSTALL_PYTHON/ascend"
43 default_tcl = '/usr'
44 default_tcl_libpath = "$TCL/lib"
45 default_tcl_cpppath = "$TCL/include"
46 default_conopt_envvar="CONOPT_PATH"
47 default_with_graphviz = True
48 default_tcl_lib = "tcl8.5"
49 default_tk_lib = "tk8.5"
50 default_tktable_lib = "Tktable2.9"
51 default_ida_prefix="$DEFAULT_PREFIX"
52 default_ipopt_libpath = "$IPOPT_PREFIX/lib"
53 default_ipopt_dll = ["$DEFAULT_PREFIX/bin/libgfortran-3.dll","$DEFAULT_PREFIX/bin/libstdc++-6.dll","$DEFAULT_PREFIX/bin/libquadmath-0.dll", None, None] # should be five here
54 default_ipopt_libs = ["$F2C_LIB","blas","lapack","pthread","ipopt"]
55 default_conopt_prefix="$DEFAULT_PREFIX"
56 default_conopt_libpath="$CONOPT_PREFIX"
57 default_conopt_cpppath="$CONOPT_PREFIX"
58 default_conopt_dlpath="$CONOPT_PREFIX"
59 default_prefix="/usr"
60 default_libpath="$DEFAULT_PREFIX/lib"
61 default_cpppath="$DEFAULT_PREFIX/include"
62 default_f2c_lib="gfortran"
63 default_swig="swig"
64
65 icon_extension = '.png'
66
67 if platform.system()=="Windows":
68 try:
69 d = os.path.split(os.path.dirname(WhereIs("gcc.exe")))[0]
70 default_prefix=d
71 except:
72 default_prefix="c:\\mingw"
73
74 default_libpath="$DEFAULT_PREFIX\\lib"
75 default_cpppath="$DEFAULT_PREFIX\\include"
76
77 # these correspond the the version of Tcl/Tk linked to in the NSIS scripts
78 default_tcl_lib = "tcl85"
79 default_tk_lib = "tk85"
80 default_tktable_lib = "Tktable28"
81
82 # on windows, we locate explicitly in gtkbrowser.py:
83 default_install_assets = ""
84
85 default_tcl = "c:\\Tcl"
86 if os.environ.get('MSYSTEM'):
87 default_tcl_libpath="$TCL\\bin"
88 else:
89 default_tcl_libpath="$TCL\\lib"
90
91 # on Windows, we build ASCEND such that it finds it support files
92 # using paths relative to the location of the executable
93 default_absolute_paths = False
94 default_dist_rel_bin = '.'
95 default_tk_rel_dist = 'tcltk'
96 default_library_rel_dist = 'models'
97 default_solvers_rel_dist = 'solvers'
98
99 # where to look for IDA solver libraries, headers, etc.
100 default_ida_prefix = "$DEFAULT_PREFIX"
101
102 # IPOPT. we now prefer to build our own version.
103 default_ipopt_libs = ["ipopt",'stdc++','coinmumps','coinmetis','coinlapack','coinblas','gfortran','pthread']
104
105 # where to look for CONOPT when compiling
106 default_conopt_prefix = "c:\\Program Files\\CONOPT"
107 default_conopt_lib="conopt3"
108
109 need_libm = False
110 python_exe = sys.executable
111 default_with_scrollkeeper=False
112 pathsep = ";"
113
114 default_f2c_lib="gfortran"
115
116 default_swig=WhereIs("swig.exe")
117
118 soname_minor = ""
119 soname_major = ""
120 # still problems with Graphviz on Windows, leave it off now by default.
121
122 if not os.path.exists(default_conopt_prefix):
123 default_conopt_prefix = None
124
125 elif platform.system()=="Darwin":
126
127 default_install_prefix = ''
128 default_install_bin = "$INSTALL_PREFIX/ASCEND.app/Contents"
129 default_install_lib = "$INSTALL_BIN"
130 default_install_models = "$INSTALL_BIN/Models"
131 default_install_solvers = "$INSTALL_BIN/Solvers"
132 default_install_ascdata = "$INSTALL_BIN/Resources"
133 default_install_include = "$INSTALL_BIN/Headers"
134 default_install_python = "$INSTALL_BIN/Python"
135 default_install_python_ascend = default_install_python
136 default_install_assets = "$INSTALL_ASCDATA/glade/"
137 # FIXME still need to work out the Tcl/Tk side of things...
138
139 # within the bundle, we'll use relative paths
140 default_absolute_paths = False
141 default_dist_rel_bin = '.'
142 default_tk_rel_dist = 'tcltk'
143
144 # we should move these to /Library/ASCEND/Models and /Library/ASCEND/Solvers, for visibility
145 default_library_rel_dist = 'Models'
146 default_solvers_rel_dist = 'Solvers'
147
148 # where to look for CONOPT when compiling
149 default_conopt_prefix = "/Library/CONOPT"
150
151 default_conopt_lib="conopt3"
152
153 need_libm = False
154 python_exe = sys.executable
155 default_with_scrollkeeper=False
156 pathsep = ";"
157
158 if not os.path.exists(default_conopt_prefix):
159 default_conopt_prefix = None
160
161 else: # LINUX, unix we hope
162
163 # the scons 'philosophy' if there is one is that the scons input arguments
164 # completely determine what external tools get picked any time there might
165 # be choices.
166 # We don't follow that philosophy with regard to tcl/tk.
167 # tcl/tk are often in multiple versions and locations on any given system.
168 # This leaves us trying to guess whether we should take:
169 # - only explicit arguments, otherwise disable tcl, tk
170 # - the first tcl/tk in the users path
171 # - the tcl/tk under a given user-specified prefix
172 # - the folklore-based canonical location of distributor's tcl/tk on a given linux dist
173 # We know one thing for sure. Any tcl installation includes tclsh, and thus
174 # it's the canonical way to find anything about tcl once tclsh is picked.
175 # So all the above reduces to 'how do we find tclsh?'
176 icon_extension = '.svg'
177
178 # here's the folklore we know.
179 if os.path.exists("/etc/debian_version"):
180 default_tcl_cpppath = "/usr/include/tcl8.4"
181 default_tcl_lib = "tcl8.4"
182 default_tk_lib = "tk8.4"
183 default_tktable_lib = "Tktable2.8"
184
185 if os.path.exists("/etc/SuSE-release"):
186 default_tcl_cpppath = "/usr/include"
187 default_tcl_lib = "tcl8.4"
188 default_tk_lib = "tk8.4"
189 default_tktable_lib = "Tktable2.9"
190
191 if os.path.exists("/etc/lsb-release"):
192 _f = file("/etc/lsb-release")
193 _r = re.compile("([A-Z][^=]*)=(.*)")
194 LSB = {}
195 for l in _f:
196 _m = _r.match(l.strip())
197 LSB[_m.group(1)] = _m.group(2)
198 print LSB
199 if LSB.has_key('DISTRIB_ID') and LSB['DISTRIB_ID'] == "Ubuntu":
200 if float(LSB['DISTRIB_RELEASE']) >= 9.04:
201 default_tcl_lib = "tcl8.5"
202 default_tk_lib = "tk8.5"
203 default_tktable_lib = "Tktable2.9"
204 default_tcl_cpppath = "/usr/include/tcl8.5"
205 if not os.path.exists(default_tcl_cpppath):
206 default_tcl_lib = "tcl8.4"
207 default_tk_lib = "tk8.4"
208 default_tktable_lib = "Tktable2.9"
209 default_tcl_cpppath = "/usr/include/tcl8.4"
210
211 # centos 5
212 if os.path.exists("/etc/redhat-release"):
213 default_tcl_cpppath = "/usr/include"
214 default_tcl_lib = "tcl"
215 if sys.maxint > 2**32:
216 default_tcl_libpath = "/usr/lib64"
217 else:
218 default_tcl_libpath = "/usr/lib"
219 default_tk_lib = "tk"
220 default_tktable_lib = "Tktable2.9"
221
222
223 default_absolute_paths = True
224 default_dist_rel_bin = '..'
225 default_tk_rel_dist = 'share/ascend/tcltk'
226 default_library_rel_dist = 'lib/ascend/models'
227 default_solvers_rel_dist = 'lib/ascend/solvers'
228
229 default_conopt_libpath="$CONOPT_PREFIX/lib"
230 default_conopt_cpppath="$CONOPT_PREFIX/include"
231 default_conopt_dlpath= default_conopt_libpath + ":/usr/local/lib"
232 default_conopt_lib="consub3"
233
234 need_libm = True
235 if not os.path.isdir(default_tcl):
236 default_tcl = '/usr'
237 python_exe = distutils.sysconfig.EXEC_PREFIX+"/bin/python"
238 default_with_scrollkeeper=False
239 pathsep = ":"
240
241 if not os.path.exists(default_ida_prefix):
242 default_ida_prefix = None
243
244 soname_clean = "${SHLIBPREFIX}ascend${SHLIBSUFFIX}"
245 soname_full = "%s%s" % (soname_clean,soname_major)
246
247 #------------------------------------------------------
248 # OPTIONS
249 #
250 # The following give the set of command-line parameters that can be passed to
251 # SCons from the commandline. Options will be 'remembered' by being cached
252 # in the file 'options.cache'; if you want to start with a clean slate, you
253 # should remove that file.
254
255 vars = Variables(['options.cache', 'config.py'])
256
257 vars.Add('HOST_PREFIX'
258 ,"Host architecture prefix"
259 ,""
260 )
261
262 vars.Add('CC'
263 ,'C Compiler command'
264 ,"${HOST_PREFIX}gcc"
265 )
266
267 vars.Add('CXX'
268 ,'C++ Compiler command'
269 ,"${HOST_PREFIX}g++"
270 )
271
272 vars.Add(BoolVariable('GCOV'
273 , 'Whether to enable coverage testing in object code'
274 , False
275 ))
276
277 if platform.system()!="Windows":
278 vars.Add(BoolVariable('WITH_GCCVISIBILITY'
279 ,"Whether to use GCC Visibility features (only applicable if available)"
280 ,True
281 ))
282
283 vars.Add(BoolVariable('WITH_SIGNALS'
284 ,"Whether to permit use of signals for flow control in the C-level code"
285 ,True
286 ))
287
288 # You can turn off building of Tcl/Tk interface
289 vars.Add(BoolVariable('WITH_TCLTK'
290 ,"Set to False if you don't want to build the original Tcl/Tk GUI."
291 , True
292 ))
293
294 # You can turn off the building of the Python interface
295 vars.Add(BoolVariable('WITH_PYTHON'
296 ,"Set to False if you don't want to build Python wrappers."
297 , True
298 ))
299
300 # Which solvers will we allow?
301 vars.Add(ListVariable('WITH_SOLVERS'
302 ,"List of the solvers you want to build. The default is the minimum that"
303 +" works. The option 'LSOD' is provided for backwards compatibility"
304 +"; the value 'LSODE' is preferred."
305 ,["QRSLV","CMSLV","LSODE","IDA","CONOPT","LRSLV","IPOPT","DOPRI5"]
306 ,['QRSLV','MPS','SLV','OPTSQP'
307 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
308 ,'LSODE','LSOD','OPTSQP',"IDA","TRON","IPOPT","DOPRI5","MAKEMPS","RADAU5"
309 ]
310 ))
311
312 # Where will the local copy of the help files be kept?
313 vars.Add(BoolVariable('WITH_DOC'
314 , "Should we try to build and install help files? If not, ASCEND will access online help files"
315 , True
316 ))
317
318 vars.Add(BoolVariable('WITH_DOC_BUILD'
319 , "If true, we'll attempt to build docs. Set false, we'll assume we already have then (eg from the tarball)"
320 , "$WITH_DOC"
321 ))
322
323 vars.Add(BoolVariable('WITH_DOC_INSTALL'
324 , "If true, SCons will install the documentation file(s). If false, assume rpm or dpkg is going to do it."
325 , "$WITH_DOC"
326 ))
327
328 vars.Add('HELP_ROOT'
329 , "Location of the main help file"
330 , "$INSTALL_DOC/book.pdf"
331 )
332
333 # Will bintoken support be enabled?
334 vars.Add(BoolVariable('WITH_BINTOKEN'
335 ,"Enable bintoken support? This means compiling models as C-code before"
336 +" running them, to increase solving speed for large models."
337 ,False
338 ))
339
340 # What should the default ASCENDLIBRARY path be?
341 # Note: users can change it by editing their ~/.ascend.ini
342 vars.Add('DEFAULT_ASCENDLIBRARY'
343 ,"Set the default value of the ASCENDLIBRARY -- the location where"
344 +" ASCEND will look for models when running ASCEND"
345 ,"$INSTALL_MODELS"
346 )
347
348 # What should the default ASCENDLIBRARY path be?
349 # Note: users can change it by editing their ~/.ascend.ini
350 vars.Add('DEFAULT_ASCENDSOLVERS'
351 ,"Set the default value of ASCENDSOLVERS -- the location where"
352 +" ASCEND will look for solver shared-library files"
353 ,"$INSTALL_SOLVERS"
354 )
355
356 # Where is SWIG?
357 vars.Add('SWIG'
358 ,"SWIG location, probably only required for MinGW and MSVC users."
359 +" Enter the location as a Windows-style path, for example"
360 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
361 ,default_swig
362 )
363
364 # Build the test suite?
365 vars.Add(BoolVariable('WITH_CUNIT'
366 ,"You can disable CUnit tests with this option. This will basically stop"
367 +" SCons from parsing the SConscript files relating to the 'test'"
368 +" target, which just might make things marginally faster. Probably"
369 +" you can just ignore this option though. SCons will sniff for Cunit"
370 +" but build the tests only if you specify the 'test' target."
371 ,True
372 ))
373
374 # Build with MMIO matrix export support?
375 vars.Add(BoolVariable('WITH_MMIO'
376 ,"Include support for exporting matrices in Matrix Market format"
377 ,True
378 ))
379
380 #----- default paths -----
381 vars.Add(PackageVariable('DEFAULT_PREFIX'
382 ,"Where are most of the shared libraries located on your system?"
383 ,default_prefix
384 ))
385
386 #------ cunit --------
387 # CUnit is a unit testing library that we use to test libascend.
388
389 # Where was CUNIT installed?
390 vars.Add(PackageVariable('CUNIT_PREFIX'
391 ,"Where are your CUnit files?"
392 ,"$DEFAULT_PREFIX"
393 ))
394
395 # Where are the CUnit includes?
396 vars.Add(PackageVariable('CUNIT_CPPPATH'
397 ,"Where are your CUnit include files?"
398 ,"$CUNIT_PREFIX/include"
399 ))
400
401 # Where are the CUnit libraries?
402 vars.Add(PackageVariable('CUNIT_LIBPATH'
403 ,"Where are your CUnit libraries?"
404 ,"$CUNIT_PREFIX/lib"
405 ))
406
407 # ----- conopt-----
408
409 vars.Add(PackageVariable("CONOPT_PREFIX"
410 ,"Prefix for your CONOPT install (CONOPT ./configure --prefix)"
411 ,default_conopt_prefix
412 ))
413
414 vars.Add("CONOPT_LIB"
415 ,"Library linked to for CONOPT. This is the name of the CONOPT .so or DLL. On Windows it seems to be called 'copopt3' but on linux it seems to be called 'consub3'."
416 ,default_conopt_lib
417 )
418
419 vars.Add(BoolVariable("CONOPT_LINKED"
420 ,"Do you want to dynamically link to CONOPT (only possible if CONOPT is available at buildtime)"
421 ,False
422 ))
423
424 vars.Add('CONOPT_CPPPATH'
425 ,"Where is your conopt.h?"
426 ,default_conopt_cpppath
427 )
428
429 vars.Add('CONOPT_LIBPATH'
430 ,"Where is your CONOPT library installed?"
431 ,default_conopt_libpath
432 )
433
434 vars.Add('CONOPT_DLPATH'
435 ,"Default (fallback) search path that ASCEND should use when dlopening the CONOPT library at runtime? This is only used if the conopt environment variable doesn't exist and doesn't point to a location where the DLL/SO is found. This is in platform-specific form (paths with ';' separator in Windows, ':' separator on Linux)."
436 ,default_conopt_dlpath
437 )
438
439 vars.Add('CONOPT_ENVVAR'
440 ,"Name of the optional environment variable which will be used for the value of the searchpath for the CONOPT DLL/SO."
441 ,default_conopt_envvar
442 )
443
444 #------- IPOPT -------
445
446 if platform.system()=="Windows":
447 vars.Add(PackageVariable("IPOPT_PREFIX"
448 ,"Prefix for your IPOPT install (IPOPT ./configure --prefix)"
449 ,default_conopt_prefix
450 ))
451
452 vars.Add("IPOPT_LIBS"
453 ,"Library linked to for IPOPT"
454 ,default_ipopt_libs
455 )
456
457 vars.Add("IPOPT_LIBPATH"
458 ,"Where is your IPOPT library installed"
459 ,default_ipopt_libpath
460 )
461
462 vars.Add('IPOPT_CPPPATH'
463 ,"Where is your IPOPT coin/IpStdCInterface.h (do not include the 'coin' in the path)"
464 ,"$IPOPT_PREFIX/include"
465 )
466
467 for i in range(5):
468 vars.Add('IPOPT_DLL%d'%(i+1)
469 ,"Exact path of IPOPT DLL (%d) to be included in the installer (Windows only)"%(i+1)
470 ,default_ipopt_dll[i]
471 )
472
473 #-------- f2c ------
474
475 vars.Add("F2C_LIB"
476 ,"F2C library (eg. g2c, gfortran, f2c)"
477 ,default_f2c_lib # the default is gfortran now
478 )
479
480 vars.Add(PackageVariable("F2C_LIBPATH"
481 ,"Directory containing F2C library (i.e. g2c, gfortran, f2c, etc.), if not already accessible"
482 ,"off"
483 ))
484
485 vars.Add("FORTRAN"
486 ,"Fortran compiler (eg g77, gfortran)"
487 ,"${HOST_PREFIX}gfortran"
488 )
489
490 vars.Add("SHFORTRAN"
491 ,"Fortran compiler for shared library object (should normally be same as FORTRAN)"
492 ,"$FORTRAN"
493 )
494
495 #------- tcl/tk --------
496
497 vars.Add('TCL'
498 ,'Base of Tcl distribution'
499 ,default_tcl
500 )
501
502 # Where are the Tcl includes?
503 vars.Add('TCL_CPPPATH'
504 ,"Where are your Tcl include files?"
505 ,default_tcl_cpppath
506 )
507
508 # Where are the Tcl libs?
509 vars.Add('TCL_LIBPATH'
510 ,"Where are your Tcl libraries?"
511 ,default_tcl_libpath
512 )
513
514 # What is the name of the Tcl lib?
515 vars.Add('TCL_LIB'
516 ,"Name of Tcl lib (eg 'tcl' or 'tcl83'), for full path to static library (if STATIC_TCLTK is set)"
517 ,default_tcl_lib
518 )
519
520 # Where are the Tk includes?
521 vars.Add('TK_CPPPATH'
522 ,"Where are your Tk include files?"
523 ,'$TCL_CPPPATH'
524 )
525
526 # Where are the Tk libs?
527 vars.Add('TK_LIBPATH'
528 ,"Where are your Tk libraries?"
529 ,'$TCL_LIBPATH'
530 )
531
532 # What is the name of the Tk lib?
533 vars.Add('TK_LIB'
534 ,"Name of Tk lib (eg 'tk' or 'tk83'), or full path to static library"
535 ,default_tk_lib
536 )
537
538 # Static linking to TkTable
539
540 vars.Add(BoolVariable('STATIC_TCLTK'
541 ,'Set true for static linking for Tcl/Tk and TkTable. EXPERIMENTAL'
542 ,False
543 ))
544
545 vars.Add('TKTABLE_LIBPATH'
546 ,'Location of TkTable static library'
547 ,'$TCL_LIBPATH/Tktable2.8'
548 )
549
550 vars.Add('TKTABLE_LIB'
551 ,'Stem name of TkTable (eg tktable2.8, no ".so" or "lib") shared library, or full path of static tktable (/usr/lib/...)'
552 ,default_tktable_lib
553 )
554
555 vars.Add('TKTABLE_CPPPATH'
556 ,'Location of TkTable header file'
557 ,'$TCL_CPPPATH'
558 )
559
560 vars.Add('X11'
561 ,'Base X11 directory. Only used when STATIC_TCLTK is turned on. EXPERIMENTAL'
562 ,'/usr/X11R6'
563 )
564
565 vars.Add('X11_LIBPATH'
566 ,'Location of X11 lib. EXPERIMENTAL'
567 ,'$X11/lib'
568 )
569
570 vars.Add('X11_CPPPATH'
571 ,'Location of X11 includes. EXPERIMENTAL'
572 ,'$X11/include'
573 )
574
575 vars.Add('X11_LIB'
576 ,'Name of X11 lib. EXPERIMENTAL'
577 ,'X11'
578 )
579
580 #----- installed file locations (for 'scons install') -----
581
582 vars.Add('INSTALL_PREFIX'
583 ,'Root location for installed files'
584 ,default_install_prefix
585 )
586
587 vars.Add('INSTALL_BIN'
588 ,'Location to put binaries during installation'
589 ,default_install_bin
590 )
591
592 vars.Add('INSTALL_LIB'
593 ,'Location to put libraries during installation'
594 ,default_install_lib
595 )
596
597 vars.Add('INSTALL_SHARE'
598 ,'Common shared-file location on this system'
599 ,"$INSTALL_PREFIX/share"
600 )
601
602 vars.Add('INSTALL_ASCDATA'
603 ,"Location of ASCEND shared data (TK, python, models etc)"
604 ,default_install_ascdata
605 )
606
607 vars.Add('INSTALL_PYTHON'
608 ,'General location for Python extensions on this system'
609 ,default_install_python
610 )
611
612 vars.Add('INSTALL_PYTHON_ASCEND'
613 ,'Location for installation of Python modules specific to ASCEND'
614 ,default_install_python_ascend
615 )
616
617 vars.Add('INSTALL_TK'
618 ,'Location for Tcl/Tk files used by ASCEND Tk GUI'
619 ,"$INSTALL_ASCDATA/tcltk"
620 )
621
622 vars.Add('INSTALL_MODELS'
623 ,"Location of ASCEND model files (.a4c,.a4l,.a4s)"
624 ,default_install_models
625 )
626
627 vars.Add('INSTALL_SOLVERS'
628 ,"Location of ASCEND solvers"
629 ,default_install_solvers
630 )
631
632 vars.Add('INSTALL_DOC'
633 ,"Location of ASCEND documentation files"
634 ,"$INSTALL_SHARE/doc/ascend-"+version
635 )
636
637 vars.Add('INSTALL_INCLUDE'
638 ,'Location to put header files during installation'
639 ,default_install_include
640 )
641
642 vars.Add('INSTALL_ROOT'
643 ,'For use by RPM only: location of %{buildroot} during rpmbuild'
644 ,""
645 )
646
647 vars.Add('EXTLIB_SUFFIX'
648 ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
649 ,"_ascend$SHLIBSUFFIX"
650 )
651
652 vars.Add('EXTLIB_PREFIX'
653 ,"Filename suffix for ASCEND 'external libraries' (for use with IMPORT"
654 ,"$SHLIBPREFIX"
655 )
656
657 #----------------------
658
659 vars.Add('PYGTK_ASSETS'
660 ,'Default location for Glade assets (will be recorded in pygtk/config.py)'
661 ,default_install_assets
662 )
663
664 vars.Add(BoolVariable('DEBUG'
665 ,"Compile source with debugger symbols, eg for use with 'gdb'"
666 ,False
667 ))
668
669 vars.Add(BoolVariable('MALLOC_DEBUG'
670 ,"Compile with debugging version of MALLOC. Required for full CUnit testing"
671 ,False
672 ))
673
674 #------ dmalloc --------
675 vars.Add(PackageVariable('DMALLOC_PREFIX'
676 ,"Where are your dmalloc files?"
677 ,"$DEFAULT_PREFIX"
678 ))
679
680 vars.Add(PackageVariable('DMALLOC_CPPPATH'
681 ,"Where are your dmalloc include files?"
682 ,default_cpppath
683 ))
684
685 vars.Add(PackageVariable('DMALLOC_LIBPATH'
686 ,"Where are your dmalloc libraries?"
687 ,default_libpath
688 ))
689
690 vars.Add(BoolVariable('WITH_DMALLOC'
691 ,"Link to the DMALLOC library (if available) for debugging of memory usage."
692 ,False
693 ))
694
695 vars.Add(BoolVariable('WITH_GRAPHVIZ'
696 ,"Link to the GRAPHVIZ library (if available, for generating incidence graphs)"
697 ,default_with_graphviz
698 ))
699
700
701 #------ ufsparse --------
702 vars.Add(PackageVariable('UFSPARSE_PREFIX'
703 ,"Where are your UFSPARSE files?"
704 ,"$DEFAULT_PREFIX"
705 ))
706
707 vars.Add(PackageVariable('UFSPARSE_CPPPATH'
708 ,"Where are your UFSPARSE include files?"
709 ,default_cpppath
710 ))
711
712 vars.Add(PackageVariable('UFSPARSE_LIBPATH'
713 ,"Where are your UFSPARSE libraries?"
714 ,default_libpath
715 ))
716
717 vars.Add(BoolVariable('WITH_UFSPARSE'
718 ,"Link to the UFSPARSE library (if available, for additional sparse matrix routines)"
719 ,True
720 ))
721
722 #-----------------------
723
724 vars.Add(BoolVariable('UPDATE_NO_YACC_LEX'
725 ,"Update the *_no_yacc* and *_no_lex* files in the source tree? (these files are created so that ASCEND can be compiled in the absence of those tools)"
726 ,False
727 ))
728
729 vars.Add('DISTTAR_NAME'
730 ,"Stem name of the tarball created by 'scons dist'. So for 'ascend-aaa.tar.bz2', set this to 'ascend-aaa'."
731 ,"ascend-"+version
732 )
733
734 vars.Add('RELEASE'
735 ,"Release number for use in RPM spec file. This should always start with a zero for releases made by the ASCEND group, in order that third parties can make 'patch' releases of higher version numbers."
736 ,"0"
737 )
738
739 vars.Add(BoolVariable('ABSOLUTE_PATHS'
740 ,"Whether to use absolute or relative paths in the installed Tcl/Tk interface. If you want to build an RPM, set this to false."
741 ,default_absolute_paths
742 ))
743
744 vars.Add('WIN_INSTALLER_NAME'
745 ,"Name of the installer .exe to create under Windows (minus the '.exe')"
746 ,"ascend-"+version+winarchtag+"-py"+pyversion+".exe"
747 )
748
749 vars.Add(BoolVariable('WITH_XTERM_COLORS'
750 ,"Set to 0 if you don't want xterm colour codes in the console output"
751 ,True
752 ))
753
754 vars.Add(BoolVariable('WITH_EXTFNS'
755 ,"Set to 0 if you don't want to attempt to build the external modules bundled with ASCEND"
756 ,True
757 ))
758
759 vars.Add(BoolVariable('WITH_SCROLLKEEPER'
760 ,"Set to to 1 if you want to install an OMF file that can be read by scrollkeeper (eg Yelp on GNOME)"
761 ,default_with_scrollkeeper
762 ))
763
764 vars.Add(BoolVariable('WITH_MSVCR71'
765 ,"Attempt to link against MSVCR71.DLL, to enable passing of FILE* objects to/from python"
766 ,False
767 ))
768
769
770 # TODO: OTHER OPTIONS?
771 # TODO: flags for optimisation
772 # TODO: turning on/off bintoken functionality
773 # TODO: Where will the 'Makefile.bt' file be installed?
774
775 # Import the outside environment
776
777 def c_escape(str):
778 return re.sub("\\\\","/",str)
779
780 envadditional={}
781
782 tools = [
783 'lex', 'yacc', 'fortran', 'swig', 'substinfile'
784 ,'disttar', 'tar', 'graphviz','sundials', 'dvi', 'pdflatex'
785 ]
786 if platform.system()=="Windows":
787 tools += ['nsis']
788
789 if os.environ.get('OSTYPE')=='msys' or os.environ.get('MSYSTEM'):
790 envenv = os.environ
791 tools += ['mingw']
792 envadditional['IS_MINGW']=True
793 else:
794 print "Assuming VC++ build environment (Note: MinGW is preferred)"
795 envenv = {
796 'PATH':os.environ['PATH']
797 ,'INCLUDE':os.environ['INCLUDE']
798 ,'LIB':os.environ['LIB']
799 ,'MSVS_IGNORE_IDE_PATHS':1
800 }
801 tools += ['default']
802 envadditional['CPPDEFINES']=['_CRT_SECURE_NO_DEPRECATE']
803 else:
804 envenv = os.environ
805 tools += ['default','doxygen','ipopt']
806
807 env = Environment(
808 ENV=envenv
809 , toolpath=['scons']
810 , tools=tools
811 , **envadditional
812 )
813
814 # Create .def files by default on Windows (or else SCons 2.0.1 never seems to be happy)
815 if platform.system()=="Windows":
816 env.Append(WINDOWS_INSERT_DEF=1)
817
818 #print "PATH =",os.environ['PATH']
819 #print "PROGSUFFIX =",env['PROGSUFFIX']
820 #print "CPPPATH =",env['CPPPATH']
821
822 vars.Update(env)
823
824 for l in ['SUNDIALS','IPOPT']:
825 var = "%s_LIBS" % l
826 if env.get(var) and not isinstance(env[var],types.ListType):
827 env[var] = env[var].split(",")
828
829 if 'LSOD' in env['WITH_SOLVERS']:
830 if 'LSODE' not in env['WITH_SOLVERS']:
831 env['WITH_SOLVERS'].append('LSODE')
832 env['WITH_SOLVERS'].remove('LSOD')
833
834 vars.Save('options.cache',env)
835
836 Help(vars.GenerateHelpText(env))
837
838 if env['ENV'].get('HOST_PREFIX'):
839 triplet = re.compile("^[a-z0-9_]+-[a-z0-9_]+-[a-z0-9]+$")
840 if not triplet.match(env['ENV']['HOST_PREFIX']):
841 print "NOTE: invalid host triplet from environment variable HOST_PREFIX has been ignored"
842 else:
843 print "NOTE: using HOST_PREFIX=%s from environment to override HOST_PREFIX SCons variable" % env['ENV']['HOST_PREFIX']
844 env['HOST_PREFIX'] = env['ENV']['HOST_PREFIX']+"-"
845
846 with_tcltk = env.get('WITH_TCLTK')
847 without_tcltk_reason = "disabled by options/config.py"
848
849 with_python = env.get('WITH_PYTHON')
850 without_python_reason = "disabled by options/config.py"
851
852 with_cunit = env.get('WITH_CUNIT')
853 without_cunit_reason = "not requested"
854
855 with_extfns = env.get('WITH_EXTFNS')
856 without_extfn_reason = "disabled by options/config.py"
857
858 with_scrollkeeper = env.get('WITH_SCROLLKEEPER')
859 without_scrollkeeper_reason = "disabled by options/config.py"
860
861 with_dmalloc = env.get('WITH_DMALLOC')
862 without_dmalloc_reason = "disabled by options/config.py"
863
864 with_graphviz = env.get('WITH_GRAPHVIZ')
865 without_graphiviz_reason = "disabled by options/config.py"
866
867 with_ufsparse = env.get('WITH_UFSPARSE')
868 without_ufsparse_reason = "disabled by options/config.py"
869
870 with_mmio = env.get('WITH_MMIO')
871 without_mmio_reason = "disabled by options/config.py"
872
873 with_signals = env.get('WITH_SIGNALS')
874 without_signals_reason = "disabled by options/config.py"
875
876 with_doc = env.get('WITH_DOC')
877
878 with_doc_build = env.get('WITH_DOC_BUILD');
879 without_doc_build_reason = "disabled by options/config.py"
880 if not with_doc:
881 with_doc_build = False
882 without_doc_build_reason = "disabled by with_doc"
883
884 with_latex2html = False
885
886 if platform.system()=="Windows":
887 with_installer=1
888 else:
889 with_installer=0
890 without_installer_reason = "only possible under Windows"
891
892 notselected = "Not selected (see config option WITH_SOLVERS)"
893
894 with_lsode = 'LSODE' in env['WITH_SOLVERS']
895 without_lsode_reason = notselected
896
897 with_ida = 'IDA' in env['WITH_SOLVERS']
898 without_ida_reason = notselected
899
900 with_dopri5 = 'DOPRI5' in env['WITH_SOLVERS']
901 without_dopri5_reason = notselected
902
903 with_radau5 = 'RADAU5' in env['WITH_SOLVERS']
904 without_radau5_reason = notselected
905
906 with_conopt = 'CONOPT' in env['WITH_SOLVERS']
907 without_conopt_reason = notselected
908
909 with_ipopt = 'IPOPT' in env['WITH_SOLVERS']
910 without_ipopt_reason = notselected
911
912 with_makemps = 'MAKEMPS' in env['WITH_SOLVERS']
913 without_makemps_reason = notselected
914
915
916 #print "SOLVERS:",env['WITH_SOLVERS']
917 #print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
918 #print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
919
920 can_install = True
921 if platform.system()=='Windows':
922 can_install = False
923
924 env['CAN_INSTALL']=can_install
925
926 #print "TCL=",env['TCL']
927 #print "TCL_CPPPATH =",env['TCL_CPPPATH']
928 #print "TCL_LIBPATH =",env['TCL_LIBPATH']
929 #print "TCL_LIB =",env['TCL_LIB']
930
931 #print "ABSOLUTE PATHS =",env['ABSOLUTE_PATHS']
932 #print "INSTALL_ASCDATA =",env['INSTALL_ASCDATA']
933 #print "INSTALL_PREFIX =",env['INSTALL_PREFIX']
934 #print "INSTALL_MODELS =",env['INSTALL_MODELS']
935 #print "INSTALL_SOLVERS =",env['INSTALL_SOLVERS']
936 #print "INSTALL_PYTHON =",env['INSTALL_PYTHON']
937 #print "INSTALL_PYTHON_ASCEND =",env['INSTALL_PYTHON_ASCEND']
938 #print "DEFAULT_ASCENDLIBRARY =",env['DEFAULT_ASCENDLIBRARY']
939 #print "DEFAULT_ASCENDSOLVERS =",env['DEFAULT_ASCENDSOLVERS']
940
941
942 #------------------------------------------------------
943 # SPECIAL CONFIGURATION TESTS
944
945 need_fortran = False
946 need_fortran_reasons = []
947
948 #----------------
949 # CC
950
951 cc_test_text = """
952 int main(void){
953 return 0;
954 }
955 """;
956
957 def CheckCC(context):
958 context.Message("Checking C compiler ('%s')... " % context.env.subst('$CC'))
959 is_ok = context.TryCompile(cc_test_text,".c")
960 context.Result(is_ok)
961 return is_ok
962
963 #----------------
964 # CXX
965
966 cxx_test_text = """
967 template<class X>
968 class pair{
969 public:
970 X a;
971 X b;
972 };
973
974 int main(void){
975 pair<double> P;
976 P.a = 0;
977 return 0;
978 }
979 """;
980
981 def CheckCXX(context):
982 context.Message("Checking C++ compiler ('%s')... " % context.env.subst('$CXX'))
983 if not context.env.get('CXX'):
984 context.Result("not found")
985 return False
986 is_ok = context.TryCompile(cxx_test_text,".cpp")
987 context.Result(is_ok)
988 return is_ok
989
990 #----------------
991
992 f77_test_text = """
993 C Hello World in Fortran 77
994
995 PROGRAM HELLO
996 PRINT*, 'Hello World!'
997 END
998 """;
999
1000 def CheckFortran(context):
1001 context.Message("Checking Fortran compiler ('%s')..." % context.env.subst('$FORTRAN'))
1002 if not context.env.get('FORTRAN'):
1003 context.Result('not found')
1004 return False
1005 is_ok = context.TryCompile(f77_test_text,".f")
1006 context.Result(is_ok)
1007 return is_ok
1008
1009 #----------------
1010 # SWIG
1011
1012 import os,re
1013
1014 def get_swig_version(env):
1015 if not WhereIs(env['SWIG']):
1016 raise RuntimeError("'%s' not found in PATH"%env.subst("$SWIG"))
1017 cmd = [env['SWIG'],'-version']
1018 p = subprocess.Popen(cmd,stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1019 output, err = p.communicate()
1020
1021 restr = r"\s*SWIG\s+Version\s+(?P<maj>[0-9]+)\.(?P<min>[0-9]+)\.(?P<pat>[0-9]+)\b"
1022 expr = re.compile(restr,re.MULTILINE|re.IGNORECASE);
1023 m = expr.match(output);
1024 if not m:
1025 raise RuntimeError("Failed match on output '%s'" % output)
1026 maj = int(m.group('maj'))
1027 min = int(m.group('min'))
1028 pat = int(m.group('pat'))
1029
1030 return (maj,min,pat)
1031
1032
1033 def CheckSwigVersion(context):
1034
1035 try:
1036 context.Message("Checking version of SWIG... ")
1037 maj,min,pat = get_swig_version(context.env)
1038 except Exception,e:
1039 context.Result("Failed (%s)" % str(e))
1040 return False;
1041
1042 context.env['SWIGVERSION']=tuple([maj,min,pat])
1043
1044 msg = "too old"
1045 res = False
1046 if maj == 1 and (
1047 min > 3
1048 or (min == 3 and pat >= 24)
1049 ):
1050 msg = "ok"
1051 res = True
1052 elif maj == 2:
1053 msg = "ok"
1054 res = True
1055
1056 context.Result("%s, %d.%d.%d" % (msg, maj,min,pat))
1057 return res;
1058
1059 #----------------
1060 # Scrollkeeper (Linux documentation system)
1061
1062 def get_scrollkeeper_omfdir(env):
1063 cmd = ['scrollkeeper-config','--omfdir']
1064 p = subprocess.Popen(cmd,stdout=subprocess.PIPE)
1065 output = p.communicate()
1066 return output.strip()
1067
1068 def CheckScrollkeeperConfig(context):
1069 try:
1070 context.Message("Checking for scrollkeeper...")
1071 dir=get_scrollkeeper_omfdir(context.env)
1072 except:
1073 context.Result("Failed to run 'scrollkeeper-config'")
1074 return 0
1075 context.env['OMFDIR']=dir
1076 context.Result("OK, %s" % dir)
1077 return 1
1078
1079 #----------------
1080 # General purpose library-and-header test
1081
1082 class KeepContext:
1083 def __init__(self,context,varprefix,static=False):
1084 self.keep = {}
1085 for k in ['LIBS','LIBPATH','CPPPATH','LINKFLAGS']:
1086 #print "Keeping env %s = %s" % (k,context.env.get(k))
1087 self.keep[k]=context.env.get(k)
1088
1089 if context.env.has_key(varprefix+'_CPPPATH'):
1090 context.env.AppendUnique(CPPPATH=[env[varprefix+'_CPPPATH']])
1091 #print "Adding '"+str(env[varprefix+'_CPPPATH'])+"' to cpp path"
1092
1093 if static:
1094 staticlib=env[varprefix+'_LIB']
1095 #print "STATIC LIB = ",staticlib
1096 context.env.Append(
1097 LINKFLAGS=[staticlib]
1098 )
1099 else:
1100 if context.env.has_key(varprefix+'_LIBPATH'):
1101 context.env.Append(LIBPATH=[env[varprefix+'_LIBPATH']])
1102 #print "Adding '"+str(env[varprefix+'_LIBPATH'])+"' to lib path"
1103
1104 if context.env.has_key(varprefix+'_LIB'):
1105 context.env.Append(LIBS=[env[varprefix+'_LIB']])
1106 #print "Adding '"+str(env[varprefix+'_LIB'])+"' to libs"
1107 elif context.env.has_key(varprefix+'_LIBS'):
1108 context.env.AppendUnique(LIBS=env[varprefix+'_LIBS'])
1109
1110 def restore(self,context):
1111 #print "RESTORING CONTEXT"
1112 #print self.keep
1113 #print "..."
1114 for k in self.keep:
1115 if self.keep[k]==None:
1116 if context.env.has_key(k):
1117 #print "Clearing "+str(k)
1118 del context.env[k];
1119 else:
1120 #print "Restoring %s to '%s'" %(k,self.keep.get(k))
1121 context.env[k]=self.keep[k];
1122
1123 def CheckExtLib(context,libname,text,ext='.c',varprefix=None,static=False,testname=None):
1124 """This method will check for variables LIBNAME_LIBPATH
1125 and LIBNAME_CPPPATH and try to compile and link the
1126 file with the provided text, linking with the
1127 library libname."""
1128
1129 if testname is None:
1130 testname = libname
1131
1132 if static:
1133 context.Message( 'Checking for static '+testname+'... ' )
1134 else:
1135 context.Message( 'Checking for '+testname+'... ' )
1136
1137 if varprefix==None:
1138 varprefix = libname.upper()
1139
1140 #print "LIBS is currently:",context.env.get('LIBS')
1141 keep = KeepContext(context,varprefix,static)
1142
1143 if not context.env.has_key(varprefix+'_LIB') and not context.env.has_key(varprefix+'_LIBS'):
1144 # if varprefix_LIB were in env, KeepContext would
1145 # have appended it already
1146 context.env.Append(LIBS=[libname])
1147
1148 is_ok = context.TryLink(text,ext)
1149
1150 #print "Link success? ",(is_ok != 0)
1151
1152 keep.restore(context)
1153
1154 # print "Restored CPPPATH="+str(context.env['CPPPATH'])
1155 # print "Restored LIBS="+str(context.env['LIBS'])
1156 # print "Restored LIBPATH="+str(context.env['LIBPATH'])
1157
1158 context.Result(is_ok)
1159 return is_ok
1160
1161 #----------------
1162 # GCC
1163
1164 gcc_test_text = """
1165 #ifndef __GNUC__
1166 # error "Not using GCC"
1167 #endif
1168
1169 int main(void){
1170 return __GNUC__;
1171 }
1172 """
1173
1174 def CheckGcc(context):
1175 context.Message("Checking for GCC... ")
1176 is_ok = context.TryCompile(gcc_test_text,".c")
1177 context.Result(is_ok)
1178 return is_ok
1179
1180 #----------------
1181 # GCC VISIBILITY feature
1182
1183 gccvisibility_test_text = """
1184 #if __GNUC__ < 4
1185 # error "Require GCC version 4 or newer"
1186 #endif
1187
1188 __attribute__ ((visibility("default"))) int x;
1189
1190 int main(void){
1191 extern int x;
1192 x = 4;
1193 }
1194 """
1195
1196 def CheckGccVisibility(context):
1197 context.Message("Checking for GCC 'visibility' capability... ")
1198 if not context.env.has_key('WITH_GCCVISIBILITY') or not env['WITH_GCCVISIBILITY']:
1199 context.Result("disabled")
1200 return 0
1201 is_ok = context.TryCompile(gccvisibility_test_text,".c")
1202 context.Result(is_ok)
1203 return is_ok
1204
1205 #----------------
1206 # YACC
1207
1208 yacc_test_text = """
1209 %{
1210 #include <stdio.h>
1211
1212 /* MSVC++ needs this before it can swallow Bison output */
1213 #ifdef _MSC_VER
1214 # define __STDC__
1215 #endif
1216 %}
1217 %token MSG
1218 %start ROOT
1219 %%
1220 ROOT:
1221 MSG { printf("HELLO"); }
1222 ;
1223 %%
1224 """
1225
1226 def CheckYacc(context):
1227 context.Message("Checking for Yacc ('%s')... " % context.env.get('YACC'))
1228 is_ok = context.TryCompile(yacc_test_text,".y")
1229 context.Result(is_ok)
1230 return is_ok
1231
1232 #----------------
1233 # LEX
1234
1235 lex_test_text = """
1236 %{
1237 #include <stdio.h>
1238 %}
1239 DIGIT [0-9]
1240 ID [a-z][a-z0-9]*
1241 %%
1242 {DIGIT}+ {
1243 printf("A digit: %s\\n",yytext);
1244 }
1245
1246 [ \\t\\n]+ /* ignore */
1247
1248 . {
1249 printf("Unrecognized guff");
1250 }
1251 %%
1252 main(){
1253 yylex();
1254 }
1255 """
1256
1257 def CheckLex(context):
1258 context.Message("Checking for Lex ('%s')... " % context.env.get('LEX'))
1259 is_ok = context.TryCompile(lex_test_text,".l")
1260 context.Result(is_ok)
1261 return is_ok
1262
1263 lexdestroy_test_text = """
1264 %{
1265 #include <stdio.h>
1266 #include <unistd.h>
1267 %}
1268
1269 %%
1270 username printf("%s", getlogin());
1271 %%
1272
1273 int yywrap(void){
1274 return 1;
1275 }
1276
1277 main(){
1278 //yylex();
1279 yylex_destroy();
1280 }
1281
1282 """
1283
1284 def CheckLexDestroy(context):
1285 context.Message("Checking for yylex_destroy... ")
1286 is_ok, outstring = context.TryRun(lexdestroy_test_text,".l")
1287 context.Result(is_ok)
1288 return is_ok
1289
1290 #----------------
1291 # CUnit test
1292
1293 cunit_test_text = """
1294 #include <CUnit/CUnit.h>
1295 int maxi(int i1, int i2){
1296 return (i1 > i2) ? i1 : i2;
1297 }
1298
1299 void test_maxi(void){
1300 CU_ASSERT(maxi(0,2) == 2);
1301 CU_ASSERT(maxi(0,-2) == 0);
1302 CU_ASSERT(maxi(2,2) == 2);
1303
1304 }
1305 int main(void){
1306 /* CU_initialize_registry() */
1307 return 0;
1308 }
1309 """
1310
1311 def CheckCUnit(context):
1312 return CheckExtLib(context,'cunit',cunit_test_text)
1313
1314 #----------------
1315 # dmalloc test
1316
1317 dmalloc_test_text = """
1318 #include <stdlib.h>
1319 #include <dmalloc.h>
1320
1321 int main(void){
1322 char *c;
1323 c = (char *)malloc(100*sizeof(char));
1324 free(c);
1325 return 0;
1326 }
1327 """
1328
1329 def CheckDMalloc(context):
1330 return CheckExtLib(context,'dmalloc',dmalloc_test_text)
1331
1332 #----------------
1333 # graphviz test
1334
1335 graphviz_test_text = """
1336 #ifdef __WIN32__
1337 # include <gvc.h>
1338 #else
1339 # include <graphviz/gvc.h>
1340 #endif
1341 int main(void){
1342 Agraph_t *g;
1343 GVC_t *gvc;
1344 gvc = gvContext();
1345 g = agopen("g", AGDIGRAPH);
1346 return 0;
1347 }
1348 """
1349
1350 def CheckGraphViz(context):
1351 return CheckExtLib(context,'graphviz',graphviz_test_text,ext=".c")
1352
1353 graphviz_boolean_test = """
1354 #ifdef __WIN32__
1355 # include <types.h>
1356 #else
1357 # include <graphviz/types.h>
1358 #endif
1359 #ifndef GV_TYPES_H
1360 # error WHERE IS GV_TYPES_H?
1361 #endif
1362 int main(void){
1363 boolean x;
1364 x = TRUE;
1365 return 0;
1366 }
1367 """
1368
1369 def CheckGraphVizBoolean(context):
1370 return CheckExtLib(context,'graphviz',graphviz_boolean_test,ext=".c" \
1371 ,testname="graphviz 'boolean' definition"
1372 )
1373
1374 #----------------
1375 # ufsparse test
1376
1377 ufsparse_test_text = """
1378 #include <ufsparse/cs.h>
1379 int main(void){
1380 cs *A,*B,*C;
1381 C = cs_multiply(A,B);
1382 return 0;
1383 }
1384 """
1385
1386 def CheckUFSparse(context):
1387 return CheckExtLib(context
1388 ,libname='cxsparse'
1389 ,varprefix='ufsparse'
1390 ,text=ufsparse_test_text
1391 ,ext=".c"
1392 )
1393
1394 #----------------
1395 # MATH test
1396
1397 math_test_text = """
1398 #ifndef _ALL_SOURCE
1399 # define _ALL_SOURCE
1400 #endif
1401 #ifndef _XOPEN_SOURCE
1402 # define _XOPEN_SOURCE
1403 #endif
1404 #ifndef _XOPEN_SOURCE_EXTENDED
1405 # define _XOPEN_SOURCE_EXTENDED 1
1406 #endif
1407 #include <math.h>
1408 int main(void){
1409 double x = 1.0; double y = 1.0; int i = 1;
1410 acosh(x); asinh(x); atanh(x); cbrt(x); expm1(x); erf(x); erfc(x); isnan(x);
1411 j0(x); j1(x); jn(i,x); ilogb(x); logb(x); log1p(x); rint(x);
1412 y0(x); y1(x); yn(i,x);
1413 /* this part causes problems with crossmingw... */
1414 #ifdef _THREAD_SAFE
1415 gamma_r(x,&i);
1416 lgamma_r(x,&i);
1417 #else
1418 gamma(x);
1419 lgamma(x);
1420 #endif
1421 hypot(x,y); nextafter(x,y); remainder(x,y); scalb(x,y);
1422 return 0;
1423 }
1424 """
1425
1426 def CheckMath(context):
1427 context.Message('Checking for IEEE math library... ')
1428 libsave=context.env.get('LIBS');
1429 context.env.AppendUnique(LIBS=['m'])
1430 is_ok=context.TryLink(math_test_text,".c")
1431 context.Result(is_ok)
1432 if libsave is None:
1433 del(context.env['LIBS'])
1434 else:
1435 context.env['LIBS']=libsave
1436 return is_ok
1437
1438 #----------------
1439 # malloc.h test
1440
1441 malloc_test_text = """
1442 #include <stdlib.h>
1443 int main(){
1444 double *x;
1445 x = malloc(sizeof(double)*5);
1446 x[4] = 3.3;
1447 free(x);
1448 }
1449 """
1450
1451 def CheckMalloc(context):
1452 context.Message("Checking for malloc...")
1453 is_ok = context.TryLink(malloc_test_text,".c")
1454 context.Result(is_ok)
1455 return is_ok
1456
1457 #----------------
1458 # dlopen test
1459
1460 dlopen_test_text = """
1461 #ifdef __WIN32__
1462 # include <windows.h>
1463 #else
1464 # include <dlfcn.h>
1465 #endif
1466 int main(){
1467 #ifdef __WIN32__
1468 HINSTANCE d;
1469 LoadLibrary("imaginary_and_nonexistent.dll");
1470 #else
1471 void *d;
1472 d = dlopen("imaginary_and_nonexistent.so", 1);
1473 #endif
1474 return 0;
1475 }
1476 """
1477
1478 def CheckDLOpen(context):
1479 context.Message("Checking for ability to load shared libraries at runtime...")
1480 libsave=context.env.get('LIBS');
1481 if platform.system()!="Windows":
1482 context.env.Append(LIBS=['dl'])
1483 is_ok = context.TryLink(dlopen_test_text,".c")
1484 context.Result(is_ok)
1485 context.env['LIBS'] = libsave
1486 return is_ok
1487
1488 #----------------
1489 # libpython test
1490
1491 libpython_test_text = """
1492 #include <Python.h>
1493 PyObject *get10(void){
1494 PyObject *p = Py_BuildValue("i", 10);
1495 return p;
1496 }
1497 int main(void){
1498 return 0;
1499 }
1500 """
1501
1502 def CheckPythonLib(context):
1503 context.Message('Checking for libpython... ')
1504
1505 if platform.system()=="Windows":
1506 python_lib='python%d%d'
1507 else:
1508 python_lib='python%d.%d'
1509
1510 try:
1511 python_libs = [python_lib % (sys.version_info[0],sys.version_info[1])]
1512 python_cpppath = [distutils.sysconfig.get_python_inc()]
1513 cfig = distutils.sysconfig.get_config_vars()
1514 except:
1515 context.Result("not found")
1516 return 0
1517
1518 lastLIBS = context.env.get('LIBS')
1519 lastLIBPATH = context.env.get('LIBPATH')
1520 lastCPPPATH = context.env.get('CPPPATH')
1521 lastLINKFLAGS = context.env.get('LINKFLAGS')
1522
1523 python_libpath = []
1524 python_linkflags = []
1525 if platform.system()=="Windows":
1526 python_libpath += [os.path.join(sys.prefix,"libs")]
1527 elif platform.system()=="Darwin":
1528 python_libpath += [cfig['LIBPL']]
1529 python_linkflags += cfig['LIBS'].split(' ')
1530 else:
1531 # checked on Linux and SunOS
1532 if cfig['LDLIBRARY']==cfig['LIBRARY']:
1533 sys.stdout.write("(static)")
1534 python_libpath += [cfig['LIBPL']]
1535 python_linkflags += cfig['LIBS'].split(' ')
1536
1537 context.env.AppendUnique(LIBS=python_libs)
1538 context.env.AppendUnique(LIBPATH=python_libpath)
1539 context.env.AppendUnique(CPPPATH=python_cpppath)
1540 context.env.AppendUnique(LINKFLAGS=python_linkflags)
1541 result = context.TryLink(libpython_test_text,".c");
1542
1543 context.Result(result)
1544
1545 if(result):
1546 context.env['PYTHON_LIBPATH']=python_libpath
1547 context.env['PYTHON_LIB']=python_libs
1548 context.env['PYTHON_CPPPATH']=python_cpppath
1549 context.env['PYTHON_LINKFLAGS']=python_linkflags
1550
1551 context.env['LIBS'] = lastLIBS
1552 context.env['LIBPATH'] = lastLIBPATH
1553 context.env['CPPPATH'] = lastCPPPATH
1554 context.env['LINKFLAGS'] = lastLINKFLAGS
1555
1556 return result
1557
1558 #----------------
1559 # IDA test
1560
1561 sundials_version_major_required = 2
1562 sundials_version_minor_min = 4
1563 sundials_version_minor_max = 4
1564
1565 sundials_version_text = """
1566 #include <sundials/sundials_config.h>
1567 #include <stdio.h>
1568 int main(){
1569 printf("%s",SUNDIALS_PACKAGE_VERSION);
1570 return 0;
1571 }
1572 """
1573
1574 ida_test_text = """
1575 #if SUNDIALS_VERSION_MAJOR==2 && SUNDIALS_VERSION_MINOR==2
1576 # include <sundials/sundials_config.h>
1577 # include <sundials/sundials_nvector.h>
1578 # include <nvector_serial.h>
1579 # include <ida.h>
1580 # include <ida/ida_spgmr.h>
1581 #else
1582 # include <sundials/sundials_config.h>
1583 # include <nvector/nvector_serial.h>
1584 # include <ida/ida.h>
1585 #endif
1586 int main(){
1587 void *ida_mem;
1588 ida_mem = IDACreate();
1589 return 0;
1590 }
1591 """
1592
1593 # slightly changed calling convention (IDACalcID) in newer versions of SUNDIALS,
1594 # so detect the version and act accordingly.
1595 def CheckSUNDIALS(context):
1596 keep = KeepContext(context,'SUNDIALS')
1597 context.Message("Checking for SUNDIALS... ")
1598 (is_ok,output) = context.TryRun(sundials_version_text,'.c')
1599 keep.restore(context)
1600 if not is_ok:
1601 context.Result(0)
1602 return 0
1603
1604 major,minor,patch = tuple([int(i) for i in output.split(".")])
1605 context.env['SUNDIALS_VERSION_MAJOR'] = major
1606 context.env['SUNDIALS_VERSION_MINOR'] = minor
1607 if major != sundials_version_major_required \
1608 or minor < sundials_version_minor_min \
1609 or minor > sundials_version_minor_max:
1610 context.Result(output+" (bad version)")
1611 # bad version
1612 return 0
1613
1614 # good version
1615 context.Result("%d.%d.%d, good" % (major,minor,patch))
1616
1617 return 1
1618
1619
1620 def CheckIDA(context):
1621 context.Message( 'Checking for IDA... ' )
1622
1623 keep = KeepContext(context,"SUNDIALS")
1624
1625 major = context.env['SUNDIALS_VERSION_MAJOR']
1626 minor = context.env['SUNDIALS_VERSION_MINOR']
1627
1628 cppdef = context.env.get('CPPDEFINES')
1629
1630 context.env.Append(CPPDEFINES=[
1631 ('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR")
1632 ,('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")
1633 ])
1634
1635 context.env['SUNDIALS_CPPPATH_EXTRA']=[]
1636 if major==2 and minor==2:
1637 context.env.Append(SUNDIALS_CPPPATH_EXTRA = ["$SUNDIALS_CPPPATH/sundials"])
1638
1639 context.env.Append(CPPDEFINES=[('SUNDIALS_VERSION_MAJOR',"$SUNDIALS_VERSION_MAJOR"),('SUNDIALS_VERSION_MINOR',"$SUNDIALS_VERSION_MINOR")])
1640 context.env.AppendUnique(LIBS=context.env['SUNDIALS_LIBS'])
1641 context.env.AppendUnique(CPPPATH=context.env['SUNDIALS_CPPPATH_EXTRA'])
1642
1643 is_ok = context.TryLink(ida_test_text,".c")
1644 context.Result(is_ok)
1645
1646 if cppdef:
1647 context.env['CPPDEFINES']=cppdef
1648 else:
1649 del context.env['CPPDEFINES']
1650
1651 keep.restore(context)
1652
1653 return is_ok
1654
1655
1656 #----------------
1657 # CONOPT test
1658
1659 conopt_test_text = """
1660 #if !defined(_WIN32)
1661 # define FNAME_LCASE_DECOR
1662 #endif
1663
1664 #include <conopt.h>
1665 #include <stdlib.h>
1666 int main(){
1667 int s, *v, e;
1668 s = COIDEF_Size();
1669 v = (int *)malloc(s*sizeof(int));
1670 e = COIDEF_Ini(v);
1671 return e;
1672 }
1673 """
1674
1675 def CheckCONOPT(context):
1676 context.Message( 'Checking for CONOPT... ' )
1677
1678 keep = KeepContext(context,"CONOPT")
1679
1680 is_ok = context.TryLink(conopt_test_text,".c")
1681 context.Result(is_ok)
1682
1683 keep.restore(context)
1684
1685 return is_ok
1686
1687 #----------------
1688 # IPOPT test
1689
1690 ipopt_test_text = """
1691 #if !defined(_WIN32)
1692 # define FNAME_LCASE_DECOR
1693 #endif
1694
1695 #include <coin/IpStdCInterface.h>
1696 int main(){
1697 Number n;
1698 IpoptProblem nlp = 0;
1699 n = 1;
1700 FreeIpoptProblem(nlp); // probably a crash if you run this
1701 return 0;
1702 }
1703 """
1704
1705 def CheckIPOPT(context):
1706 context.Message( 'Checking for IPOPT... ' )
1707
1708 keep = KeepContext(context,"IPOPT")
1709 is_ok = context.TryLink(ipopt_test_text,".c")
1710 context.Result(is_ok)
1711
1712 keep.restore(context)
1713
1714 return is_ok
1715
1716 #----------------
1717 # Tcl test
1718
1719 # TCL and TK required version 8.1 through 8.5:
1720 tcltk_minor_newest_acceptable = 5
1721 tcltk_major_required = 8
1722
1723 tcl_check_text = r"""
1724 #include <tcl.h>
1725 #include <stdio.h>
1726 int main(void){
1727 printf("%s",TCL_PATCH_LEVEL);
1728 return 0;
1729 }
1730 """
1731
1732 def CheckTcl(context):
1733 return CheckExtLib(context,'tcl',tcl_check_text,static=env['STATIC_TCLTK'])
1734
1735 def CheckTclVersion(context):
1736 keep = KeepContext(context,'TCL',static=env['STATIC_TCLTK'])
1737 context.Message("Checking Tcl version... ")
1738 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
1739 keep.restore(context)
1740 if not is_ok:
1741 context.Result("failed to run check")
1742 return 0
1743
1744 major,minor,patch = tuple([int(i) for i in output.split(".")])
1745 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1746 context.Result(output+" (bad version)")
1747 # bad version
1748 return 0
1749
1750 # good version
1751 context.Result(output+", good")
1752 return 1
1753
1754 #----------------
1755 # Tk test
1756
1757 tk_check_text = r"""
1758 #include <tk.h>
1759 #include <stdio.h>
1760 int main(void){
1761 printf("%s",TK_PATCH_LEVEL);
1762 return 0;
1763 }
1764 """
1765 def CheckTk(context):
1766 return CheckExtLib(context,'tk',tk_check_text,static=env['STATIC_TCLTK'])
1767
1768
1769 def CheckTkVersion(context):
1770 keep = KeepContext(context,'TK',static=context.env['STATIC_TCLTK'])
1771 context.Message("Checking Tk version... ")
1772 #print "LINKFLAGS =",context.env['LINKFLAGS']
1773 (is_ok,output) = context.TryRun(tk_check_text,'.c')
1774 keep.restore(context)
1775 if not is_ok:
1776 context.Result("failed to run check")
1777 return 0
1778
1779 major,minor,patch = tuple([int(i) for i in output.split(".")])
1780 if major != tcltk_major_required or minor > tcltk_minor_newest_acceptable:
1781 # bad version
1782 context.Result(output+" (bad version)")
1783 return 0
1784
1785 # good version
1786 context.Result(output+" (good)")
1787 return 1
1788
1789 #----------------
1790 # Tktable test
1791
1792 tktable_check_text = r"""
1793 #include <tkTable.h>
1794 #include <stdio.h>
1795 int main(void){
1796 Table mytable;
1797 return 0;
1798 }
1799 """
1800
1801 def CheckTkTable(context):
1802 return CheckExtLib(context,'tktable',tktable_check_text,static=env['STATIC_TCLTK'])
1803
1804 #---------------
1805 # X11 test
1806
1807 x11_check_text = r"""
1808 #include <X11/Xlib.h>
1809 #include <X11/IntrinsicP.h>
1810 #include <X11/Intrinsic.h>
1811 #include <X11/ObjectP.h>
1812 #include <X11/Object.h>
1813 int main(void){
1814 Object mything;
1815 return 0;
1816 }
1817 """
1818
1819 def CheckX11(context):
1820 return CheckExtLib(context,'X11',x11_check_text)
1821
1822 #----------------
1823 # Check that we can raise and catch sigint
1824
1825 sigint_test_text = r"""
1826 #include <signal.h>
1827 #include <setjmp.h>
1828 #include <stdlib.h>
1829 static jmp_buf g_jmpenv;
1830 void sighandler(int sig){
1831 longjmp(g_jmpenv,sig);
1832 }
1833 void testsigint(){
1834 raise(SIGINT);
1835 }
1836 int main(void){
1837 signal(SIGINT,&sighandler);
1838 switch(setjmp(g_jmpenv)){
1839 case 0:
1840 testsigint();
1841 exit(1);
1842 case SIGINT:
1843 exit(0);
1844 default:
1845 exit(2);
1846 }
1847 }
1848 """
1849
1850 def CheckSIGINT(context):
1851 context.Message("Checking SIGINT is catchable... ")
1852 (is_ok,output)=context.TryRun(sigint_test_text,".c")
1853 context.Result(is_ok)
1854 return is_ok
1855
1856 #----------------
1857 # Check that we're able to catch floating point errors
1858
1859 sigfpe_test_text = r"""
1860 #include <signal.h>
1861 #include <setjmp.h>
1862 #include <stdlib.h>
1863 #include <fenv.h>
1864 static jmp_buf g_jmpenv;
1865 void fpehandler(int sig){
1866 longjmp(g_jmpenv,sig);
1867 }
1868 int main(void){
1869 fenv_t myfenv;
1870 fegetenv(&myfenv);
1871 fesetenv(&myfenv);
1872 feenableexcept(FE_ALL_EXCEPT);
1873 signal(SIGFPE,&fpehandler);
1874 double x;
1875 switch(setjmp(g_jmpenv)){
1876 case 0:
1877 x = 1.0 / 0.0;
1878 /* failed to catch */
1879 exit(1);
1880 case SIGFPE:
1881 exit(0);
1882 }
1883 }
1884 """
1885
1886 def CheckFPE(context):
1887 context.Message("Checking C99 FPE behaviour... ")
1888 (is_ok,output) = context.TryRun(sigfpe_test_text,'.c')
1889 context.Result(is_ok)
1890 return is_ok
1891
1892 #----------------
1893 # signal reset needed?
1894
1895 sigreset_test_text = r"""
1896 #include <signal.h>
1897 #include <setjmp.h>
1898 #include <stdlib.h>
1899 #include <stdio.h>
1900 typedef void SigHandlerFn(int);
1901 static jmp_buf g_jmpenv;
1902 void sighandler(int sig){
1903 longjmp(g_jmpenv,sig);
1904 }
1905 void testsigint(){
1906 /* fprintf(stderr,"Raising SIGINT\n"); */
1907 raise(SIGINT);
1908 }
1909 int main(void){
1910 SigHandlerFn *last,*saved;
1911 saved = signal(SIGINT,&sighandler);
1912 if(saved!=SIG_DFL){
1913 fprintf(stderr,"Default handler (%p) was not correctly set\n",SIG_DFL);
1914 exit(3);
1915 }
1916 switch(setjmp(g_jmpenv)){
1917 case 0:
1918 testsigint();
1919 fprintf(stderr,"Back from SIGINT\n");
1920 exit(1);
1921 case SIGINT:
1922 break;
1923 default:
1924 exit(2);
1925 };
1926 last = signal(SIGINT,SIG_DFL);
1927 if(last!=&sighandler){
1928 printf("1");
1929 exit(0);
1930 }
1931 printf("0");
1932 exit(0);
1933 }
1934 """
1935
1936 def CheckSigReset(context):
1937 context.Message("Checking signal handler reset... ")
1938 libsave=context.env.get('LIBS')
1939 context.env.AppendUnique(LIBS=['m'])
1940 (is_ok,output) = context.TryRun(sigreset_test_text,'.c')
1941
1942 if libsave is None:
1943 del(context.env['LIBS'])
1944 else:
1945 context.env['LIBS']=libsave
1946
1947 if not is_ok:
1948 context.Result("ERROR")
1949 return False
1950 if int(output)==1:
1951 context.Result("required");
1952 context.env['ASC_RESETNEEDED'] = True
1953 else:
1954 context.Result("not required");
1955 context.env['ASC_RESETNEEDED'] = False
1956 return True
1957
1958 #----------------
1959 # LyX on this system?
1960
1961 def CheckLyx(context):
1962 context.Message("Checking for LyX... ")
1963 r = context.env.WhereIs("lyx")
1964 if r:
1965 context.Result(r)
1966 else:
1967 context.Result(0)
1968 return r
1969
1970 #----------------
1971 # Latex2HTML on this system?
1972
1973 def CheckLatex2HTML(context):
1974 context.Message("Checking for latex2html...")
1975 if context.env.WhereIs("latex2html"):
1976 r = True
1977 else:
1978 r = False
1979 context.Result(r)
1980 return r
1981
1982 #----------------
1983 # GCC Version sniffing
1984
1985 # TODO FIXME
1986
1987 gcc_version4 = False
1988
1989 #------------------------------------------------------
1990 # CONFIGURATION
1991
1992 conf = Configure(env
1993 , custom_tests = {
1994 'CheckCC' : CheckCC
1995 , 'CheckCXX' : CheckCXX
1996 , 'CheckFortran' : CheckFortran
1997 , 'CheckMath' : CheckMath
1998 , 'CheckMalloc' : CheckMalloc
1999 , 'CheckDLOpen' : CheckDLOpen
2000 , 'CheckSwigVersion' : CheckSwigVersion
2001 , 'CheckPythonLib' : CheckPythonLib
2002 , 'CheckCUnit' : CheckCUnit
2003 , 'CheckDMalloc' : CheckDMalloc
2004 , 'CheckLyx' : CheckLyx
2005 , 'CheckLatex2HTML' : CheckLatex2HTML
2006 , 'CheckGraphViz' : CheckGraphViz
2007 , 'CheckGraphVizBoolean' : CheckGraphVizBoolean
2008 , 'CheckUFSparse' : CheckUFSparse
2009 , 'CheckTcl' : CheckTcl
2010 , 'CheckTclVersion' : CheckTclVersion
2011 , 'CheckTk' : CheckTk
2012 , 'CheckTkVersion' : CheckTkVersion
2013 , 'CheckGcc' : CheckGcc
2014 , 'CheckGccVisibility' : CheckGccVisibility
2015 , 'CheckYacc' : CheckYacc
2016 , 'CheckLex' : CheckLex
2017 , 'CheckLexDestroy' : CheckLexDestroy
2018 , 'CheckTkTable' : CheckTkTable
2019 , 'CheckX11' : CheckX11
2020 , 'CheckIDA' : CheckIDA
2021 , 'CheckSUNDIALS' : CheckSUNDIALS
2022 , 'CheckCONOPT' : CheckCONOPT
2023 , 'CheckIPOPT' : CheckIPOPT
2024 , 'CheckScrollkeeperConfig' : CheckScrollkeeperConfig
2025 , 'CheckFPE' : CheckFPE
2026 , 'CheckSIGINT' : CheckSIGINT
2027 , 'CheckSigReset' : CheckSigReset
2028 # , 'CheckIsNan' : CheckIsNan
2029 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
2030 }
2031 # , config_h = "config.h"
2032 )
2033
2034 def sconsversioncheck():
2035
2036 # uncomment the following line to skip the version check:
2037 # return 1
2038
2039 import SCons
2040 v = SCons.__version__.split(".")
2041 if v[0] != '0':
2042 if v[0] == '1' or v[0] == '2':
2043 return 1;
2044 return 0
2045 if int(v[1]) >= 97:
2046 return 1
2047 if v[1] != '96':
2048 return 0
2049 micro = int(v[2])
2050 if micro == 92 or micro == 93 or micro == 96:
2051 return 1;
2052 return 0
2053
2054 if not sconsversioncheck():
2055 print "Scons version is not OK. Please try version 0.96.92 or 0.96.93,"
2056 print "or consult the developers in the case of newer versions. Modify"
2057 print "the function 'sconsversioncheck' in the file SConstruct if you"
2058 print "want to *force* SCons to continue."
2059 Exit(1)
2060
2061 # check C compiler
2062
2063 if conf.CheckCC() is False:
2064 print "Failed to build simple test file with your C compiler."
2065 print "Check your compiler is installed and running correctly."
2066 Exit(1)
2067
2068 if conf.CheckCXX() is False:
2069 print "Failed to build simple test file with your C++ compiler."
2070 print "Check your compiler is installed and running correctly."
2071 print "You can set your C++ compiler using the CXX scons option."
2072 Exit(1)
2073
2074 # stdio -- just to check that compiler is behaving
2075
2076 if conf.CheckHeader('stdio.h') is False:
2077 print "CPPPATH =",env.get('CPPPATH')
2078 print "Did not find 'stdio.h'! Check your compiler configuration."
2079 print ""
2080 print "You environment is printed here:"
2081 for k,v in os.environ.iteritems():
2082 print "%-30s%s" % ("%s :" % k, v)
2083 Exit(1)
2084
2085 # sizes of vars used in libascend eg in gl_list etc.
2086
2087 _sizes = {
2088 "VOID_P" : "void *"
2089 ,"INT" : "int"
2090 ,"LONG" : "long"
2091 ,"LONG_LONG" : "long long"
2092 ,"UINT" : "unsigned int"
2093 ,"ULONG" : "unsigned long"
2094 ,"ULONGLONG" : "unsigned long long"
2095 }
2096
2097 for _var,_type in _sizes.iteritems():
2098 _size = conf.CheckTypeSize(_type)
2099 if not _size:
2100 print "Couldn't determine 'sizeof(%s)'" % _type
2101 Exit(1)
2102 conf.env["SIZEOF_%s" % _var] = str(_size)
2103
2104 # check for some string functions
2105
2106 if conf.CheckFunc('sprintf') is False:
2107 print "Didn't find sprintf";
2108 Exit(1)
2109
2110 if conf.CheckFunc('strdup'):
2111 conf.env['HAVE_STRDUP'] = True
2112
2113 if conf.CheckFunc('snprintf'):
2114 conf.env['HAVE_SNPRINTF'] = True
2115 elif conf.CheckFunc('_snprintf'):
2116 conf.env['HAVE__SNPRINTF'] = True
2117
2118 # attempt to support MSVCRT 7.1 on Windows
2119
2120 if platform.system()=="Windows" and env.get('WITH_MSVCR71'):
2121 conf.env.Append(LIBS='msvcr71')
2122
2123 # Math library
2124
2125 conf.env['HAVE_IEEE']=True
2126
2127 if need_libm and (conf.CheckMath() is False):
2128 conf.env['HAVE_IEEE']=False
2129 print 'Did not find math library, exiting!'
2130 Exit(1)
2131
2132 # Malloc
2133
2134 if conf.CheckMalloc() is False:
2135 conf.env['HAVE_MALLOC']=False
2136 print "Did not find functioning 'malloc', exiting!"
2137 Exit(1)
2138
2139 # dlopen/LoadLibrary
2140
2141 # CURRENTLY BREAKS LATER TEST (libsave?)
2142 #if conf.CheckDLOpen() is False:
2143 # print "Did not find functioning dlopen/LoadLibrary, exiting!"
2144 # Exit(1)
2145
2146 # Where is 'isnan'?
2147
2148 if conf.CheckFunc('isnan') is False and conf.CheckFunc('_isnan') is False:
2149 print "Didn't find isnan"
2150 # Exit(1)
2151
2152 # GCC visibility
2153
2154 if conf.CheckGcc():
2155 conf.env['HAVE_GCC']=True;
2156 if env.get('WITH_GCCVISIBILITY') and conf.CheckGccVisibility():
2157 conf.env['HAVE_GCCVISIBILITY']=True;
2158 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
2159 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
2160 conf.env.Append(CCFLAGS=['-Wall'])
2161
2162 # Catching SIGINT
2163
2164 if env['WITH_SIGNALS']:
2165 if not conf.CheckSIGINT():
2166 with_signals = False
2167 without_signals_reason = "SIGINT uncatchable"
2168
2169 # Catching SIGFPE
2170
2171 if conf.CheckFPE():
2172 conf.env['HAVE_C99FPE']=True
2173 else:
2174 conf.env['HAVE_C99FPE']=False
2175
2176 # Checking for signal reset requirement
2177
2178 if conf.CheckSigReset() is False:
2179 print "Unable to determine if signal reset is required"
2180 Exit(1)
2181
2182 # YACC
2183
2184 if conf.CheckYacc():
2185 conf.env['HAVE_YACC']=True
2186
2187 if conf.CheckLex():
2188 conf.env['HAVE_LEX']=True
2189
2190 if conf.CheckLexDestroy():
2191 conf.env['HAVE_LEXDESTROY']=True
2192
2193 # Tcl/Tk
2194
2195 if with_tcltk:
2196 if conf.CheckTcl():
2197 if conf.CheckTclVersion():
2198 if conf.CheckTk():
2199 if with_tcltk and conf.CheckTkVersion():
2200 if env['STATIC_TCLTK']:
2201 if conf.CheckTkTable():
2202 pass
2203 else:
2204 without_tcltk_reason = "TkTable not found"
2205 with_tcltk = False
2206 else:
2207 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
2208 with_tcltk = False
2209 else:
2210 without_tcltk_reason = "Tk not found."
2211 with_tcltk = False
2212 else:
2213 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
2214 with_tcltk = False
2215
2216 else:
2217 without_tcltk_reason = "Tcl not found."
2218 with_tcltk = False
2219
2220 if env['STATIC_TCLTK']:
2221 conf.CheckX11()
2222
2223 # Python... obviously we're already running python, so we just need to
2224 # check that we can link to the python library OK:
2225
2226 if not conf.CheckPythonLib():
2227 without_python_reason = 'libpython2.x not found or not linkable'
2228 with_python = False
2229 env['WITH_PYTHON']=False
2230
2231 # SWIG version
2232
2233 if with_python and conf.CheckSwigVersion() is False:
2234 without_python_reason = 'SWIG >= 1.3.24 is required'
2235 with_python = False
2236 env['WITH_PYTHON']=False
2237
2238 # CUnit
2239
2240 if with_cunit:
2241 if not conf.CheckCUnit():
2242 without_cunit_reason = 'CUnit not found'
2243 with_cunit = False
2244 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
2245
2246 # DMALLOC
2247
2248 if with_dmalloc:
2249 if not conf.CheckDMalloc():
2250 without_dmalloc_reason = 'dmalloc not found'
2251 with_dmalloc = False
2252
2253 # GRAPHVIZ
2254
2255 if with_graphviz:
2256 if not conf.CheckGraphViz():
2257 without_graphviz_reason = 'graphviz not found'
2258 with_graphviz = False
2259 env['WITH_GRAPHVIZ'] = False
2260 env['HAVE_GRAPHVIZ_BOOLEAN'] = conf.CheckGraphVizBoolean()
2261
2262 # UFSPARSE
2263
2264 if with_ufsparse:
2265 if not conf.CheckUFSparse():
2266 without_ufsparse_reason = 'ufsparse not found'
2267 with_ufsparse = False
2268 env['WITH_UFSPARSE'] = False
2269
2270 # IDA
2271
2272 if with_ida:
2273 if not conf.CheckSUNDIALS():
2274 with_ida = False
2275 without_ida_reason = "SUNDIALS not found, or bad version"
2276 elif not conf.CheckIDA():
2277 with_ida = False
2278 without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
2279
2280 # CONOPT
2281
2282 if not with_conopt:
2283 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
2284 elif conf.CheckCONOPT() is False:
2285 if conf.env.get('CONOPT_LINKED'):
2286 conf.env['CONOPT_LINKED'] = False
2287 # we no longer require CONOPT at buildtime in order to build support for it
2288 #with_conopt = False
2289 #without_conpt_reason = "CONOPT not found"
2290
2291 # IPOPT
2292
2293 if not with_ipopt:
2294 without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
2295 elif not conf.CheckIPOPT():
2296 with_ipopt = False
2297 without_ipopt_reason = "IPOPT not found"
2298
2299 # BLAS
2300
2301 need_blas=False
2302
2303 if with_lsode:
2304 need_fortran = True
2305 need_fortran_reasons.append("LSODE")
2306 need_blas=True
2307
2308 if with_ipopt:
2309 need_blas=True
2310
2311 if need_blas:
2312 if conf.CheckLib('blas'):
2313 with_local_blas = False
2314 without_local_blas_reason = "Found BLAS installed on system"
2315 else:
2316 with_local_blas = True
2317 need_fortran = True
2318 need_fortran_reasons.append("BLAS")
2319 else:
2320 with_local_blas= False;
2321 without_local_blas_reason = "BLAS not required"
2322
2323 # FORTRAN
2324
2325 # we'll assume now (2012) that we always have gfortran available on our system.
2326
2327 if need_fortran and conf.CheckFortran() is False:
2328 print "Failed to build simple test file with your Fortran compiler."
2329 print "Check your compiler is installed and running correctly."
2330 print "You can set your Fortran compiler using the FORTRAN scons option."
2331 print "The fortran compiler is REQUIRED to build:",", ".join(need_fortran_reasons)
2332 print "Perhaps try examining the value of your WITH_SOLVERS option (remove LSODE, etc)."
2333 Exit(1)
2334
2335 #else:
2336 # print "FORTRAN not required"
2337
2338 # F2C
2339
2340 if need_fortran:
2341 if platform.system()=="Windows":
2342 pass
2343 #conf.env.Append(LIBPATH='c:\mingw\lib')
2344
2345 # scrollkeeper
2346
2347 if with_scrollkeeper:
2348 if conf.CheckScrollkeeperConfig() is False:
2349 with_scrollkeeper=False
2350 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
2351
2352 # lyx
2353
2354 if with_doc_build:
2355 if not conf.CheckLyx():
2356 with_doc_build = False
2357 without_doc_build_reason="unable to locate LyX"
2358
2359 # TODO: -D_HPUX_SOURCE is needed
2360
2361 # TODO: detect if dynamic libraries are possible or not
2362
2363 if platform.system()=="Windows" and env.has_key('MSVS'):
2364 _found_windows_h = conf.CheckHeader('Windows.h')
2365
2366 if not _found_windows_h:
2367 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
2368 Exit(1)
2369
2370 if with_python and conf.CheckHeader(['basetsd.h','BaseTsd.h']) is False:
2371 with_python = 0;
2372 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
2373
2374 conf.Finish()
2375
2376 #print "-=-=-=-=-=-=-=-=- LIBS =",env.get('LIBS')
2377
2378 #---------------------------------------
2379 # SUBSTITUTION DICTIONARY for .in files
2380
2381 release = env.get('RELEASE')
2382 if release=="0.":
2383 release="0"
2384
2385 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
2386
2387 subst_dict = {
2388 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
2389 ,'@DEFAULT_ASCENDSOLVERS@':env['DEFAULT_ASCENDSOLVERS']
2390 , '@GLADE_FILE@':'ascend.glade'
2391 , '@HELP_ROOT@':''
2392 , '@ICON_EXTENSION@':icon_extension
2393 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
2394 , '@INSTALL_BIN@':env['INSTALL_BIN']
2395 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
2396 , '@INSTALL_LIB@':env['INSTALL_LIB']
2397 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
2398 , '@INSTALL_SOLVERS@':env['INSTALL_SOLVERS']
2399 , '@INSTALL_PYTHON@':env['INSTALL_PYTHON']
2400 , '@INSTALL_PYTHON_ASCEND@':env['INSTALL_PYTHON_ASCEND']
2401 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
2402 , '@VERSION@':version
2403 , '@RELEASE@':release
2404 , '@SONAME_MAJOR_INT@':soname_major_int
2405 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
2406 , '@WEBHELPROOT@':'http://ascendwiki.cheme.cmu.edu/Category:Documentation'
2407 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
2408 , '@SHLIBPREFIX@':env['SHLIBPREFIX']
2409 , '@EXTLIB_SUFFIX@':env['EXTLIB_SUFFIX']
2410 , '@EXTLIB_PREFIX@':env['EXTLIB_PREFIX']
2411 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
2412 , '@PYTHON@' : python_exe
2413 , '@PYVERSION@' : pyversion
2414 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
2415 , '@WITH_GRAPHVIZ@': str(int(env.get('WITH_GRAPHVIZ')))
2416 #define ASC_ABSOLUTE_PATHS @ASC_ABSOLUTE_PATHS@
2417 #if ASC_ABSOLUTE_PATHS
2418 # define ASCENDDIST_DEFAULT "@ASCENDDIST_DEFAULT@"
2419 # define ASCENDTK_DEFAULT "@ASCENDTK_DEFAULT@"
2420 # define ASCENDLIBRARY_DEFAULT "@ASCENDLIBRARY_DEFAULT@"
2421 # define ASCENDSOLVERS_DEFAULT "@ASCENDSOLVERS_DEFAULT@"
2422 #else
2423 # define ASC_DIST_REL_BIN "@ASC_DIST_REL_BIN@"
2424 # define ASC_TK_REL_DIST "@ASC_TK_REL_DIST@"
2425 # define ASC_LIBRARY_REL_DIST "@ASC_LIBRARY_REL_DIST@"
2426 # define ASC_SOLVERS_REL_DIST "@ASC_SOLVERS_REL_DIST@"
2427 #endif
2428 , '@ASC_ABSOLUTE_PATHS@': str(int(env.get('ABSOLUTE_PATHS')))
2429 , '@ASCENDDIST_DEFAULT@': c_escape(env['INSTALL_PREFIX'])
2430 , '@ASCENDTK_DEFAULT@': c_escape(os.path.abspath(env.subst(env['INSTALL_TK'])))
2431 , '@ASCENDLIBRARY_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDLIBRARY'])))
2432 , '@ASCENDSOLVERS_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDSOLVERS'])))
2433 , '@ASC_DIST_REL_BIN@' : default_dist_rel_bin
2434 , '@ASC_TK_REL_DIST@' : default_tk_rel_dist
2435 , '@ASC_LIBRARY_REL_DIST@' : default_library_rel_dist
2436 , '@ASC_SOLVERS_REL_DIST@' : default_solvers_rel_dist
2437 , '@SIZEOF_VOID_P@' : env['SIZEOF_VOID_P']
2438 , '@SIZEOF_INT@' : env['SIZEOF_INT']
2439 , '@SIZEOF_LONG@' : env['SIZEOF_LONG']
2440 , '@SIZEOF_LONG_LONG@' : env['SIZEOF_LONG_LONG']
2441 , '@SIZEOF_UINT@' : env['SIZEOF_UINT']
2442 , '@SIZEOF_ULONG@' : env['SIZEOF_ULONG']
2443 , '@SIZEOF_ULONGLONG@' : env['SIZEOF_ULONGLONG']
2444 }
2445
2446 if env.get('WITH_DOC'):
2447 #print "WITH_DOC:",env['WITH_DOC']
2448 subst_dict['@HELP_ROOT@']=env['HELP_ROOT']
2449
2450 # bool options...
2451 for k,v in {
2452 'ASC_WITH_DMALLOC':with_dmalloc
2453 ,'ASC_WITH_UFSPARSE':with_ufsparse
2454 ,'ASC_WITH_MMIO':with_mmio
2455 ,'ASC_SIGNAL_TRAPS':with_signals
2456 ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
2457 ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
2458 ,'HAVE_IEEE':env.get('HAVE_IEEE')
2459 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
2460 ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
2461 ,'ASC_HAVE_LEXDESTROY':env.get('HAVE_LEXDESTROY')
2462 ,'HAVE_SNPRINTF':env.get('HAVE_SNPRINTF')
2463 ,'HAVE__SNPRINTF':env.get('HAVE__SNPRINTF')
2464 }.iteritems():
2465
2466 if v: subst_dict["/\\* #\\s*define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
2467
2468 if with_python:
2469 subst_dict['@ASCXX_USE_PYTHON@']="1"
2470 env['WITH_PYTHON']=1;
2471
2472 if with_latex2html:
2473 env['WITH_LATEX2HTML']=1
2474
2475 if env.has_key('HAVE_GCCVISIBILITY'):
2476 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
2477
2478 env.Append(SUBST_DICT=subst_dict)
2479
2480 #for k,v in subst_dict.iteritems():
2481 # print "%-50s%s" % ("'%s'"%k,v)
2482
2483 # REMOVED: long command-line support on Win2k
2484
2485 #------------------------------------------------------
2486 # RECIPE: SWIG scanner
2487
2488 import SCons.Script
2489
2490 SWIGScanner = SCons.Scanner.ClassicCPP(
2491 "SWIGScan"
2492 , ".i"
2493 , "CPPPATH"
2494 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
2495 )
2496
2497 env.Append(SCANNERS=[SWIGScanner])
2498
2499 #------------------------------------------------------
2500 # Recipe for 'CHMOD' ACTION
2501
2502 import SCons
2503 from SCons.Script.SConscript import SConsEnvironment
2504 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2505 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2506
2507 def InstallPerm(env, dest, files, perm):
2508 obj = env.Install(dest, files)
2509 for i in obj:
2510 env.AddPostAction(i, env.Chmod(str(i), perm))
2511
2512 def InstallPermAs(env, dest, filen, perm):
2513 obj = env.InstallAs(dest, filen)
2514 for i in obj:
2515 env.AddPostAction(i, env.Chmod(str(i), perm))
2516 return dest
2517
2518 SConsEnvironment.InstallPerm = InstallPerm
2519
2520 # define wrappers
2521 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2522 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2523 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2524 SConsEnvironment.InstallSharedAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2525 SConsEnvironment.InstallLibraryAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2526
2527 #------------------------------------------------------
2528 # BUILD...
2529
2530 # so that #include <ascend/modulename/headername.h> works across all modules...
2531 env.AppendUnique(CPPPATH=['#'])
2532
2533 if env['DEBUG']:
2534 env.Append(
2535 CCFLAGS=['-g']
2536 ,LINKFLAGS=['-g']
2537 )
2538
2539 if env['GCOV']:
2540 env.Append(
2541 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2542 , LIBS=['gcov']
2543 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2544 )
2545
2546 #FIXME there must be a better way of doing this...
2547
2548 if with_ida:
2549 env.Append(WITH_IDA=1)
2550
2551 if with_conopt:
2552 env.Append(WITH_CONOPT=1)
2553
2554 if with_ipopt:
2555 env.Append(WITH_IPOPT=1)
2556
2557 if with_dopri5:
2558 env.Append(WITH_DOPRI5=1)
2559
2560 if with_radau5:
2561 env.Append(WITH_RADAU5=1)
2562
2563 if with_makemps:
2564 env.Append(WITH_MAKEMPS=1)
2565
2566 if with_graphviz and env.get('GRAPHVIZ_RPATH'):
2567 env.Append(RPATH=env['GRAPHVIZ_RPATH'])
2568
2569 #-------------
2570 # TCL/TK GUI
2571
2572 if with_tcltk:
2573 env.SConscript(['tcltk/SConscript'],'env')
2574 else:
2575 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2576
2577 #-------------
2578 # PYTHON INTERFACE
2579
2580 if with_python:
2581 env.SConscript(['ascxx/SConscript'],'env')
2582 env.SConscript(['pygtk/SConscript'],'env')
2583 else:
2584 print "Skipping... Python bindings aren't being built:",without_python_reason
2585
2586 #------------
2587 # BASE/GENERIC SUBDIRECTORIES
2588
2589 libascend_env = env.Clone()
2590
2591 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
2592
2593 srcs = []
2594 for d in dirs:
2595 heresrcs = libascend_env.SConscript('ascend/'+d+'/SConscript','libascend_env')
2596 srcs += heresrcs
2597
2598 #-------------
2599 # IMPORTED CODE: LSODE, BLAS, etc
2600
2601 if with_local_blas:
2602 env['blasobjs'] = env.SConscript(['blas/SConscript'],'env')
2603 else:
2604 env['blasobjs'] = []
2605 print "Skipping... BLAS won't be built:", without_local_blas_reason
2606
2607 if not with_ida:
2608 print "Skipping... IDA won't be built:", without_ida_reason
2609
2610 if not with_dopri5:
2611 print "Skipping... DOPRI5 won't be built:", without_dopri5_reason
2612
2613 if with_mmio:
2614 srcs += env.SConscript(['mmio/SConscript'],'env')
2615 else:
2616 print "Skipping... MMIO export won't be built:", without_mmio_reason
2617 #-------------
2618 # LIBASCEND -- all 'core' functionality
2619
2620 # FIXME want to move these bits to ascend/SConscript
2621
2622 libascend_env.Append(
2623 CPPPATH=['#']
2624 ,LIBS=['m']
2625 )
2626
2627 if platform.system()=="Linux":
2628 libascend_env.Append(LIBS=['dl'])
2629
2630 if with_dmalloc:
2631 libascend_env.Append(LIBS=['dmalloc'])
2632
2633 if with_ufsparse:
2634 libascend_env.Append(LIBS=['cxsparse'])
2635
2636 if platform.system()=="Linux":
2637 libascend_env.Append(LINKFLAGS=['-Wl,-soname,%s' % soname_full])
2638
2639 libascend = libascend_env.SharedLibrary('ascend',srcs)
2640
2641 # create local symlink for the soname stuff.
2642 #print "SONAME =",env.subst(soname_full)
2643
2644 env['libascend'] = libascend
2645 libtargets = [libascend]
2646
2647 if platform.system()=="Linux":
2648 if soname_major:
2649 libascend_env.Command(soname_full,libascend,Move("$TARGET","$SOURCE"))
2650 #print "MAKING LINK, SONAME_MAJOR =",soname_major
2651 liblink = libascend_env.Command(soname_full, libascend, "ln -s $SOURCE $TARGET")
2652 libtargets.append(liblink)
2653
2654 # for use in declaring dependent shared libraries in SConscript files (eg solvers/*/SConscript)
2655
2656 env.Alias('libascend',libtargets)
2657
2658 #-------------
2659 # UNIT TESTS (C CODE)
2660
2661 test_env = env.Clone()
2662 test_env.Append(
2663 CPPPATH="#"
2664 )
2665
2666 if with_cunit:
2667 testdirs = ['general','solver','utilities','linear','compiler','system','packages','integrator']
2668 testsrcs = []
2669 for testdir in testdirs:
2670 path = 'ascend/'+testdir+'/test/'
2671 test_env.SConscript([path+'SConscript'],'test_env')
2672 testsrcs += [i.path for i in test_env['TESTSRCS_'+testdir.upper()]]
2673 test_env['TESTDIRS'] = testdirs
2674
2675 #print "TESTSRCS =",testsrcs
2676
2677 test_env.SConscript(['test/SConscript'],'test_env')
2678
2679 env.Alias('test',[env.Dir('test')])
2680
2681 else:
2682 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2683
2684 #-------------
2685 # EXTERNAL SOLVERS
2686
2687 env['extfns']=[]
2688 env['BUILDING_ASCEND'] = 1
2689
2690 env.SConscript(['solvers/SConscript'],'env')
2691
2692 #-------------
2693 # EXTERNAL FUNCTIONS
2694
2695 modeldirs = env.SConscript(['models/SConscript'],'env')
2696
2697 if not with_extfns:
2698 print "Skipping... External modules aren't being built:",without_extfns_reason
2699
2700 for _f in env['extfns']:
2701 env.Depends(_f,'libascend')
2702 env.Alias('extfns',env['extfns'])
2703
2704 #-------------
2705 # FPROPS python bindings
2706
2707 env.Alias('pyfprops',env.get('pyfprops'))
2708
2709 #------------------------------------------------------
2710 # CREATE ASCEND-CONFIG scriptlet
2711
2712 ascendconfig = env.SubstInFile('ascend-config.in')
2713
2714 #------------------------------------------------------
2715 # INSTALLATION
2716
2717 if env.get('CAN_INSTALL'):
2718
2719 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE','INSTALL_DOC','INSTALL_PYTHON']
2720 install_dirs = [Dir(env.subst("$INSTALL_ROOT$"+d)) for d in dirs]
2721 install_dirs += modeldirs + [Dir(env.subst("$INSTALL_ROOT$INSTALL_SOLVERS"))]
2722
2723 #env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_LIB")),libascend)
2724
2725 libname = "${INSTALL_LIB}/%s%s" % (soname_full,soname_minor)
2726 install_lib = env.InstallLibraryAs("${INSTALL_ROOT}"+libname, [libascend])
2727 if env['ABSOLUTE_PATHS']:
2728 link_target = libname
2729 else:
2730 link_target = "%s%s" % (soname_full,soname_minor)
2731
2732 link1 = "${INSTALL_LIB}/%s" % soname_clean
2733 install_link1 = None
2734 if env.subst(link1) != env.subst(libname):
2735 # v--link to create v--file to link to command
2736 install_link1 = env.Command("${INSTALL_ROOT}"+link1,install_lib
2737 # v-- command to do it (note the trick about
2738 ,"ln -f -s %s $TARGET" % link_target
2739 )
2740
2741 link2 = "${INSTALL_LIB}/%s" % soname_full
2742 install_link2 = None
2743 if soname_minor:
2744 install_link2 = env.Command("${INSTALL_ROOT}"+link2,install_lib
2745 ,"ln -f -s %s $TARGET" % link_target
2746 )
2747
2748 env.InstallProgram(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),ascendconfig)
2749
2750 # MAC OS X INSTALL STUFF
2751 # in this case, we're installing to INSTALL_PREFIX, assumed to be a folder
2752 # created using Disk Utility as a new DMG which will be distributed.
2753 if platform.system()=="Darwin":
2754 # extra stuff for inside the .app
2755 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),"mac/Info.plist")
2756 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN/Resources/")),"mac/ascend.icns")
2757
2758 # related files the .dmg folder
2759 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"README-osx.txt")
2760 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"LICENSE.txt")
2761 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"CHANGELOG.txt")
2762 env.Command("$INSTALL_ROOT$INSTALL_PREFIX/Applications Folder","/Applications","ln -f -s $SOURCE $TARGET")
2763 install_dirs += [Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX"))]
2764
2765 # GTK libraries and related files
2766 gtkfiles = []
2767 gtksource = "dist/PyGTK.bundle/"
2768 def visit(gtkfiles,dirname,fnames):
2769 gtkfiles += Glob("%s/*" % dirname)
2770 os.path.walk(gtksource,visit,gtkfiles)
2771
2772 #print "GTKFILES ="
2773 #
2774 for f in gtkfiles:
2775 r = os.path.commonprefix([gtksource,f.path])
2776 dirname,filename = os.path.split(f.path[len(r):])
2777 dest = os.path.join(env.subst("$INSTALL_ROOT$INSTALL_BIN/PyGTK.bundle"),dirname)
2778 # print "%s --> %s" %(f,dest)
2779 env.Install(Dir(dest),f)
2780
2781 # ALIAS FOR ALL INSTALLATION
2782 env.Alias('install',install_dirs)
2783
2784 #------------------------------------------------------
2785 # WINDOWS INSTALLER
2786
2787 if not env.get('NSIS'):
2788 with_installer = False
2789 without_installer_reason = "NSIS not found"
2790
2791 if with_installer:
2792 pyarch = ""
2793 instarch = "win32"
2794 if platform.architecture()[0] == "64bit":
2795 instarch = "x64"
2796 pyarch = ".amd64"
2797 inst64 = 1
2798 nsisdefs = {
2799 'OUTFILE':"#dist/$WIN_INSTALLER_NAME"
2800 ,"VERSION":version
2801 ,'PYVERSION':pyversion
2802 ,'PYPATCH':".%d"%sys.version_info[2]
2803 ,'PYARCH':str(pyarch)
2804 ,'INSTARCH':str(instarch)
2805 }
2806 # support up to 5 extra dependency DLLs to accompany IPOPT
2807 for i in range(5):
2808 _fl = ''; _dl = ''
2809 if env.get('IPOPT_DLL%d'%(i+1)):
2810 _fl = "File %s"%os.path.normcase(os.path.normpath(env.subst("$IPOPT_DLL%d"%(i+1))))
2811 _dl = "Delete \"$$INSTDIR\\%s\""%os.path.split(env.subst("$IPOPT_DLL%d"%(i+1)))[1]
2812 nsisdefs['FILE_IPOPT_%d'%(i+1)] = _fl
2813 nsisdefs['DEL_IPOPT_%d'%(i+1)] = _dl
2814 env.Append(NSISDEFINES=nsisdefs)
2815 installer = env.Installer('nsis/installer.nsi')
2816
2817 for i in range(5):
2818 if env.get('IPOPT_DLL%d'%(i+1)):
2819 env.Depends(installer,env['IPOPT_DLL%d'%(i+1)])
2820
2821 env.Depends(installer,["pygtk","ascxx","tcltk","ascend.dll","models","solvers","ascend-config",'pygtk/ascend'])
2822 env.Depends(installer,"doc/book.pdf")
2823 env.Depends(installer,["nsis/detect.nsi","nsis/dependencies.nsi","nsis/download.nsi"])
2824 env.Alias('installer',installer)
2825 else:
2826 print "Skipping... Windows installer isn't being built:",without_installer_reason
2827
2828 #------------------------------------------------------
2829 # CREATE the SPEC file for generation of RPM packages
2830
2831 if platform.system()=="Linux":
2832 env.SubstInFile('ascend.spec.in')
2833
2834 #------------------------------------------------------
2835 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
2836
2837 #if with_scrollkeeper:
2838 # #env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
2839 # #env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
2840
2841 #------------------------------------------------------
2842 # DISTRIBUTION TAR FILE
2843
2844 env['DISTTAR_FORMAT']='bz2'
2845 env.Append(
2846 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.lib','.cc','.cache',
2847 '.pyc','.cvsignore','.dblite','.log','.pl','.out','.exe','.aux','.idx',
2848 '.toc','.lof','.lot','.mm','.warnings','.tm2','.swp',',tmp','.gz',
2849 '.bz2','.7z','.deb','.dsc','.changes','.bak','.tex','.tmp','.def']
2850 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist','debian','doxy']
2851 , DISTTAR_EXCLUDERES=[r"_wrap\.cc?$", r"~$", r"ascxx/ascpy\.py","ascxx/testipopt$"
2852 ,r"/lib.*\.so\.[.0-9]+$", r"tcltk/asc4dev$", r"tcltk/interface/typelex\.c$"
2853 ,r"ascend/compiler/ascParse\.[ch]$", r"ascend/solver/conoptconfig\.h$"
2854 ,r"ascend/utilities/config\.h$", r"pygtk/config\.h$", r"pygtk/config\.py$"
2855 ,r"pygtk/ascdev$", r"ascxx/testconopt$", r"ascend/compiler/scanner\.c$"
2856 ,r"datareader/.*TY\.csv$"
2857 ,r"ascxx/ascpy_wrap\.h",r"ascxx/config\.h$"
2858 ,r"tcltk/interface/ascend4$",r"ascxx/testslvreq$",r"test/test$"
2859 ,r"models/johnpye/datareader/.*\.tm2\.Z$"
2860 ,r"models/johnpye/fprops/[a-z][a-z0-9]+(.*\.exe)?$" # FPROPS test executables
2861 ,r"fprops/fluids/fluids_list\.h$" # FPROPS fluids list
2862 ]
2863 )
2864
2865 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
2866 , [env.Dir('#')]
2867 )
2868
2869 env.Depends(tar,'ascend.spec')
2870 env.Depends(tar,'doc/book.pdf')
2871
2872 #------------------------------------------------------
2873 # DEBIAN TARBALL for use with Build Service
2874
2875 import glob
2876 deb_files = glob.glob('debian/*.install')
2877 deb_files += glob.glob('debian/*.docs')
2878 deb_files += glob.glob('debian/*.dirs')
2879 deb_files += glob.glob('debian/*.man')
2880 deb_files += glob.glob('debian/*.manpages')
2881 deb_files += ['debian/%s' % s for s in ['rules','control','changelog','compat','copyright','dirs']]
2882
2883 deb_tar = env.Tar(
2884 'dist/debian.tar.gz'
2885 ,deb_files
2886 ,TARFLAGS = ['cz']
2887 )
2888
2889 Alias('dist',[tar,deb_tar])
2890
2891 #------------------------------------------------------
2892 # DOCUMENTATION
2893
2894 #print "WITH_DOC_BUILD = ",with_doc_build
2895
2896 if with_doc_build:
2897 #user's manual
2898 env.SConscript('doc/SConscript',['env'])
2899 else:
2900 print "Skipping... Documentation isn't being built:",without_doc_build_reason
2901
2902 #------------------------------------------------------
2903 # RPM BUILD
2904
2905 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
2906 # (check * for the version number used to create the tarball)
2907
2908 #------------------------------------------------------
2909 # DEFAULT TARGETS
2910
2911 default_targets =['libascend','solvers']
2912 if with_tcltk:
2913 default_targets.append('tcltk')
2914 if with_python:
2915 default_targets.append('ascxx')
2916 default_targets.append('pygtk')
2917 default_targets.append('pyfprops')
2918 if with_extfns:
2919 default_targets.append('extfns')
2920 if with_doc_build:
2921 default_targets.append('doc')
2922
2923 env.Default(default_targets)
2924
2925 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
2926
2927 # vim: set syntax=python:

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