/[ascend]/trunk/SConstruct
ViewVC logotype

Annotation of /trunk/SConstruct

Parent Directory Parent Directory | Revision Log Revision Log


Revision 416 - (hide annotations) (download)
Mon Apr 3 05:17:50 2006 UTC (13 years, 8 months ago) by johnpye
File size: 14403 byte(s)
Debug output for MSVC build
1 johnpye 393 import os, commands, platform, distutils.sysconfig, os.path
2 johnpye 385
3     #------------------------------------------------------
4     # OPTIONS
5 johnpye 392 #
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 johnpye 385
9     opts = Options(['options.cache', 'config.py'])
10     print "PLATFORM = ",platform.system()
11    
12 johnpye 392 # Import the outside environment
13     env = Environment(ENV=os.environ)
14 johnpye 385
15 johnpye 415 if platform.system()=='Windows' and env.has_key('MSVS'):
16 johnpye 414 print "INCLUDE =",env['ENV']['INCLUDE']
17 johnpye 416 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 johnpye 414 env.Append(CPPPATH=env['ENV']['INCLUDE'])
23     env.Append(LIBPATH=env['ENV']['LIB'])
24    
25 johnpye 385 # Package linking option
26 johnpye 386 opts.Add(EnumOption(
27     'PACKAGE_LINKING'
28 johnpye 385 , 'Style of linking for external libraries'
29     , 'DYNAMIC_PACKAGES'
30 johnpye 386 , ['DYNAMIC_PACKAGES', 'STATIC_PACKAGES', 'NO_PACKAGES']
31     ))
32 johnpye 385
33 johnpye 392 # You can turn off building of Tcl/Tk interface
34 johnpye 386 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 johnpye 392 # You can turn off the building of the Python interface
41 johnpye 387 opts.Add(BoolOption(
42     'WITHOUT_PYTHON'
43     ,"Set to True if you don't want to build Python wrappers."
44     , False
45     ))
46    
47 johnpye 392 # Which solvers will we allow?
48     opts.Add(ListOption(
49     'WITH_SOLVERS'
50 johnpye 393 ,"List of the solvers you want to build. The default is the minimum that"
51     +" works."
52 johnpye 392 ,["QRSLV","CMSLV"]
53     ,['QRSLV','MPS','SLV','OPTSQP'
54     ,'NGSLV','CMSLV','LRSLV','MINOS','CONOPT'
55     ,'LSOD','OPTSQP'
56     ]
57     ))
58    
59 johnpye 393 # 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 johnpye 398 # What should the default ASCENDLIBRARY path be?
75     # Note: users can change it by editing their ~/.ascend.ini
76 johnpye 393 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 johnpye 398 # 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 johnpye 404 +" 'c:\\msys\\1.0\\home\\john\\swigwin-1.3.29\\swig.exe'."
89 johnpye 398 )
90    
91 johnpye 400 # 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 johnpye 393
100 johnpye 400 # Where are the CUnit includes?
101     opts.Add(PackageOption(
102     'CUNIT_CPPPATH'
103     ,"Where are your CUnit include files?"
104     ,"off"
105     ))
106 johnpye 392
107 johnpye 404 # Where are the CUnit libraries?
108 johnpye 400 opts.Add(PackageOption(
109     'CUNIT_LIBPATH'
110 johnpye 404 ,"Where are your CUnit libraries?"
111 johnpye 400 ,"off"
112     ))
113    
114 johnpye 404 # 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 johnpye 405 # Where are the Tk includes?
129     opts.Add(PackageOption(
130     'TK_CPPPATH'
131     ,"Where are your Tk include files?"
132     ,None
133     ))
134 johnpye 404
135 johnpye 405 # Where are the Tk libs?
136     opts.Add(PackageOption(
137     'TK_LIBPATH'
138     ,"Where are your Tk libraries?"
139     ,None
140     ))
141    
142    
143 johnpye 392 # TODO: OTHER OPTIONS?
144    
145     # TODO: flags for optimisation
146    
147 johnpye 393 # TODO: turning on/off bintoken functionality
148    
149 johnpye 400 # TODO: Where will the 'Makefile.bt' file be installed
150     # ....
151    
152 johnpye 385 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 johnpye 386 with_tcltk_gui = (env['WITHOUT_TCLTK_GUI']==False)
160    
161 johnpye 387 with_python = (env['WITHOUT_PYTHON']==False)
162 johnpye 413 without_python_reason = None
163 johnpye 387
164 johnpye 400 with_cunit_tests = env['WITH_CUNIT_TESTS']
165    
166 johnpye 392 print "SOLVERS:",env['WITH_SOLVERS']
167 johnpye 393
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 johnpye 385 #------------------------------------------------------
186 johnpye 398 # SPECIAL CONFIGURATION TESTS
187    
188 johnpye 400 #----------------
189     # SWIG
190    
191 johnpye 398 import os,re
192    
193 johnpye 413 def get_swig_version(env):
194 johnpye 403 cmd = env['SWIG']+' -version'
195     (cin,coutcerr) = os.popen4(cmd);
196     output = coutcerr.read()
197 johnpye 398
198 johnpye 403 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 johnpye 398 m = expr.search(output);
201     if not m:
202 johnpye 413 return None
203 johnpye 398 maj = int(m.group('maj'))
204     min = int(m.group('min'))
205     pat = int(m.group('pat'))
206 johnpye 413
207     return (maj,min,pat)
208 johnpye 398
209 johnpye 413
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 johnpye 398 if maj == 1 and (
220 johnpye 400 min > 3
221     or (min == 3 and pat >= 24)
222 johnpye 398 ):
223     context.Result("ok, %d.%d.%d" % (maj,min,pat))
224     return 1;
225 johnpye 401 else:
226     context.Result("too old, %d.%d.%d" % (maj,min,pat))
227     return 0;
228 johnpye 398
229 johnpye 400 #----------------
230     # General purpose library-and-header test
231    
232 johnpye 404 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 johnpye 400
243 johnpye 404 cpppath_add = []
244     if context.env.has_key(varprefix+'_CPPPATH'):
245     cpppath_add = [env[varprefix+'_CPPPATH']]
246 johnpye 405
247     context.env.Append(
248     LIBPATH = libpath_add
249     , CPPPATH = cpppath_add
250     )
251 johnpye 404
252     def restore(self,context):
253     for k in self.keep:
254     context.env[k]=self.keep[k];
255    
256 johnpye 400 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 johnpye 405 context.Message( 'Checking for '+libname+'... ' )
263 johnpye 400
264     if varprefix==None:
265     varprefix = libname.upper()
266    
267 johnpye 404 keep = KeepContext(context,varprefix)
268 johnpye 400
269 johnpye 405 context.env.Append(LIBS=[libname])
270    
271 johnpye 404 is_ok = context.TryLink(text,ext)
272 johnpye 400
273 johnpye 405 keep.restore(context)
274 johnpye 400
275 johnpye 404 context.Result(is_ok)
276     return is_ok
277    
278     #----------------
279     # CUnit test
280    
281 johnpye 400 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 johnpye 404 return 0;
296 johnpye 400 }
297     """
298    
299     def CheckCUnit(context):
300 johnpye 412 return context.CheckExtLib(context
301 johnpye 400 ,'cunit'
302     ,cunit_test_text
303     )
304    
305 johnpye 404 #----------------
306 johnpye 405 # Tcl test
307 johnpye 404
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 johnpye 405 return CheckExtLib(context,'tcl',tcl_check_text)
319    
320     def CheckTclVersion(context):
321 johnpye 404 keep = KeepContext(context,'TCL')
322 johnpye 405 context.Message("Checking Tcl version... ")
323     (is_ok,output) = context.TryRun(tcl_check_text,'.c')
324 johnpye 404 keep.restore(context)
325     if not is_ok:
326 johnpye 405 context.Result("failed to run check")
327 johnpye 404 return 0
328 johnpye 405 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 johnpye 404 return 1
337    
338 johnpye 405 #----------------
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 johnpye 404 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 johnpye 400
367 johnpye 404 # good version
368     return 1
369    
370 johnpye 398 #------------------------------------------------------
371 johnpye 385 # CONFIGURATION
372    
373     conf = Configure(env
374     , custom_tests = {
375 johnpye 398 'CheckSwigVersion' : CheckSwigVersion
376 johnpye 400 , 'CheckCUnit' : CheckCUnit
377 johnpye 404 , 'CheckTcl' : CheckTcl
378     , 'CheckTclVersion' : CheckTclVersion
379 johnpye 405 , 'CheckTk' : CheckTk
380     , 'CheckTkVersion' : CheckTkVersion
381 johnpye 400 # , 'CheckIsNan' : CheckIsNan
382     # , 'CheckCppUnitConfig' : CheckCppUnitConfig
383 johnpye 385 }
384     , config_h = "config.h"
385     )
386    
387 johnpye 398
388 johnpye 385 # Math library
389 johnpye 414 if not conf.CheckLibWithHeader(['m','c','libc'], 'math.h', 'C'):
390     print 'Did not find math library, exiting!'
391     Exit(1)
392 johnpye 385
393     # Where is 'isnan'?
394    
395     if not conf.CheckFunc('isnan'):
396     print "Didn't find isnan"
397 johnpye 414 # Exit(1)
398 johnpye 385
399 johnpye 387 # Tcl/Tk
400 johnpye 386
401 johnpye 405 if conf.CheckTcl() and conf.CheckTk():
402 johnpye 404 if with_tcltk_gui and not conf.CheckTclVersion():
403 johnpye 405 without_tcltk_reason = "Require Tcl <= 8.3 Tcl."
404 johnpye 404 with_tcltk_gui = False
405 johnpye 386
406 johnpye 405 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 johnpye 412 with_tcltk_gui = False
412    
413 johnpye 395 # 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 johnpye 391 if platform.system()=="Windows":
417 johnpye 395 python_lib='python24'
418 johnpye 391 else:
419 johnpye 395 python_lib='python2.4'
420 johnpye 391
421 johnpye 395 # SWIG version
422    
423 johnpye 396 if platform.system()=="Windows":
424     env['ENV']['SWIGFEATURES']='-O'
425     else:
426     env['ENV']['SWIGFEATURES']='-O'
427 johnpye 395
428 johnpye 413
429     if not conf.CheckSwigVersion():
430     without_python_reason = 'SWIG >= 1.3.24 is required'
431     with_python = False
432    
433 johnpye 400 # CUnit
434    
435     if with_cunit_tests:
436 johnpye 404 if not conf.CheckCUnit():
437     print "CUnit not found. Use 'scons WITH_CUNIT_TESTS=0'"
438     Exit(1)
439 johnpye 400
440 johnpye 385 # TODO: -D_HPUX_SOURCE is needed
441    
442     # TODO: check size of void*
443    
444 johnpye 393 # TODO: detect if dynamic libraries are possible or not
445    
446 johnpye 395 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 johnpye 385 #------------------------------------------------------
453 johnpye 393 # RECIPE: 'SubstInFile', used in pygtk SConscript
454    
455     import re
456 johnpye 395 from SCons.Script import * # the usual scons stuff you get in a SConscript
457 johnpye 393
458 johnpye 395 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 johnpye 393 """
468 johnpye 395 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 johnpye 393
490 johnpye 395 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 johnpye 393
504 johnpye 395 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 johnpye 393
509 johnpye 395 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 johnpye 393
522 johnpye 395 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 johnpye 393 #------------------------------------------------------
528 johnpye 385 # SUBDIRECTORIES....
529    
530 johnpye 393
531 johnpye 385 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 johnpye 386
543     if with_tcltk_gui:
544     env.SConscript(['tcltk98/generic/interface/SConscript'],'env')
545 johnpye 391 else:
546 johnpye 405 print "Skipping... Tcl/Tk GUI isn't being built:",without_tcltk_reason
547 johnpye 386
548 johnpye 387 if with_python:
549     env.SConscript(['pygtk/interface/SConscript'],'env')
550 johnpye 391 else:
551 johnpye 413 print "Skipping... Python GUI isn't being built:",without_python_reason
552 johnpye 400
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