/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3400 - (show annotations) (download)
Thu Jun 14 13:08:43 2018 UTC (6 months ago) by jpye
File size: 80989 byte(s)
added GetNotesList test

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

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