/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2719 - (show annotations) (download)
Thu Dec 5 05:42:21 2013 UTC (6 years, 7 months ago) by jpye
File size: 75666 byte(s)
Add test for cpow (MinGW32 problem), add file with list of expected passing test cases.
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 if conf.CheckFunc('cpow'):
2119 conf.env['HAVE_CPOW'] = True
2120
2121 # attempt to support MSVCRT 7.1 on Windows
2122
2123 if platform.system()=="Windows" and env.get('WITH_MSVCR71'):
2124 conf.env.Append(LIBS='msvcr71')
2125
2126 # Math library
2127
2128 conf.env['HAVE_IEEE']=True
2129
2130 if need_libm and (conf.CheckMath() is False):
2131 conf.env['HAVE_IEEE']=False
2132 print 'Did not find math library, exiting!'
2133 Exit(1)
2134
2135 # Malloc
2136
2137 if conf.CheckMalloc() is False:
2138 conf.env['HAVE_MALLOC']=False
2139 print "Did not find functioning 'malloc', exiting!"
2140 Exit(1)
2141
2142 # dlopen/LoadLibrary
2143
2144 # CURRENTLY BREAKS LATER TEST (libsave?)
2145 #if conf.CheckDLOpen() is False:
2146 # print "Did not find functioning dlopen/LoadLibrary, exiting!"
2147 # Exit(1)
2148
2149 # Where is 'isnan'?
2150
2151 if conf.CheckFunc('isnan') is False and conf.CheckFunc('_isnan') is False:
2152 print "Didn't find isnan"
2153 # Exit(1)
2154
2155 # GCC visibility
2156
2157 if conf.CheckGcc():
2158 conf.env['HAVE_GCC']=True;
2159 if env.get('WITH_GCCVISIBILITY') and conf.CheckGccVisibility():
2160 conf.env['HAVE_GCCVISIBILITY']=True;
2161 conf.env.Append(CCFLAGS=['-fvisibility=hidden'])
2162 conf.env.Append(CPPDEFINES=['HAVE_GCCVISIBILITY'])
2163 conf.env.Append(CCFLAGS=['-Wall'])
2164
2165 # Catching SIGINT
2166
2167 if env['WITH_SIGNALS']:
2168 if not conf.CheckSIGINT():
2169 with_signals = False
2170 without_signals_reason = "SIGINT uncatchable"
2171
2172 # Catching SIGFPE
2173
2174 if conf.CheckFPE():
2175 conf.env['HAVE_C99FPE']=True
2176 else:
2177 conf.env['HAVE_C99FPE']=False
2178
2179 # Checking for signal reset requirement
2180
2181 if conf.CheckSigReset() is False:
2182 print "Unable to determine if signal reset is required"
2183 Exit(1)
2184
2185 # YACC
2186
2187 if conf.CheckYacc():
2188 conf.env['HAVE_YACC']=True
2189
2190 if conf.CheckLex():
2191 conf.env['HAVE_LEX']=True
2192
2193 if conf.CheckLexDestroy():
2194 conf.env['HAVE_LEXDESTROY']=True
2195
2196 # Tcl/Tk
2197
2198 if with_tcltk:
2199 if conf.CheckTcl():
2200 if conf.CheckTclVersion():
2201 if conf.CheckTk():
2202 if with_tcltk and conf.CheckTkVersion():
2203 if env['STATIC_TCLTK']:
2204 if conf.CheckTkTable():
2205 pass
2206 else:
2207 without_tcltk_reason = "TkTable not found"
2208 with_tcltk = False
2209 else:
2210 without_tcltk_reason = "Require Tk version <= 8.4. See 'scons -h'"
2211 with_tcltk = False
2212 else:
2213 without_tcltk_reason = "Tk not found."
2214 with_tcltk = False
2215 else:
2216 without_tcltk_reason = "Require Tcl <= 8.4 Tcl."
2217 with_tcltk = False
2218
2219 else:
2220 without_tcltk_reason = "Tcl not found."
2221 with_tcltk = False
2222
2223 if env['STATIC_TCLTK']:
2224 conf.CheckX11()
2225
2226 # Python... obviously we're already running python, so we just need to
2227 # check that we can link to the python library OK:
2228
2229 if not conf.CheckPythonLib():
2230 without_python_reason = 'libpython2.x not found or not linkable'
2231 with_python = False
2232 env['WITH_PYTHON']=False
2233
2234 # SWIG version
2235
2236 if with_python and conf.CheckSwigVersion() is False:
2237 without_python_reason = 'SWIG >= 1.3.24 is required'
2238 with_python = False
2239 env['WITH_PYTHON']=False
2240
2241 # CUnit
2242
2243 if with_cunit:
2244 if not conf.CheckCUnit():
2245 without_cunit_reason = 'CUnit not found'
2246 with_cunit = False
2247 #print "CUNIT NOT FOUND, LIBS=",conf.env.get('LIBS')
2248
2249 # DMALLOC
2250
2251 if with_dmalloc:
2252 if not conf.CheckDMalloc():
2253 without_dmalloc_reason = 'dmalloc not found'
2254 with_dmalloc = False
2255
2256 # GRAPHVIZ
2257
2258 if with_graphviz:
2259 if not conf.CheckGraphViz():
2260 without_graphviz_reason = 'graphviz not found'
2261 with_graphviz = False
2262 env['WITH_GRAPHVIZ'] = False
2263 env['HAVE_GRAPHVIZ_BOOLEAN'] = conf.CheckGraphVizBoolean()
2264
2265 # UFSPARSE
2266
2267 if with_ufsparse:
2268 if not conf.CheckUFSparse():
2269 without_ufsparse_reason = 'ufsparse not found'
2270 with_ufsparse = False
2271 env['WITH_UFSPARSE'] = False
2272
2273 # IDA
2274
2275 if with_ida:
2276 if not conf.CheckSUNDIALS():
2277 with_ida = False
2278 without_ida_reason = "SUNDIALS not found, or bad version"
2279 elif not conf.CheckIDA():
2280 with_ida = False
2281 without_ida_reason = "Unable to compile/link against SUNDIALS/IDA"
2282
2283 # CONOPT
2284
2285 if not with_conopt:
2286 without_conopt_reason = "Not selected (see config option WITH_SOLVERS)"
2287 elif conf.CheckCONOPT() is False:
2288 if conf.env.get('CONOPT_LINKED'):
2289 conf.env['CONOPT_LINKED'] = False
2290 # we no longer require CONOPT at buildtime in order to build support for it
2291 #with_conopt = False
2292 #without_conpt_reason = "CONOPT not found"
2293
2294 # IPOPT
2295
2296 if not with_ipopt:
2297 without_ipopt_reason = "Not selected (see config option WITH_SOLVERS)"
2298 elif not conf.CheckIPOPT():
2299 with_ipopt = False
2300 without_ipopt_reason = "IPOPT not found"
2301
2302 # BLAS
2303
2304 need_blas=False
2305
2306 if with_lsode:
2307 need_fortran = True
2308 need_fortran_reasons.append("LSODE")
2309 need_blas=True
2310
2311 if with_ipopt:
2312 need_blas=True
2313
2314 if need_blas:
2315 if conf.CheckLib('blas'):
2316 with_local_blas = False
2317 without_local_blas_reason = "Found BLAS installed on system"
2318 else:
2319 with_local_blas = True
2320 need_fortran = True
2321 need_fortran_reasons.append("BLAS")
2322 else:
2323 with_local_blas= False;
2324 without_local_blas_reason = "BLAS not required"
2325
2326 # FORTRAN
2327
2328 # we'll assume now (2012) that we always have gfortran available on our system.
2329
2330 if need_fortran and conf.CheckFortran() is False:
2331 print "Failed to build simple test file with your Fortran compiler."
2332 print "Check your compiler is installed and running correctly."
2333 print "You can set your Fortran compiler using the FORTRAN scons option."
2334 print "The fortran compiler is REQUIRED to build:",", ".join(need_fortran_reasons)
2335 print "Perhaps try examining the value of your WITH_SOLVERS option (remove LSODE, etc)."
2336 Exit(1)
2337
2338 #else:
2339 # print "FORTRAN not required"
2340
2341 # F2C
2342
2343 if need_fortran:
2344 if platform.system()=="Windows":
2345 pass
2346 #conf.env.Append(LIBPATH='c:\mingw\lib')
2347
2348 # scrollkeeper
2349
2350 if with_scrollkeeper:
2351 if conf.CheckScrollkeeperConfig() is False:
2352 with_scrollkeeper=False
2353 without_scrollkeeper_reason="unable to detect scrollkeeper-config"
2354
2355 # lyx
2356
2357 if with_doc_build:
2358 if not conf.CheckLyx():
2359 with_doc_build = False
2360 without_doc_build_reason="unable to locate LyX"
2361
2362 # TODO: -D_HPUX_SOURCE is needed
2363
2364 # TODO: detect if dynamic libraries are possible or not
2365
2366 if platform.system()=="Windows" and env.has_key('MSVS'):
2367 _found_windows_h = conf.CheckHeader('Windows.h')
2368
2369 if not _found_windows_h:
2370 print "Could not locate 'Windows.h' in CPPPATH. Check your configuration."
2371 Exit(1)
2372
2373 if with_python and conf.CheckHeader(['basetsd.h','BaseTsd.h']) is False:
2374 with_python = 0;
2375 without_python_reason = "Header file 'basetsd.h' not found. Install the MS Platform SDK."
2376
2377 conf.Finish()
2378
2379 #print "-=-=-=-=-=-=-=-=- LIBS =",env.get('LIBS')
2380
2381 #---------------------------------------
2382 # SUBSTITUTION DICTIONARY for .in files
2383
2384 release = env.get('RELEASE')
2385 if release=="0.":
2386 release="0"
2387
2388 #print "SUBSTITUTED CONOPT_LIBPATH:",c_escape(env.subst("$CONOPT_LIBPATH"))
2389
2390 subst_dict = {
2391 '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
2392 ,'@DEFAULT_ASCENDSOLVERS@':env['DEFAULT_ASCENDSOLVERS']
2393 , '@GLADE_FILE@':'ascend.glade'
2394 , '@HELP_ROOT@':''
2395 , '@ICON_EXTENSION@':icon_extension
2396 , '@INSTALL_ASCDATA@':env['INSTALL_ASCDATA']
2397 , '@INSTALL_BIN@':env['INSTALL_BIN']
2398 , '@INSTALL_INCLUDE@':env['INSTALL_INCLUDE']
2399 , '@INSTALL_LIB@':env['INSTALL_LIB']
2400 , '@INSTALL_MODELS@':env['INSTALL_MODELS']
2401 , '@INSTALL_SOLVERS@':env['INSTALL_SOLVERS']
2402 , '@INSTALL_PYTHON@':env['INSTALL_PYTHON']
2403 , '@INSTALL_PYTHON_ASCEND@':env['INSTALL_PYTHON_ASCEND']
2404 , '@PYGTK_ASSETS@':env['PYGTK_ASSETS']
2405 , '@VERSION@':version
2406 , '@RELEASE@':release
2407 , '@SONAME_MAJOR_INT@':soname_major_int
2408 , '@DISTTAR_NAME@':env['DISTTAR_NAME']
2409 , '@WEBHELPROOT@':'http://ascendwiki.cheme.cmu.edu/Category:Documentation'
2410 , '@SHLIBSUFFIX@':env['SHLIBSUFFIX']
2411 , '@SHLIBPREFIX@':env['SHLIBPREFIX']
2412 , '@EXTLIB_SUFFIX@':env['EXTLIB_SUFFIX']
2413 , '@EXTLIB_PREFIX@':env['EXTLIB_PREFIX']
2414 , '@ASC_ENV_TK_DEFAULT@' : '$$ASCENDDIST/tcltk'
2415 , '@PYTHON@' : python_exe
2416 , '@PYVERSION@' : pyversion
2417 , '@SOURCE_ROOT@':c_escape(os.path.abspath(str(env.Dir("#"))))
2418 , '@WITH_GRAPHVIZ@': str(int(env.get('WITH_GRAPHVIZ')))
2419 #define ASC_ABSOLUTE_PATHS @ASC_ABSOLUTE_PATHS@
2420 #if ASC_ABSOLUTE_PATHS
2421 # define ASCENDDIST_DEFAULT "@ASCENDDIST_DEFAULT@"
2422 # define ASCENDTK_DEFAULT "@ASCENDTK_DEFAULT@"
2423 # define ASCENDLIBRARY_DEFAULT "@ASCENDLIBRARY_DEFAULT@"
2424 # define ASCENDSOLVERS_DEFAULT "@ASCENDSOLVERS_DEFAULT@"
2425 #else
2426 # define ASC_DIST_REL_BIN "@ASC_DIST_REL_BIN@"
2427 # define ASC_TK_REL_DIST "@ASC_TK_REL_DIST@"
2428 # define ASC_LIBRARY_REL_DIST "@ASC_LIBRARY_REL_DIST@"
2429 # define ASC_SOLVERS_REL_DIST "@ASC_SOLVERS_REL_DIST@"
2430 #endif
2431 , '@ASC_ABSOLUTE_PATHS@': str(int(env.get('ABSOLUTE_PATHS')))
2432 , '@ASCENDDIST_DEFAULT@': c_escape(env['INSTALL_PREFIX'])
2433 , '@ASCENDTK_DEFAULT@': c_escape(os.path.abspath(env.subst(env['INSTALL_TK'])))
2434 , '@ASCENDLIBRARY_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDLIBRARY'])))
2435 , '@ASCENDSOLVERS_DEFAULT@': c_escape(os.path.abspath(env.subst(env['DEFAULT_ASCENDSOLVERS'])))
2436 , '@ASC_DIST_REL_BIN@' : default_dist_rel_bin
2437 , '@ASC_TK_REL_DIST@' : default_tk_rel_dist
2438 , '@ASC_LIBRARY_REL_DIST@' : default_library_rel_dist
2439 , '@ASC_SOLVERS_REL_DIST@' : default_solvers_rel_dist
2440 , '@SIZEOF_VOID_P@' : env['SIZEOF_VOID_P']
2441 , '@SIZEOF_INT@' : env['SIZEOF_INT']
2442 , '@SIZEOF_LONG@' : env['SIZEOF_LONG']
2443 , '@SIZEOF_LONG_LONG@' : env['SIZEOF_LONG_LONG']
2444 , '@SIZEOF_UINT@' : env['SIZEOF_UINT']
2445 , '@SIZEOF_ULONG@' : env['SIZEOF_ULONG']
2446 , '@SIZEOF_ULONGLONG@' : env['SIZEOF_ULONGLONG']
2447 }
2448
2449 if env.get('WITH_DOC'):
2450 #print "WITH_DOC:",env['WITH_DOC']
2451 subst_dict['@HELP_ROOT@']=env['HELP_ROOT']
2452
2453 # bool options...
2454 for k,v in {
2455 'ASC_WITH_DMALLOC':with_dmalloc
2456 ,'ASC_WITH_UFSPARSE':with_ufsparse
2457 ,'ASC_WITH_MMIO':with_mmio
2458 ,'ASC_SIGNAL_TRAPS':with_signals
2459 ,'ASC_RESETNEEDED':env.get('ASC_RESETNEEDED')
2460 ,'HAVE_C99FPE':env.get('HAVE_C99FPE')
2461 ,'HAVE_IEEE':env.get('HAVE_IEEE')
2462 ,'ASC_XTERM_COLORS':env.get('WITH_XTERM_COLORS')
2463 ,'MALLOC_DEBUG':env.get('MALLOC_DEBUG')
2464 ,'ASC_HAVE_LEXDESTROY':env.get('HAVE_LEXDESTROY')
2465 ,'HAVE_SNPRINTF':env.get('HAVE_SNPRINTF')
2466 ,'HAVE__SNPRINTF':env.get('HAVE__SNPRINTF')
2467 }.iteritems():
2468
2469 if v: subst_dict["/\\* #\\s*define %s @%s@ \\*/" % (k,k)]='# define %s 1 ' % k
2470
2471 if with_python:
2472 subst_dict['@ASCXX_USE_PYTHON@']="1"
2473 env['WITH_PYTHON']=1;
2474
2475 if with_latex2html:
2476 env['WITH_LATEX2HTML']=1
2477
2478 if env.has_key('HAVE_GCCVISIBILITY'):
2479 subst_dict['@HAVE_GCCVISIBILITY@'] = "1"
2480
2481 env.Append(SUBST_DICT=subst_dict)
2482
2483 #for k,v in subst_dict.iteritems():
2484 # print "%-50s%s" % ("'%s'"%k,v)
2485
2486 # REMOVED: long command-line support on Win2k
2487
2488 #------------------------------------------------------
2489 # RECIPE: SWIG scanner
2490
2491 import SCons.Script
2492
2493 SWIGScanner = SCons.Scanner.ClassicCPP(
2494 "SWIGScan"
2495 , ".i"
2496 , "CPPPATH"
2497 , '^[ \t]*[%,#][ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'
2498 )
2499
2500 env.Append(SCANNERS=[SWIGScanner])
2501
2502 #------------------------------------------------------
2503 # Recipe for 'CHMOD' ACTION
2504
2505 import SCons
2506 from SCons.Script.SConscript import SConsEnvironment
2507 SConsEnvironment.Chmod = SCons.Action.ActionFactory(os.chmod,
2508 lambda dest, mode: 'Chmod("%s", 0%o)' % (dest, mode))
2509
2510 def InstallPerm(env, dest, files, perm):
2511 obj = env.Install(dest, files)
2512 for i in obj:
2513 env.AddPostAction(i, env.Chmod(str(i), perm))
2514
2515 def InstallPermAs(env, dest, filen, perm):
2516 obj = env.InstallAs(dest, filen)
2517 for i in obj:
2518 env.AddPostAction(i, env.Chmod(str(i), perm))
2519 return dest
2520
2521 SConsEnvironment.InstallPerm = InstallPerm
2522
2523 # define wrappers
2524 SConsEnvironment.InstallProgram = lambda env, dest, files: InstallPerm(env, dest, files, 0755)
2525 SConsEnvironment.InstallHeader = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2526 SConsEnvironment.InstallShared = lambda env, dest, files: InstallPerm(env, dest, files, 0644)
2527 SConsEnvironment.InstallSharedAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2528 SConsEnvironment.InstallLibraryAs = lambda env, dest, files: InstallPermAs(env, dest, files, 0644)
2529
2530 #------------------------------------------------------
2531 # BUILD...
2532
2533 # so that #include <ascend/modulename/headername.h> works across all modules...
2534 env.AppendUnique(CPPPATH=['#'])
2535
2536 if env['DEBUG']:
2537 env.Append(
2538 CCFLAGS=['-g']
2539 ,LINKFLAGS=['-g']
2540 )
2541
2542 if env['GCOV']:
2543 env.Append(
2544 CPPFLAGS=['-g','-fprofile-arcs','-ftest-coverage']
2545 , LIBS=['gcov']
2546 , LINKFLAGS=['-fprofile-arcs','-ftest-coverage']
2547 )
2548
2549 #FIXME there must be a better way of doing this...
2550
2551 if with_ida:
2552 env.Append(WITH_IDA=1)
2553
2554 if with_conopt:
2555 env.Append(WITH_CONOPT=1)
2556
2557 if with_ipopt:
2558 env.Append(WITH_IPOPT=1)
2559
2560 if with_dopri5:
2561 env.Append(WITH_DOPRI5=1)
2562
2563 if with_radau5:
2564 env.Append(WITH_RADAU5=1)
2565
2566 if with_makemps:
2567 env.Append(WITH_MAKEMPS=1)
2568
2569 if with_graphviz and env.get('GRAPHVIZ_RPATH'):
2570 env.Append(RPATH=env['GRAPHVIZ_RPATH'])
2571
2572 #-------------
2573 # TCL/TK GUI
2574
2575 if with_tcltk:
2576 env.SConscript(['tcltk/SConscript'],'env')
2577 else:
2578 print "Skipping... Tcl/Tk bindings aren't being built:",without_tcltk_reason
2579
2580 #-------------
2581 # PYTHON INTERFACE
2582
2583 if with_python:
2584 env.SConscript(['ascxx/SConscript'],'env')
2585 env.SConscript(['pygtk/SConscript'],'env')
2586 else:
2587 print "Skipping... Python bindings aren't being built:",without_python_reason
2588
2589 #------------
2590 # BASE/GENERIC SUBDIRECTORIES
2591
2592 libascend_env = env.Clone()
2593
2594 dirs = ['general','utilities','compiler','system','solver','integrator','packages','linear']
2595
2596 srcs = []
2597 for d in dirs:
2598 heresrcs = libascend_env.SConscript('ascend/'+d+'/SConscript','libascend_env')
2599 srcs += heresrcs
2600
2601 #-------------
2602 # IMPORTED CODE: LSODE, BLAS, etc
2603
2604 if with_local_blas:
2605 env['blasobjs'] = env.SConscript(['blas/SConscript'],'env')
2606 else:
2607 env['blasobjs'] = []
2608 print "Skipping... BLAS won't be built:", without_local_blas_reason
2609
2610 if not with_ida:
2611 print "Skipping... IDA won't be built:", without_ida_reason
2612
2613 if not with_dopri5:
2614 print "Skipping... DOPRI5 won't be built:", without_dopri5_reason
2615
2616 if with_mmio:
2617 srcs += env.SConscript(['mmio/SConscript'],'env')
2618 else:
2619 print "Skipping... MMIO export won't be built:", without_mmio_reason
2620 #-------------
2621 # LIBASCEND -- all 'core' functionality
2622
2623 # FIXME want to move these bits to ascend/SConscript
2624
2625 libascend_env.Append(
2626 CPPPATH=['#']
2627 ,LIBS=['m']
2628 )
2629
2630 if platform.system()=="Linux":
2631 libascend_env.Append(LIBS=['dl'])
2632
2633 if with_dmalloc:
2634 libascend_env.Append(LIBS=['dmalloc'])
2635
2636 if with_ufsparse:
2637 libascend_env.Append(LIBS=['cxsparse'])
2638
2639 if platform.system()=="Linux":
2640 libascend_env.Append(LINKFLAGS=['-Wl,-soname,%s' % soname_full])
2641
2642 libascend = libascend_env.SharedLibrary('ascend',srcs)
2643
2644 # create local symlink for the soname stuff.
2645 #print "SONAME =",env.subst(soname_full)
2646
2647 env['libascend'] = libascend
2648 libtargets = [libascend]
2649
2650 if platform.system()=="Linux":
2651 if soname_major:
2652 libascend_env.Command(soname_full,libascend,Move("$TARGET","$SOURCE"))
2653 #print "MAKING LINK, SONAME_MAJOR =",soname_major
2654 liblink = libascend_env.Command(soname_full, libascend, "ln -s $SOURCE $TARGET")
2655 libtargets.append(liblink)
2656
2657 # for use in declaring dependent shared libraries in SConscript files (eg solvers/*/SConscript)
2658
2659 env.Alias('libascend',libtargets)
2660
2661 #-------------
2662 # UNIT TESTS (C CODE)
2663
2664 test_env = env.Clone()
2665 test_env.Append(
2666 CPPPATH="#"
2667 )
2668
2669 if with_cunit:
2670 testdirs = ['general','solver','utilities','linear','compiler','system','packages','integrator']
2671 testsrcs = []
2672 for testdir in testdirs:
2673 path = 'ascend/'+testdir+'/test/'
2674 test_env.SConscript([path+'SConscript'],'test_env')
2675 testsrcs += [i.path for i in test_env['TESTSRCS_'+testdir.upper()]]
2676 test_env['TESTDIRS'] = testdirs
2677
2678 #print "TESTSRCS =",testsrcs
2679
2680 test_env.SConscript(['test/SConscript'],'test_env')
2681
2682 env.Alias('test',[env.Dir('test')])
2683
2684 else:
2685 print "Skipping... CUnit tests aren't being built:",without_cunit_reason
2686
2687 #-------------
2688 # EXTERNAL SOLVERS
2689
2690 env['extfns']=[]
2691 env['BUILDING_ASCEND'] = 1
2692
2693 env.SConscript(['solvers/SConscript'],'env')
2694
2695 #-------------
2696 # EXTERNAL FUNCTIONS
2697
2698 modeldirs = env.SConscript(['models/SConscript'],'env')
2699
2700 if not with_extfns:
2701 print "Skipping... External modules aren't being built:",without_extfns_reason
2702
2703 for _f in env['extfns']:
2704 env.Depends(_f,'libascend')
2705 env.Alias('extfns',env['extfns'])
2706
2707 #-------------
2708 # FPROPS python bindings
2709
2710 env.Alias('pyfprops',env.get('pyfprops'))
2711
2712 #------------------------------------------------------
2713 # CREATE ASCEND-CONFIG scriptlet
2714
2715 ascendconfig = env.SubstInFile('ascend-config.in')
2716
2717 #------------------------------------------------------
2718 # INSTALLATION
2719
2720 if env.get('CAN_INSTALL'):
2721
2722 dirs = ['INSTALL_BIN','INSTALL_ASCDATA','INSTALL_LIB', 'INSTALL_INCLUDE','INSTALL_DOC','INSTALL_PYTHON']
2723 install_dirs = [Dir(env.subst("$INSTALL_ROOT$"+d)) for d in dirs]
2724 install_dirs += modeldirs + [Dir(env.subst("$INSTALL_ROOT$INSTALL_SOLVERS"))]
2725
2726 #env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_LIB")),libascend)
2727
2728 libname = "${INSTALL_LIB}/%s%s" % (soname_full,soname_minor)
2729 install_lib = env.InstallLibraryAs("${INSTALL_ROOT}"+libname, [libascend])
2730 if env['ABSOLUTE_PATHS']:
2731 link_target = libname
2732 else:
2733 link_target = "%s%s" % (soname_full,soname_minor)
2734
2735 link1 = "${INSTALL_LIB}/%s" % soname_clean
2736 install_link1 = None
2737 if env.subst(link1) != env.subst(libname):
2738 # v--link to create v--file to link to command
2739 install_link1 = env.Command("${INSTALL_ROOT}"+link1,install_lib
2740 # v-- command to do it (note the trick about
2741 ,"ln -f -s %s $TARGET" % link_target
2742 )
2743
2744 link2 = "${INSTALL_LIB}/%s" % soname_full
2745 install_link2 = None
2746 if soname_minor:
2747 install_link2 = env.Command("${INSTALL_ROOT}"+link2,install_lib
2748 ,"ln -f -s %s $TARGET" % link_target
2749 )
2750
2751 env.InstallProgram(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),ascendconfig)
2752
2753 # MAC OS X INSTALL STUFF
2754 # in this case, we're installing to INSTALL_PREFIX, assumed to be a folder
2755 # created using Disk Utility as a new DMG which will be distributed.
2756 if platform.system()=="Darwin":
2757 # extra stuff for inside the .app
2758 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN")),"mac/Info.plist")
2759 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_BIN/Resources/")),"mac/ascend.icns")
2760
2761 # related files the .dmg folder
2762 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"README-osx.txt")
2763 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"LICENSE.txt")
2764 env.InstallShared(Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX")),"CHANGELOG.txt")
2765 env.Command("$INSTALL_ROOT$INSTALL_PREFIX/Applications Folder","/Applications","ln -f -s $SOURCE $TARGET")
2766 install_dirs += [Dir(env.subst("$INSTALL_ROOT$INSTALL_PREFIX"))]
2767
2768 # GTK libraries and related files
2769 gtkfiles = []
2770 gtksource = "dist/PyGTK.bundle/"
2771 def visit(gtkfiles,dirname,fnames):
2772 gtkfiles += Glob("%s/*" % dirname)
2773 os.path.walk(gtksource,visit,gtkfiles)
2774
2775 #print "GTKFILES ="
2776 #
2777 for f in gtkfiles:
2778 r = os.path.commonprefix([gtksource,f.path])
2779 dirname,filename = os.path.split(f.path[len(r):])
2780 dest = os.path.join(env.subst("$INSTALL_ROOT$INSTALL_BIN/PyGTK.bundle"),dirname)
2781 # print "%s --> %s" %(f,dest)
2782 env.Install(Dir(dest),f)
2783
2784 # ALIAS FOR ALL INSTALLATION
2785 env.Alias('install',install_dirs)
2786
2787 #------------------------------------------------------
2788 # WINDOWS INSTALLER
2789
2790 if not env.get('NSIS'):
2791 with_installer = False
2792 without_installer_reason = "NSIS not found"
2793
2794 if with_installer:
2795 pyarch = ""
2796 instarch = "win32"
2797 if platform.architecture()[0] == "64bit":
2798 instarch = "x64"
2799 pyarch = ".amd64"
2800 inst64 = 1
2801 nsisdefs = {
2802 'OUTFILE':"#dist/$WIN_INSTALLER_NAME"
2803 ,"VERSION":version
2804 ,'PYVERSION':pyversion
2805 ,'PYPATCH':".%d"%sys.version_info[2]
2806 ,'PYARCH':str(pyarch)
2807 ,'INSTARCH':str(instarch)
2808 }
2809 # support up to 5 extra dependency DLLs to accompany IPOPT
2810 for i in range(5):
2811 _fl = ''; _dl = ''
2812 if env.get('IPOPT_DLL%d'%(i+1)):
2813 _fl = "File %s"%os.path.normcase(os.path.normpath(env.subst("$IPOPT_DLL%d"%(i+1))))
2814 _dl = "Delete \"$$INSTDIR\\%s\""%os.path.split(env.subst("$IPOPT_DLL%d"%(i+1)))[1]
2815 nsisdefs['FILE_IPOPT_%d'%(i+1)] = _fl
2816 nsisdefs['DEL_IPOPT_%d'%(i+1)] = _dl
2817 env.Append(NSISDEFINES=nsisdefs)
2818 installer = env.Installer('nsis/installer.nsi')
2819
2820 for i in range(5):
2821 if env.get('IPOPT_DLL%d'%(i+1)):
2822 env.Depends(installer,env['IPOPT_DLL%d'%(i+1)])
2823
2824 env.Depends(installer,["pygtk","ascxx","tcltk","ascend.dll","models","solvers","ascend-config",'pygtk/ascend'])
2825 env.Depends(installer,"doc/book.pdf")
2826 env.Depends(installer,["nsis/detect.nsi","nsis/dependencies.nsi","nsis/download.nsi"])
2827 env.Alias('installer',installer)
2828 else:
2829 print "Skipping... Windows installer isn't being built:",without_installer_reason
2830
2831 #------------------------------------------------------
2832 # CREATE the SPEC file for generation of RPM packages
2833
2834 if platform.system()=="Linux":
2835 env.SubstInFile('ascend.spec.in')
2836
2837 #------------------------------------------------------
2838 # CREATE OMF FILE FOR USE WITH SCROLLKEEPER
2839
2840 #if with_scrollkeeper:
2841 # #env.SubstInFile('#/pygtk/gnome/ascend.omf.in')
2842 # #env.InstallShared(env['INSTALL_ROOT']+env['OMFDIR'],"#/pygtk/gnome/ascend.omf")
2843
2844 #------------------------------------------------------
2845 # DISTRIBUTION TAR FILE
2846
2847 env['DISTTAR_FORMAT']='bz2'
2848 env.Append(
2849 DISTTAR_EXCLUDEEXTS=['.o','.os','.so','.a','.dll','.lib','.cc','.cache',
2850 '.pyc','.cvsignore','.dblite','.log','.pl','.out','.exe','.aux','.idx',
2851 '.toc','.lof','.lot','.mm','.warnings','.tm2','.swp',',tmp','.gz',
2852 '.bz2','.7z','.deb','.dsc','.changes','.bak','.tex','.tmp','.def']
2853 , DISTTAR_EXCLUDEDIRS=['CVS','.svn','.sconf_temp', 'dist','debian','doxy']
2854 , DISTTAR_EXCLUDERES=[r"_wrap\.cc?$", r"~$", r"ascxx/ascpy\.py","ascxx/testipopt$"
2855 ,r"/lib.*\.so\.[.0-9]+$", r"tcltk/asc4dev$", r"tcltk/interface/typelex\.c$"
2856 ,r"ascend/compiler/ascParse\.[ch]$", r"ascend/solver/conoptconfig\.h$"
2857 ,r"ascend/utilities/config\.h$", r"pygtk/config\.h$", r"pygtk/config\.py$"
2858 ,r"pygtk/ascdev$", r"ascxx/testconopt$", r"ascend/compiler/scanner\.c$"
2859 ,r"datareader/.*TY\.csv$"
2860 ,r"ascxx/ascpy_wrap\.h",r"ascxx/config\.h$"
2861 ,r"tcltk/interface/ascend4$",r"ascxx/testslvreq$",r"test/test$"
2862 ,r"models/johnpye/datareader/.*\.tm2\.Z$"
2863 ,r"models/johnpye/fprops/[a-z][a-z0-9]+(.*\.exe)?$" # FPROPS test executables
2864 ,r"fprops/fluids/fluids_list\.h$" # FPROPS fluids list
2865 ]
2866 )
2867
2868 tar = env.DistTar("dist/"+env['DISTTAR_NAME']
2869 , [env.Dir('#')]
2870 )
2871
2872 env.Depends(tar,'ascend.spec')
2873 env.Depends(tar,'doc/book.pdf')
2874
2875 #------------------------------------------------------
2876 # DEBIAN TARBALL for use with Build Service
2877
2878 import glob
2879 deb_files = glob.glob('debian/*.install')
2880 deb_files += glob.glob('debian/*.docs')
2881 deb_files += glob.glob('debian/*.dirs')
2882 deb_files += glob.glob('debian/*.man')
2883 deb_files += glob.glob('debian/*.manpages')
2884 deb_files += ['debian/%s' % s for s in ['rules','control','changelog','compat','copyright','dirs']]
2885
2886 deb_tar = env.Tar(
2887 'dist/debian.tar.gz'
2888 ,deb_files
2889 ,TARFLAGS = ['cz']
2890 )
2891
2892 Alias('dist',[tar,deb_tar])
2893
2894 #------------------------------------------------------
2895 # DOCUMENTATION
2896
2897 #print "WITH_DOC_BUILD = ",with_doc_build
2898
2899 if with_doc_build:
2900 #user's manual
2901 env.SConscript('doc/SConscript',['env'])
2902 else:
2903 print "Skipping... Documentation isn't being built:",without_doc_build_reason
2904
2905 #------------------------------------------------------
2906 # RPM BUILD
2907
2908 # for RPM builds, 'scons dist' then 'rpmbuild -ta dist/ascend-*.tar.bz2'
2909 # (check * for the version number used to create the tarball)
2910
2911 #------------------------------------------------------
2912 # DEFAULT TARGETS
2913
2914 default_targets =['libascend','solvers']
2915 if with_tcltk:
2916 default_targets.append('tcltk')
2917 if with_python:
2918 default_targets.append('ascxx')
2919 default_targets.append('pygtk')
2920 default_targets.append('pyfprops')
2921 if with_extfns:
2922 default_targets.append('extfns')
2923 if with_doc_build:
2924 default_targets.append('doc')
2925
2926 env.Default(default_targets)
2927
2928 print "Building targets:"," ".join([str(i) for i in BUILD_TARGETS])
2929
2930 # vim: set syntax=python:

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