SPRAAK
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
Installation Guide

Requirements

SPRAAK has the following dependencies:

Python (version 2.5 or higher)
All scripts in SPRAAK are written in Python2
A Posix-compliant thread library
To speed up the processing, some components in SPRAAK can make use of multiple threads. Currently, SPRAAK uses the POSIX standard.

The functionality of SPRAAK can be further extended when the link libraries and header files for the following components are available:

python
When not only the Python excutable but also the Python header files and library are installed, Python functionality can be made available from with the SPRAAK system (e.g. a Python signal pre-processing block, a Python lattice post-processing block, ...).
zlib
This library allows reading and writing gzip-compressed files.
libbz2
This library allows reading and writing bzip2-compressed files.
readline
This library allows reading allow and interactive command line in spr_cwr_main
gcrypt
This library allows reading and writing encrypted files.

For building the SPRAAK binaries, SPRAAK also relies on:

A C99 compliant compiler
Note
None of the current compilers (gcc, visual-C, ...) are 100% C99 compliant. However, since SPRAAK avoids the more 'difficult' C99 constructs, this is not a problem.
SPRAAK works optimally in combination with gcc and clang/llvm (even on Windows, we use gcc; see below on how to install a working gcc-based compilation enviroment on Windows).
Scons (version 1.1 or higher)
Scons is a Python based make-system.

For building the documentation (optional), SPRAAK relies on:

Doxygen (1.5 or higher)
Doxygen is used to create the documentation.
Graphviz (dot)
Doxygen cat use 'dot' to draw dependency graphs. If 'dot' cannot be found, the dependency graphs will be omitted from the documentation.
pdflatex
Pdflatex can be used for creating the manuals in pdf format.

Linux (and more in general *nix) system

On all *nix distributions on which SPRAAK was tested, all dependencies could be solved with standard packages that came with the *nix distribution. See the documentation of the distribution on how to install additional packages.

Windows

For compiling SPRAAK on Windows, we advise the MSYS2 build enviroment (good for building SPRAAK as native Windows applications, but not a complete *nix on Windows enviroment). Optionally, the Cygwin environment (a close to complete *nix enviroment on Windows) can be used to compile the SPRAAK applications as Cygwin applications (untested) and/or for deploying SPRAAK on Windows machines (either using the native Windows binaries or the Cygwin binaries).

Installing the MSYS2 64 bits build environment:
  • Download and install 'msys2-x86_64-*.exe' from www.msys2.org
  • Follow the instructions on www.msys2.org to update all components.
  • Install the extra components needed to build SPRAAK:
    pacman -S scons doxygen mingw-w64-x86_64-clang mingw-w64-x86_64-zlib mingw-w64-x86_64-bzip2 mingw-w64-x86_64-winpthreads mingw-w64-x86_64-readline mingw-w64-x86_64-termcap
  • Optional: install extra components to facilitate developing and testing in msys2
    pacman -S vim openssh man diffutils tcsh
    # switch back to dumb path completion if you find the smart completion behaves randomly
    pacman -R bash-completion
  • To compile SPRAAK, start the 'MSYS2 MingW 64-bit' environment from the 'MSYS2 64bit' environment
Installing the MSYS2 32 bits build environment:
  • Download and install 'msys2-i686-*.exe' from www.msys2.org
  • Follow the instructions on www.msys2.org to update all components.
  • Install the extra components needed to build SPRAAK:
    pacman -S scons doxygen mingw-w64-i686-clang mingw-w64-i686-zlib mingw-w64-i686-bzip2 mingw-w64-i686-winpthreads mingw-w64-i686-readline mingw-w64-i686-termcap
  • Optional: install extra components to facilitate developing and testing in msys2
    pacman -S vim openssh man diffutils tcsh
    # switch back to dumb path completion if you find the smart completion behaves randomly
    pacman -R bash-completion
  • To compile SPRAAK, start the 'MSYS2 MingW 32-bit' environment from the 'MSYS2 32bit' environment
Note
Both Graphviz (dot) and pdflatex are missing in the msys2 environment, and hence SPRAAK's documentation will be somewhat less rich when build on Windows.
Due to a bug in Python/scons, the compile process may try to write temporary files in 'C:\Windows', and due to the more strict security features in Windows 7/8/10, this directory is no longer writable for everyone.
Solution1: Start the MSYS2 shell in 'administrator' mode (this does not work if one wants to install SPRAAK on a network drive since the administrator cannot access network drives).
Solution2: Use cygwin (MSYS2 does not map ownership by default – see the MSYS2 documentation for details on how to change this behavior) to change the ownership of '/cygdrive/c/Windows'
chown ${USER}:${USER} /cygdrive/c/Windows

