/[ascend]/branches/python3/SConstruct
ViewVC logotype

Contents of /branches/python3/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3506 - (show annotations) (download)
Wed Mar 8 23:02:10 2023 UTC (6 months, 2 weeks ago) by jpye
File size: 75608 byte(s)
solving ascxx compile issues in MSYS2 (maybe breaks other things)

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

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