1 #################################################################################
3 # Copyright (c) 2007-2008 Luca Bruno #
5 # This file is part of Smalltalk YX. #
7 # Permission is hereby granted, free of charge, to any person obtaining a copy #
8 # of this software and associated documentation files (the "Software"), to deal #
9 # in the Software without restriction, including without limitation the rights #
10 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell #
11 # copies of the Software, and to permit persons to whom the Software is #
12 # furnished to do so, subject to the following conditions: #
14 # The above copyright notice and this permission notice shall be included in #
15 # all copies or substantial portions of the Software. #
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
20 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER #
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING #
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER #
23 # DEALINGS IN THE SOFTWARE. #
25 #################################################################################
28 from SCons
import Conftest
32 opts
= Options ('options.cache')
34 if env
['PLATFORM'] == 'win32':
35 opts
.AddOptions (PathOption('prefix',
36 'Installation prefix',
37 'C:\\\\Syx', PathOption
.PathAccept
))
38 env
['bindir'] = env
['datadir'] = env
['rootdir'] = env
['libdir'] = '$prefix'
39 env
['plugindir'] = '$prefix\\\\lib'
40 env
['imagepath'] = '$prefix\\\\default.sim'
41 env
['includedir'] = '$prefix\\\\include'
42 env
['docdir'] = '$prefix\\\\doc'
46 'Installation prefix',
47 '/usr/local', PathOption
.PathAccept
),
48 PathOption('exec_prefix',
49 'Installation prefix for executables and object code libraries',
50 '$prefix', PathOption
.PathAccept
),
52 'Installation prefix for user executables',
53 '$exec_prefix/bin', PathOption
.PathAccept
),
55 'Installation prefix for machine-independent data',
56 '$prefix/share', PathOption
.PathAccept
),
58 'Installation prefix for all smalltalk data',
59 '$datadir/syx', PathOption
.PathAccept
),
60 PathOption('imagepath',
61 'Installation path for the default binary image',
62 '$rootdir/default.sim', PathOption
.PathAccept
),
64 'Installation prefix for documentation',
65 '$datadir/doc', PathOption
.PathAccept
),
67 'Installation prefix for object code libraries',
68 '$exec_prefix/lib', PathOption
.PathAccept
),
69 PathOption('plugindir',
70 'Installation prefix for object code plugins',
71 '$libdir/syx', PathOption
.PathAccept
),
72 PathOption('includedir',
73 'Installation prefix for C header files',
74 '$prefix/include', PathOption
.PathAccept
))
77 ('host', """cross-compile to build programs to run on HOST""", ''),
78 EnumOption ('endianness',
79 """Specify manually the endianness of the host machine (auto, big, little)""",
80 'auto', allowed_values
=('auto', 'little', 'big'), ignorecase
=True),
81 BoolOption ('shared', """Build shared library objects""", True),
82 BoolOption ('static', """Build static library objects""", True),
83 BoolOption ('plugins', """Build with plugins support""", True),
84 BoolOption ('bignum', """Build with infinite-precision numbers (needs gmp library)""", True),
85 BoolOption ('attach', """Attach a debugger for test failures""", False),
86 EnumOption ('debug', """Debug output and symbols""", 'normal',
87 allowed_values
=('no', 'normal', 'info', 'full'),
89 BoolOption ('profile', """Compile and link statically with -pg (gprof)""", False),
90 BoolOption ('iprofile', """Enable internal profiling""", False),
91 BoolOption ('doc', """Build reference documentation (needs Doxygen)""", True),
93 BoolOption ('GTK', """Build the syx-gtk plugin to support graphical user interfaces""", True),
94 BoolOption ('WINGUI', """Build the syx-wingui plugin to support native windows user interfaces""", True),
95 BoolOption ('READLINE', """Build the syx-readline plugin to add more console features""", True),
96 BoolOption ('X11', """Build the syx-x11 plugin to wrap the X11 library""", True))
99 opts
.Save ('options.cache', env
)
102 LINK
=os
.getenv ('LINK')
105 env
.Replace(CC
= env
.WhereIs (CC
))
107 env
.Replace(LINK
= env
.WhereIs (CC
))
109 env
.Replace(LINK
= env
.WhereIs (LINK
))
111 env
.Replace(AR
= env
.WhereIs (AR
))
113 # Custimize the help message
114 env
.Help (opts
.GenerateHelpText (env
) + """
115 Type: 'scons' to build Syx.
116 'scons doc=no' to create disable building the reference
119 'scons endianness=auto,big,little'
120 specify the endianness of the target
121 machine (default: auto)
123 'scons host=arch-os' cross-compile to build programs
124 to run on the specified host
126 'scons debug=no' release build with high optimization.
127 'scons debug=normal' add debug symbols (default).
128 'scons debug=info' display more messages.
129 'scons debug=full' trace the entire execution stack of Smalltalk.
130 'scons profile=yes' compile and link statically with -pg (gprof).
131 'scons test' to test Syx.
132 'scons test attach=yes'
133 to test Syx and attach a debugger if a
136 'scons install' to install Syx.
137 'scons sdist' to create a directory with source distribution.
138 'scons bdist' to create a directory with binary distribution
139 (implies 'scons install').
144 def check_endianness (ctx
):
145 ctx
.Message ("Checking for machine endianness...")
146 if env
['endianness'] != 'auto':
147 if env
['endianness'] == 'big':
148 Conftest
._Have
(ctx
, 'WORDS_BIGENDIAN', 1)
150 Conftest
._Have
(ctx
, 'WORDS_BIGENDIAN', 0)
151 ctx
.Result (env
['endianness'])
154 ret
= ctx
.TryRun ("""
156 int main (int argc, char **argv)
158 static const int i = 1;
159 if ((*(char*)&i) == 0)
169 Conftest
._Have
(ctx
, 'WORDS_BIGENDIAN', 1)
171 Conftest
._Have
(ctx
, 'WORDS_BIGENDIAN', 0)
175 print "Can't build Syx without determining machine endianness"
179 def check_inline (ctx
):
180 ctx
.Message ("Checking for inline...")
181 ret
= ctx
.TryRun ("""
183 inline int foo () { return 0; }
184 int main () { return foo (); }
187 Conftest
._Have
(ctx
, 'HAVE_INLINE', 1)
190 Conftest
._Have
(ctx
, 'HAVE_INLINE', 0)
193 def check__inline (ctx
):
194 ctx
.Message ("Checking for __inline...")
195 ret
= ctx
.TryRun ("""
196 __inline int foo () { return 0; }
197 int main () { return foo (); }
200 Conftest
._Have
(ctx
, 'HAVE__INLINE', 1)
203 Conftest
._Have
(ctx
, 'HAVE__INLINE', 0)
206 def check__inline__ (ctx
):
207 ctx
.Message ("Checking for __inline__...")
208 ret
= ctx
.TryRun ("""
209 __inline__ int foo () { return 0; }
210 int main () { return foo (); }
213 Conftest
._Have
(ctx
, 'HAVE__INLINE__', 1)
216 Conftest
._Have
(ctx
, 'HAVE__INLINE__', 0)
219 conf
= Configure (env
, custom_tests
={ 'CheckEndianness' : check_endianness
,
220 'CheckInline' : check_inline
,
221 'Check__Inline': check__inline
,
222 'Check__Inline__': check__inline__
}, config_h
="syx/syx-config.h")
228 cenv
= env
.Clone (ENV
=os
.environ
)
230 print 'Cross-compile to run on %s...' % env
['host']
232 tool
= env
['host']+'-gcc'
233 env
['CC'] = cenv
.WhereIs (tool
)
234 print 'Checking for %s... %s' % (tool
, env
['CC'])
236 print "Can't find a valid C compiler"
239 tool
= env
['host']+'-ar'
240 env
['AR'] = cenv
.WhereIs (tool
)
241 print 'Checking for %s... %s' % (tool
, env
['AR'])
243 tool
= env
['host']+'-as'
244 env
['AS'] = cenv
.WhereIs (tool
)
245 print 'Checking for %s... %s' % (tool
, env
['AS'])
247 tool
= env
['host']+'-ranlib'
248 env
['RANLIB'] = cenv
.WhereIs (tool
)
249 print 'Checking for %s... %s' % (tool
, env
['RANLIB'])
251 tool
= env
['host']+'-windres'
252 env
['RC'] = cenv
.WhereIs (tool
)
253 print 'Checking for %s... %s' % (tool
, env
['RC'])
255 if 'wince' in env
['host']:
256 env
.MergeFlags("-DWINCE")
261 print 'Mandatory headers...'
263 for h
in ['string.h', 'sys/stat.h', 'time.h', 'stdio.h', 'assert.h', 'fcntl.h',
265 if not conf
.CheckCHeader (h
):
266 print "Can't build Syx without %s header!" % h
270 print 'Optional headers...'
272 for h
in ['stdarg.h', 'byteswap.h', 'errno.h', 'unistd.h', 'stdint.h', 'sys/time.h']:
273 conf
.CheckCHeader (h
)
274 for t
in ['int64_t']:
275 conf
.CheckType (t
, '#include <stdint.h>', 'c')
277 if env
['PLATFORM'] == 'win32':
278 have_windows_h
= conf
.CheckCHeader ('windows.h')
281 print 'Mandatory functions...'
283 for f
in ['strtol', 'strtod']:
284 if not conf
.CheckFunc (f
):
285 print "Can't build Syx without %s function!" % f
288 if env
['PLATFORM'] == 'win32':
290 if 'wince' in env
['host']:
292 conf
.CheckLib ('coredll')
294 if not conf
.CheckLibWithHeader (lib
, 'winsock2.h', 'c', 'select(0, NULL, NULL, NULL, NULL);'):
295 print "Can't build Syx without select function!"
298 if not conf
.CheckFunc ('select'):
299 print "Can't build Syx without select function!"
302 if not conf
.CheckLibWithHeader ('m', 'math.h', 'c', 'floor((double)3.4) == (double)3.0;'):
303 print "Can't build Syx without the math library!"
306 if not conf
.CheckEndianness ():
309 "Assume we have __inline__"
310 if not (conf
.CheckInline () or conf
.Check__Inline () or conf
.Check__Inline__ ()) and env
['host']:
311 env
.MergeFlags ("-DHAVE__INLINE__")
314 print 'Optional functions...'
316 for f
in ['fstat', 'access', 'getenv', 'perror', 'signal']:
320 if not conf
.CheckLibWithHeader ('gmp', 'gmp.h', 'c', 'mpz_t t; mpz_init (t); mpz_clear (t);'):
321 print "WARNING: gmp library not found. Multiple-precision numbers won't be supported"
324 if (env
['PLATFORM'] == 'win32' and have_windows_h
) or conf
.CheckLibWithHeader ('dl', 'dlfcn.h', 'c', 'dlopen(0, 0);'):
325 env
.MergeFlags ('-DWITH_PLUGINS')
327 print 'WARNING: building without plugins support'
328 env
['plugins'] = False
336 env
.MergeFlags ('-Wall -Wno-strict-aliasing -I#.')
337 env
.MergeFlags (os
.getenv('CFLAGS'))
338 env
['LINKFLAGS'].append (os
.getenv('CFLAGS'))
340 if env
['PLATFORM'] == 'darwin':
341 env
.MergeFlags ('-fno-common')
344 env
.MergeFlags ('-DSYX_PROFILE')
346 if 'wince' in env
['host']:
347 env
.MergeFlags ('-DROOT_PATH="" -DIMAGE_PATH="default.sim" -DPLUGIN_PATH="lib"')
348 elif env
['PLATFORM'] == 'win32':
349 env
.MergeFlags ('-DROOT_PATH="." -DIMAGE_PATH="default.sim" -DPLUGIN_PATH="lib"')
351 env
.MergeFlags ('-DROOT_PATH="$rootdir" -DIMAGE_PATH="$imagepath" -DPLUGIN_PATH="$plugindir"')
353 if env
['debug'] == 'no':
354 env
.MergeFlags ('-O3')
355 elif env
['debug'] == 'normal':
356 env
.MergeFlags ('-g -O2')
357 elif env
['debug'] == 'info':
358 env
.MergeFlags ('-g -O -DSYX_DEBUG_INFO')
359 elif env
['debug'] == 'full':
360 env
.MergeFlags ('-g -O -DSYX_DEBUG_INFO -DSYX_DEBUG_FULL')
362 if env
['PLATFORM'] == 'win32':
363 env
.MergeFlags ('-DWINDOWS')
365 distdir
= '#syx-0.1.7'
369 def builder_syxinstall (target
, sources
):
370 t1
= env
.Install (target
, sources
)
371 env
.Alias ('install', t1
)
372 if env
['PLATFORM'] != 'win32':
373 t
= env
.Install (os
.path
.join (distdir
, target
), sources
)
374 env
.Alias ('bdist', t
)
377 setattr (env
, 'SyxInstall', builder_syxinstall
)
381 env
.MergeFlags ('-L#build/lib')
384 env
['LINKFLAGS'].append('-pg')
385 env
.MergeFlags ('-pg')
386 env
['shared'] = False
389 env
.BuildDir ('build/lib', 'syx', False)
390 env
.SConscript (dirs
=['build/lib'], exports
=['env', 'distdir'])
392 env
.BuildDir ('build/bin', 'src', False)
393 env
.SConscript (dirs
=['build/bin'], exports
=['env', 'distdir'])
395 env
.BuildDir ('build/plugins', 'plugins', False)
396 env
.SConscript (dirs
=['build/plugins'], exports
=['env', 'distdir'])
398 env
.SConscript (dirs
=['tests'], exports
=['env', 'distdir'])
399 env
.SConscript (dirs
=['examples'], exports
=['env', 'distdir'])
403 env
['doxygen'] = env
.WhereIs ('doxygen')
404 if env
['doc'] and env
['doxygen']:
405 target
= env
.Command ('doc/reference', '#Doxyfile', '$doxygen $SOURCES')
407 path
= os
.path
.join (env
['docdir'], distdir
[1:])
408 t1
= env
.SyxInstall (path
, target
)
409 env
.Alias ('install', t1
)
410 env
.Clean ('install', t1
)
414 kernel_sources
= glob
.glob ('st/kernel/*.st')
415 path
= os
.path
.join (env
['rootdir'], 'st', 'kernel')
416 env
.SyxInstall (path
, kernel_sources
)
418 foreign_sources
= glob
.glob ('st/foreign/*.st')
419 path
= os
.path
.join (env
['rootdir'], 'st', 'foreign')
420 env
.SyxInstall (path
, foreign_sources
)
422 if env
['PLATFORM'] == 'posix':
423 desktoppath
= os
.path
.join (env
['datadir'], 'applications')
424 desktopapps
= [os
.path
.join ('#share', 'syx.desktop'), os
.path
.join ('#share', 'syximage.desktop')]
425 env
.SyxInstall (desktoppath
, desktopapps
)
427 path
= os
.path
.join (env
['datadir'], 'pixmaps')
428 env
.SyxInstall (path
, os
.path
.join ('#share', 'syx.png'))
429 env
.SyxInstall (path
, os
.path
.join ('#share', 'gnome-application-syx.png'))
431 path
= os
.path
.join (env
['datadir'], 'application-registry')
432 env
.SyxInstall (path
, os
.path
.join ('#share', 'syx.applications'))
434 path
= os
.path
.join (env
['datadir'], 'mime-info')
435 env
.SyxInstall (path
, os
.path
.join ('#share', 'syx.keys'))
436 mimepath
= os
.path
.join (env
['datadir'], 'mime')
437 mimesource
= os
.path
.join ('#share', 'syx.xml')
438 env
.SyxInstall (os
.path
.join (mimepath
, 'packages'), mimesource
)
440 update_mime_database
= env
.WhereIs ('update-mime-database')
441 if update_mime_database
:
442 target
= env
.Command (mimepath
, mimesource
, 'update-mime-database $TARGET')
443 env
.Alias ('install', target
)
445 update_desktop_database
= env
.WhereIs ('update-desktop-database')
446 if update_desktop_database
:
447 target
= env
.Command (desktoppath
, desktopapps
, 'update-desktop-database')
448 env
.Alias ('install', target
)
450 # Source distribution
452 path
= os
.path
.join (distdir
, 'st', 'kernel')
453 target
= env
.Install (path
, kernel_sources
)
454 env
.Alias ('sdist', target
)
456 path
= os
.path
.join (distdir
, 'st', 'foreign')
457 target
= env
.Install (path
, foreign_sources
)
458 env
.Alias ('sdist', target
)
460 sources
= ['INSTALL', 'README', 'AUTHORS', 'ChangeLog', 'COPYING', 'SConstruct', 'TODO', 'NEWS', 'Doxyfile',
461 'README-BINARIES', 'syx.sln', 'syx.vcproj', 'makefile.vc',
462 'autogen.sh', 'compile', 'missing', 'mkinstalldirs', 'ltmain.sh', 'install-sh',
463 'configure', 'configure.ac', 'aclocal.m4', 'config.guess', 'config.sub', 'depcomp',
464 'Makefile.in', 'Makefile.am']
465 target
= env
.Install (distdir
, sources
)
466 env
.Alias ('sdist', target
)
468 sources
= ['#share/syx.desktop', '#share/syx.png', '#share/gnome-application-syx.png',
469 '#share/syx.applications', '#share/syx.keys', '#share/syx.xml', '#share/syximage.desktop']
470 target
= env
.Install (os
.path
.join (distdir
, 'share'), sources
)
471 env
.Alias ('sdist', target
)
473 target
= env
.Install (os
.path
.join (distdir
, 'doc', 'reference', 'html', 'extras'), '#doc/reference/html/extras/footer.html')
474 env
.Alias ('sdist', target
)
476 # Binary distribution
478 target
= env
.Install (distdir
, '#README-BINARIES')
479 env
.Alias ('bdist', target
)