OSX / MacOS

SPRAAK can be compiled on OSX. The required extra tools can be readily obtained via macports and other open software package managers such as fink. Hereunder, the different steps when using macports are described.

Xcode
Install Xcode via the App-store and run Xcode (the last step is required to complete the installation).
Xcode command line tools
Install the command line tools by opening a command window and running the following command
xcode-select --install
If this fails, you can also try to install the command line tools from the developer website: https://developer.apple.com/download/more/
Macports
Download and install the macports package for your version of OSX from one of these sources
  1. https://guide.macports.org/
  2. https://github.com/macports/macports-base/releases/
Update and install packages
Update and install the packages needed to compile SPRAAK by opening a command terminal and issuing the following commands:
sudo port selfupdate
sudo port upgrade outdated
sudo port install scons zlib libedit
# zlib and libedit are also needed by scons, so you don't even need to request for their installation
If you intend to use python interactively, then you may also have to install the following package (see the warnings when installing python2.7 if this is needed or not)
sudo port install py27-readline
To create the documentation, you need to install the following extra packages
sudo port install doxygen graphviz
Install SPRAAK
Install SPRAAK using scons as explained in Configuring & installing
Note
installing on a mounted disk may cause clang (the compiler used by OSX) to fail, so first try installing SPRAAK on a native OSX volume before filling a bug report

Other/new platforms

SPRAAK depend on standard libraries and open-source tools only, so migration to other platforms should be possible. Hereunder, we list some of the more challenging tools to obtain.

Scons
Scons can be donwloaded from http://www.scons.org. Choose the appropriate download type in the right column. If you choose the tarball, you can proceed as follows:
tar zxvf scons-*.tar.gz
cd scons-*
Read the README file. It explains the installation procedure and prerequisites.
As a quickstart, you can type
python setup.py install --prefix=$SPRAAK_BASE_DIR/scons_base
to install scons in the directory referred to above as $SPRAAK_BASE_DIR/scons_base
Posix threads
The Posix thread library is available by default on all unix systems.
On windows, you can use the pthreads-win32 library: see sourceware.org/pthreads-win32/
Doxygen
Doxygen can be downloaded directly from www.doxygen.org
Graphviz (dot)
Doxygen cat use 'dot' to draw dependency graphs. If 'dot' cannot be found, the dependency graphs will be omitted from the documentation. For Linux system, we advise to use the Graphviz package that commes with the distribution. Alternatively, one can download Graphviz from http://www.graphviz.org/ At the time of writing no Cygwin package for Graphviz was available. It should be possible to manually build the Graphviz tools from source in Cygwin, but your mileage may vary.
pdflatex
Pdflatex can be used for creating the manuals in pdf format and can be found in lexlive.

Configuring & installing

SPRAAK uses 'scons' (a Python build-tool) the compile and install the software.

All user configurable settings (location of the different files, compiler options, ...) are grouped in the file 'config.py' in the root directory of the SPRAAK package. See the comments in config.py and the section Package structure for more info.

The default configuration of SPRAAK allows multiple versions (32 and 64 bits versions; different operating systems and/or processors; debug, release and profile versions; ...) to be installed and maintained in parallel on a single shared file system. Hence, the default directory structure differs somewhat from what is typical in packages ment for local installation only. See Package structure for more details.

To see the all possible build options, run

scons -h

Calling

scons install

