/[ascend]/trunk/SConstruct
ViewVC logotype

Contents of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 416 - (show annotations) (download)
Mon Apr 3 05:17:50 2006 UTC (14 years ago) by johnpye
File size: 14403 byte(s)
Debug output for MSVC build
1 import os, commands, platform, distutils.sysconfig, os.path
2
3 #------------------------------------------------------
4 # OPTIONS
5 #
6 # Note that if you set the options via the command line, they will be
7 # remembered in the file 'options.cache'. It's a feature ;-)
8
9 opts = Options(['options.cache', 'config.py'])
10 print "PLATFORM = ",platform.system()
11
12 # Import the outside environment
13 env = Environment(ENV=os.environ)
14
15 if platform.system()=='Windows' and env.has_key('MSVS'):
16 print "INCLUDE =",env['ENV']['INCLUDE']
17 print "LIB =",env['ENV']['LIB']
18 print "LINK =",env['LINK']
19 print "LINKCOM =",env['LINKCOM']
20 print "AR =",env['AR']
21 print "ARCOM =",env['ARCOM']
22 env.Append(CPPPATH=env['ENV']['INCLUDE'])
23 env.Append(LIBPATH=env['ENV']['LIB'])
24
25 # Package linking option
26 opts.Add(EnumOption(
27 'PACKAGE_LINKING'
28 , 'Style of linking for external libraries'
29 , 'DYNAMIC_PACKAGES'
30 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
31 ))
32
33 # You can turn off building of Tcl/Tk interface
34 opts.Add(BoolOption(
35 'WITHOUT_TCLTK_GUI'
36 ,"Set to True if you don't want to build the original Tcl/Tk GUI."
37 , False
38 ))
39
40 # You can turn off the building of the Python interface
41 opts.Add(BoolOption(
42 'WITHOUT_PYTHON'
43 ,"Set to True if you don't want to build Python wrappers."
44 , False
45 ))
46
47 # Which solvers will we allow?
48 opts.Add(ListOption(
49 'WITH_SOLVERS'
50 ,"List of the solvers you want to build. The default is the minimum that"
51 +" works."
52 ,["QRSLV","CMSLV"]
53 ,['QRSLV','MPS','SLV','OPTSQP'
54 ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
55 ,'LSOD','OPTSQP'
56 ]
57 ))
58
59 # Where will the local copy of the help files be kept?
60 opts.Add(PackageOption(
61 'WITH_LOCAL_HELP'
62 , "Directory containing the local copy of the help files (optional)"
63 , "no"
64 ))
65
66 # Will bintoken support be enabled?
67 opts.Add(BoolOption(
68 'WITH_BINTOKEN'
69 ,"Enable bintoken support? This means compiling models as C-code before"
70 +" running them, to increase solving speed for large models."
71 ,False
72 ))
73
74 # What should the default ASCENDLIBRARY path be?
75 # Note: users can change it by editing their ~/.ascend.ini
76 opts.Add(
77 'DEFAULT_ASCENDLIBRARY'
78 ,"Set the default value of the ASCENDLIBRARY -- the location where"
79 +" ASCEND will look for models when running ASCEND"
80 ,os.path.expanduser("~/src/ascend/trunk/models")
81 )
82
83 # Where is SWIG?
84 opts.Add(
85 'SWIG'
86 ,"SWIG location, probably only required for MinGW and MSVC users."
87 +" Enter the location as a Windows-style path, for example"
88 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
89 )
90
91 # Build the test suite?
92 opts.Add(BoolOption(
93 'WITH_CUNIT_TESTS'
94 ,"Whether to build the CUnit tests. Default is off. If set to on,"
95 +" you must have CUnit installed somewhere that SCons can"
96 +" find it."
97 ,False
98 ))
99
100 # Where are the CUnit includes?
101 opts.Add(PackageOption(
102 'CUNIT_CPPPATH'
103 ,"Where are your CUnit include files?"
104 ,"off"
105 ))
106
107 # Where are the CUnit libraries?
108 opts.Add(PackageOption(
109 'CUNIT_LIBPATH'
110 ,"Where are your CUnit libraries?"
111 ,"off"
112 ))
113
114 # Where are the Tcl includes?
115 opts.Add(PackageOption(
116 'TCL_CPPPATH'
117 ,"Where are your Tcl include files?"
118 ,None
119 ))
120
121 # Where are the Tcl libs?
122 opts.Add(PackageOption(
123 'TCL_LIBPATH'
124 ,"Where are your Tcl libraries?"
125 ,None
126 ))
127
128 # Where are the Tk includes?
129 opts.Add(PackageOption(
130 'TK_CPPPATH'
131 ,"Where are your Tk include files?"
132 ,None
133 ))
134
135 # Where are the Tk libs?
136 opts.Add(PackageOption(
137 'TK_LIBPATH'
138 ,"Where are your Tk libraries?"
139 ,None
140 ))
141
142
143 # TODO: OTHER OPTIONS?
144
145 # TODO: flags for optimisation
146
147 # TODO: turning on/off bintoken functionality
148
149 # TODO: Where will the 'Makefile.bt' file be installed
150 # ....
151
152 opts.Update(env)
153 opts.Save('options.cache',env)
154
155 Help(opts.GenerateHelpText(env))
156
157 env.Append(CPPDEFINES=env['PACKAGE_LINKING'])
158
159 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
160
161 with_python = (env['WITHOUT_PYTHON']==False)
162 without_python_reason = None
163
164 with_cunit_tests = env['WITH_CUNIT_TESTS']
165
166 print "SOLVERS:",env['WITH_SOLVERS']
167
168 print "WITH_LOCAL_HELP:",env['WITH_LOCAL_HELP']
169 print "WITH_BINTOKEN:",env['WITH_BINTOKEN']
170 print "DEFAULT_ASCENDLIBRARY:",env['DEFAULT_ASCENDLIBRARY']
171
172 subst_dict = {
173 '@WEBHELPROOT@':'http://pye.dyndns.org/ascend/manual/'
174 , '@GLADE_FILE@':'glade/ascend.glade'
175 , '@DEFAULT_ASCENDLIBRARY@':env['DEFAULT_ASCENDLIBRARY']
176 , '@ASCEND_ICON@':'glade/ascend.png'
177 , '@HELP_ROOT@':''
178 }
179
180 if env['WITH_LOCAL_HELP']:
181 subst_dict['@HELP_ROOT@']=env['WITH_LOCAL_HELP']
182
183 env.Append(SUBST_DICT=subst_dict)
184
185 #------------------------------------------------------
186 # SPECIAL CONFIGURATION TESTS
187
188 #----------------
189 # SWIG
190
191 import os,re
192
193 def get_swig_version(env):
194 cmd = env['SWIG']+' -version'
195 (cin,coutcerr) = os.popen4(cmd);
196 output = coutcerr.read()
197
198 restr = "SWIG\\s+Version\\s+(?P<maj>[0-9]+)\\.(?P<min>[0-9]+)\\.(?P<pat>[0-9]+)\\s*$"
199 expr = re.compile(restr,re.M);
200 m = expr.search(output);
201 if not m:
202 return None
203 maj = int(m.group('maj'))
204 min = int(m.group('min'))
205 pat = int(m.group('pat'))
206
207 return (maj,min,pat)
208
209
210 def CheckSwigVersion(context):
211
212 try:
213 context.Message("Checking version of SWIG... ")
214 maj,min,pat = get_swig_version(context.env)
215 except:
216 context.Result("Failed to detect version, or failed to run SWIG")
217 return 0;
218
219 if maj == 1 and (
220 min > 3
221 or (min == 3 and pat >= 24)
222 ):
223 context.Result("ok, %d.%d.%d" % (maj,min,pat))
224 return 1;
225 else:
226 context.Result("too old, %d.%d.%d" % (maj,min,pat))
227 return 0;
228
229 #----------------
230 # General purpose library-and-header test
231
232 class KeepContext:
233 def __init__(self,context,varprefix):
234 self.keep = {}
235 for k in ['LIBS','LIBPATH','CPPPATH']:
236 if context.env.has_key(k):
237 self.keep[k] = context.env[k]
238
239 libpath_add = []
240 if context.env.has_key(varprefix+'_LIBPATH'):
241 libpath_add = [env[varprefix+'_LIBPATH']]
242
243 cpppath_add = []
244 if context.env.has_key(varprefix+'_CPPPATH'):
245 cpppath_add = [env[varprefix+'_CPPPATH']]
246
247 context.env.Append(
248 LIBPATH = libpath_add
249 , CPPPATH = cpppath_add
250 )
251
252 def restore(self,context):
253 for k in self.keep:
254 context.env[k]=self.keep[k];
255
256 def CheckExtLib(context,libname,text,ext='.c',varprefix=None):
257 """This method will check for variables LIBNAME_LIBPATH
258 and LIBNAME_CPPPATH and try to compile and link the
259 file with the provided text, linking with the
260 library libname."""
261
262 context.Message( 'Checking for '+libname+'... ' )
263
264 if varprefix==None:
265 varprefix = libname.upper()
266
267 keep = KeepContext(context,varprefix)
268
269 context.env.Append(LIBS=[libname])
270
271 is_ok = context.TryLink(text,ext)
272
273 keep.restore(context)
274
275 context.Result(is_ok)
276 return is_ok
277
278 #----------------
279 # CUnit test
280
281 cunit_test_text = """
282 #include <CUnit/Cunit.h>
283 int maxi(int i1, int i2){
284 return (i1 > i2) ? i1 : i2;
285 }
286
287 void test_maxi(void){
288 CU_ASSERT(maxi(0,2) == 2);
289 CU_ASSERT(maxi(0,-2) == 0);
290 CU_ASSERT(maxi(2,2) == 2);
291
292 }
293 int main(void){
294 /* CU_initialize_registry() */
295 return 0;
296 }
297 """
298
299 def CheckCUnit(context):
300 return context.CheckExtLib(context
301 ,'cunit'
302 ,cunit_test_text
303 )
304
305 #----------------
306 # Tcl test
307
308 tcl_check_text = r"""
309 #include <tcl.h>
310 #include <stdio.h>
311 int main(void){
312 printf("%s",TCL_PATCH_LEVEL);
313 return 0;
314 }
315 """
316
317 def CheckTcl(context):
318 return CheckExtLib(context,'tcl',tcl_check_text)
319
320 def CheckTclVersion(context):
321 keep = KeepContext(context,'TCL')
322 context.Message("Checking Tcl version... ")
323 (is_ok,output) = context.TryRun(tcl_check_text,'.c')
324 keep.restore(context)
325 if not is_ok:
326 context.Result("failed to run check")
327 return 0
328 context.Result(output)
329
330 major,minor,patch = tuple(int(i) for i in output.split("."))
331 if major != 8 or minor > 3:
332 # bad version
333 return 0
334
335 # good version
336 return 1
337
338 #----------------
339 # Tcl test
340
341 tk_check_text = r"""
342 #include <tk.h>
343 #include <stdio.h>
344 int main(void){
345 printf("%s",TK_PATCH_LEVEL);
346 return 0;
347 }
348 """
349 def CheckTk(context):
350 return CheckExtLib(context,'tk',tk_check_text)
351
352 def CheckTkVersion(context):
353 keep = KeepContext(context,'TK')
354 context.Message("Checking Tk version... ")
355 (is_ok,output) = context.TryRun(tk_check_text,'.c')
356 keep.restore(context)
357 if not is_ok:
358 context.Result("failed to run check")
359 return 0
360 context.Result(output)
361
362 major,minor,patch = tuple(int(i) for i in output.split("."))
363 if major != 8 or minor > 3:
364 # bad version
365 return 0
366
367 # good version
368 return 1
369
370 #------------------------------------------------------
371 # CONFIGURATION
372
373 conf = Configure(env
374 , custom_tests = {
375 'CheckSwigVersion' : CheckSwigVersion
376 , 'CheckCUnit' : CheckCUnit
377 , 'CheckTcl' : CheckTcl
378 , 'CheckTclVersion' : CheckTclVersion
379 , 'CheckTk' : CheckTk
380 , 'CheckTkVersion' : CheckTkVersion
381 # , 'CheckIsNan' : CheckIsNan
382 # , 'CheckCppUnitConfig' : CheckCppUnitConfig
383 }
384 , config_h = "config.h"
385 )
386
387
388 # Math library
389 if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
390 print 'Did not find math library, exiting!'
391 Exit(1)
392
393 # Where is 'isnan'?
394
395 if not conf.CheckFunc('isnan'):
396 print "Didn't find isnan"
397 # Exit(1)
398
399 # Tcl/Tk
400
401 if conf.CheckTcl() and conf.CheckTk():
402 if with_tcltk_gui and not conf.CheckTclVersion():
403 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
404 with_tcltk_gui = False
405
406 if with_tcltk_gui and not conf.CheckTkVersion():
407 without_tcltk_reason += "Require Tk version <= 8.3. See 'scons -h'"
408 with_tcltk_gui = False
409 else:
410 without_tcltk_reason = "Tcl/Tk not found."
411 with_tcltk_gui = False
412
413 # Python... obviously we're already running python, so we just need to
414 # check that we can link to the python library OK:
415
416 if platform.system()=="Windows":
417 python_lib='python24'
418 else:
419 python_lib='python2.4'
420
421 # SWIG version
422
423 if platform.system()=="Windows":
424 env['ENV']['SWIGFEATURES']='-O'
425 else:
426 env['ENV']['SWIGFEATURES']='-O'
427
428
429 if not conf.CheckSwigVersion():
430 without_python_reason = 'SWIG >= 1.3.24 is required'
431 with_python = False
432
433 # CUnit
434
435 if with_cunit_tests:
436 if not conf.CheckCUnit():
437 print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
438 Exit(1)
439
440 # TODO: -D_HPUX_SOURCE is needed
441
442 # TODO: check size of void*
443
444 # TODO: detect if dynamic libraries are possible or not
445
446 conf.Finish()
447
448 env.Append(PYTHON_LIBPATH=[distutils.sysconfig.PREFIX+"/libs"])
449 env.Append(PYTHON_LIB=[python_lib])
450 env.Append(PYTHON_CPPPATH=[distutils.sysconfig.get_python_inc()])
451
452 #------------------------------------------------------
453 # RECIPE: 'SubstInFile', used in pygtk SConscript
454
455 import re
456 from SCons.Script import * # the usual scons stuff you get in a SConscript
457
458 def TOOL_SUBST(env):
459 """Adds SubstInFile builder, which substitutes the keys->values of SUBST_DICT
460 from the source to the target.
461 The values of SUBST_DICT first have any construction variables expanded
462 (its keys are not expanded).
463 If a value of SUBST_DICT is a python callable function, it is called and
464 the result is expanded as the value.
465 If there's more than one source and more than one target, each target gets
466 substituted from the corresponding source.
467 """
468 env.Append(TOOLS = 'SUBST')
469 def do_subst_in_file(targetfile, sourcefile, dict):
470 """Replace all instances of the keys of dict with their values.
471 For example, if dict is {'%VERSION%': '1.2345', '%BASE%': 'MyProg'},
472 then all instances of %VERSION% in the file will be replaced with 1.2345 etc.
473 """
474 try:
475 f = open(sourcefile, 'rb')
476 contents = f.read()
477 f.close()
478 except:
479 raise SCons.Errors.UserError, "Can't read source file %s"%sourcefile
480 for (k,v) in dict.items():
481 contents = re.sub(k, v, contents)
482 try:
483 f = open(targetfile, 'wb')
484 f.write(contents)
485 f.close()
486 except:
487 raise SCons.Errors.UserError, "Can't write target file %s"%targetfile
488 return 0 # success
489
490 def subst_in_file(target, source, env):
491 if not env.has_key('SUBST_DICT'):
492 raise SCons.Errors.UserError, "SubstInFile requires SUBST_DICT to be set."
493 d = dict(env['SUBST_DICT']) # copy it
494 for (k,v) in d.items():
495 if callable(v):
496 d[k] = env.subst(v())
497 elif SCons.Util.is_String(v):
498 d[k]=env.subst(v)
499 else:
500 raise SCons.Errors.UserError, "SubstInFile: key %s: %s must be a string or callable"%(k, repr(v))
501 for (t,s) in zip(target, source):
502 return do_subst_in_file(str(t), str(s), d)
503
504 def subst_in_file_string(target, source, env):
505 """This is what gets printed on the console."""
506 return '\n'.join(['Substituting vars from %s into %s'%(str(s), str(t))
507 for (t,s) in zip(target, source)])
508
509 def subst_emitter(target, source, env):
510 """Add dependency from substituted SUBST_DICT to target.
511 Returns original target, source tuple unchanged.
512 """
513 d = env['SUBST_DICT'].copy() # copy it
514 for (k,v) in d.items():
515 if callable(v):
516 d[k] = env.subst(v())
517 elif SCons.Util.is_String(v):
518 d[k]=env.subst(v)
519 Depends(target, SCons.Node.Python.Value(d))
520 return target, source
521
522 subst_action=SCons.Action.Action(subst_in_file, subst_in_file_string)
523 env['BUILDERS']['SubstInFile'] = Builder(action=subst_action, emitter=subst_emitter)
524
525 TOOL_SUBST(env)
526
527 #------------------------------------------------------
528 # SUBDIRECTORIES....
529
530
531 env.Append(CPPPATH=['..'])
532
533 env.SConscript(['base/generic/general/SConscript'],'env')
534
535 env.SConscript(['base/generic/utilities/SConscript'],'env')
536
537 env.SConscript(['base/generic/compiler/SConscript'],'env')
538
539 env.SConscript(['base/generic/solver/SConscript'],'env')
540
541 env.SConscript(['base/generic/packages/SConscript'],'env')
542
543 if with_tcltk_gui:
544 env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
545 else:
546 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
547
548 if with_python:
549 env.SConscript(['pygtk/interface/SConscript'],'env')
550 else:
551 print "Skipping... Python GUI isn't being built:",without_python_reason
552
553 if with_cunit_tests:
554 testdirs = ['general','solver','utilities']
555 for testdir in testdirs:
556 path = 'base/generic/'+testdir+'/test/'
557 env.SConscript([path+'SConscript'],'env')
558 env.SConscript(['test/SConscript'],'env')
559 env.SConscript(['base/generic/test/SConscript'],'env')
560
561
562 else:
563 print "Skipping... CUnit tests aren't being built"
564
565 #------------------------------------------------------
566 # INSTALLATION
567
568 # TODO: add install options

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