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

Contents of /branches/python3/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3507 - (show annotations) (download)
Wed Mar 8 23:37:58 2023 UTC (9 months ago) by jpye
File size: 75720 byte(s)
fix for python linking in ascxx/testslvreq (better approach would be to compile alternative version with ASCXX_USE_PYTHON unset)

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

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