/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3413 - (show annotations) (download)
Wed Jun 26 09:33:37 2019 UTC (5 months, 2 weeks ago) by jpye
File size: 81072 byte(s)
FPROPS 'cutest' doesn't get built if CUnit not detected via ASCEND.

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

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