will make a build using the default option (CONFIG=release, COMPILER=gcc, ARCH=auto, EXPORT=developer). This results in a library and executables that are aimed for final release (don't contain debug, profile, ... information). At the same time, the header files and the documentation are aimed at developers, i.e. they expose everything.

Compiling SPRAAK without the documentation can be done with:

scons install-ltd

By default, the resulting SPRAAK binaries will run on recent CPUs (less than 10 years old) only. If older CPUs must be supported, add the 'ARCH=compatible' option. On the other hand, by targetting a specific CPU (adding option 'ARCH=native'), somewhat faster binaries can be obtained at the expense of compatibility.

On Linux, the clang/llvm compiler results in somewhat faster (and smaller) binaries, especially on modern CPUs (with support for 256bit vectors or better).

scons COMPILER=clang ARCH=native install

In order to be able to run the programs, users have to adjust their login scripts so that the PATH environment variable includes the location of the SPRAAK executables. On systems which do not support locating dynamic library files relative w.r.t. the executables, the LD_LIBRARY_PATH environment variable (or equivalent) must be adjusted to include the location of the SPRAAK library as well.

Note
The spr_version.py script can set/adjust all necassary environment variables on supported platforms.

Testing the software

The examples directory contains a series of example experiments that may be used to test if the software behaves correctly. See Introduction and Background for more details on the different examples and the expected outcome.

Package structure

The source files for the SPRAAK package are organized as follow:

./src/lib/
The C-code that will be compiled to form the SPRAAK library. The documentation and some additional information for constructing headers files is embedded in the C-code.
./src/prog/
The C-code that will be compiled to form the SPRAAK executables. The documentation is embedded in the C-code.
./src/doc/
Free-standing documentation (i.e. documentation that has no 1-to-1 link to any of files in ./src/{lib,prog}).
./scripts/spr_parser.py
The parser to extract header files and documentation for the C source files and to create the object oriented glue code for each class.
./scripts/spr_*
High level Python scripts in SPRAAK framework.
./scripts/spraak/
A library of Python code, used by the SPRAAK scripts.
./SConstruct
The master build-file (using scons).
./config.py
Build-file containing all user configurable options.
./sysdep.py
Build-file containing the code to detect system dependent features, bugs, libraries, ...

Other files, related to but not an integrated part of SPRAAK, can be found in:

./src_ext/
Extra C-code for interfacing SPRAAK (library and/or file IO) with other environments such as Matlab.
./scripts/alien/
High level scripts that have been found to be useful in combination with SPRAAK

Upon building (using the default settings), the following directory structure will be created:

./build/
All items derived by the build process: header files, documentation in intermediate form, object files, libraries, ...
./build/include/<lvl>/spraak/
The include files with all items at export level <lvl> or higher.
./build/include/<lvl>/spraak_classdef/
The class specific definition derived by the parser with all items at export level <lvl> or higher.
./build/include/<arch>/spraak/
Architecture dependent include files.
./build/parse_tmp/
All information extracted by the parser (spr_parser.py) stored in raw format.
./build/doc_tmp/<lvl>/
The documentation in Doxygen format as extracted by the parser; contains only the items at export level <lvl> or higher.
./build/doc/<lvl>/html/
The documentation in html format as derived by Doxygen.
./build/doc/<lvl>/latex/
The documentation in pdflatex format as derived by Doxygen.
./build/<arch>/obj/
Object files created during the build process.
./build/<arch>/lib/
The library file.
./build/<arch>/bin/
The executables.
./export
All installed items (scripts, executables, libraries, header files and documentation).
Note
The default setup expect that the package maintainer only installs (scons install) the desired export level <lvl> for his environment. If one wants to install multiple export levels (or make sure only a given export level can be installed), the file config.py must be adjusted!
./export/bin/spr_*
The (Python) scripts.
./export/bin/spraak/
The Python library used by the scripts.
./export/bin/<arch>/
The executables.
./export/lib/<arch>
The library file.
./export/include/
Include files.
./export/doc/html/
Documentation in html format.

The export level <lvl> can have the following values:

pub_hi
header files, documentation, library aimed at users.
pub_lo
header files, documentation, library aimed at programmers.
devel
header files, documentation, library aimed at developers.

The <arch> infix combines information about the operating system, CPU and configuration (debug, release, ...) into a single name.

In order to facilitate package management, SPRAAK also allows for setting symbolic links from the 'export' directories to some final destination directories (e.g. /usr/bin, /usr/lib and /usr/include). This way, all files from the SPRAAK package can be kept in a single directory while users still can have access to the full functionality without having the expand their PATH, LD_LIBRARY_PATH, ...). Furthermore, when SPRAAK is removed, upgraded, ... the worst that can happen is some dangling links in the /usr/bin, /usr/lib, and /usr/include/ directories. See the comments in config.py for more info.

config.py

