/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3399 - (show annotations) (download)
Thu Jun 14 08:56:46 2018 UTC (5 days, 18 hours ago) by jpye
File size: 81039 byte(s)
add detection of pcre

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

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