1 # This file defines all user configurable options.
2 # Since all options are defined using standard python code, platform specific
3 # code, complex customization and even cross-compiling should be possible.
4 
5 # Some useful variables which are set when calling this code:
6 # - spraak.os operating system (linux, windows, osx, ...)
7 # - spraak.cpu cpu family (x86_64, i686, power, ...)
8 # - spraak.cc default compiler for this platform (gcc, icc, cc, ...)
9 # - spraak.cc_ver version number of the default compiler [major minor ...]
10 # - spraak.config string describing the requested configuration, e.g. "release", "debug", "regression", "profile", ...
11 # - spraak.arch string describing the target architecture+config
12 # set to spraak.os+'_'+spraak.cpu+('' if(spraak.config=="release") else '_'+spraak.config)
13 # Note: this configuration script is allowed to change the above
14 # variables (e.g. forcing 32bits executables on a 64bit platform) but
15 # incorrect/inconsistent values are likely to lead to unexpected behavior
16 
17 
18 ##
19 ## destination directories for the final install
20 ##
21 # Windows is always a bit different :-)
22 not_windows = (spraak.os!="Windows")
23 # base installation directory
24 spraak.prefix = '.'
25 # directory for architecture independent executables (scripts)
26 spraak.bindir = spraak.prefix+'/bin'
27 # directory for architecture dependent executables
28 spraak.bindir_arch = spraak.prefix+'/bin/'+spraak.arch
29 # directory for architecture independent libraries (scripts)
30 spraak.libdir = (spraak.prefix+'/lib' if(not_windows) else spraak.bindir)
31 # directory for architecture dependent libraries; must be identical to 'bindir_arch' on some platforms (e.g. Windows)
32 spraak.libdir_arch = (spraak.prefix+'/lib/'+spraak.arch if(not_windows) else spraak.bindir_arch)
33 # directory for include files
34 spraak.includedir = spraak.prefix+'/include'
35 # documentation directories (two formats)
36 spraak.docdir_html = spraak.prefix+'/doc/html'
37 spraak.docdir_pdf = spraak.prefix+'/doc/pdf'
38 # read-only architecture-independent data
39 spraak.datadir = spraak.prefix+'/data'
40 # In order to keep all files form spraak in a single subdirectory, the build
41 # process allows setting symbolic links from the default system bin, lib and
42 # include directories to the package specific bin(_arch), lib(_arch) and
43 # include directories specified above.
44 # Set to None if not wanted.
45 spraak.bindir_link = None
46 spraak.libdir_link = None
47 spraak.includedir_link = None
48 # some file systems do not support symbolic links, and hence the files must by copied
49 spraak.symlink_support = not_windows
50 
51 
52 ##
53 ## build directory (the build sub-directory structure is not configurable)
54 ##
55 spraak.builddir = spraak.prefix+'/build'
56 
57 
58 ##
59 ## configurable options
60 ##
61 
62 # typical number of threads (CPU cores available)
63 # 0 : compile single threaded (no support for multi-threading at all)
64 # 1 : optimize for single threaded operation but allow multiple threads
65 # N : optimize for N concurrent threads
66 spraak.Nthreads = 2
67 
68 
69 ##
70 ## external libraries that provide additional functionality
71 ##
72 
73 # possible values:
74 # - None : functionality is not desired
75 # - "auto" : automatic scan for the library and/or headers
76 # - pull/path/name : exact location (directory) of the header files(s)
77 # - pull/path/name/lib : exact location (file without extension and without 'lib' prefix) of the library
78 
79 # python: use python functionality in the C-code such as python pre-processing
80 # or lattice processing modules (NIY)
81 spraak.python = None
82 spraak.python_h = None
83 
84 # zlib: handling gzipped files
85 spraak.zlib = "auto"
86 spraak.zlib_h = "auto"
87 
88 # bzlib: handling bzip2-compressed files (NIY)
89 spraak.bzlib = None
90 spraak.bzlib_h = None
91 
92 # flac: handling flac-compressed audio (NIY)
93 spraak.flac = None
94 spraak.flac_h = None
95 
96 # gcrypt: gnu privacy guard cryptography -- strong encryption of data (NIY)
97 spraak.gcrypt = None
98 spraak.gcrypt_h = None
99 
100 # arpack: handling larger sparse (or structured) eigen/singular value problems (NIY)
101 spraak.arpack = "auto"
102 spraak.arpack_h = "auto"
103 
104 # readline: read lines from the terminal with editing
105 spraak.readline = "auto"
106 spraak.readline_h = "auto"
107 
108 # editline: read lines from the terminal with editing
109 spraak.editline = "auto"
110 spraak.editline_h = "auto"
111 
112 
113 ##
114 ## compiler & linker flags
115 ##
116 
117 def select_best_match(opt_dict,spraak):
118  # the compiler options are typically architecture dependent and hence are best
119  # specified using a dictionary having as key a string containing the following
120  # fields separated with a single space:
121  # spraak.os spraak.cpu spraak.cc spraak.cc_ver[0] spraak.config
122  # Don't cares are indicated with '*'.
123  sel = [spraak.os,spraak.cpu,spraak.cc,str(spraak.cc_ver[0]),spraak.config];
124  best_opt = None;
125  best_cnt = 9;
126  for opt_str,opt_val in opt_dict.iteritems():
127  cnt = 6;
128  for ndx,val in enumerate(opt_str.split()):
129  if(val == sel[ndx]):
130  cnt -= 1;
131  elif(val != "*"):
132  opt_val = None;
133  if((opt_val!=None) and (cnt<best_cnt)):
134  best_opt = opt_val;
135  best_cnt = cnt;
136  if(best_opt == None):
137  print "ERROR No match found for %s %s %s %s %s"%(spraak.os,spraak.cpu,spraak.cc,str(spraak.cc_ver[0]),spraak.config)
138  spraak.signal_error = 1;
139  return(best_opt);
140 
141 
142 # Optimization & configuration flags
143 # Note1: Currently -pic (or -fpie) MUST be specified when compiling programs.
144 # If not, the programs will duplicate the public variables from the libraries
145 # resulting in the program routines using one version of the public variables
146 # and the library routines using another version.
147 
148 # Note2: the -fno-tree-vectorize flag avoid problems on 32bits Windows systems when compiling with MingW.
149 # Without this flag the compiler generates movaps instructions (move 4 quadwords, assumed correct alignment).
150 # This instruction requires the arguments to be aligned on a 16 byte boundary, but without the flag, MingW (i686-w64-mingw32-gcc v4.7.3)
151 # generates a spraak.ddl library which (when used in python) violates this requirement.
152 # This this leads to a segmentation fault (only apparent when using gdb - otherwise it seems to be trapped but not reported by python).
153 # Whether this is a compiler bug or a result of loading the dll with the ctypes dll method in python (32 bits, maybe not compiled with the O3 flag) is not clear.
154 # The -fno-tree-vectorize flag suppresses the generation of this # movaps instruction and solves the segmentation fault.
155 # Note that the moveups instruction could have been generated (this does not have the mentioned restriction) which would not lead to a segmentation fault.
156 # This instruction is equally fast as moveaps on modern day intel cpu's.
157 
158 cflags_opt = { "* * gcc * release" : "-O2",
159  "* * gcc * debug" : "-O2 -g",
160  "* * gcc * regression" : "-O2 -g -DSPR_REGRESSION=1",
161  "* * gcc * profile" : "-O2 -pg",
162  "* * gcc * coverage" : "-O1 -ftest-coverage -fprofile-arcs",
163  "* x86_64 gcc * release" : "-O3 -fno-keep-static-consts -maccumulate-outgoing-args -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
164  "* x86_64 gcc * debug" : "-g -O3 -maccumulate-outgoing-args -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
165  "* i686 gcc * release" : "-O3 -fno-keep-static-consts -maccumulate-outgoing-args -fstrict-aliasing -fomit-frame-pointer -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
166  "* i686 gcc * debug" : "-g -O3 -maccumulate-outgoing-args -fstrict-aliasing -fomit-frame-pointer -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
167  "Windows i686 gcc * release" : "-O3 -fno-tree-vectorize -fno-keep-static-consts -maccumulate-outgoing-args -fstrict-aliasing -fomit-frame-pointer -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
168  "Windows i686 gcc * debug" : "-g -O3 -fno-tree-vectorize -maccumulate-outgoing-args -fstrict-aliasing -fomit-frame-pointer -ffast-math -mieee-fp -funroll-loops -fpeel-loops -funswitch-loops -finline-limit=250 --param max-unroll-times=4",
169  "OSX * gcc * release" : "-O3 -ffast-math -mieee-fp", # is, depending on the version of the OS either gcc or clang
170  "OSX * gcc * debug" : "-g -O3 -ffast-math -mieee-fp", # is, depending on the version of the OS either gcc or clang
171  "* * clang * release" : "-O3 -ffast-math",
172  "* * clang * debug" : "-g -O3 -ffast-math",
173  "* x86_64 clang * release" : "-O3 -ffast-math -mieee-fp",
174  "* x86_64 clang * debug" : "-g -O3 -ffast-math -mieee-fp",
175  "* i686 clang * release" : "-O3 -ffast-math -mieee-fp",
176  "* i686 clang * debug" : "-g -O3 -ffast-math -mieee-fp",
177  }
178 # we target processors of less then 10 years old, so we require at least support for sse3 on Intel/AMD processors (the gain with going for sse4.1 is negligible, and AVX requiring is too agressive)
179 cpu_x86_nbits = {"i686":"-m32 ", "x86_64":"-m64 "}.get(spraak.cpu,"");
180 cpu_x86_nbits = {"m32":"-m32 ", "m64":"-m64 "}.get(env["CROSS"],cpu_x86_nbits);
181 arch_gcc_i686 = cpu_x86_nbits + {"auto":"-march=core2 -mtune=core2 -malign-double ", "native":"-march=native -mtune=native -malign-double ", "compatible":""}[env["ARCH"]];
182 arch_clang_i686 = cpu_x86_nbits + {"auto":"-march=core2 -mtune=core2 ", "native":"-march=native -mtune=native ", "compatible":""}[env["ARCH"]];
183 arch_x86 = cpu_x86_nbits + {"auto":"-march=core2 -msse3 -mtune=native ", "native":"-march=native -mtune=native ", "compatible":""}[env["ARCH"]];
184 
185 cflags_cfg = { "* * * * *" : "",
186  "* * gcc * *" : "-std=gnu99 -fpic -fsigned-char",
187  "* i686 gcc * *" : "-std=gnu99 -fpic " + arch_gcc_i686 + "-W -Wall -Wno-uninitialized -Wno-unused-value -fsigned-char -fasynchronous-unwind-tables",
188  "Windows i686 gcc * *" : "-std=gnu99 " + arch_gcc_i686 + "-W -Wall -Wno-uninitialized -Wno-unused-value -fsigned-char",
189  "* x86_64 gcc * *" : "-std=gnu99 -fpic " + arch_x86 + "-W -Wall -Wno-uninitialized -Wno-unused-value -fsigned-char -fasynchronous-unwind-tables",
190  "Windows x86_64 gcc * *" : "-std=gnu99 " + arch_x86 + "-W -Wall -Wno-uninitialized -Wno-unused-value -fsigned-char",
191  "* i686 clang * *" : "-std=c99 -fpic " + arch_clang_i686 + "-W -Wall -Wno-incompatible-pointer-types-discards-qualifiers -fsigned-char -fasynchronous-unwind-tables",
192  "Windows i686 clang * *" : "-std=c99 " + arch_clang_i686 + "-W -Wall -Wno-incompatible-pointer-types-discards-qualifiers -fsigned-char",
193  "* x86_64 clang * *" : "-std=c99 -fpic " + arch_x86 + "-W -Wall -Wno-incompatible-pointer-types-discards-qualifiers -fsigned-char -fasynchronous-unwind-tables",
194  "Windows x86_64 clang * *" : "-std=c99 " + arch_x86 + "-W -Wall -Wno-incompatible-pointer-types-discards-qualifiers -fsigned-char",
195  }
196 cflags_shobj ={ "* * * * *" : "-DSPR_INCL_LVL=-1",
197  "Linux * * * *" : "-DSPR_INCL_LVL=-1 -fvisibility=hidden -fno-common",
198  "OSX * * * *" : "-DSPR_INCL_LVL=-1 -fno-common",
199  "Windows * * * *" : "-DSPR_INCL_LVL=-1 -fno-common",
200  }
201 spraak.cflags = select_best_match(cflags_cfg,spraak)+' '+select_best_match(cflags_opt,spraak)
202 spraak.shcflags = select_best_match(cflags_shobj,spraak)+' '+spraak.cflags
203 
204 # extra libraries (and header files) for the linker (and compiler)
205 ldlibs = { "Linux * * * *" : "m dl rt pthread",
206  "Linux * gcc * *" : "m dl rt pthread gcc_s",
207  "OSX * * * *" : "m dl pthread",
208  "Windows * * * *" : "m wsock32 winmm",
209  }
210 ldpath = { "* * * * *" : "",
211  "Windows * gcc * *" : "extern/lib",
212  }
213 ldcpph = { "* * * * *" : "",
214  "Windows * gcc * *" : "extern/include",
215  }
216 spraak.ldlibs = select_best_match(ldlibs,spraak)
217 spraak.ldpath = select_best_match(ldpath,spraak)
218 spraak.ldcpph = select_best_match(ldcpph,spraak)
219 
220 # other linker flags for linking programs / making the dynamic library
221 
222 ldflags = { "Linux * * * *" : cpu_x86_nbits + "-rdynamic -Wl,-z,origin -Wl,-rpath,'$$ORIGIN/lib'",
223  "Linux * * * profile" : cpu_x86_nbits + "-pg -rdynamic -Wl,-z,origin -Wl,-rpath,'$$ORIGIN/lib'",
224  "Linux * * * coverage" : cpu_x86_nbits + "-ftest-coverage -fprofile-arcs -rdynamic -Wl,-z,origin -Wl,-rpath,'$$ORIGIN/lib'",
225  "OSX * * * *" : cpu_x86_nbits + "-rdynamic",
226  "Windows * * * *" : cpu_x86_nbits + "-static-libgcc -Wl,--disable-stdcall-fixup -Wl,--enable-auto-import",
227  "* * * * *" : ""
228  }
229 spraak.ldflags = select_best_match(ldflags,spraak)
230 ldlibflags = { "* * * * *" : "",
231  "Linux * * * *" : cpu_x86_nbits + "-rdynamic -Wl,-O -Wl,--enable-new-dtags -Wl,--as-needed",
232  "OSX * * * *" : cpu_x86_nbits + "-dynamiclib -install_name @executable_path/lib/libspraak.dylib",
233  "Windows * * * *" : cpu_x86_nbits + "-static-libgcc -Wl,--out-implib=spraak.dll.a -Wl,--enable-stdcall-fixup -Wl,--export-all-symbols -Wl,--enable-auto-import",
234  }
235 spraak.ldlibflags = select_best_match(ldlibflags,spraak)
236 
237 # C preprocessor flags, e.g. -I<include_dir> if you have headers in a nonstandard directory <include_dir>
238 cppflags = { "* * * * *" : "",
239  "* * gcc * *" : "-D_XOPEN_SOURCE=600 -D_ISOC99_SOURCE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT",
240  "* * clang * *" : "-D_XOPEN_SOURCE=600 -D_ISOC99_SOURCE -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_REENTRANT",
241  }
242 spraak.cppflags = select_best_match(cppflags,spraak)
243 
244 
245 ##
246 ## bugs that escape auto-detection (see the bug-specific comments below)
247 ##
248 
249 bugs = { "* * * * *" : [],
250  "* x86_64 * * *" : (["x86_twin48_18"] if(env["ARCH"]=="compatible") else [])
251  }
252 for bug in select_best_match(bugs,spraak):
253  setattr(spraak,'sysdep_bug_'+bug,True);
254 # x86_twin48_18, x86_no_twin64
255 # Most 64 bits processors with the x86 instruction set made by AMD lack
256 # support for twin 64bits atomic operations (load, store, cas).
257 # A work-around is using single (no twin) 64bits atomic operations and
258 # subdividing the 64bits value in 48 bits for a pointer and 18 bits for a
259 # transaction counter (the missing 2 bits result from a required 4byte
260 # pointer alignment). This is however not 100% safe (only 18 bits for the
261 # transaction counter, so overrun problems cannot be ruled out).
262 # The end result is that users have the following options:
263 # - if you only use Intel core2 or AMD barcelona/phenom processors, then
264 # all is OK (there are no bugs).
265 # - else, if you can live with the extremely small chance that a
266 # multi-threaded application goes wrong (requires a heavily over-loaded
267 # computer), then specify the 'x86_twin48_18' option
268 # - else, specify the 'x86_no_twin64' option (will result in locked instead
269 # of lock-free implementations of some core routines).
270 
271 ##
272 ## other bugs & features
273 ##
274 
275 # uncomment those that are relevant to your setup
276 # - sphere_shortpack_v0: used in the very first releases of wsj0, outmoded
277 
278 spraak.sysdep_bug_sphere_shortpack_v0 = True;