sleepyhead111 commited on
Commit
d0a4e82
·
verified ·
1 Parent(s): 27fb65a

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. mosesdecoder/jam-files/LICENSE_1_0.txt +23 -0
  2. mosesdecoder/jam-files/boost-build/tools/auto-index.jam +212 -0
  3. mosesdecoder/jam-files/boost-build/tools/bison.jam +32 -0
  4. mosesdecoder/jam-files/boost-build/tools/boostbook-config.jam +13 -0
  5. mosesdecoder/jam-files/boost-build/tools/borland.jam +220 -0
  6. mosesdecoder/jam-files/boost-build/tools/builtin.jam +960 -0
  7. mosesdecoder/jam-files/boost-build/tools/cast.jam +91 -0
  8. mosesdecoder/jam-files/boost-build/tools/common.jam +983 -0
  9. mosesdecoder/jam-files/boost-build/tools/como.jam +29 -0
  10. mosesdecoder/jam-files/boost-build/tools/cray.jam +112 -0
  11. mosesdecoder/jam-files/boost-build/tools/cw.jam +246 -0
  12. mosesdecoder/jam-files/boost-build/tools/darwin.jam +583 -0
  13. mosesdecoder/jam-files/boost-build/tools/docutils.jam +85 -0
  14. mosesdecoder/jam-files/boost-build/tools/doxygen-config.jam +11 -0
  15. mosesdecoder/jam-files/boost-build/tools/fortran.jam +55 -0
  16. mosesdecoder/jam-files/boost-build/tools/gettext.jam +230 -0
  17. mosesdecoder/jam-files/boost-build/tools/ifort.jam +44 -0
  18. mosesdecoder/jam-files/boost-build/tools/intel-darwin.jam +220 -0
  19. mosesdecoder/jam-files/boost-build/tools/intel-win.jam +184 -0
  20. mosesdecoder/jam-files/boost-build/tools/mpi.jam +583 -0
  21. mosesdecoder/jam-files/boost-build/tools/msvc.jam +1398 -0
  22. mosesdecoder/jam-files/boost-build/tools/notfile.jam +74 -0
  23. mosesdecoder/jam-files/boost-build/tools/pathscale.jam +168 -0
  24. mosesdecoder/jam-files/boost-build/tools/pch.jam +95 -0
  25. mosesdecoder/jam-files/boost-build/tools/qt.jam +17 -0
  26. mosesdecoder/jam-files/boost-build/tools/qt3.jam +209 -0
  27. mosesdecoder/jam-files/boost-build/tools/qt4.jam +724 -0
  28. mosesdecoder/jam-files/boost-build/tools/sun.jam +142 -0
  29. mosesdecoder/jam-files/boost-build/tools/testing.jam +581 -0
  30. mosesdecoder/jam-files/boost-build/tools/types/html.jam +4 -0
  31. mosesdecoder/jam-files/boost-build/tools/types/obj.jam +9 -0
  32. mosesdecoder/jam-files/boost-build/tools/types/objc.jam +26 -0
  33. mosesdecoder/jam-files/boost-build/tools/types/preprocessed.jam +9 -0
  34. mosesdecoder/jam-files/boost-build/tools/types/qt.jam +10 -0
  35. mosesdecoder/jam-files/boost-build/tools/types/register.jam +39 -0
  36. mosesdecoder/jam-files/boost-build/tools/unix.jam +224 -0
  37. mosesdecoder/jam-files/boost-build/tools/xsltproc.jam +194 -0
  38. mosesdecoder/jam-files/empty_test_main.cc +8 -0
  39. mosesdecoder/jam-files/engine/class.h +14 -0
  40. mosesdecoder/jam-files/engine/command.c +84 -0
  41. mosesdecoder/jam-files/engine/compile.c +271 -0
  42. mosesdecoder/jam-files/engine/cwd.h +35 -0
  43. mosesdecoder/jam-files/engine/debug.c +145 -0
  44. mosesdecoder/jam-files/engine/debug.h +55 -0
  45. mosesdecoder/jam-files/engine/execcmd.c +121 -0
  46. mosesdecoder/jam-files/engine/execnt.c +1232 -0
  47. mosesdecoder/jam-files/engine/execunix.c +559 -0
  48. mosesdecoder/jam-files/engine/filesys.h +56 -0
  49. mosesdecoder/jam-files/engine/frames.h +42 -0
  50. mosesdecoder/jam-files/engine/hash.c +387 -0
mosesdecoder/jam-files/LICENSE_1_0.txt ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Boost Software License - Version 1.0 - August 17th, 2003
2
+
3
+ Permission is hereby granted, free of charge, to any person or organization
4
+ obtaining a copy of the software and accompanying documentation covered by
5
+ this license (the "Software") to use, reproduce, display, distribute,
6
+ execute, and transmit the Software, and to prepare derivative works of the
7
+ Software, and to permit third-parties to whom the Software is furnished to
8
+ do so, all subject to the following:
9
+
10
+ The copyright notices in the Software and this entire statement, including
11
+ the above license grant, this restriction and the following disclaimer,
12
+ must be included in all copies of the Software, in whole or in part, and
13
+ all derivative works of the Software, unless such copies or derivative
14
+ works are solely in the form of machine-executable object code generated by
15
+ a source language processor.
16
+
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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
20
+ SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
21
+ FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
22
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
+ DEALINGS IN THE SOFTWARE.
mosesdecoder/jam-files/boost-build/tools/auto-index.jam ADDED
@@ -0,0 +1,212 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import feature ;
3
+ import generators ;
4
+ import "class" ;
5
+ import toolset ;
6
+ import targets ;
7
+ import "class" : new ;
8
+ import project ;
9
+
10
+ feature.feature auto-index : off "on" ;
11
+ feature.feature auto-index-internal : off "on" ;
12
+ feature.feature auto-index-verbose : off "on" ;
13
+ feature.feature auto-index-no-duplicates : off "on" ;
14
+ feature.feature auto-index-script : : free path ;
15
+ feature.feature auto-index-prefix : : free path ;
16
+ feature.feature auto-index-type : : free ;
17
+ feature.feature auto-index-section-names : "on" off ;
18
+
19
+ toolset.flags auto-index.auto-index FLAGS <auto-index-internal>on : --internal-index ;
20
+ toolset.flags auto-index.auto-index SCRIPT <auto-index-script> ;
21
+ toolset.flags auto-index.auto-index PREFIX <auto-index-prefix> ;
22
+ toolset.flags auto-index.auto-index INDEX_TYPE <auto-index-type> ;
23
+ toolset.flags auto-index.auto-index FLAGS <auto-index-verbose>on : --verbose ;
24
+ toolset.flags auto-index.auto-index FLAGS <auto-index-no-duplicates>on : --no-duplicates ;
25
+ toolset.flags auto-index.auto-index FLAGS <auto-index-section-names>off : --no-section-names ;
26
+
27
+ # <auto-index-binary> shell command to run AutoIndex
28
+ # <auto-index-binary-dependencies> targets to build AutoIndex from sources.
29
+ feature.feature <auto-index-binary> : : free ;
30
+ feature.feature <auto-index-binary-dependencies> : : free dependency ;
31
+
32
+ class auto-index-generator : generator
33
+ {
34
+ import common modules path targets build-system ;
35
+ rule run ( project name ? : property-set : sources * )
36
+ {
37
+ # AutoIndex invocation command and dependencies.
38
+ local auto-index-binary = [ modules.peek auto-index : .command ] ;
39
+ local auto-index-binary-dependencies ;
40
+
41
+ if $(auto-index-binary)
42
+ {
43
+ # Use user-supplied command.
44
+ auto-index-binary = [ common.get-invocation-command auto-index : auto-index : $(auto-index-binary) ] ;
45
+ }
46
+ else
47
+ {
48
+ # Search for AutoIndex sources in sensible places, like
49
+ # $(BOOST_ROOT)/tools/auto_index
50
+ # $(BOOST_BUILD_PATH)/../../auto_index
51
+
52
+ # And build auto-index executable from sources.
53
+
54
+ local boost-root = [ modules.peek : BOOST_ROOT ] ;
55
+ local boost-build-path = [ build-system.location ] ;
56
+ local boost-build-path2 = [ modules.peek : BOOST_BUILD_PATH ] ;
57
+
58
+ local auto-index-dir ;
59
+
60
+ if $(boost-root)
61
+ {
62
+ auto-index-dir += [ path.join $(boost-root) tools ] ;
63
+ }
64
+
65
+ if $(boost-build-path)
66
+ {
67
+ auto-index-dir += $(boost-build-path)/../.. ;
68
+ }
69
+ if $(boost-build-path2)
70
+ {
71
+ auto-index-dir += $(boost-build-path2)/.. ;
72
+ }
73
+
74
+ #ECHO $(auto-index-dir) ;
75
+ auto-index-dir = [ path.glob $(auto-index-dir) : auto_index ] ;
76
+ #ECHO $(auto-index-dir) ;
77
+
78
+ # If the AutoIndex source directory was found, mark its main target
79
+ # as a dependency for the current project. Otherwise, try to find
80
+ # 'auto-index' in user's PATH
81
+ if $(auto-index-dir)
82
+ {
83
+ auto-index-dir = [ path.make $(auto-index-dir[1]) ] ;
84
+ auto-index-dir = $(auto-index-dir)/build ;
85
+
86
+ #ECHO $(auto-index-dir) ;
87
+
88
+ # Get the main-target in AutoIndex directory.
89
+ local auto-index-main-target = [ targets.resolve-reference $(auto-index-dir) : $(project) ] ;
90
+
91
+ #ECHO $(auto-index-main-target) ;
92
+
93
+ # The first element are actual targets, the second are
94
+ # properties found in target-id. We do not care about these
95
+ # since we have passed the id ourselves.
96
+ auto-index-main-target =
97
+ [ $(auto-index-main-target[1]).main-target auto_index ] ;
98
+
99
+ #ECHO $(auto-index-main-target) ;
100
+
101
+ auto-index-binary-dependencies =
102
+ [ $(auto-index-main-target).generate [ $(property-set).propagated ] ] ;
103
+
104
+ # Ignore usage-requirements returned as first element.
105
+ auto-index-binary-dependencies = $(auto-index-binary-dependencies[2-]) ;
106
+
107
+ # Some toolsets generate extra targets (e.g. RSP). We must mark
108
+ # all targets as dependencies for the project, but we will only
109
+ # use the EXE target for auto-index-to-boostbook translation.
110
+ for local target in $(auto-index-binary-dependencies)
111
+ {
112
+ if [ $(target).type ] = EXE
113
+ {
114
+ auto-index-binary =
115
+ [ path.native
116
+ [ path.join
117
+ [ $(target).path ]
118
+ [ $(target).name ]
119
+ ]
120
+ ] ;
121
+ }
122
+ }
123
+ }
124
+ else
125
+ {
126
+ ECHO "AutoIndex warning: The path to the auto-index executable was" ;
127
+ ECHO " not provided. Additionally, couldn't find AutoIndex" ;
128
+ ECHO " sources searching in" ;
129
+ ECHO " * BOOST_ROOT/tools/auto-index" ;
130
+ ECHO " * BOOST_BUILD_PATH/../../auto-index" ;
131
+ ECHO " Will now try to find a precompiled executable by searching" ;
132
+ ECHO " the PATH for 'auto-index'." ;
133
+ ECHO " To disable this warning in the future, or to completely" ;
134
+ ECHO " avoid compilation of auto-index, you can explicitly set the" ;
135
+ ECHO " path to a auto-index executable command in user-config.jam" ;
136
+ ECHO " or site-config.jam with the call" ;
137
+ ECHO " using auto-index : /path/to/auto-index ;" ;
138
+
139
+ # As a last resort, search for 'auto-index' command in path. Note
140
+ # that even if the 'auto-index' command is not found,
141
+ # get-invocation-command will still return 'auto-index' and might
142
+ # generate an error while generating the virtual-target.
143
+
144
+ auto-index-binary = [ common.get-invocation-command auto-index : auto-index ] ;
145
+ }
146
+ }
147
+
148
+ # Add $(auto-index-binary-dependencies) as a dependency of the current
149
+ # project and set it as the <auto-index-binary> feature for the
150
+ # auto-index-to-boostbook rule, below.
151
+ property-set = [ $(property-set).add-raw
152
+ <dependency>$(auto-index-binary-dependencies)
153
+ <auto-index-binary>$(auto-index-binary)
154
+ <auto-index-binary-dependencies>$(auto-index-binary-dependencies)
155
+ ] ;
156
+
157
+ #ECHO "binary = " $(auto-index-binary) ;
158
+ #ECHO "dependencies = " $(auto-index-binary-dependencies) ;
159
+
160
+ if [ $(property-set).get <auto-index> ] = "on"
161
+ {
162
+ return [ generator.run $(project) $(name) : $(property-set) : $(sources) ] ;
163
+ }
164
+ else
165
+ {
166
+ return [ generators.construct $(project) $(name) : DOCBOOK : $(property-set)
167
+ : $(sources) ] ;
168
+ }
169
+ }
170
+ }
171
+
172
+ # Initialization of toolset.
173
+ #
174
+ # Parameters:
175
+ # command ? -> path to AutoIndex executable.
176
+ #
177
+ # When command is not supplied toolset will search for AutoIndex directory and
178
+ # compile the executable from source. If that fails we still search the path for
179
+ # 'auto_index'.
180
+ #
181
+ rule init (
182
+ command ? # path to the AutoIndex executable.
183
+ )
184
+ {
185
+ if ! $(.initialized)
186
+ {
187
+ .initialized = true ;
188
+ .command = $(command) ;
189
+ }
190
+ }
191
+
192
+ toolset.flags auto-index.auto-index AI-COMMAND <auto-index-binary> ;
193
+ toolset.flags auto-index.auto-index AI-DEPENDENCIES <auto-index-binary-dependencies> ;
194
+
195
+ generators.register [ class.new auto-index-generator auto-index.auto-index : DOCBOOK : DOCBOOK(%.auto_index) ] ;
196
+ generators.override auto-index.auto-index : boostbook.boostbook-to-docbook ;
197
+
198
+ rule auto-index ( target : source : properties * )
199
+ {
200
+ # Signal dependency of auto-index sources on <auto-index-binary-dependencies>
201
+ # upon invocation of auto-index-to-boostbook.
202
+ #ECHO "AI-COMMAND= " $(AI-COMMAND) ;
203
+ DEPENDS $(target) : [ on $(target) return $(AI-DEPENDENCIES) ] ;
204
+ #DEPENDS $(target) : [ on $(target) return $(SCRIPT) ] ;
205
+ }
206
+
207
+ actions auto-index
208
+ {
209
+ $(AI-COMMAND) $(FLAGS) "--prefix="$(PREFIX) "--script="$(SCRIPT) "--index-type="$(INDEX_TYPE) "--in="$(>) "--out="$(<)
210
+ }
211
+
212
+
mosesdecoder/jam-files/boost-build/tools/bison.jam ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003 Vladimir Prus
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ import generators ;
6
+ import feature ;
7
+ import type ;
8
+ import property ;
9
+
10
+ feature.feature bison.prefix : : free ;
11
+ type.register Y : y ;
12
+ type.register YY : yy ;
13
+ generators.register-standard bison.bison : Y : C H ;
14
+ generators.register-standard bison.bison : YY : CPP HPP ;
15
+
16
+ rule init ( )
17
+ {
18
+ }
19
+
20
+ rule bison ( dst dst_header : src : properties * )
21
+ {
22
+ local r = [ property.select bison.prefix : $(properties) ] ;
23
+ if $(r)
24
+ {
25
+ PREFIX_OPT on $(<) = -p $(r:G=) ;
26
+ }
27
+ }
28
+
29
+ actions bison
30
+ {
31
+ bison $(PREFIX_OPT) -d -o $(<[1]) $(>)
32
+ }
mosesdecoder/jam-files/boost-build/tools/boostbook-config.jam ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #~ Copyright 2005 Rene Rivera.
2
+ #~ Distributed under the Boost Software License, Version 1.0.
3
+ #~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Automatic configuration for BoostBook tools. To use, just import this module.
6
+ #
7
+ # This module is deprecated.
8
+ # using boostbook ;
9
+ # with no arguments now suffices.
10
+
11
+ import toolset : using ;
12
+
13
+ using boostbook ;
mosesdecoder/jam-files/boost-build/tools/borland.jam ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2005 Dave Abrahams
2
+ # Copyright 2003 Rene Rivera
3
+ # Copyright 2003, 2004, 2005 Vladimir Prus
4
+ # Distributed under the Boost Software License, Version 1.0.
5
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ # Support for the Borland's command line compiler
8
+
9
+ import property ;
10
+ import generators ;
11
+ import os ;
12
+ import toolset : flags ;
13
+ import feature : get-values ;
14
+ import type ;
15
+ import common ;
16
+
17
+ feature.extend toolset : borland ;
18
+
19
+ rule init ( version ? : command * : options * )
20
+ {
21
+ local condition = [ common.check-init-parameters borland :
22
+ version $(version) ] ;
23
+
24
+ local command = [ common.get-invocation-command borland : bcc32.exe
25
+ : $(command) ] ;
26
+
27
+ common.handle-options borland : $(condition) : $(command) : $(options) ;
28
+
29
+ if $(command)
30
+ {
31
+ command = [ common.get-absolute-tool-path $(command[-1]) ] ;
32
+ }
33
+ root = $(command:D) ;
34
+
35
+ flags borland.compile STDHDRS $(condition) : $(root)/include/ ;
36
+ flags borland.link STDLIBPATH $(condition) : $(root)/lib ;
37
+ flags borland.link RUN_PATH $(condition) : $(root)/bin ;
38
+ flags borland .root $(condition) : $(root)/bin/ ;
39
+ }
40
+
41
+
42
+ # A borland-specific target type
43
+ type.register BORLAND.TDS : tds ;
44
+
45
+ # Declare generators
46
+
47
+ generators.register-linker borland.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>borland ;
48
+ generators.register-linker borland.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : <toolset>borland ;
49
+
50
+ generators.register-archiver borland.archive : OBJ : STATIC_LIB : <toolset>borland ;
51
+ generators.register-c-compiler borland.compile.c++ : CPP : OBJ : <toolset>borland ;
52
+ generators.register-c-compiler borland.compile.c : C : OBJ : <toolset>borland ;
53
+ generators.register-standard borland.asm : ASM : OBJ : <toolset>borland ;
54
+
55
+ # Declare flags
56
+
57
+ flags borland.compile OPTIONS <debug-symbols>on : -v ;
58
+ flags borland.link OPTIONS <debug-symbols>on : -v ;
59
+
60
+ flags borland.compile OPTIONS <optimization>off : -Od ;
61
+ flags borland.compile OPTIONS <optimization>speed : -O2 ;
62
+ flags borland.compile OPTIONS <optimization>space : -O1 ;
63
+
64
+ if $(.BORLAND_HAS_FIXED_INLINING_BUGS)
65
+ {
66
+ flags borland CFLAGS <inlining>off : -vi- ;
67
+ flags borland CFLAGS <inlining>on : -vi -w-inl ;
68
+ flags borland CFLAGS <inlining>full : -vi -w-inl ;
69
+ }
70
+ else
71
+ {
72
+ flags borland CFLAGS : -vi- ;
73
+ }
74
+
75
+ flags borland.compile OPTIONS <warnings>off : -w- ;
76
+ flags borland.compile OPTIONS <warnings>all : -w ;
77
+ flags borland.compile OPTIONS <warnings-as-errors>on : -w! ;
78
+
79
+
80
+ # Deal with various runtime configs...
81
+
82
+ # This should be not for DLL
83
+ flags borland OPTIONS <user-interface>console : -tWC ;
84
+
85
+ # -tWR sets -tW as well, so we turn it off here and then turn it
86
+ # on again later if we need it:
87
+ flags borland OPTIONS <runtime-link>shared : -tWR -tWC ;
88
+ flags borland OPTIONS <user-interface>gui : -tW ;
89
+
90
+ flags borland OPTIONS <main-target-type>LIB/<link>shared : -tWD ;
91
+ # Hmm.. not sure what's going on here.
92
+ flags borland OPTIONS : -WM- ;
93
+ flags borland OPTIONS <threading>multi : -tWM ;
94
+
95
+
96
+
97
+ flags borland.compile OPTIONS <cxxflags> ;
98
+ flags borland.compile DEFINES <define> ;
99
+ flags borland.compile INCLUDES <include> ;
100
+
101
+ flags borland NEED_IMPLIB <main-target-type>LIB/<link>shared : "" ;
102
+
103
+ #
104
+ # for C++ compiles the following options are turned on by default:
105
+ #
106
+ # -j5 stops after 5 errors
107
+ # -g255 allow an unlimited number of warnings
108
+ # -q no banner
109
+ # -c compile to object
110
+ # -P C++ code regardless of file extention
111
+ # -a8 8 byte alignment, this option is on in the IDE by default
112
+ # and effects binary compatibility.
113
+ #
114
+
115
+ # -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(C++FLAGS) -I"$(HDRS)" -I"$(STDHDRS)" -o"$(<)" "$(>)"
116
+
117
+
118
+ actions compile.c++
119
+ {
120
+ "$(CONFIG_COMMAND)" -j5 -g255 -q -c -P -a8 -Vx- -Ve- -b- $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -I"$(STDHDRS)" -o"$(<)" "$(>)"
121
+ }
122
+
123
+ # For C, we don't pass -P flag
124
+ actions compile.c
125
+ {
126
+ "$(CONFIG_COMMAND)" -j5 -g255 -q -c -a8 -Vx- -Ve- -b- $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -I"$(STDHDRS)" -o"$(<)" "$(>)"
127
+ }
128
+
129
+
130
+ # Declare flags and action for linking
131
+ toolset.flags borland.link OPTIONS <debug-symbols>on : -v ;
132
+ toolset.flags borland.link LIBRARY_PATH <library-path> ;
133
+ toolset.flags borland.link FINDLIBS_ST <find-static-library> ;
134
+ toolset.flags borland.link FINDLIBS_SA <find-shared-library> ;
135
+ toolset.flags borland.link LIBRARIES <library-file> ;
136
+
137
+ flags borland.link OPTIONS <linkflags> ;
138
+ flags borland.link OPTIONS <link>shared : -tWD ;
139
+
140
+ flags borland.link LIBRARY_PATH_OPTION <toolset>borland : -L : unchecked ;
141
+ flags borland.link LIBRARY_OPTION <toolset>borland : "" : unchecked ;
142
+
143
+
144
+
145
+ # bcc32 needs to have ilink32 in the path in order to invoke it, so explicitly
146
+ # specifying $(BCC_TOOL_PATH)bcc32 doesn't help. You need to add
147
+ # $(BCC_TOOL_PATH) to the path
148
+ # The NEED_IMPLIB variable controls whether we need to invoke implib.
149
+
150
+ flags borland.archive AROPTIONS <archiveflags> ;
151
+
152
+ # Declare action for archives. We don't use response file
153
+ # since it's hard to get "+-" there.
154
+ # The /P256 increases 'page' size -- with too low
155
+ # values tlib fails when building large applications.
156
+ # CONSIDER: don't know what 'together' is for...
157
+ actions updated together piecemeal archive
158
+ {
159
+ $(.set-path)$(.root:W)$(.old-path)
160
+ tlib $(AROPTIONS) /P256 /u /a /C "$(<:W)" +-"$(>:W)"
161
+ }
162
+
163
+
164
+ if [ os.name ] = CYGWIN
165
+ {
166
+ .set-path = "cmd /S /C set \"PATH=" ;
167
+ .old-path = ";%PATH%\" \"&&\"" ;
168
+
169
+
170
+ # Couldn't get TLIB to stop being confused about pathnames
171
+ # containing dashes (it seemed to treat them as option separators
172
+ # when passed through from bash), so we explicitly write the
173
+ # command into a .bat file and execute that. TLIB is also finicky
174
+ # about pathname style! Forward slashes, too, are treated as
175
+ # options.
176
+ actions updated together piecemeal archive
177
+ {
178
+ chdir $(<:D)
179
+ echo +-$(>:BS) > $(<:BS).rsp
180
+ $(.set-path)$(.root)$(.old-path) "tlib.exe" $(AROPTIONS) /P256 /C $(<:BS) @$(<:BS).rsp && $(RM) $(<:BS).rsp
181
+ }
182
+ }
183
+ else if [ os.name ] = NT
184
+ {
185
+ .set-path = "set \"PATH=" ;
186
+ .old-path = ";%PATH%\"
187
+ " ;
188
+ }
189
+ else
190
+ {
191
+ .set-path = "PATH=\"" ;
192
+ .old-path = "\":$PATH
193
+ export PATH
194
+ " ;
195
+ }
196
+
197
+ RM = [ common.rm-command ] ;
198
+
199
+ nl = "
200
+ " ;
201
+
202
+ actions link
203
+ {
204
+ $(.set-path)$(.root:W)$(.old-path) "$(CONFIG_COMMAND)" -v -q $(OPTIONS) -L"$(LIBRARY_PATH:W)" -L"$(STDLIBPATH:W)" -e"$(<[1]:W)" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")"
205
+ }
206
+
207
+
208
+ actions link.dll bind LIBRARIES RSP
209
+ {
210
+ $(.set-path)$(.root:W)$(.old-path) "$(CONFIG_COMMAND)" -v -q $(OPTIONS) -L"$(LIBRARY_PATH:W)" -L"$(STDLIBPATH:W)" -e"$(<[1]:W)" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")" && "$(.root)implib" "$(<[2]:W)" "$(<[1]:W)"
211
+ }
212
+
213
+ # It seems impossible to specify output file with directory when compiling
214
+ # asm files using bcc32, so use tasm32 directly.
215
+ # /ml makes all symbol names case-sensitive
216
+ actions asm
217
+ {
218
+ $(.set-path)$(.root:W)$(.old-path) tasm32.exe /ml "$(>)" "$(<)"
219
+ }
220
+
mosesdecoder/jam-files/boost-build/tools/builtin.jam ADDED
@@ -0,0 +1,960 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2002, 2003, 2004, 2005 Dave Abrahams
2
+ # Copyright 2002, 2005, 2006, 2007, 2010 Rene Rivera
3
+ # Copyright 2006 Juergen Hunold
4
+ # Copyright 2005 Toon Knapen
5
+ # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
6
+ # Distributed under the Boost Software License, Version 1.0.
7
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
8
+
9
+ # Defines standard features and rules.
10
+
11
+ import alias ;
12
+ import "class" : new ;
13
+ import errors ;
14
+ import feature ;
15
+ import generators ;
16
+ import numbers ;
17
+ import os ;
18
+ import path ;
19
+ import print ;
20
+ import project ;
21
+ import property ;
22
+ import regex ;
23
+ import scanner ;
24
+ import sequence ;
25
+ import stage ;
26
+ import symlink ;
27
+ import toolset ;
28
+ import type ;
29
+ import targets ;
30
+ import types/register ;
31
+ import utility ;
32
+ import virtual-target ;
33
+ import message ;
34
+ import convert ;
35
+
36
+ # FIXME: the following generate module import is not needed here but removing it
37
+ # too hastly will break using code (e.g. the main Boost library Jamroot file)
38
+ # that forgot to import the generate module before calling the generate rule.
39
+ import generate ;
40
+
41
+
42
+ .os-names = aix bsd cygwin darwin freebsd hpux iphone linux netbsd
43
+ openbsd osf qnx qnxnto sgi solaris unix unixware windows
44
+ elf # Not actually an OS -- used for targeting bare metal where
45
+ # object format is ELF. This catches both -elf and -eabi gcc
46
+ # targets and well as other compilers targeting ELF. It is not
47
+ # clear how often do we need to key of ELF specifically as opposed
48
+ # to other bare metal targets, but let's stick with gcc naming.
49
+ ;
50
+
51
+ # Feature used to determine which OS we're on. New <target-os> and <host-os>
52
+ # features should be used instead.
53
+ local os = [ modules.peek : OS ] ;
54
+ feature.feature os : $(os) : propagated link-incompatible ;
55
+
56
+
57
+ # Translates from bjam current OS to the os tags used in host-os and target-os,
58
+ # i.e. returns the running host-os.
59
+ #
60
+ local rule default-host-os ( )
61
+ {
62
+ local host-os ;
63
+ if [ os.name ] in $(.os-names:U)
64
+ {
65
+ host-os = [ os.name ] ;
66
+ }
67
+ else
68
+ {
69
+ switch [ os.name ]
70
+ {
71
+ case NT : host-os = windows ;
72
+ case AS400 : host-os = unix ;
73
+ case MINGW : host-os = windows ;
74
+ case BSDI : host-os = bsd ;
75
+ case COHERENT : host-os = unix ;
76
+ case DRAGONFLYBSD : host-os = bsd ;
77
+ case IRIX : host-os = sgi ;
78
+ case MACOSX : host-os = darwin ;
79
+ case KFREEBSD : host-os = freebsd ;
80
+ case LINUX : host-os = linux ;
81
+ case SUNOS :
82
+ ECHO "SunOS is not a supported operating system." ;
83
+ ECHO "We believe last version of SunOS was released in 1992, " ;
84
+ ECHO "so if you get this message, something is very wrong with configuration logic. " ;
85
+ ECHO "Please report this as a bug. " ;
86
+ EXIT ;
87
+ case * : host-os = unix ;
88
+ }
89
+ }
90
+ return $(host-os:L) ;
91
+ }
92
+
93
+
94
+ # The two OS features define a known set of abstract OS names. The host-os is
95
+ # the OS under which bjam is running. Even though this should really be a fixed
96
+ # property we need to list all the values to prevent unknown value errors. Both
97
+ # set the default value to the current OS to account for the default use case of
98
+ # building on the target OS.
99
+ feature.feature host-os : $(.os-names) ;
100
+ feature.set-default host-os : [ default-host-os ] ;
101
+
102
+ feature.feature target-os : $(.os-names) : propagated link-incompatible ;
103
+ feature.set-default target-os : [ default-host-os ] ;
104
+
105
+
106
+ feature.feature toolset : : implicit propagated symmetric ;
107
+ feature.feature stdlib : native : propagated composite ;
108
+ feature.feature link : shared static : propagated ;
109
+ feature.feature runtime-link : shared static : propagated ;
110
+ feature.feature runtime-debugging : on off : propagated ;
111
+ feature.feature optimization : off speed space : propagated ;
112
+ feature.feature profiling : off on : propagated ;
113
+ feature.feature inlining : off on full : propagated ;
114
+ feature.feature threading : single multi : propagated ;
115
+ feature.feature rtti : on off : propagated ;
116
+ feature.feature exception-handling : on off : propagated ;
117
+
118
+ # Whether there is support for asynchronous EH (e.g. catching SEGVs).
119
+ feature.feature asynch-exceptions : off on : propagated ;
120
+
121
+ # Whether all extern "C" functions are considered nothrow by default.
122
+ feature.feature extern-c-nothrow : off on : propagated ;
123
+
124
+ feature.feature debug-symbols : on off : propagated ;
125
+ # Controls whether the binary should be stripped -- that is have
126
+ # everything not necessary to running removed. This option should
127
+ # not be very often needed. Also, this feature will show up in
128
+ # target paths of everything, not just binaries. Should fix that
129
+ # when impelementing feature relevance.
130
+ feature.feature strip : off on : propagated ;
131
+ feature.feature define : : free ;
132
+ feature.feature undef : : free ;
133
+ feature.feature "include" : : free path ; #order-sensitive ;
134
+ feature.feature cflags : : free ;
135
+ feature.feature cxxflags : : free ;
136
+ feature.feature fflags : : free ;
137
+ feature.feature asmflags : : free ;
138
+ feature.feature linkflags : : free ;
139
+ feature.feature archiveflags : : free ;
140
+ feature.feature version : : free ;
141
+
142
+ # Generic, i.e. non-language specific, flags for tools.
143
+ feature.feature flags : : free ;
144
+ feature.feature location-prefix : : free ;
145
+
146
+
147
+ # The following features are incidental since they have no effect on built
148
+ # products. Not making them incidental will result in problems in corner cases,
149
+ # e.g.:
150
+ #
151
+ # unit-test a : a.cpp : <use>b ;
152
+ # lib b : a.cpp b ;
153
+ #
154
+ # Here, if <use> is not incidental, we would decide we have two targets for
155
+ # a.obj with different properties and complain about it.
156
+ #
157
+ # Note that making a feature incidental does not mean it is ignored. It may be
158
+ # ignored when creating a virtual target, but the rest of build process will use
159
+ # them.
160
+ feature.feature use : : free dependency incidental ;
161
+ feature.feature dependency : : free dependency incidental ;
162
+ feature.feature implicit-dependency : : free dependency incidental ;
163
+
164
+ feature.feature warnings :
165
+ on # Enable default/"reasonable" warning level for the tool.
166
+ all # Enable all possible warnings issued by the tool.
167
+ off # Disable all warnings issued by the tool.
168
+ : incidental propagated ;
169
+
170
+ feature.feature warnings-as-errors :
171
+ off # Do not fail the compilation if there are warnings.
172
+ on # Fail the compilation if there are warnings.
173
+ : incidental propagated ;
174
+
175
+ # Feature that allows us to configure the maximal template instantiation depth
176
+ # level allowed by a C++ compiler. Applies only to C++ toolsets whose compilers
177
+ # actually support this configuration setting.
178
+ #
179
+ # Note that Boost Build currently does not allow defining features that take any
180
+ # positive integral value as a parameter, which is what we need here, so we just
181
+ # define some of the values here and leave it up to the user to extend this set
182
+ # as he needs using the feature.extend rule.
183
+ #
184
+ # TODO: This should be upgraded as soon as Boost Build adds support for custom
185
+ # validated feature values or at least features allowing any positive integral
186
+ # value. See related Boost Build related trac ticket #194.
187
+ #
188
+ feature.feature c++-template-depth
189
+ :
190
+ [ numbers.range 64 1024 : 64 ]
191
+ [ numbers.range 20 1000 : 10 ]
192
+ # Maximum template instantiation depth guaranteed for ANSI/ISO C++
193
+ # conforming programs.
194
+ 17
195
+ :
196
+ incidental optional propagated ;
197
+
198
+ feature.feature source : : free dependency incidental ;
199
+ feature.feature library : : free dependency incidental ;
200
+ feature.feature file : : free dependency incidental ;
201
+ feature.feature find-shared-library : : free ; #order-sensitive ;
202
+ feature.feature find-static-library : : free ; #order-sensitive ;
203
+ feature.feature library-path : : free path ; #order-sensitive ;
204
+
205
+ # Internal feature.
206
+ feature.feature library-file : : free dependency ;
207
+
208
+ feature.feature name : : free ;
209
+ feature.feature tag : : free ;
210
+ feature.feature search : : free path ; #order-sensitive ;
211
+ feature.feature location : : free path ;
212
+ feature.feature dll-path : : free path ;
213
+ feature.feature hardcode-dll-paths : true false : incidental ;
214
+
215
+
216
+ # An internal feature that holds the paths of all dependency shared libraries.
217
+ # On Windows, it is needed so that we can add all those paths to PATH when
218
+ # running applications. On Linux, it is needed to add proper -rpath-link command
219
+ # line options.
220
+ feature.feature xdll-path : : free path ;
221
+
222
+ # Provides means to specify def-file for windows DLLs.
223
+ feature.feature def-file : : free dependency ;
224
+
225
+ feature.feature suppress-import-lib : false true : incidental ;
226
+
227
+ # Internal feature used to store the name of a bjam action to call when building
228
+ # a target.
229
+ feature.feature action : : free ;
230
+
231
+ # This feature is used to allow specific generators to run. For example, QT
232
+ # tools can only be invoked when QT library is used. In that case, <allow>qt
233
+ # will be in usage requirement of the library.
234
+ feature.feature allow : : free ;
235
+
236
+ # The addressing model to generate code for. Currently a limited set only
237
+ # specifying the bit size of pointers.
238
+ feature.feature address-model : 16 32 64 32_64 : propagated optional ;
239
+
240
+ # Type of CPU architecture to compile for.
241
+ feature.feature architecture :
242
+ # x86 and x86-64
243
+ x86
244
+
245
+ # ia64
246
+ ia64
247
+
248
+ # Sparc
249
+ sparc
250
+
251
+ # RS/6000 & PowerPC
252
+ power
253
+
254
+ # MIPS/SGI
255
+ mips1 mips2 mips3 mips4 mips32 mips32r2 mips64
256
+
257
+ # HP/PA-RISC
258
+ parisc
259
+
260
+ # Advanced RISC Machines
261
+ arm
262
+
263
+ # Combined architectures for platforms/toolsets that support building for
264
+ # multiple architectures at once. "combined" would be the default multi-arch
265
+ # for the toolset.
266
+ combined
267
+ combined-x86-power
268
+
269
+ : propagated optional ;
270
+
271
+ # The specific instruction set in an architecture to compile.
272
+ feature.feature instruction-set :
273
+ # x86 and x86-64
274
+ native i386 i486 i586 i686 pentium pentium-mmx pentiumpro pentium2 pentium3
275
+ pentium3m pentium-m pentium4 pentium4m prescott nocona core2 conroe conroe-xe
276
+ conroe-l allendale mermon mermon-xe kentsfield kentsfield-xe penryn wolfdale
277
+ yorksfield nehalem k6 k6-2 k6-3 athlon athlon-tbird athlon-4 athlon-xp
278
+ athlon-mp k8 opteron athlon64 athlon-fx winchip-c6 winchip2 c3 c3-2
279
+
280
+ # ia64
281
+ itanium itanium1 merced itanium2 mckinley
282
+
283
+ # Sparc
284
+ v7 cypress v8 supersparc sparclite hypersparc sparclite86x f930 f934
285
+ sparclet tsc701 v9 ultrasparc ultrasparc3
286
+
287
+ # RS/6000 & PowerPC
288
+ 401 403 405 405fp 440 440fp 505 601 602 603 603e 604 604e 620 630 740 7400
289
+ 7450 750 801 821 823 860 970 8540 power-common ec603e g3 g4 g5 power power2
290
+ power3 power4 power5 powerpc powerpc64 rios rios1 rsc rios2 rs64a
291
+
292
+ # MIPS
293
+ 4kc 4kp 5kc 20kc m4k r2000 r3000 r3900 r4000 r4100 r4300 r4400 r4600 r4650
294
+ r6000 r8000 rm7000 rm9000 orion sb1 vr4100 vr4111 vr4120 vr4130 vr4300
295
+ vr5000 vr5400 vr5500
296
+
297
+ # HP/PA-RISC
298
+ 700 7100 7100lc 7200 7300 8000
299
+
300
+ # Advanced RISC Machines
301
+ armv2 armv2a armv3 armv3m armv4 armv4t armv5 armv5t armv5te armv6 armv6j iwmmxt ep9312
302
+
303
+ : propagated optional ;
304
+
305
+ # Used to select a specific variant of C++ ABI if the compiler supports several.
306
+ feature.feature c++abi : : propagated optional ;
307
+
308
+ feature.feature conditional : : incidental free ;
309
+
310
+ # The value of 'no' prevents building of a target.
311
+ feature.feature build : yes no : optional ;
312
+
313
+ # Windows-specific features
314
+
315
+ feature.feature user-interface : console gui wince native auto ;
316
+
317
+ feature.feature variant : : implicit composite propagated symmetric ;
318
+
319
+
320
+ # Declares a new variant.
321
+ #
322
+ # First determines explicit properties for this variant, by refining parents'
323
+ # explicit properties with the passed explicit properties. The result is
324
+ # remembered and will be used if this variant is used as parent.
325
+ #
326
+ # Second, determines the full property set for this variant by adding to the
327
+ # explicit properties default values for all missing non-symmetric properties.
328
+ #
329
+ # Lastly, makes appropriate value of 'variant' property expand to the full
330
+ # property set.
331
+ #
332
+ rule variant ( name # Name of the variant
333
+ : parents-or-properties * # Specifies parent variants, if
334
+ # 'explicit-properties' are given, and
335
+ # explicit-properties or parents otherwise.
336
+ : explicit-properties * # Explicit properties.
337
+ )
338
+ {
339
+ local parents ;
340
+ if ! $(explicit-properties)
341
+ {
342
+ if $(parents-or-properties[1]:G)
343
+ {
344
+ explicit-properties = $(parents-or-properties) ;
345
+ }
346
+ else
347
+ {
348
+ parents = $(parents-or-properties) ;
349
+ }
350
+ }
351
+ else
352
+ {
353
+ parents = $(parents-or-properties) ;
354
+ }
355
+
356
+ # The problem is that we have to check for conflicts between base variants.
357
+ if $(parents[2])
358
+ {
359
+ errors.error "multiple base variants are not yet supported" ;
360
+ }
361
+
362
+ local inherited ;
363
+ # Add explicitly specified properties for parents.
364
+ for local p in $(parents)
365
+ {
366
+ # TODO: This check may be made stricter.
367
+ if ! [ feature.is-implicit-value $(p) ]
368
+ {
369
+ errors.error "Invalid base variant" $(p) ;
370
+ }
371
+
372
+ inherited += $(.explicit-properties.$(p)) ;
373
+ }
374
+ property.validate $(explicit-properties) ;
375
+ explicit-properties = [ property.refine $(inherited)
376
+ : $(explicit-properties) ] ;
377
+
378
+ # Record explicitly specified properties for this variant. We do this after
379
+ # inheriting parents' properties so they affect other variants derived from
380
+ # this one.
381
+ .explicit-properties.$(name) = $(explicit-properties) ;
382
+
383
+ feature.extend variant : $(name) ;
384
+ feature.compose <variant>$(name) : $(explicit-properties) ;
385
+ }
386
+ IMPORT $(__name__) : variant : : variant ;
387
+
388
+
389
+ variant debug : <optimization>off <debug-symbols>on <inlining>off
390
+ <runtime-debugging>on ;
391
+ variant release : <optimization>speed <debug-symbols>off <inlining>full
392
+ <runtime-debugging>off <define>NDEBUG ;
393
+ variant profile : release : <profiling>on <debug-symbols>on ;
394
+
395
+
396
+ class searched-lib-target : abstract-file-target
397
+ {
398
+ rule __init__ ( name
399
+ : project
400
+ : shared ?
401
+ : search *
402
+ : action
403
+ )
404
+ {
405
+ abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project)
406
+ : $(action) : ;
407
+
408
+ self.shared = $(shared) ;
409
+ self.search = $(search) ;
410
+ }
411
+
412
+ rule shared ( )
413
+ {
414
+ return $(self.shared) ;
415
+ }
416
+
417
+ rule search ( )
418
+ {
419
+ return $(self.search) ;
420
+ }
421
+
422
+ rule actualize-location ( target )
423
+ {
424
+ NOTFILE $(target) ;
425
+ }
426
+
427
+ rule path ( )
428
+ {
429
+ }
430
+ }
431
+
432
+
433
+ # The generator class for libraries (target type LIB). Depending on properties
434
+ # it will request building of the appropriate specific library type --
435
+ # -- SHARED_LIB, STATIC_LIB or SHARED_LIB.
436
+ #
437
+ class lib-generator : generator
438
+ {
439
+ rule __init__ ( * : * )
440
+ {
441
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
442
+ }
443
+
444
+ rule run ( project name ? : property-set : sources * )
445
+ {
446
+ # The lib generator is composing, and can be only invoked with an
447
+ # explicit name. This check is present in generator.run (and so in
448
+ # builtin.linking-generator) but duplicated here to avoid doing extra
449
+ # work.
450
+ if $(name)
451
+ {
452
+ local properties = [ $(property-set).raw ] ;
453
+ # Determine the needed target type.
454
+ local actual-type ;
455
+ # <source>files can be generated by <conditional>@rule feature
456
+ # in which case we do not consider it a SEARCHED_LIB type.
457
+ if ! <source> in $(properties:G) &&
458
+ ( <search> in $(properties:G) || <name> in $(properties:G) )
459
+ {
460
+ actual-type = SEARCHED_LIB ;
461
+ }
462
+ else if <file> in $(properties:G)
463
+ {
464
+ actual-type = LIB ;
465
+ }
466
+ else if <link>shared in $(properties)
467
+ {
468
+ actual-type = SHARED_LIB ;
469
+ }
470
+ else
471
+ {
472
+ actual-type = STATIC_LIB ;
473
+ }
474
+ property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
475
+ # Construct the target.
476
+ return [ generators.construct $(project) $(name) : $(actual-type)
477
+ : $(property-set) : $(sources) ] ;
478
+ }
479
+ }
480
+
481
+ rule viable-source-types ( )
482
+ {
483
+ return * ;
484
+ }
485
+ }
486
+
487
+
488
+ generators.register [ new lib-generator builtin.lib-generator : : LIB ] ;
489
+
490
+
491
+ # The implementation of the 'lib' rule. Beyond standard syntax that rule allows
492
+ # simplified: "lib a b c ;".
493
+ #
494
+ rule lib ( names + : sources * : requirements * : default-build * :
495
+ usage-requirements * )
496
+ {
497
+ if $(names[2])
498
+ {
499
+ if <name> in $(requirements:G)
500
+ {
501
+ errors.user-error "When several names are given to the 'lib' rule" :
502
+ "it is not allowed to specify the <name> feature." ;
503
+ }
504
+ if $(sources)
505
+ {
506
+ errors.user-error "When several names are given to the 'lib' rule" :
507
+ "it is not allowed to specify sources." ;
508
+ }
509
+ }
510
+
511
+ # This is a circular module dependency so it must be imported here.
512
+ import targets ;
513
+
514
+ local project = [ project.current ] ;
515
+ local result ;
516
+
517
+ for local name in $(names)
518
+ {
519
+ local r = $(requirements) ;
520
+ # Support " lib a ; " and " lib a b c ; " syntax.
521
+ if ! $(sources) && ! <name> in $(requirements:G)
522
+ && ! <file> in $(requirements:G)
523
+ {
524
+ r += <name>$(name) ;
525
+ }
526
+ result += [ targets.main-target-alternative
527
+ [ new typed-target $(name) : $(project) : LIB
528
+ : [ targets.main-target-sources $(sources) : $(name) ]
529
+ : [ targets.main-target-requirements $(r) : $(project) ]
530
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
531
+ : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
532
+ ] ] ;
533
+ }
534
+ return $(result) ;
535
+ }
536
+ IMPORT $(__name__) : lib : : lib ;
537
+
538
+
539
+ class searched-lib-generator : generator
540
+ {
541
+ import property-set ;
542
+
543
+ rule __init__ ( )
544
+ {
545
+ # The requirements cause the generators to be tried *only* when we're
546
+ # building a lib target with a 'search' feature. This seems ugly --- all
547
+ # we want is to make sure searched-lib-generator is not invoked deep
548
+ # inside transformation search to produce intermediate targets.
549
+ generator.__init__ searched-lib-generator : : SEARCHED_LIB ;
550
+ }
551
+
552
+ rule run ( project name ? : property-set : sources * )
553
+ {
554
+ if $(name)
555
+ {
556
+ # If 'name' is empty, it means we have not been called to build a
557
+ # top-level target. In this case, we just fail immediately, because
558
+ # searched-lib-generator cannot be used to produce intermediate
559
+ # targets.
560
+
561
+ local properties = [ $(property-set).raw ] ;
562
+ local shared ;
563
+ if <link>shared in $(properties)
564
+ {
565
+ shared = true ;
566
+ }
567
+
568
+ local search = [ feature.get-values <search> : $(properties) ] ;
569
+
570
+ local a = [ new null-action $(property-set) ] ;
571
+ local lib-name = [ feature.get-values <name> : $(properties) ] ;
572
+ lib-name ?= $(name) ;
573
+ local t = [ new searched-lib-target $(lib-name) : $(project)
574
+ : $(shared) : $(search) : $(a) ] ;
575
+ # We return sources for a simple reason. If there is
576
+ # lib png : z : <name>png ;
577
+ # the 'z' target should be returned, so that apps linking to 'png'
578
+ # will link to 'z', too.
579
+ return [ property-set.create <xdll-path>$(search) ]
580
+ [ virtual-target.register $(t) ] $(sources) ;
581
+ }
582
+ }
583
+ }
584
+
585
+ generators.register [ new searched-lib-generator ] ;
586
+
587
+
588
+ class prebuilt-lib-generator : generator
589
+ {
590
+ rule __init__ ( * : * )
591
+ {
592
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
593
+ }
594
+
595
+ rule run ( project name ? : property-set : sources * )
596
+ {
597
+ local f = [ $(property-set).get <file> ] ;
598
+ return $(f) $(sources) ;
599
+ }
600
+ }
601
+
602
+ generators.register
603
+ [ new prebuilt-lib-generator builtin.prebuilt : : LIB : <file> ] ;
604
+
605
+ generators.override builtin.prebuilt : builtin.lib-generator ;
606
+
607
+ class preprocessed-target-class : basic-target
608
+ {
609
+ import generators ;
610
+ rule construct ( name : sources * : property-set )
611
+ {
612
+ local result = [ generators.construct [ project ]
613
+ $(name) : PREPROCESSED_CPP : $(property-set) : $(sources) ] ;
614
+ if ! $(result)
615
+ {
616
+ result = [ generators.construct [ project ]
617
+ $(name) : PREPROCESSED_C : $(property-set) : $(sources) ] ;
618
+ }
619
+ if ! $(result)
620
+ {
621
+ local s ;
622
+ for x in $(sources)
623
+ {
624
+ s += [ $(x).name ] ;
625
+ }
626
+ local p = [ project ] ;
627
+ errors.user-error
628
+ "In project" [ $(p).name ] :
629
+ "Could not construct preprocessed file \"$(name)\" from $(s:J=, )." ;
630
+ }
631
+ return $(result) ;
632
+ }
633
+ }
634
+
635
+ rule preprocessed ( name : sources * : requirements * : default-build * :
636
+ usage-requirements * )
637
+ {
638
+ local project = [ project.current ] ;
639
+ return [ targets.main-target-alternative
640
+ [ new preprocessed-target-class $(name) : $(project)
641
+ : [ targets.main-target-sources $(sources) : $(name) ]
642
+ : [ targets.main-target-requirements $(r) : $(project) ]
643
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
644
+ : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ]
645
+ ] ] ;
646
+ }
647
+
648
+ IMPORT $(__name__) : preprocessed : : preprocessed ;
649
+
650
+ class compile-action : action
651
+ {
652
+ import sequence ;
653
+
654
+ rule __init__ ( targets * : sources * : action-name : properties * )
655
+ {
656
+ action.__init__ $(targets) : $(sources) : $(action-name) : $(properties) ;
657
+ }
658
+
659
+ # For all virtual targets for the same dependency graph as self, i.e. which
660
+ # belong to the same main target, add their directories to the include path.
661
+ #
662
+ rule adjust-properties ( property-set )
663
+ {
664
+ local s = [ $(self.targets[1]).creating-subvariant ] ;
665
+ return [ $(property-set).add-raw
666
+ [ $(s).implicit-includes "include" : H ] ] ;
667
+ }
668
+ }
669
+
670
+
671
+ # Declare a special compiler generator. The only thing it does is changing the
672
+ # type used to represent 'action' in the constructed dependency graph to
673
+ # 'compile-action'. That class in turn adds additional include paths to handle
674
+ # cases when a source file includes headers which are generated themselves.
675
+ #
676
+ class C-compiling-generator : generator
677
+ {
678
+ rule __init__ ( id : source-types + : target-types + : requirements *
679
+ : optional-properties * )
680
+ {
681
+ generator.__init__ $(id) : $(source-types) : $(target-types) :
682
+ $(requirements) : $(optional-properties) ;
683
+ }
684
+
685
+ rule action-class ( )
686
+ {
687
+ return compile-action ;
688
+ }
689
+ }
690
+
691
+
692
+ rule register-c-compiler ( id : source-types + : target-types + : requirements *
693
+ : optional-properties * )
694
+ {
695
+ generators.register [ new C-compiling-generator $(id) : $(source-types) :
696
+ $(target-types) : $(requirements) : $(optional-properties) ] ;
697
+ }
698
+
699
+ # FIXME: this is ugly, should find a better way (we would like client code to
700
+ # register all generators as "generators.some-rule" instead of
701
+ # "some-module.some-rule".)
702
+ #
703
+ IMPORT $(__name__) : register-c-compiler : : generators.register-c-compiler ;
704
+
705
+
706
+ # The generator class for handling EXE and SHARED_LIB creation.
707
+ #
708
+ class linking-generator : generator
709
+ {
710
+ import path ;
711
+ import project ;
712
+ import property-set ;
713
+ import type ;
714
+
715
+ rule __init__ ( id
716
+ composing ? : # The generator will be composing if a non-empty
717
+ # string is passed or the parameter is not given. To
718
+ # make the generator non-composing, pass an empty
719
+ # string ("").
720
+ source-types + :
721
+ target-types + :
722
+ requirements * )
723
+ {
724
+ composing ?= true ;
725
+ generator.__init__ $(id) $(composing) : $(source-types)
726
+ : $(target-types) : $(requirements) ;
727
+ }
728
+
729
+ rule run ( project name ? : property-set : sources + )
730
+ {
731
+ sources += [ $(property-set).get <library> ] ;
732
+
733
+ # Add <library-path> properties for all searched libraries.
734
+ local extra ;
735
+ for local s in $(sources)
736
+ {
737
+ if [ $(s).type ] = SEARCHED_LIB
738
+ {
739
+ local search = [ $(s).search ] ;
740
+ extra += <library-path>$(search) ;
741
+ }
742
+ }
743
+
744
+ # It is possible that sources include shared libraries that did not came
745
+ # from 'lib' targets, e.g. .so files specified as sources. In this case
746
+ # we have to add extra dll-path properties and propagate extra xdll-path
747
+ # properties so that application linking to us will get xdll-path to
748
+ # those libraries.
749
+ local extra-xdll-paths ;
750
+ for local s in $(sources)
751
+ {
752
+ if [ type.is-derived [ $(s).type ] SHARED_LIB ] && ! [ $(s).action ]
753
+ {
754
+ # Unfortunately, we do not have a good way to find the path to a
755
+ # file, so use this nasty approach.
756
+ #
757
+ # TODO: This needs to be done better. One thing that is really
758
+ # broken with this is that it does not work correctly with
759
+ # projects having multiple source locations.
760
+ local p = [ $(s).project ] ;
761
+ local location = [ path.root [ $(s).name ]
762
+ [ $(p).get source-location ] ] ;
763
+ extra-xdll-paths += [ path.parent $(location) ] ;
764
+ }
765
+ }
766
+
767
+ # Hardcode DLL paths only when linking executables.
768
+ # Pros: do not need to relink libraries when installing.
769
+ # Cons: "standalone" libraries (plugins, python extensions) can not
770
+ # hardcode paths to dependent libraries.
771
+ if [ $(property-set).get <hardcode-dll-paths> ] = true
772
+ && [ type.is-derived $(self.target-types[1]) EXE ]
773
+ {
774
+ local xdll-path = [ $(property-set).get <xdll-path> ] ;
775
+ extra += <dll-path>$(xdll-path) <dll-path>$(extra-xdll-paths) ;
776
+ }
777
+
778
+ if $(extra)
779
+ {
780
+ property-set = [ $(property-set).add-raw $(extra) ] ;
781
+ }
782
+
783
+ local result = [ generator.run $(project) $(name) : $(property-set)
784
+ : $(sources) ] ;
785
+
786
+ local ur ;
787
+ if $(result)
788
+ {
789
+ ur = [ extra-usage-requirements $(result) : $(property-set) ] ;
790
+ ur = [ $(ur).add
791
+ [ property-set.create <xdll-path>$(extra-xdll-paths) ] ] ;
792
+ }
793
+ return $(ur) $(result) ;
794
+ }
795
+
796
+ rule extra-usage-requirements ( created-targets * : property-set )
797
+ {
798
+ local result = [ property-set.empty ] ;
799
+ local extra ;
800
+
801
+ # Add appropricate <xdll-path> usage requirements.
802
+ local raw = [ $(property-set).raw ] ;
803
+ if <link>shared in $(raw)
804
+ {
805
+ local paths ;
806
+ local pwd = [ path.pwd ] ;
807
+ for local t in $(created-targets)
808
+ {
809
+ if [ type.is-derived [ $(t).type ] SHARED_LIB ]
810
+ {
811
+ paths += [ path.root [ path.make [ $(t).path ] ] $(pwd) ] ;
812
+ }
813
+ }
814
+ extra += $(paths:G=<xdll-path>) ;
815
+ }
816
+
817
+ # We need to pass <xdll-path> features that we've got from sources,
818
+ # because if a shared library is built, exe using it needs to know paths
819
+ # to other shared libraries this one depends on in order to be able to
820
+ # find them all at runtime.
821
+
822
+ # Just pass all features in property-set, it is theorically possible
823
+ # that we will propagate <xdll-path> features explicitly specified by
824
+ # the user, but then the user is to blaim for using an internal feature.
825
+ local values = [ $(property-set).get <xdll-path> ] ;
826
+ extra += $(values:G=<xdll-path>) ;
827
+
828
+ if $(extra)
829
+ {
830
+ result = [ property-set.create $(extra) ] ;
831
+ }
832
+ return $(result) ;
833
+ }
834
+
835
+ rule generated-targets ( sources + : property-set : project name ? )
836
+ {
837
+ local sources2 ; # Sources to pass to inherited rule.
838
+ local properties2 ; # Properties to pass to inherited rule.
839
+ local libraries ; # Library sources.
840
+
841
+ # Searched libraries are not passed as arguments to the linker but via
842
+ # some option. So, we pass them to the action using a property.
843
+ properties2 = [ $(property-set).raw ] ;
844
+ local fsa ;
845
+ local fst ;
846
+ for local s in $(sources)
847
+ {
848
+ if [ type.is-derived [ $(s).type ] SEARCHED_LIB ]
849
+ {
850
+ local name = [ $(s).name ] ;
851
+ if [ $(s).shared ]
852
+ {
853
+ fsa += $(name) ;
854
+ }
855
+ else
856
+ {
857
+ fst += $(name) ;
858
+ }
859
+ }
860
+ else
861
+ {
862
+ sources2 += $(s) ;
863
+ }
864
+ }
865
+ properties2 += <find-shared-library>$(fsa:J=&&)
866
+ <find-static-library>$(fst:J=&&) ;
867
+
868
+ return [ generator.generated-targets $(sources2)
869
+ : [ property-set.create $(properties2) ] : $(project) $(name) ] ;
870
+ }
871
+ }
872
+
873
+
874
+ rule register-linker ( id composing ? : source-types + : target-types +
875
+ : requirements * )
876
+ {
877
+ generators.register [ new linking-generator $(id) $(composing)
878
+ : $(source-types) : $(target-types) : $(requirements) ] ;
879
+ }
880
+
881
+
882
+ # The generator class for handling STATIC_LIB creation.
883
+ #
884
+ class archive-generator : generator
885
+ {
886
+ import property-set ;
887
+
888
+ rule __init__ ( id composing ? : source-types + : target-types +
889
+ : requirements * )
890
+ {
891
+ composing ?= true ;
892
+ generator.__init__ $(id) $(composing) : $(source-types)
893
+ : $(target-types) : $(requirements) ;
894
+ }
895
+
896
+ rule run ( project name ? : property-set : sources + )
897
+ {
898
+ sources += [ $(property-set).get <library> ] ;
899
+
900
+ local result = [ generator.run $(project) $(name) : $(property-set)
901
+ : $(sources) ] ;
902
+
903
+ # For static linking, if we get a library in source, we can not directly
904
+ # link to it so we need to cause our dependencies to link to that
905
+ # library. There are two approaches:
906
+ # - adding the library to the list of returned targets.
907
+ # - using the <library> usage requirements.
908
+ # The problem with the first is:
909
+ #
910
+ # lib a1 : : <file>liba1.a ;
911
+ # lib a2 : a2.cpp a1 : <link>static ;
912
+ # install dist : a2 ;
913
+ #
914
+ # here we will try to install 'a1', even though it is not necessary in
915
+ # the general case. With the second approach, even indirect dependants
916
+ # will link to the library, but it should not cause any harm. So, return
917
+ # all LIB sources together with created targets, so that dependants link
918
+ # to them.
919
+ local usage-requirements ;
920
+ if [ $(property-set).get <link> ] = static
921
+ {
922
+ for local t in $(sources)
923
+ {
924
+ if [ type.is-derived [ $(t).type ] LIB ]
925
+ {
926
+ usage-requirements += <library>$(t) ;
927
+ }
928
+ }
929
+ }
930
+
931
+ usage-requirements = [ property-set.create $(usage-requirements) ] ;
932
+
933
+ return $(usage-requirements) $(result) ;
934
+ }
935
+ }
936
+
937
+
938
+ rule register-archiver ( id composing ? : source-types + : target-types +
939
+ : requirements * )
940
+ {
941
+ generators.register [ new archive-generator $(id) $(composing)
942
+ : $(source-types) : $(target-types) : $(requirements) ] ;
943
+ }
944
+
945
+
946
+ # Generator that accepts everything and produces nothing. Useful as a general
947
+ # fallback for toolset-specific actions like PCH generation.
948
+ #
949
+ class dummy-generator : generator
950
+ {
951
+ import property-set ;
952
+
953
+ rule run ( project name ? : property-set : sources + )
954
+ {
955
+ return [ property-set.empty ] ;
956
+ }
957
+ }
958
+
959
+ IMPORT $(__name__) : register-linker register-archiver
960
+ : : generators.register-linker generators.register-archiver ;
mosesdecoder/jam-files/boost-build/tools/cast.jam ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2005 Vladimir Prus.
2
+ # Distributed under the Boost Software License, Version 1.0. (See
3
+ # accompanying file LICENSE_1_0.txt or copy at
4
+ # http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ # Defines main target 'cast', used to change type for target. For example, in Qt
7
+ # library one wants two kinds of CPP files -- those that just compiled and those
8
+ # that are passed via the MOC tool.
9
+ #
10
+ # This is done with:
11
+ #
12
+ # exe main : main.cpp [ cast _ moccable-cpp : widget.cpp ] ;
13
+ #
14
+ # Boost.Build will assign target type CPP to both main.cpp and widget.cpp. Then,
15
+ # the cast rule will change target type of widget.cpp to MOCCABLE-CPP, and Qt
16
+ # support will run the MOC tool as part of the build process.
17
+ #
18
+ # At the moment, the 'cast' rule only works for non-derived (source) targets.
19
+ #
20
+ # TODO: The following comment is unclear or incorrect. Clean it up.
21
+ # > Another solution would be to add a separate main target 'moc-them' that
22
+ # > would moc all the passed sources, no matter what their type is, but I prefer
23
+ # > cast, as defining a new target type + generator for that type is somewhat
24
+ # > simpler than defining a main target rule.
25
+
26
+ import "class" : new ;
27
+ import errors ;
28
+ import project ;
29
+ import property-set ;
30
+ import targets ;
31
+ import type ;
32
+
33
+
34
+ class cast-target-class : typed-target
35
+ {
36
+ import type ;
37
+
38
+ rule __init__ ( name : project : type : sources * : requirements * :
39
+ default-build * : usage-requirements * )
40
+ {
41
+ typed-target.__init__ $(name) : $(project) : $(type) : $(sources) :
42
+ $(requirements) : $(default-build) : $(usage-requirements) ;
43
+ }
44
+
45
+ rule construct ( name : source-targets * : property-set )
46
+ {
47
+ local result ;
48
+ for local s in $(source-targets)
49
+ {
50
+ if ! [ class.is-a $(s) : file-target ]
51
+ {
52
+ import errors ;
53
+ errors.user-error Source to the 'cast' rule is not a file! ;
54
+ }
55
+ if [ $(s).action ]
56
+ {
57
+ import errors ;
58
+ errors.user-error Only non-derived target are allowed for
59
+ 'cast'. : when building [ full-name ] ;
60
+ }
61
+ local r = [ $(s).clone-with-different-type $(self.type) ] ;
62
+ result += [ virtual-target.register $(r) ] ;
63
+ }
64
+ return [ property-set.empty ] $(result) ;
65
+ }
66
+ }
67
+
68
+
69
+ rule cast ( name type : sources * : requirements * : default-build * :
70
+ usage-requirements * )
71
+ {
72
+ local project = [ project.current ] ;
73
+
74
+ local real-type = [ type.type-from-rule-name $(type) ] ;
75
+ if ! $(real-type)
76
+ {
77
+ errors.user-error No type corresponds to the main target rule name
78
+ '$(type)' : "Hint: try a lowercase name" ;
79
+ }
80
+
81
+ targets.main-target-alternative [ new cast-target-class $(name) : $(project)
82
+ : $(real-type)
83
+ : [ targets.main-target-sources $(sources) : $(name) ]
84
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
85
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
86
+ : [ targets.main-target-usage-requirements $(usage-requirements) :
87
+ $(project) ] ] ;
88
+ }
89
+
90
+
91
+ IMPORT $(__name__) : cast : : cast ;
mosesdecoder/jam-files/boost-build/tools/common.jam ADDED
@@ -0,0 +1,983 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003, 2005 Dave Abrahams
2
+ # Copyright 2005, 2006 Rene Rivera
3
+ # Copyright 2005 Toon Knapen
4
+ # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
5
+ # Distributed under the Boost Software License, Version 1.0.
6
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
7
+
8
+ # Provides actions common to all toolsets, such as creating directories and
9
+ # removing files.
10
+
11
+ import os ;
12
+ import modules ;
13
+ import utility ;
14
+ import print ;
15
+ import type ;
16
+ import feature ;
17
+ import errors ;
18
+ import path ;
19
+ import sequence ;
20
+ import toolset ;
21
+ import virtual-target ;
22
+
23
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
24
+ {
25
+ .debug-configuration = true ;
26
+ }
27
+ if [ MATCH (--show-configuration) : [ modules.peek : ARGV ] ]
28
+ {
29
+ .show-configuration = true ;
30
+ }
31
+
32
+ # Configurations
33
+ #
34
+ # The following class helps to manage toolset configurations. Each configuration
35
+ # has a unique ID and one or more parameters. A typical example of a unique ID
36
+ # is a condition generated by 'common.check-init-parameters' rule. Other kinds
37
+ # of IDs can be used. Parameters may include any details about the configuration
38
+ # like 'command', 'path', etc.
39
+ #
40
+ # A toolset configuration may be in one of the following states:
41
+ #
42
+ # - registered
43
+ # Configuration has been registered (e.g. explicitly or by auto-detection
44
+ # code) but has not yet been marked as used, i.e. 'toolset.using' rule has
45
+ # not yet been called for it.
46
+ # - used
47
+ # Once called 'toolset.using' rule marks the configuration as 'used'.
48
+ #
49
+ # The main difference between the states above is that while a configuration is
50
+ # 'registered' its options can be freely changed. This is useful in particular
51
+ # for autodetection code - all detected configurations may be safely overwritten
52
+ # by user code.
53
+
54
+ class configurations
55
+ {
56
+ import errors ;
57
+
58
+ rule __init__ ( )
59
+ {
60
+ }
61
+
62
+ # Registers a configuration.
63
+ #
64
+ # Returns 'true' if the configuration has been added and an empty value if
65
+ # it already exists. Reports an error if the configuration is 'used'.
66
+ #
67
+ rule register ( id )
68
+ {
69
+ if $(id) in $(self.used)
70
+ {
71
+ errors.error "common: the configuration '$(id)' is in use" ;
72
+ }
73
+
74
+ local retval ;
75
+
76
+ if ! $(id) in $(self.all)
77
+ {
78
+ self.all += $(id) ;
79
+
80
+ # Indicate that a new configuration has been added.
81
+ retval = true ;
82
+ }
83
+
84
+ return $(retval) ;
85
+ }
86
+
87
+ # Mark a configuration as 'used'.
88
+ #
89
+ # Returns 'true' if the state of the configuration has been changed to
90
+ # 'used' and an empty value if it the state has not been changed. Reports an
91
+ # error if the configuration is not known.
92
+ #
93
+ rule use ( id )
94
+ {
95
+ if ! $(id) in $(self.all)
96
+ {
97
+ errors.error "common: the configuration '$(id)' is not known" ;
98
+ }
99
+
100
+ local retval ;
101
+
102
+ if ! $(id) in $(self.used)
103
+ {
104
+ self.used += $(id) ;
105
+
106
+ # Indicate that the configuration has been marked as 'used'.
107
+ retval = true ;
108
+ }
109
+
110
+ return $(retval) ;
111
+ }
112
+
113
+ # Return all registered configurations.
114
+ #
115
+ rule all ( )
116
+ {
117
+ return $(self.all) ;
118
+ }
119
+
120
+ # Return all used configurations.
121
+ #
122
+ rule used ( )
123
+ {
124
+ return $(self.used) ;
125
+ }
126
+
127
+ # Returns the value of a configuration parameter.
128
+ #
129
+ rule get ( id : param )
130
+ {
131
+ return $(self.$(param).$(id)) ;
132
+ }
133
+
134
+ # Sets the value of a configuration parameter.
135
+ #
136
+ rule set ( id : param : value * )
137
+ {
138
+ self.$(param).$(id) = $(value) ;
139
+ }
140
+ }
141
+
142
+
143
+ # The rule for checking toolset parameters. Trailing parameters should all be
144
+ # parameter name/value pairs. The rule will check that each parameter either has
145
+ # a value in each invocation or has no value in each invocation. Also, the rule
146
+ # will check that the combination of all parameter values is unique in all
147
+ # invocations.
148
+ #
149
+ # Each parameter name corresponds to a subfeature. This rule will declare a
150
+ # subfeature the first time a non-empty parameter value is passed and will
151
+ # extend it with all the values.
152
+ #
153
+ # The return value from this rule is a condition to be used for flags settings.
154
+ #
155
+ rule check-init-parameters ( toolset requirement * : * )
156
+ {
157
+ local sig = $(toolset) ;
158
+ local condition = <toolset>$(toolset) ;
159
+ local subcondition ;
160
+ for local index in 2 3 4 5 6 7 8 9
161
+ {
162
+ local name = $($(index)[1]) ;
163
+ local value = $($(index)[2]) ;
164
+
165
+ if $(value)-is-not-empty
166
+ {
167
+ condition = $(condition)-$(value) ;
168
+ if $(.had-unspecified-value.$(toolset).$(name))
169
+ {
170
+ errors.user-error
171
+ "$(toolset) initialization: parameter '$(name)'"
172
+ "inconsistent" : "no value was specified in earlier"
173
+ "initialization" : "an explicit value is specified now" ;
174
+ }
175
+ # The below logic is for intel compiler. It calls this rule with
176
+ # 'intel-linux' and 'intel-win' as toolset, so we need to get the
177
+ # base part of toolset name. We can not pass 'intel' as toolset
178
+ # because in that case it will be impossible to register versionless
179
+ # intel-linux and intel-win toolsets of a specific version.
180
+ local t = $(toolset) ;
181
+ local m = [ MATCH ([^-]*)- : $(toolset) ] ;
182
+ if $(m)
183
+ {
184
+ t = $(m[1]) ;
185
+ }
186
+ if ! $(.had-value.$(toolset).$(name))
187
+ {
188
+ if ! $(.declared-subfeature.$(t).$(name))
189
+ {
190
+ feature.subfeature toolset $(t) : $(name) : : propagated ;
191
+ .declared-subfeature.$(t).$(name) = true ;
192
+ }
193
+ .had-value.$(toolset).$(name) = true ;
194
+ }
195
+ feature.extend-subfeature toolset $(t) : $(name) : $(value) ;
196
+ subcondition += <toolset-$(t):$(name)>$(value) ;
197
+ }
198
+ else
199
+ {
200
+ if $(.had-value.$(toolset).$(name))
201
+ {
202
+ errors.user-error
203
+ "$(toolset) initialization: parameter '$(name)'"
204
+ "inconsistent" : "an explicit value was specified in an"
205
+ "earlier initialization" : "no value is specified now" ;
206
+ }
207
+ .had-unspecified-value.$(toolset).$(name) = true ;
208
+ }
209
+ sig = $(sig)$(value:E="")- ;
210
+ }
211
+ if $(sig) in $(.all-signatures)
212
+ {
213
+ local message =
214
+ "duplicate initialization of $(toolset) with the following parameters: " ;
215
+ for local index in 2 3 4 5 6 7 8 9
216
+ {
217
+ local p = $($(index)) ;
218
+ if $(p)
219
+ {
220
+ message += "$(p[1]) = $(p[2]:E=<unspecified>)" ;
221
+ }
222
+ }
223
+ message += "previous initialization at $(.init-loc.$(sig))" ;
224
+ errors.user-error
225
+ $(message[1]) : $(message[2]) : $(message[3]) : $(message[4]) :
226
+ $(message[5]) : $(message[6]) : $(message[7]) : $(message[8]) ;
227
+ }
228
+ .all-signatures += $(sig) ;
229
+ .init-loc.$(sig) = [ errors.nearest-user-location ] ;
230
+
231
+ # If we have a requirement, this version should only be applied under that
232
+ # condition. To accomplish this we add a toolset requirement that imposes
233
+ # the toolset subcondition, which encodes the version.
234
+ if $(requirement)
235
+ {
236
+ local r = <toolset>$(toolset) $(requirement) ;
237
+ r = $(r:J=,) ;
238
+ toolset.add-requirements $(r):$(subcondition) ;
239
+ }
240
+
241
+ # We add the requirements, if any, to the condition to scope the toolset
242
+ # variables and options to this specific version.
243
+ condition += $(requirement) ;
244
+
245
+ if $(.show-configuration)
246
+ {
247
+ ECHO notice: $(condition) ;
248
+ }
249
+ return $(condition:J=/) ;
250
+ }
251
+
252
+
253
+ # A helper rule to get the command to invoke some tool. If
254
+ # 'user-provided-command' is not given, tries to find binary named 'tool' in
255
+ # PATH and in the passed 'additional-path'. Otherwise, verifies that the first
256
+ # element of 'user-provided-command' is an existing program.
257
+ #
258
+ # This rule returns the command to be used when invoking the tool. If we can not
259
+ # find the tool, a warning is issued. If 'path-last' is specified, PATH is
260
+ # checked after 'additional-paths' when searching for 'tool'.
261
+ #
262
+ rule get-invocation-command-nodefault ( toolset : tool :
263
+ user-provided-command * : additional-paths * : path-last ? )
264
+ {
265
+ local command ;
266
+ if ! $(user-provided-command)
267
+ {
268
+ command = [ find-tool $(tool) : $(additional-paths) : $(path-last) ] ;
269
+ if ! $(command) && $(.debug-configuration)
270
+ {
271
+ ECHO "warning: toolset $(toolset) initialization: can not find tool $(tool)" ;
272
+ ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
273
+ }
274
+ }
275
+ else
276
+ {
277
+ command = [ check-tool $(user-provided-command) ] ;
278
+ if ! $(command) && $(.debug-configuration)
279
+ {
280
+ ECHO "warning: toolset $(toolset) initialization: " ;
281
+ ECHO "warning: can not find user-provided command " '$(user-provided-command)' ;
282
+ ECHO "warning: initialized from" [ errors.nearest-user-location ] ;
283
+ }
284
+ }
285
+
286
+ return $(command) ;
287
+ }
288
+
289
+
290
+ # Same as get-invocation-command-nodefault, except that if no tool is found,
291
+ # returns either the user-provided-command, if present, or the 'tool' parameter.
292
+ #
293
+ rule get-invocation-command ( toolset : tool : user-provided-command * :
294
+ additional-paths * : path-last ? )
295
+ {
296
+ local result = [ get-invocation-command-nodefault $(toolset) : $(tool) :
297
+ $(user-provided-command) : $(additional-paths) : $(path-last) ] ;
298
+
299
+ if ! $(result)
300
+ {
301
+ if $(user-provided-command)
302
+ {
303
+ result = $(user-provided-command) ;
304
+ }
305
+ else
306
+ {
307
+ result = $(tool) ;
308
+ }
309
+ }
310
+ return $(result) ;
311
+ }
312
+
313
+
314
+ # Given an invocation command return the absolute path to the command. This
315
+ # works even if command has no path element and was found on the PATH.
316
+ #
317
+ rule get-absolute-tool-path ( command )
318
+ {
319
+ if $(command:D)
320
+ {
321
+ return $(command:D) ;
322
+ }
323
+ else
324
+ {
325
+ local m = [ GLOB [ modules.peek : PATH Path path ] : $(command) $(command).exe ] ;
326
+ return $(m[1]:D) ;
327
+ }
328
+ }
329
+
330
+
331
+ # Attempts to find tool (binary) named 'name' in PATH and in 'additional-paths'.
332
+ # If found in PATH, returns 'name' and if found in additional paths, returns
333
+ # absolute name. If the tool is found in several directories, returns the
334
+ # first path found. Otherwise, returns an empty string. If 'path-last' is
335
+ # specified, PATH is searched after 'additional-paths'.
336
+ #
337
+ rule find-tool ( name : additional-paths * : path-last ? )
338
+ {
339
+ local path = [ path.programs-path ] ;
340
+ local match = [ path.glob $(path) : $(name) $(name).exe ] ;
341
+ local additional-match = [ path.glob $(additional-paths) : $(name) $(name).exe ] ;
342
+
343
+ local result ;
344
+ if $(path-last)
345
+ {
346
+ result = $(additional-match) ;
347
+ if ! $(result) && $(match)
348
+ {
349
+ result = $(name) ;
350
+ }
351
+ }
352
+ else
353
+ {
354
+ if $(match)
355
+ {
356
+ result = $(name) ;
357
+ }
358
+ else
359
+ {
360
+ result = $(additional-match) ;
361
+ }
362
+ }
363
+ if $(result)
364
+ {
365
+ return [ path.native $(result[1]) ] ;
366
+ }
367
+ }
368
+
369
+
370
+ # Checks if 'command' can be found either in path or is a full name to an
371
+ # existing file.
372
+ #
373
+ local rule check-tool-aux ( command )
374
+ {
375
+ if $(command:D)
376
+ {
377
+ if [ path.exists $(command) ]
378
+ # Both NT and Cygwin will run .exe files by their unqualified names.
379
+ || ( [ os.on-windows ] && [ path.exists $(command).exe ] )
380
+ # Only NT will run .bat & .cmd files by their unqualified names.
381
+ || ( ( [ os.name ] = NT ) && ( [ path.exists $(command).bat ] ||
382
+ [ path.exists $(command).cmd ] ) )
383
+ {
384
+ return $(command) ;
385
+ }
386
+ }
387
+ else
388
+ {
389
+ if [ GLOB [ modules.peek : PATH Path path ] : $(command) ]
390
+ {
391
+ return $(command) ;
392
+ }
393
+ }
394
+ }
395
+
396
+
397
+ # Checks that a tool can be invoked by 'command'. If command is not an absolute
398
+ # path, checks if it can be found in 'path'. If comand is an absolute path,
399
+ # check that it exists. Returns 'command' if ok or empty string otherwise.
400
+ #
401
+ local rule check-tool ( xcommand + )
402
+ {
403
+ if [ check-tool-aux $(xcommand[1]) ] ||
404
+ [ check-tool-aux $(xcommand[-1]) ]
405
+ {
406
+ return $(xcommand) ;
407
+ }
408
+ }
409
+
410
+
411
+ # Handle common options for toolset, specifically sets the following flag
412
+ # variables:
413
+ # - CONFIG_COMMAND to $(command)
414
+ # - OPTIONS for compile to the value of <compileflags> in $(options)
415
+ # - OPTIONS for compile.c to the value of <cflags> in $(options)
416
+ # - OPTIONS for compile.c++ to the value of <cxxflags> in $(options)
417
+ # - OPTIONS for compile.fortran to the value of <fflags> in $(options)
418
+ # - OPTIONS for link to the value of <linkflags> in $(options)
419
+ #
420
+ rule handle-options ( toolset : condition * : command * : options * )
421
+ {
422
+ if $(.debug-configuration)
423
+ {
424
+ ECHO "notice: will use '$(command)' for $(toolset), condition $(condition:E=(empty))" ;
425
+ }
426
+
427
+ # The last parameter ('unchecked') says it is OK to set flags for another
428
+ # module.
429
+ toolset.flags $(toolset) CONFIG_COMMAND $(condition) : $(command)
430
+ : unchecked ;
431
+
432
+ toolset.flags $(toolset).compile OPTIONS $(condition) :
433
+ [ feature.get-values <compileflags> : $(options) ] : unchecked ;
434
+
435
+ toolset.flags $(toolset).compile.c OPTIONS $(condition) :
436
+ [ feature.get-values <cflags> : $(options) ] : unchecked ;
437
+
438
+ toolset.flags $(toolset).compile.c++ OPTIONS $(condition) :
439
+ [ feature.get-values <cxxflags> : $(options) ] : unchecked ;
440
+
441
+ toolset.flags $(toolset).compile.fortran OPTIONS $(condition) :
442
+ [ feature.get-values <fflags> : $(options) ] : unchecked ;
443
+
444
+ toolset.flags $(toolset).link OPTIONS $(condition) :
445
+ [ feature.get-values <linkflags> : $(options) ] : unchecked ;
446
+ }
447
+
448
+
449
+ # Returns the location of the "program files" directory on a Windows platform.
450
+ #
451
+ rule get-program-files-dir ( )
452
+ {
453
+ local ProgramFiles = [ modules.peek : ProgramFiles ] ;
454
+ if $(ProgramFiles)
455
+ {
456
+ ProgramFiles = "$(ProgramFiles:J= )" ;
457
+ }
458
+ else
459
+ {
460
+ ProgramFiles = "c:\\Program Files" ;
461
+ }
462
+ return $(ProgramFiles) ;
463
+ }
464
+
465
+
466
+ if [ os.name ] = NT
467
+ {
468
+ RM = del /f /q ;
469
+ CP = copy /b ;
470
+ IGNORE = "2>nul >nul & setlocal" ;
471
+ LN ?= $(CP) ;
472
+ # Ugly hack to convince copy to set the timestamp of the
473
+ # destination to the current time by concatenating the
474
+ # source with a nonexistent file. Note that this requires
475
+ # /b (binary) as the default when concatenating files is /a (ascii).
476
+ WINDOWS-CP-HACK = "+ this-file-does-not-exist-A698EE7806899E69" ;
477
+ }
478
+ else
479
+ {
480
+ RM = rm -f ;
481
+ CP = cp ;
482
+ LN = ln ;
483
+ }
484
+
485
+
486
+ rule rm-command ( )
487
+ {
488
+ return $(RM) ;
489
+ }
490
+
491
+
492
+ rule copy-command ( )
493
+ {
494
+ return $(CP) ;
495
+ }
496
+
497
+
498
+ if "\n" = "n"
499
+ {
500
+ # Escape characters are not supported. Use ugly hacks that won't work,
501
+ # see below.
502
+ nl = "
503
+ " ;
504
+ q = "" ;
505
+ }
506
+ else
507
+ {
508
+ nl = "\n" ;
509
+ q = "\"" ;
510
+ }
511
+
512
+ # Returns the command needed to set an environment variable on the current
513
+ # platform. The variable setting persists through all following commands and is
514
+ # visible in the environment seen by subsequently executed commands. In other
515
+ # words, on Unix systems, the variable is exported, which is consistent with the
516
+ # only possible behavior on Windows systems.
517
+ #
518
+ rule variable-setting-command ( variable : value )
519
+ {
520
+ if [ os.name ] = NT
521
+ {
522
+ return "set $(variable)=$(value)$(nl)" ;
523
+ }
524
+ else
525
+ {
526
+ # If we don't have escape characters support in bjam, the below blows
527
+ # up on CYGWIN, since the $(nl) variable holds a Windows new-line \r\n
528
+ # sequence that messes up the executed export command which then reports
529
+ # that the passed variable name is incorrect.
530
+ # But we have a check for cygwin in kernel/bootstrap.jam already.
531
+ return "$(variable)=$(q)$(value)$(q)$(nl)export $(variable)$(nl)" ;
532
+ }
533
+ }
534
+
535
+
536
+ # Returns a command to sets a named shell path variable to the given NATIVE
537
+ # paths on the current platform.
538
+ #
539
+ rule path-variable-setting-command ( variable : paths * )
540
+ {
541
+ local sep = [ os.path-separator ] ;
542
+ return [ variable-setting-command $(variable) : $(paths:J=$(sep)) ] ;
543
+ }
544
+
545
+
546
+ # Returns a command that prepends the given paths to the named path variable on
547
+ # the current platform.
548
+ #
549
+ rule prepend-path-variable-command ( variable : paths * )
550
+ {
551
+ return [ path-variable-setting-command $(variable)
552
+ : $(paths) [ os.expand-variable $(variable) ] ] ;
553
+ }
554
+
555
+
556
+ # Return a command which can create a file. If 'r' is result of invocation, then
557
+ # 'r foobar' will create foobar with unspecified content. What happens if file
558
+ # already exists is unspecified.
559
+ #
560
+ rule file-creation-command ( )
561
+ {
562
+ if [ os.name ] = NT
563
+ {
564
+ # A few alternative implementations on Windows:
565
+ #
566
+ # 'type NUL >> '
567
+ # That would construct an empty file instead of a file containing
568
+ # a space and an end-of-line marker but it would also not change
569
+ # the target's timestamp in case the file already exists.
570
+ #
571
+ # 'type NUL > '
572
+ # That would construct an empty file instead of a file containing
573
+ # a space and an end-of-line marker but it would also destroy an
574
+ # already existing file by overwriting it with an empty one.
575
+ #
576
+ # I guess the best solution would be to allow Boost Jam to define
577
+ # built-in functions such as 'create a file', 'touch a file' or 'copy a
578
+ # file' which could be used from inside action code. That would allow
579
+ # completely portable operations without this kind of kludge.
580
+ # (22.02.2009.) (Jurko)
581
+ return "echo. > " ;
582
+ }
583
+ else
584
+ {
585
+ return "touch " ;
586
+ }
587
+ }
588
+
589
+
590
+ # Returns a command that may be used for 'touching' files. It is not a real
591
+ # 'touch' command on NT because it adds an empty line at the end of file but it
592
+ # works with source files.
593
+ #
594
+ rule file-touch-command ( )
595
+ {
596
+ if [ os.name ] = NT
597
+ {
598
+ return "echo. >> " ;
599
+ }
600
+ else
601
+ {
602
+ return "touch " ;
603
+ }
604
+ }
605
+
606
+
607
+ rule MkDir
608
+ {
609
+ # If dir exists, do not update it. Do this even for $(DOT).
610
+ NOUPDATE $(<) ;
611
+
612
+ if $(<) != $(DOT) && ! $($(<)-mkdir)
613
+ {
614
+ # Cheesy gate to prevent multiple invocations on same dir.
615
+ $(<)-mkdir = true ;
616
+
617
+ # Schedule the mkdir build action.
618
+ common.mkdir $(<) ;
619
+
620
+ # Prepare a Jam 'dirs' target that can be used to make the build only
621
+ # construct all the target directories.
622
+ DEPENDS dirs : $(<) ;
623
+
624
+ # Recursively create parent directories. $(<:P) = $(<)'s parent & we
625
+ # recurse until root.
626
+
627
+ local s = $(<:P) ;
628
+ if [ os.name ] = NT
629
+ {
630
+ switch $(s)
631
+ {
632
+ case *: : s = ;
633
+ case *:\\ : s = ;
634
+ }
635
+ }
636
+
637
+ if $(s)
638
+ {
639
+ if $(s) != $(<)
640
+ {
641
+ DEPENDS $(<) : $(s) ;
642
+ MkDir $(s) ;
643
+ }
644
+ else
645
+ {
646
+ NOTFILE $(s) ;
647
+ }
648
+ }
649
+ }
650
+ }
651
+
652
+
653
+ #actions MkDir1
654
+ #{
655
+ # mkdir "$(<)"
656
+ #}
657
+
658
+ # The following quick-fix actions should be replaced using the original MkDir1
659
+ # action once Boost Jam gets updated to correctly detect different paths leading
660
+ # up to the same filesystem target and triggers their build action only once.
661
+ # (todo) (04.07.2008.) (Jurko)
662
+
663
+ if [ os.name ] = NT
664
+ {
665
+ actions mkdir
666
+ {
667
+ if not exist "$(<)\\" mkdir "$(<)"
668
+ }
669
+ }
670
+ else
671
+ {
672
+ actions mkdir
673
+ {
674
+ mkdir -p "$(<)"
675
+ }
676
+ }
677
+
678
+ actions piecemeal together existing Clean
679
+ {
680
+ $(RM) "$(>)"
681
+ }
682
+
683
+
684
+ rule copy
685
+ {
686
+ }
687
+
688
+
689
+ actions copy
690
+ {
691
+ $(CP) "$(>)" $(WINDOWS-CP-HACK) "$(<)"
692
+ }
693
+
694
+
695
+ rule RmTemps
696
+ {
697
+ }
698
+
699
+
700
+ actions quietly updated piecemeal together RmTemps
701
+ {
702
+ $(RM) "$(>)" $(IGNORE)
703
+ }
704
+
705
+
706
+ actions hard-link
707
+ {
708
+ $(RM) "$(<)" 2$(NULL_OUT) $(NULL_OUT)
709
+ $(LN) "$(>)" "$(<)" $(NULL_OUT)
710
+ }
711
+
712
+
713
+ # Given a target, as given to a custom tag rule, returns a string formatted
714
+ # according to the passed format. Format is a list of properties that is
715
+ # represented in the result. For each element of format the corresponding target
716
+ # information is obtained and added to the result string. For all, but the
717
+ # literal, the format value is taken as the as string to prepend to the output
718
+ # to join the item to the rest of the result. If not given "-" is used as a
719
+ # joiner.
720
+ #
721
+ # The format options can be:
722
+ #
723
+ # <base>[joiner]
724
+ # :: The basename of the target name.
725
+ # <toolset>[joiner]
726
+ # :: The abbreviated toolset tag being used to build the target.
727
+ # <threading>[joiner]
728
+ # :: Indication of a multi-threaded build.
729
+ # <runtime>[joiner]
730
+ # :: Collective tag of the build runtime.
731
+ # <version:/version-feature | X.Y[.Z]/>[joiner]
732
+ # :: Short version tag taken from the given "version-feature" in the
733
+ # build properties. Or if not present, the literal value as the
734
+ # version number.
735
+ # <property:/property-name/>[joiner]
736
+ # :: Direct lookup of the given property-name value in the build
737
+ # properties. /property-name/ is a regular expression. E.g.
738
+ # <property:toolset-.*:flavor> will match every toolset.
739
+ # /otherwise/
740
+ # :: The literal value of the format argument.
741
+ #
742
+ # For example this format:
743
+ #
744
+ # boost_ <base> <toolset> <threading> <runtime> <version:boost-version>
745
+ #
746
+ # Might return:
747
+ #
748
+ # boost_thread-vc80-mt-gd-1_33.dll, or
749
+ # boost_regex-vc80-gd-1_33.dll
750
+ #
751
+ # The returned name also has the target type specific prefix and suffix which
752
+ # puts it in a ready form to use as the value from a custom tag rule.
753
+ #
754
+ rule format-name ( format * : name : type ? : property-set )
755
+ {
756
+ local result = "" ;
757
+ for local f in $(format)
758
+ {
759
+ switch $(f:G)
760
+ {
761
+ case <base> :
762
+ result += $(name:B) ;
763
+
764
+ case <toolset> :
765
+ result += [ join-tag $(f:G=) : [ toolset-tag $(name) : $(type) :
766
+ $(property-set) ] ] ;
767
+
768
+ case <threading> :
769
+ result += [ join-tag $(f:G=) : [ threading-tag $(name) : $(type)
770
+ : $(property-set) ] ] ;
771
+
772
+ case <runtime> :
773
+ result += [ join-tag $(f:G=) : [ runtime-tag $(name) : $(type) :
774
+ $(property-set) ] ] ;
775
+
776
+ case <qt> :
777
+ result += [ join-tag $(f:G=) : [ qt-tag $(name) : $(type) :
778
+ $(property-set) ] ] ;
779
+
780
+ case <address-model> :
781
+ result += [ join-tag $(f:G=) : [ address-model-tag $(name) : $(type) :
782
+ $(property-set) ] ] ;
783
+
784
+ case <version:*> :
785
+ local key = [ MATCH <version:(.*)> : $(f:G) ] ;
786
+ local version = [ $(property-set).get <$(key)> ] ;
787
+ version ?= $(key) ;
788
+ version = [ MATCH "^([^.]+)[.]([^.]+)[.]?([^.]*)" : $(version) ] ;
789
+ result += [ join-tag $(f:G=) : $(version[1])_$(version[2]) ] ;
790
+
791
+ case <property:*> :
792
+ local key = [ MATCH <property:(.*)> : $(f:G) ] ;
793
+ local p0 = [ MATCH <($(key))> : [ $(property-set).raw ] ] ;
794
+ if $(p0)
795
+ {
796
+ local p = [ $(property-set).get <$(p0)> ] ;
797
+ if $(p)
798
+ {
799
+ result += [ join-tag $(f:G=) : $(p) ] ;
800
+ }
801
+ }
802
+
803
+ case * :
804
+ result += $(f:G=) ;
805
+ }
806
+ }
807
+ result = [ virtual-target.add-prefix-and-suffix $(result:J=) : $(type) :
808
+ $(property-set) ] ;
809
+ return $(result) ;
810
+ }
811
+
812
+
813
+ local rule join-tag ( joiner ? : tag ? )
814
+ {
815
+ if ! $(joiner) { joiner = - ; }
816
+ return $(joiner)$(tag) ;
817
+ }
818
+
819
+
820
+ local rule toolset-tag ( name : type ? : property-set )
821
+ {
822
+ local tag = ;
823
+
824
+ local properties = [ $(property-set).raw ] ;
825
+ switch [ $(property-set).get <toolset> ]
826
+ {
827
+ case borland* : tag += bcb ;
828
+ case clang* :
829
+ {
830
+ switch [ $(property-set).get <toolset-clang:platform> ]
831
+ {
832
+ case darwin : tag += clang-darwin ;
833
+ case linux : tag += clang ;
834
+ }
835
+ }
836
+ case como* : tag += como ;
837
+ case cw : tag += cw ;
838
+ case darwin* : tag += xgcc ;
839
+ case edg* : tag += edg ;
840
+ case gcc* :
841
+ {
842
+ switch [ $(property-set).get <toolset-gcc:flavor> ]
843
+ {
844
+ case *mingw* : tag += mgw ;
845
+ case * : tag += gcc ;
846
+ }
847
+ }
848
+ case intel :
849
+ if [ $(property-set).get <toolset-intel:platform> ] = win
850
+ {
851
+ tag += iw ;
852
+ }
853
+ else
854
+ {
855
+ tag += il ;
856
+ }
857
+ case kcc* : tag += kcc ;
858
+ case kylix* : tag += bck ;
859
+ #case metrowerks* : tag += cw ;
860
+ #case mingw* : tag += mgw ;
861
+ case mipspro* : tag += mp ;
862
+ case msvc* : tag += vc ;
863
+ case qcc* : tag += qcc ;
864
+ case sun* : tag += sw ;
865
+ case tru64cxx* : tag += tru ;
866
+ case vacpp* : tag += xlc ;
867
+ }
868
+ local version = [ MATCH "<toolset.*version>([0123456789]+)[.]([0123456789]*)"
869
+ : $(properties) ] ;
870
+ # For historical reasons, vc6.0 and vc7.0 use different naming.
871
+ if $(tag) = vc
872
+ {
873
+ if $(version[1]) = 6
874
+ {
875
+ # Cancel minor version.
876
+ version = 6 ;
877
+ }
878
+ else if $(version[1]) = 7 && $(version[2]) = 0
879
+ {
880
+ version = 7 ;
881
+ }
882
+ }
883
+ # On intel, version is not added, because it does not matter and it is the
884
+ # version of vc used as backend that matters. Ideally, we should encode the
885
+ # backend version but that would break compatibility with V1.
886
+ if $(tag) = iw
887
+ {
888
+ version = ;
889
+ }
890
+
891
+ # On borland, version is not added for compatibility with V1.
892
+ if $(tag) = bcb
893
+ {
894
+ version = ;
895
+ }
896
+
897
+ tag += $(version) ;
898
+
899
+ return $(tag:J=) ;
900
+ }
901
+
902
+
903
+ local rule threading-tag ( name : type ? : property-set )
904
+ {
905
+ local tag = ;
906
+ local properties = [ $(property-set).raw ] ;
907
+ if <threading>multi in $(properties) { tag = mt ; }
908
+
909
+ return $(tag:J=) ;
910
+ }
911
+
912
+
913
+ local rule runtime-tag ( name : type ? : property-set )
914
+ {
915
+ local tag = ;
916
+
917
+ local properties = [ $(property-set).raw ] ;
918
+ if <runtime-link>static in $(properties) { tag += s ; }
919
+
920
+ # This is an ugly thing. In V1, there is code to automatically detect which
921
+ # properties affect a target. So, if <runtime-debugging> does not affect gcc
922
+ # toolset, the tag rules will not even see <runtime-debugging>. Similar
923
+ # functionality in V2 is not implemented yet, so we just check for toolsets
924
+ # known to care about runtime debugging.
925
+ if ( <toolset>msvc in $(properties) ) ||
926
+ ( <stdlib>stlport in $(properties) ) ||
927
+ ( <toolset-intel:platform>win in $(properties) )
928
+ {
929
+ if <runtime-debugging>on in $(properties) { tag += g ; }
930
+ }
931
+
932
+ if <python-debugging>on in $(properties) { tag += y ; }
933
+ if <variant>debug in $(properties) { tag += d ; }
934
+ if <stdlib>stlport in $(properties) { tag += p ; }
935
+ if <stdlib-stlport:iostream>hostios in $(properties) { tag += n ; }
936
+
937
+ return $(tag:J=) ;
938
+ }
939
+
940
+ # Create a tag for the Qt library version
941
+ # "<qt>4.6.0" will result in tag "qt460"
942
+ local rule qt-tag ( name : type ? : property-set )
943
+ {
944
+ local properties = [ $(property-set).get <qt> ] ;
945
+ local version = [ MATCH "([0123456789]+)[.]?([0123456789]*)[.]?([0123456789]*)"
946
+ : $(properties) ] ;
947
+ local tag = "qt"$(version:J=) ;
948
+ return $(tag) ;
949
+ }
950
+
951
+ # Create a tag for the address-model
952
+ # <address-model>64 will simply generate "64"
953
+ local rule address-model-tag ( name : type ? : property-set )
954
+ {
955
+ local tag = ;
956
+ local version = [ $(property-set).get <address-model> ] ;
957
+ return $(version) ;
958
+ }
959
+
960
+ rule __test__ ( )
961
+ {
962
+ import assert ;
963
+
964
+ local save-os = [ modules.peek os : .name ] ;
965
+
966
+ modules.poke os : .name : LINUX ;
967
+
968
+ assert.result "PATH=\"foo:bar:baz\"\nexport PATH\n"
969
+ : path-variable-setting-command PATH : foo bar baz ;
970
+
971
+ assert.result "PATH=\"foo:bar:$PATH\"\nexport PATH\n"
972
+ : prepend-path-variable-command PATH : foo bar ;
973
+
974
+ modules.poke os : .name : NT ;
975
+
976
+ assert.result "set PATH=foo;bar;baz\n"
977
+ : path-variable-setting-command PATH : foo bar baz ;
978
+
979
+ assert.result "set PATH=foo;bar;%PATH%\n"
980
+ : prepend-path-variable-command PATH : foo bar ;
981
+
982
+ modules.poke os : .name : $(save-os) ;
983
+ }
mosesdecoder/jam-files/boost-build/tools/como.jam ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2004.
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt
4
+ # or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ # This is a generic 'como' toolset. Depending on the current system, it
7
+ # forwards either to 'como-linux' or 'como-win' modules.
8
+
9
+ import feature ;
10
+ import os ;
11
+ import toolset ;
12
+
13
+ feature.extend toolset : como ;
14
+ feature.subfeature toolset como : platform : : propagated link-incompatible ;
15
+
16
+ rule init ( * : * )
17
+ {
18
+ if [ os.name ] = LINUX
19
+ {
20
+ toolset.using como-linux :
21
+ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
22
+ }
23
+ else
24
+ {
25
+ toolset.using como-win :
26
+ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
27
+
28
+ }
29
+ }
mosesdecoder/jam-files/boost-build/tools/cray.jam ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2001 David Abrahams.
2
+ # Copyright 2004, 2005 Markus Schoepflin.
3
+ # Copyright 2011, John Maddock
4
+ # Distributed under the Boost Software License, Version 1.0.
5
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ #
8
+ # Cray C++ Compiler
9
+ # See http://docs.cray.com/books/S-2179-50/html-S-2179-50/S-2179-50-toc.html
10
+ #
11
+
12
+ import feature generators common ;
13
+ import toolset : flags ;
14
+
15
+ feature.extend toolset : cray ;
16
+
17
+ # Inherit from Unix toolset to get library ordering magic.
18
+ toolset.inherit cray : unix ;
19
+
20
+ generators.override cray.prebuilt : builtin.lib-generator ;
21
+ generators.override cray.prebuilt : builtin.prebuilt ;
22
+ generators.override cray.searched-lib-generator : searched-lib-generator ;
23
+
24
+
25
+ rule init ( version ? : command * : options * )
26
+ {
27
+ local condition = [ common.check-init-parameters cray : version $(version) ] ;
28
+
29
+ local command = [ common.get-invocation-command cray : CC : $(command) ] ;
30
+
31
+ if $(command)
32
+ {
33
+ local root = [ common.get-absolute-tool-path $(command[-1]) ] ;
34
+
35
+ if $(root)
36
+ {
37
+ flags cray .root $(condition) : "\"$(root)\"/" ;
38
+ }
39
+ }
40
+ # If we can't find 'CC' anyway, at least show 'CC' in the commands
41
+ command ?= CC ;
42
+
43
+ common.handle-options cray : $(condition) : $(command) : $(options) ;
44
+ }
45
+
46
+ generators.register-c-compiler cray.compile.c++ : CPP : OBJ : <toolset>cray ;
47
+ generators.register-c-compiler cray.compile.c : C : OBJ : <toolset>cray ;
48
+
49
+
50
+
51
+ # No static linking as far as I can tell.
52
+ # flags cxx LINKFLAGS <runtime-link>static : -bstatic ;
53
+ flags cray.compile OPTIONS <debug-symbols>on : -Gn ;
54
+ flags cray.link OPTIONS <debug-symbols>on : -Gn ;
55
+
56
+ flags cray.compile OPTIONS <optimization>off : -O0 ;
57
+ flags cray.compile OPTIONS <optimization>speed : -O3 ;
58
+ flags cray.compile OPTIONS <optimization>space : -O1 ;
59
+
60
+ flags cray.compile OPTIONS <cflags> ;
61
+ flags cray.compile.c++ OPTIONS <cxxflags> ;
62
+ flags cray.compile DEFINES <define> ;
63
+ flags cray.compile INCLUDES <include> ;
64
+ flags cray.link OPTIONS <linkflags> ;
65
+
66
+ flags cray.link LIBPATH <library-path> ;
67
+ flags cray.link LIBRARIES <library-file> ;
68
+ flags cray.link FINDLIBS-ST <find-static-library> ;
69
+ flags cray.link FINDLIBS-SA <find-shared-library> ;
70
+
71
+ actions link bind LIBRARIES
72
+ {
73
+ $(CONFIG_COMMAND) $(OPTIONS) -o "$(<)" -L$(LIBPATH) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA)
74
+ }
75
+
76
+ # When creating dynamic libraries, we don't want to be warned about unresolved
77
+ # symbols, therefore all unresolved symbols are marked as expected by
78
+ # '-expect_unresolved *'. This also mirrors the behaviour of the GNU tool
79
+ # chain.
80
+
81
+ actions link.dll bind LIBRARIES
82
+ {
83
+ $(CONFIG_COMMAND) -shared $(OPTIONS) -o "$(<[1])" -L$(LIBPATH) "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-ST) -l$(FINDLIBS-SA)
84
+ }
85
+
86
+
87
+ # Note: Relaxed ANSI mode (-std) is used for compilation because in strict ANSI
88
+ # C89 mode (-std1) the compiler doesn't accept C++ comments in C files. As -std
89
+ # is the default, no special flag is needed.
90
+ actions compile.c
91
+ {
92
+ $(.root:E=)cc -c $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -o "$(<)" "$(>)"
93
+ }
94
+
95
+ # Note: The compiler is forced to compile the files as C++ (-x cxx) because
96
+ # otherwise it will silently ignore files with no file extension.
97
+ #
98
+ # Note: We deliberately don't suppress any warnings on the compiler command
99
+ # line, the user can always do this in a customized toolset later on.
100
+
101
+ actions compile.c++
102
+ {
103
+ $(CONFIG_COMMAND) -c -h gnu $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -o "$(<)" "$(>)"
104
+ }
105
+
106
+ # Always create archive from scratch. See the gcc toolet for rationale.
107
+ RM = [ common.rm-command ] ;
108
+ actions together piecemeal archive
109
+ {
110
+ $(RM) "$(<)"
111
+ ar rc $(<) $(>)
112
+ }
mosesdecoder/jam-files/boost-build/tools/cw.jam ADDED
@@ -0,0 +1,246 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) Reece H Dunn 2004
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or copy at
4
+ # http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ # based on the msvc.jam toolset
7
+
8
+ import property ;
9
+ import generators ;
10
+ import os ;
11
+ import type ;
12
+ import toolset : flags ;
13
+ import errors : error ;
14
+ import feature : feature get-values ;
15
+ import path ;
16
+ import sequence : unique ;
17
+ import common ;
18
+
19
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
20
+ {
21
+ .debug-configuration = true ;
22
+ }
23
+
24
+ feature.extend toolset : cw ;
25
+
26
+ toolset.add-requirements <toolset>cw,<runtime-link>shared:<threading>multi ;
27
+
28
+ nl = "
29
+ " ;
30
+
31
+ rule init ( version ? : command * : options * )
32
+ {
33
+ # TODO: fix the $(command[1]) = $(compiler) issue
34
+
35
+ setup = [ get-values <setup> : $(options) ] ;
36
+ setup ?= cwenv.bat ;
37
+ compiler = [ get-values <compiler> : $(options) ] ;
38
+ compiler ?= mwcc ;
39
+ linker = [ get-values <linker> : $(options) ] ;
40
+ linker ?= mwld ;
41
+
42
+ local condition = [ common.check-init-parameters cw :
43
+ version $(version) ] ;
44
+
45
+ command = [ common.get-invocation-command cw : mwcc.exe : $(command) :
46
+ [ default-paths $(version) ] ] ;
47
+
48
+ common.handle-options cw : $(condition) : $(command) : $(options) ;
49
+
50
+ local root = [ feature.get-values <root> : $(options) ] ;
51
+ if $(command)
52
+ {
53
+ command = [ common.get-absolute-tool-path $(command[-1]) ] ;
54
+ }
55
+ local tool-root = $(command) ;
56
+
57
+ setup = $(tool-root)\\$(setup) ;
58
+
59
+ # map the batch file in setup so it can be executed
60
+
61
+ other-tools = $(tool-root:D) ;
62
+ root ?= $(other-tools:D) ;
63
+
64
+ flags cw.link RUN_PATH $(condition) :
65
+ "$(root)\\Win32-x86 Support\\Libraries\\Runtime"
66
+ "$(root)\\Win32-x86 Support\\Libraries\\Runtime\\Libs\\MSL_All-DLLs" ;
67
+
68
+ setup = "set \"CWFOLDER="$(root)"\" && call \""$(setup)"\" > nul " ;
69
+
70
+ if [ os.name ] = NT
71
+ {
72
+ setup = $(setup)"
73
+ " ;
74
+ }
75
+ else
76
+ {
77
+ setup = "cmd /S /C "$(setup)" \"&&\" " ;
78
+ }
79
+
80
+ # bind the setup command to the tool so it can be executed before the
81
+ # command
82
+
83
+ local prefix = $(setup) ;
84
+
85
+ flags cw.compile .CC $(condition) : $(prefix)$(compiler) ;
86
+ flags cw.link .LD $(condition) : $(prefix)$(linker) ;
87
+ flags cw.archive .LD $(condition) : $(prefix)$(linker) ;
88
+
89
+ if [ MATCH ^([89]\\.) : $(version) ]
90
+ {
91
+ if [ os.name ] = NT
92
+ {
93
+ # The runtime libraries
94
+ flags cw.compile CFLAGS <runtime-link>static/<threading>single/<runtime-debugging>off : -runtime ss ;
95
+ flags cw.compile CFLAGS <runtime-link>static/<threading>single/<runtime-debugging>on : -runtime ssd ;
96
+
97
+ flags cw.compile CFLAGS <runtime-link>static/<threading>multi/<runtime-debugging>off : -runtime sm ;
98
+ flags cw.compile CFLAGS <runtime-link>static/<threading>multi/<runtime-debugging>on : -runtime smd ;
99
+
100
+ flags cw.compile CFLAGS <runtime-link>shared/<runtime-debugging>off : -runtime dm ;
101
+ flags cw.compile CFLAGS <runtime-link>shared/<runtime-debugging>on : -runtime dmd ;
102
+ }
103
+ }
104
+ }
105
+
106
+
107
+ local rule default-paths ( version ? ) # FIXME
108
+ {
109
+ local possible-paths ;
110
+ local ProgramFiles = [ common.get-program-files-dir ] ;
111
+
112
+ # TODO: add support for cw8 and cw9 detection
113
+
114
+ local version-6-path = $(ProgramFiles)"\\Metrowerks\\CodeWarrior" ;
115
+ possible-paths += $(version-6-path) ;
116
+
117
+ # perform post-processing
118
+
119
+ possible-paths
120
+ = $(possible-paths)"\\Other Metrowerks Tools\\Command Line Tools" ;
121
+
122
+ possible-paths += [ modules.peek : PATH Path path ] ;
123
+
124
+ return $(possible-paths) ;
125
+ }
126
+
127
+
128
+
129
+
130
+ ## declare generators
131
+
132
+ generators.register-c-compiler cw.compile.c++ : CPP : OBJ : <toolset>cw ;
133
+ generators.register-c-compiler cw.compile.c : C : OBJ : <toolset>cw ;
134
+
135
+ generators.register-linker cw.link
136
+ : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
137
+ : EXE
138
+ : <toolset>cw
139
+ ;
140
+ generators.register-linker cw.link.dll
141
+ : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB
142
+ : SHARED_LIB IMPORT_LIB
143
+ : <toolset>cw
144
+ ;
145
+
146
+ generators.register-archiver cw.archive
147
+ : OBJ
148
+ : STATIC_LIB
149
+ : <toolset>cw
150
+ ;
151
+
152
+ ## compilation phase
153
+
154
+ flags cw WHATEVER <toolset-cw:version> ;
155
+
156
+ flags cw.compile CFLAGS <debug-symbols>on : -g ;
157
+ flags cw.compile CFLAGS <optimization>off : -O0 ;
158
+ flags cw.compile CFLAGS <optimization>speed : -O4,p ;
159
+ flags cw.compile CFLAGS <optimization>space : -O4,s ;
160
+ flags cw.compile CFLAGS <inlining>off : -inline off ;
161
+ flags cw.compile CFLAGS <inlining>on : -inline on ;
162
+ flags cw.compile CFLAGS <inlining>full : -inline all ;
163
+ flags cw.compile CFLAGS <exception-handling>off : -Cpp_exceptions off ;
164
+
165
+
166
+ flags cw.compile CFLAGS <rtti>on : -RTTI on ;
167
+ flags cw.compile CFLAGS <rtti>off : -RTTI off ;
168
+
169
+ flags cw.compile CFLAGS <warnings>on : -w on ;
170
+ flags cw.compile CFLAGS <warnings>off : -w off ;
171
+ flags cw.compile CFLAGS <warnings>all : -w all ;
172
+ flags cw.compile CFLAGS <warnings-as-errors>on : -w error ;
173
+
174
+ flags cw.compile USER_CFLAGS <cflags> : ;
175
+ flags cw.compile.c++ USER_CFLAGS <cxxflags> : ;
176
+
177
+ flags cw.compile DEFINES <define> ;
178
+ flags cw.compile UNDEFS <undef> ;
179
+ flags cw.compile INCLUDES <include> ;
180
+
181
+ actions compile.c
182
+ {
183
+ $(.CC) -c -cwd include -lang c -U$(UNDEFS) $(CFLAGS) $(USER_CFLAGS) -I- -o "$(<)" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES)")"
184
+ }
185
+ actions compile.c++
186
+ {
187
+ $(.CC) -c -cwd include -lang c++ -U$(UNDEFS) $(CFLAGS) $(USER_CFLAGS) -I- -o "$(<)" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)-D$(DEFINES) $(nl)"-I$(INCLUDES)")"
188
+ }
189
+
190
+ ## linking phase
191
+
192
+ flags cw.link DEF_FILE <def-file> ;
193
+
194
+ flags cw LINKFLAGS : -search ;
195
+ flags cw LINKFLAGS <debug-symbols>on : -g ;
196
+ flags cw LINKFLAGS <user-interface>console : -subsystem console ;
197
+ flags cw LINKFLAGS <user-interface>gui : -subsystem windows ;
198
+ flags cw LINKFLAGS <user-interface>wince : -subsystem wince ;
199
+ flags cw LINKFLAGS <user-interface>native : -subsystem native ;
200
+ flags cw LINKFLAGS <user-interface>auto : -subsystem auto ;
201
+
202
+ flags cw LINKFLAGS <main-target-type>LIB/<link>static : -library ;
203
+
204
+ flags cw.link USER_LINKFLAGS <linkflags> ;
205
+ flags cw.link LINKPATH <library-path> ;
206
+
207
+ flags cw.link FINDLIBS_ST <find-static-library> ;
208
+ flags cw.link FINDLIBS_SA <find-shared-library> ;
209
+ flags cw.link LIBRARY_OPTION <toolset>cw : "" : unchecked ;
210
+ flags cw.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
211
+
212
+ rule link.dll ( targets + : sources * : properties * )
213
+ {
214
+ DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
215
+ }
216
+
217
+ if [ os.name ] in NT
218
+ {
219
+ actions archive
220
+ {
221
+ if exist "$(<[1])" DEL "$(<[1])"
222
+ $(.LD) -library -o "$(<[1])" @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")"
223
+ }
224
+ }
225
+ else # cygwin
226
+ {
227
+ actions archive
228
+ {
229
+ _bbv2_out_="$(<)"
230
+ if test -f "$_bbv2_out_" ; then
231
+ _bbv2_existing_="$(<:W)"
232
+ fi
233
+ $(.LD) -library -o "$(<:W)" $_bbv2_existing_ @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")"
234
+ }
235
+ }
236
+
237
+ actions link bind DEF_FILE
238
+ {
239
+ $(.LD) -o "$(<[1]:W)" -L"$(LINKPATH)" $(LINKFLAGS) $(USER_LINKFLAGS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")"
240
+ }
241
+
242
+ actions link.dll bind DEF_FILE
243
+ {
244
+ $(.LD) -shared -o "$(<[1]:W)" -implib "$(<[2]:W)" -L"$(LINKPATH)" $(LINKFLAGS) -f"$(DEF_FILE)" $(USER_LINKFLAGS) @"@($(<[1]:W).rsp:E=$(nl)"$(>)" $(nl)$(LIBRARIES_MENTIONED_BY_FILE) $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST:S=.lib)" $(nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA:S=.lib)")"
245
+ }
246
+
mosesdecoder/jam-files/boost-build/tools/darwin.jam ADDED
@@ -0,0 +1,583 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003 Christopher Currie
2
+ # Copyright 2006 Dave Abrahams
3
+ # Copyright 2003, 2004, 2005, 2006 Vladimir Prus
4
+ # Copyright 2005-2007 Mat Marcus
5
+ # Copyright 2005-2007 Adobe Systems Incorporated
6
+ # Copyright 2007-2010 Rene Rivera
7
+ # Distributed under the Boost Software License, Version 1.0.
8
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
9
+
10
+ # Please see http://article.gmane.org/gmane.comp.lib.boost.build/3389/
11
+ # for explanation why it's a separate toolset.
12
+
13
+ import feature : feature ;
14
+ import toolset : flags ;
15
+ import type ;
16
+ import common ;
17
+ import generators ;
18
+ import path : basename ;
19
+ import version ;
20
+ import property-set ;
21
+ import regex ;
22
+ import errors ;
23
+
24
+ ## Use a framework.
25
+ feature framework : : free ;
26
+
27
+ ## The MacOSX version to compile for, which maps to the SDK to use (sysroot).
28
+ feature macosx-version : : propagated link-incompatible symmetric optional ;
29
+
30
+ ## The minimal MacOSX version to target.
31
+ feature macosx-version-min : : propagated optional ;
32
+
33
+ ## A dependency, that is forced to be included in the link.
34
+ feature force-load : : free dependency incidental ;
35
+
36
+ #############################################################################
37
+
38
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
39
+ {
40
+ .debug-configuration = true ;
41
+ }
42
+
43
+ feature.extend toolset : darwin ;
44
+ import gcc ;
45
+ toolset.inherit-generators darwin : gcc : gcc.mingw.link gcc.mingw.link.dll ;
46
+
47
+ generators.override darwin.prebuilt : builtin.prebuilt ;
48
+ generators.override darwin.searched-lib-generator : searched-lib-generator ;
49
+
50
+ # Override default do-nothing generators.
51
+ generators.override darwin.compile.c.pch : pch.default-c-pch-generator ;
52
+ generators.override darwin.compile.c++.pch : pch.default-cpp-pch-generator ;
53
+
54
+ type.set-generated-target-suffix PCH : <toolset>darwin : gch ;
55
+
56
+ toolset.inherit-rules darwin : gcc : localize ;
57
+ toolset.inherit-flags darwin : gcc
58
+ : <runtime-link>static
59
+ <architecture>arm/<address-model>32
60
+ <architecture>arm/<address-model>64
61
+ <architecture>arm/<instruction-set>
62
+ <architecture>x86/<address-model>32
63
+ <architecture>x86/<address-model>64
64
+ <architecture>x86/<instruction-set>
65
+ <architecture>power/<address-model>32
66
+ <architecture>power/<address-model>64
67
+ <architecture>power/<instruction-set> ;
68
+
69
+ # Options:
70
+ #
71
+ # <root>PATH
72
+ # Platform root path. The common autodetection will set this to
73
+ # "/Developer". And when a command is given it will be set to
74
+ # the corresponding "*.platform/Developer" directory.
75
+ #
76
+ rule init ( version ? : command * : options * : requirement * )
77
+ {
78
+ # First time around, figure what is host OSX version
79
+ if ! $(.host-osx-version)
80
+ {
81
+ .host-osx-version = [ MATCH "^([0-9.]+)"
82
+ : [ SHELL "/usr/bin/sw_vers -productVersion" ] ] ;
83
+ if $(.debug-configuration)
84
+ {
85
+ ECHO notice: OSX version on this machine is $(.host-osx-version) ;
86
+ }
87
+ }
88
+
89
+ # - The root directory of the tool install.
90
+ local root = [ feature.get-values <root> : $(options) ] ;
91
+
92
+ # - The bin directory where to find the commands to execute.
93
+ local bin ;
94
+
95
+ # - The configured compile driver command.
96
+ local command = [ common.get-invocation-command darwin : g++ : $(command) ] ;
97
+
98
+ # The version as reported by the compiler
99
+ local real-version ;
100
+
101
+ # - Autodetect the root and bin dir if not given.
102
+ if $(command)
103
+ {
104
+ bin ?= [ common.get-absolute-tool-path $(command[1]) ] ;
105
+ if $(bin) = "/usr/bin"
106
+ {
107
+ root ?= /Developer ;
108
+ }
109
+ else
110
+ {
111
+ local r = $(bin:D) ;
112
+ r = $(r:D) ;
113
+ root ?= $(r) ;
114
+ }
115
+ }
116
+
117
+ # - Autodetect the version if not given.
118
+ if $(command)
119
+ {
120
+ # - The 'command' variable can have multiple elements. When calling
121
+ # the SHELL builtin we need a single string.
122
+ local command-string = $(command:J=" ") ;
123
+ real-version = [ MATCH "^([0-9.]+)"
124
+ : [ SHELL "$(command-string) -dumpversion" ] ] ;
125
+ version ?= $(real-version) ;
126
+ }
127
+
128
+ .real-version.$(version) = $(real-version) ;
129
+
130
+ # - Define the condition for this toolset instance.
131
+ local condition =
132
+ [ common.check-init-parameters darwin $(requirement) : version $(version) ] ;
133
+
134
+ # - Set the toolset generic common options.
135
+ common.handle-options darwin : $(condition) : $(command) : $(options) ;
136
+
137
+ # - GCC 4.0 and higher in Darwin does not have -fcoalesce-templates.
138
+ if $(real-version) < "4.0.0"
139
+ {
140
+ flags darwin.compile.c++ OPTIONS $(condition) : -fcoalesce-templates ;
141
+ }
142
+ # - GCC 4.2 and higher in Darwin does not have -Wno-long-double.
143
+ if $(real-version) < "4.2.0"
144
+ {
145
+ flags darwin.compile OPTIONS $(condition) : -Wno-long-double ;
146
+ }
147
+
148
+ # - Set the link flags common with the GCC toolset.
149
+ gcc.init-link-flags darwin darwin $(condition) ;
150
+
151
+ # - The symbol strip program.
152
+ local strip ;
153
+ if <striper> in $(options)
154
+ {
155
+ # We can turn off strip by specifying it as empty. In which
156
+ # case we switch to using the linker to do the strip.
157
+ flags darwin.link.dll OPTIONS
158
+ $(condition)/<main-target-type>LIB/<link>shared/<address-model>32/<strip>on : -Wl,-x ;
159
+ flags darwin.link.dll OPTIONS
160
+ $(condition)/<main-target-type>LIB/<link>shared/<address-model>/<strip>on : -Wl,-x ;
161
+ flags darwin.link OPTIONS
162
+ $(condition)/<main-target-type>EXE/<address-model>32/<strip>on : -s ;
163
+ flags darwin.link OPTIONS
164
+ $(condition)/<main-target-type>EXE/<address-model>/<strip>on : -s ;
165
+ }
166
+ else
167
+ {
168
+ # Otherwise we need to find a strip program to use. And hence
169
+ # also tell the link action that we need to use a strip
170
+ # post-process.
171
+ flags darwin.link NEED_STRIP $(condition)/<strip>on : "" ;
172
+ strip =
173
+ [ common.get-invocation-command darwin
174
+ : strip : [ feature.get-values <striper> : $(options) ] : $(bin) : search-path ] ;
175
+ flags darwin.link .STRIP $(condition) : $(strip[1]) ;
176
+ if $(.debug-configuration)
177
+ {
178
+ ECHO notice: using strip for $(condition) at $(strip[1]) ;
179
+ }
180
+ }
181
+
182
+ # - The archive builder (libtool is the default as creating
183
+ # archives in darwin is complicated.
184
+ local archiver =
185
+ [ common.get-invocation-command darwin
186
+ : libtool : [ feature.get-values <archiver> : $(options) ] : $(bin) : search-path ] ;
187
+ flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ;
188
+ if $(.debug-configuration)
189
+ {
190
+ ECHO notice: using archiver for $(condition) at $(archiver[1]) ;
191
+ }
192
+
193
+ # - Initialize the SDKs available in the root for this tool.
194
+ local sdks = [ init-available-sdk-versions $(condition) : $(root) ] ;
195
+
196
+ #~ ECHO --- ;
197
+ #~ ECHO --- bin :: $(bin) ;
198
+ #~ ECHO --- root :: $(root) ;
199
+ #~ ECHO --- version :: $(version) ;
200
+ #~ ECHO --- condition :: $(condition) ;
201
+ #~ ECHO --- strip :: $(strip) ;
202
+ #~ ECHO --- archiver :: $(archiver) ;
203
+ #~ ECHO --- sdks :: $(sdks) ;
204
+ #~ ECHO --- ;
205
+ #~ EXIT ;
206
+ }
207
+
208
+ # Add and set options for a discovered SDK version.
209
+ local rule init-sdk ( condition * : root ? : version + : version-feature ? )
210
+ {
211
+ local rule version-to-feature ( version + )
212
+ {
213
+ switch $(version[1])
214
+ {
215
+ case iphone* :
216
+ {
217
+ return $(version[1])-$(version[2-]:J=.) ;
218
+ }
219
+ case mac* :
220
+ {
221
+ return $(version[2-]:J=.) ;
222
+ }
223
+ case * :
224
+ {
225
+ return $(version:J=.) ;
226
+ }
227
+ }
228
+ }
229
+
230
+ if $(version-feature)
231
+ {
232
+ if $(.debug-configuration)
233
+ {
234
+ ECHO notice: available sdk for $(condition)/<macosx-version>$(version-feature) at $(root) ;
235
+ }
236
+
237
+ # Add the version to the features for specifying them.
238
+ if ! $(version-feature) in [ feature.values macosx-version ]
239
+ {
240
+ feature.extend macosx-version : $(version-feature) ;
241
+ }
242
+ if ! $(version-feature) in [ feature.values macosx-version-min ]
243
+ {
244
+ feature.extend macosx-version-min : $(version-feature) ;
245
+ }
246
+
247
+ # Set the flags the version needs to compile with, first
248
+ # generic options.
249
+ flags darwin.compile OPTIONS $(condition)/<macosx-version>$(version-feature)
250
+ : -isysroot $(root) ;
251
+ flags darwin.link OPTIONS $(condition)/<macosx-version>$(version-feature)
252
+ : -isysroot $(root) ;
253
+
254
+ # Then device variation options.
255
+ switch $(version[1])
256
+ {
257
+ case iphonesim* :
258
+ {
259
+ local N = $(version[2]) ;
260
+ if ! $(version[3]) { N += 00 ; }
261
+ else if [ regex.match (..) : $(version[3]) ] { N += $(version[3]) ; }
262
+ else { N += 0$(version[3]) ; }
263
+ if ! $(version[4]) { N += 00 ; }
264
+ else if [ regex.match (..) : $(version[4]) ] { N += $(version[4]) ; }
265
+ else { N += 0$(version[4]) ; }
266
+ N = $(N:J=) ;
267
+ flags darwin.compile OPTIONS <macosx-version-min>$(version-feature)
268
+ : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ;
269
+ flags darwin.link OPTIONS <macosx-version-min>$(version-feature)
270
+ : -D__IPHONE_OS_VERSION_MIN_REQUIRED=$(N) ;
271
+ }
272
+
273
+ case iphone* :
274
+ {
275
+ flags darwin.compile OPTIONS <macosx-version-min>$(version-feature)
276
+ : -miphoneos-version-min=$(version[2-]:J=.) ;
277
+ flags darwin.link OPTIONS <macosx-version-min>$(version-feature)
278
+ : -miphoneos-version-min=$(version[2-]:J=.) ;
279
+ }
280
+
281
+ case mac* :
282
+ {
283
+ flags darwin.compile OPTIONS <macosx-version-min>$(version-feature)
284
+ : -mmacosx-version-min=$(version[2-]:J=.) ;
285
+ flags darwin.link OPTIONS <macosx-version-min>$(version-feature)
286
+ : -mmacosx-version-min=$(version[2-]:J=.) ;
287
+ }
288
+ }
289
+
290
+ if $(version[3]) > 0
291
+ {
292
+ # We have a minor version of an SDK. We want to set up
293
+ # previous minor versions, plus the current minor version.
294
+ # So we recurse to set up the previous minor versions, up to
295
+ # the current version.
296
+ local minor-minus-1 = [ CALC $(version[3]) - 1 ] ;
297
+ return
298
+ [ init-sdk $(condition) : $(root)
299
+ : $(version[1-2]) $(minor-minus-1) : [ version-to-feature $(version[1-2]) $(minor-minus-1) ] ]
300
+ $(version-feature) ;
301
+ }
302
+ else
303
+ {
304
+ return $(version-feature) ;
305
+ }
306
+ }
307
+ else if $(version[4])
308
+ {
309
+ # We have a patch version of an SDK. We want to set up
310
+ # both the specific patch version, and the minor version.
311
+ # So we recurse to set up the patch version. Plus the minor version.
312
+ return
313
+ [ init-sdk $(condition) : $(root)
314
+ : $(version[1-3]) : [ version-to-feature $(version[1-3]) ] ]
315
+ [ init-sdk $(condition) : $(root)
316
+ : $(version) : [ version-to-feature $(version) ] ] ;
317
+ }
318
+ else
319
+ {
320
+ # Yes, this is intentionally recursive.
321
+ return
322
+ [ init-sdk $(condition) : $(root)
323
+ : $(version) : [ version-to-feature $(version) ] ] ;
324
+ }
325
+ }
326
+
327
+ # Determine the MacOSX SDK versions installed and their locations.
328
+ local rule init-available-sdk-versions ( condition * : root ? )
329
+ {
330
+ root ?= /Developer ;
331
+ local sdks-root = $(root)/SDKs ;
332
+ local sdks = [ GLOB $(sdks-root) : MacOSX*.sdk iPhoneOS*.sdk iPhoneSimulator*.sdk ] ;
333
+ local result ;
334
+ for local sdk in $(sdks)
335
+ {
336
+ local sdk-match = [ MATCH ([^0-9]+)([0-9]+)[.]([0-9x]+)[.]?([0-9x]+)? : $(sdk:D=) ] ;
337
+ local sdk-platform = $(sdk-match[1]:L) ;
338
+ local sdk-version = $(sdk-match[2-]) ;
339
+ if $(sdk-version)
340
+ {
341
+ switch $(sdk-platform)
342
+ {
343
+ case macosx :
344
+ {
345
+ sdk-version = mac $(sdk-version) ;
346
+ }
347
+ case iphoneos :
348
+ {
349
+ sdk-version = iphone $(sdk-version) ;
350
+ }
351
+ case iphonesimulator :
352
+ {
353
+ sdk-version = iphonesim $(sdk-version) ;
354
+ }
355
+ case * :
356
+ {
357
+ sdk-version = $(sdk-version:J=-) ;
358
+ }
359
+ }
360
+ result += [ init-sdk $(condition) : $(sdk) : $(sdk-version) ] ;
361
+ }
362
+ }
363
+ return $(result) ;
364
+ }
365
+
366
+ # Generic options.
367
+ flags darwin.compile OPTIONS <flags> ;
368
+
369
+ # The following adds objective-c support to darwin.
370
+ # Thanks to http://thread.gmane.org/gmane.comp.lib.boost.build/13759
371
+
372
+ generators.register-c-compiler darwin.compile.m : OBJECTIVE_C : OBJ : <toolset>darwin ;
373
+ generators.register-c-compiler darwin.compile.mm : OBJECTIVE_CPP : OBJ : <toolset>darwin ;
374
+
375
+ rule setup-address-model ( targets * : sources * : properties * )
376
+ {
377
+ local ps = [ property-set.create $(properties) ] ;
378
+ local arch = [ $(ps).get <architecture> ] ;
379
+ local address-model = [ $(ps).get <address-model> ] ;
380
+ local osx-version = [ $(ps).get <macosx-version> ] ;
381
+ local gcc-version = [ $(ps).get <toolset-darwin:version> ] ;
382
+ gcc-version = $(.real-version.$(gcc-version)) ;
383
+ local options ;
384
+
385
+ local support-ppc64 = 1 ;
386
+
387
+ osx-version ?= $(.host-osx-version) ;
388
+
389
+ switch $(osx-version)
390
+ {
391
+ case iphone* :
392
+ {
393
+ support-ppc64 = ;
394
+ }
395
+
396
+ case * :
397
+ if $(osx-version) && ! [ version.version-less [ regex.split $(osx-version) \\. ] : 10 6 ]
398
+ {
399
+ # When targeting 10.6:
400
+ # - gcc 4.2 will give a compiler errir if ppc64 compilation is requested
401
+ # - gcc 4.0 will compile fine, somehow, but then fail at link time
402
+ support-ppc64 = ;
403
+ }
404
+ }
405
+ switch $(arch)
406
+ {
407
+ case combined :
408
+ {
409
+ if $(address-model) = 32_64 {
410
+ if $(support-ppc64) {
411
+ options = -arch i386 -arch ppc -arch x86_64 -arch ppc64 ;
412
+ } else {
413
+ # Build 3-way binary
414
+ options = -arch i386 -arch ppc -arch x86_64 ;
415
+ }
416
+ } else if $(address-model) = 64 {
417
+ if $(support-ppc64) {
418
+ options = -arch x86_64 -arch ppc64 ;
419
+ } else {
420
+ errors.user-error "64-bit PPC compilation is not supported when targeting OSX 10.6 or later" ;
421
+ }
422
+ } else {
423
+ options = -arch i386 -arch ppc ;
424
+ }
425
+ }
426
+
427
+ case x86 :
428
+ {
429
+ if $(address-model) = 32_64 {
430
+ options = -arch i386 -arch x86_64 ;
431
+ } else if $(address-model) = 64 {
432
+ options = -arch x86_64 ;
433
+ } else {
434
+ options = -arch i386 ;
435
+ }
436
+ }
437
+
438
+ case power :
439
+ {
440
+ if ! $(support-ppc64)
441
+ && ( $(address-model) = 32_64 || $(address-model) = 64 )
442
+ {
443
+ errors.user-error "64-bit PPC compilation is not supported when targeting OSX 10.6 or later" ;
444
+ }
445
+
446
+ if $(address-model) = 32_64 {
447
+ options = -arch ppc -arch ppc64 ;
448
+ } else if $(address-model) = 64 {
449
+ options = -arch ppc64 ;
450
+ } else {
451
+ options = -arch ppc ;
452
+ }
453
+ }
454
+
455
+ case arm :
456
+ {
457
+ options = -arch armv6 ;
458
+ }
459
+ }
460
+
461
+ if $(options)
462
+ {
463
+ OPTIONS on $(targets) += $(options) ;
464
+ }
465
+ }
466
+
467
+ rule setup-threading ( targets * : sources * : properties * )
468
+ {
469
+ gcc.setup-threading $(targets) : $(sources) : $(properties) ;
470
+ }
471
+
472
+ rule setup-fpic ( targets * : sources * : properties * )
473
+ {
474
+ gcc.setup-fpic $(targets) : $(sources) : $(properties) ;
475
+ }
476
+
477
+ rule compile.m ( targets * : sources * : properties * )
478
+ {
479
+ LANG on $(<) = "-x objective-c" ;
480
+ gcc.setup-fpic $(targets) : $(sources) : $(properties) ;
481
+ setup-address-model $(targets) : $(sources) : $(properties) ;
482
+ }
483
+
484
+ actions compile.m
485
+ {
486
+ "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
487
+ }
488
+
489
+ rule compile.mm ( targets * : sources * : properties * )
490
+ {
491
+ LANG on $(<) = "-x objective-c++" ;
492
+ gcc.setup-fpic $(targets) : $(sources) : $(properties) ;
493
+ setup-address-model $(targets) : $(sources) : $(properties) ;
494
+ }
495
+
496
+ actions compile.mm
497
+ {
498
+ "$(CONFIG_COMMAND)" $(LANG) $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
499
+ }
500
+
501
+ # Set the max header padding to allow renaming of libs for installation.
502
+ flags darwin.link.dll OPTIONS : -headerpad_max_install_names ;
503
+
504
+ # To link the static runtime we need to link to all the core runtime libraries.
505
+ flags darwin.link OPTIONS <runtime-link>static
506
+ : -nodefaultlibs -shared-libgcc -lstdc++-static -lgcc_eh -lgcc -lSystem ;
507
+
508
+ # Strip as much as possible when optimizing.
509
+ flags darwin.link OPTIONS <optimization>speed : -Wl,-dead_strip -no_dead_strip_inits_and_terms ;
510
+ flags darwin.link OPTIONS <optimization>space : -Wl,-dead_strip -no_dead_strip_inits_and_terms ;
511
+
512
+ # Dynamic/shared linking.
513
+ flags darwin.compile OPTIONS <link>shared : -dynamic ;
514
+
515
+ # Misc options.
516
+ flags darwin.compile OPTIONS : -gdwarf-2 -fexceptions ;
517
+ #~ flags darwin.link OPTIONS : -fexceptions ;
518
+
519
+ # Add the framework names to use.
520
+ flags darwin.link FRAMEWORK <framework> ;
521
+
522
+ #
523
+ flags darwin.link FORCE_LOAD <force-load> ;
524
+
525
+ # This is flag is useful for debugging the link step
526
+ # uncomment to see what libtool is doing under the hood
527
+ #~ flags darwin.link.dll OPTIONS : -Wl,-v ;
528
+
529
+ _ = " " ;
530
+
531
+ # set up the -F option to include the paths to any frameworks used.
532
+ local rule prepare-framework-path ( target + )
533
+ {
534
+ # The -framework option only takes basename of the framework.
535
+ # The -F option specifies the directories where a framework
536
+ # is searched for. So, if we find <framework> feature
537
+ # with some path, we need to generate property -F option.
538
+ local framework-paths = [ on $(target) return $(FRAMEWORK:D) ] ;
539
+
540
+ # Be sure to generate no -F if there's no path.
541
+ for local framework-path in $(framework-paths)
542
+ {
543
+ if $(framework-path) != ""
544
+ {
545
+ FRAMEWORK_PATH on $(target) += -F$(framework-path) ;
546
+ }
547
+ }
548
+ }
549
+
550
+ rule link ( targets * : sources * : properties * )
551
+ {
552
+ DEPENDS $(targets) : [ on $(targets) return $(FORCE_LOAD) ] ;
553
+ setup-address-model $(targets) : $(sources) : $(properties) ;
554
+ prepare-framework-path $(<) ;
555
+ }
556
+
557
+ # Note that using strip without any options was reported to result in broken
558
+ # binaries, at least on OS X 10.5.5, see:
559
+ # http://svn.boost.org/trac/boost/ticket/2347
560
+ # So we pass -S -x.
561
+ actions link bind LIBRARIES FORCE_LOAD
562
+ {
563
+ "$(CONFIG_COMMAND)" -L"$(LINKPATH)" -o "$(<)" "$(>)" -Wl,-force_load$(_)"$(FORCE_LOAD)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
564
+ $(NEED_STRIP)"$(.STRIP)" $(NEED_STRIP)-S $(NEED_STRIP)-x $(NEED_STRIP)"$(<)"
565
+ }
566
+
567
+ rule link.dll ( targets * : sources * : properties * )
568
+ {
569
+ setup-address-model $(targets) : $(sources) : $(properties) ;
570
+ prepare-framework-path $(<) ;
571
+ }
572
+
573
+ actions link.dll bind LIBRARIES
574
+ {
575
+ "$(CONFIG_COMMAND)" -dynamiclib -Wl,-single_module -install_name "$(<:B)$(<:S)" -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(FRAMEWORK_PATH) -framework$(_)$(FRAMEWORK:D=:S=) $(OPTIONS) $(USER_OPTIONS)
576
+ }
577
+
578
+ # We use libtool instead of ar to support universal binary linking
579
+ # TODO: Find a way to use the underlying tools, i.e. lipo, to do this.
580
+ actions piecemeal archive
581
+ {
582
+ "$(.LIBTOOL)" -static -o "$(<:T)" $(ARFLAGS) "$(>:T)"
583
+ }
mosesdecoder/jam-files/boost-build/tools/docutils.jam ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright David Abrahams 2004. Distributed under the Boost
2
+ # Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Support for docutils ReStructuredText processing.
6
+
7
+ import type ;
8
+ import scanner ;
9
+ import generators ;
10
+ import os ;
11
+ import common ;
12
+ import toolset ;
13
+ import path ;
14
+ import feature : feature ;
15
+ import property ;
16
+
17
+ .initialized = ;
18
+
19
+ type.register ReST : rst ;
20
+
21
+ class rst-scanner : common-scanner
22
+ {
23
+ rule __init__ ( paths * )
24
+ {
25
+ common-scanner.__init__ . $(paths) ;
26
+ }
27
+
28
+ rule pattern ( )
29
+ {
30
+ return "^[ ]*\\.\\.[ ]+include::[ ]+([^
31
+ ]+)"
32
+ "^[ ]*\\.\\.[ ]+image::[ ]+([^
33
+ ]+)"
34
+ "^[ ]*\\.\\.[ ]+figure::[ ]+([^
35
+ ]+)"
36
+ ;
37
+ }
38
+ }
39
+
40
+ scanner.register rst-scanner : include ;
41
+ type.set-scanner ReST : rst-scanner ;
42
+
43
+ generators.register-standard docutils.html : ReST : HTML ;
44
+
45
+ rule init ( docutils-dir ? : tools-dir ? )
46
+ {
47
+ docutils-dir ?= [ modules.peek : DOCUTILS_DIR ] ;
48
+ tools-dir ?= $(docutils-dir)/tools ;
49
+
50
+ if ! $(.initialized)
51
+ {
52
+ .initialized = true ;
53
+ .docutils-dir = $(docutils-dir) ;
54
+ .tools-dir = $(tools-dir:R="") ;
55
+
56
+ .setup = [
57
+ common.prepend-path-variable-command PYTHONPATH
58
+ : $(.docutils-dir) $(.docutils-dir)/extras ] ;
59
+ RST2XXX = [ common.find-tool rst2html ] ;
60
+ }
61
+ }
62
+
63
+ rule html ( target : source : properties * )
64
+ {
65
+ if ! [ on $(target) return $(RST2XXX) ]
66
+ {
67
+ local python-cmd = [ property.select <python.interpreter> : $(properties) ] ;
68
+ RST2XXX on $(target) = $(python-cmd:G=:E="python") $(.tools-dir)/rst2html.py ;
69
+ }
70
+ }
71
+
72
+
73
+ feature docutils : : free ;
74
+ feature docutils-html : : free ;
75
+ feature docutils-cmd : : free ;
76
+ toolset.flags docutils COMMON-FLAGS : <docutils> ;
77
+ toolset.flags docutils HTML-FLAGS : <docutils-html> ;
78
+ toolset.flags docutils RST2XXX : <docutils-cmd> ;
79
+
80
+ actions html
81
+ {
82
+ $(.setup)
83
+ "$(RST2XXX)" $(COMMON-FLAGS) $(HTML-FLAGS) $(>) $(<)
84
+ }
85
+
mosesdecoder/jam-files/boost-build/tools/doxygen-config.jam ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #~ Copyright 2005, 2006 Rene Rivera.
2
+ #~ Distributed under the Boost Software License, Version 1.0.
3
+ #~ (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Automatic configuration for Doxygen tools. To use, just import this module.
6
+
7
+ import toolset : using ;
8
+
9
+ ECHO "warning: doxygen-config.jam is deprecated. Use 'using doxygen ;' instead." ;
10
+
11
+ using doxygen ;
mosesdecoder/jam-files/boost-build/tools/fortran.jam ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2004 Toon Knapen
2
+ #
3
+ # Use, modification and distribution is subject to the Boost Software
4
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5
+ # http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ #
8
+ # This file contains common settings for all fortran tools
9
+ #
10
+
11
+ import "class" : new ;
12
+ import feature : feature ;
13
+
14
+ import type ;
15
+ import generators ;
16
+ import common ;
17
+
18
+ type.register FORTRAN : f F for f77 ;
19
+ type.register FORTRAN90 : f90 F90 ;
20
+
21
+ feature fortran : : free ;
22
+ feature fortran90 : : free ;
23
+
24
+ class fortran-compiling-generator : generator
25
+ {
26
+ rule __init__ ( id : source-types + : target-types + : requirements * : optional-properties * )
27
+ {
28
+ generator.__init__ $(id) : $(source-types) : $(target-types) : $(requirements) : $(optional-properties) ;
29
+ }
30
+ }
31
+
32
+ rule register-fortran-compiler ( id : source-types + : target-types + : requirements * : optional-properties * )
33
+ {
34
+ local g = [ new fortran-compiling-generator $(id) : $(source-types) : $(target-types) : $(requirements) : $(optional-properties) ] ;
35
+ generators.register $(g) ;
36
+ }
37
+
38
+ class fortran90-compiling-generator : generator
39
+ {
40
+ rule __init__ ( id : source-types + : target-types + : requirements * : optional-properties * )
41
+ {
42
+ generator.__init__ $(id) : $(source-types) : $(target-types) : $(requirements) : $(optional-properties) ;
43
+ }
44
+ }
45
+
46
+ rule register-fortran90-compiler ( id : source-types + : target-types + : requirements * : optional-properties * )
47
+ {
48
+ local g = [ new fortran90-compiling-generator $(id) : $(source-types) : $(target-types) : $(requirements) : $(optional-properties) ] ;
49
+ generators.register $(g) ;
50
+ }
51
+
52
+ # FIXME: this is ugly, should find a better way (we'd want client code to
53
+ # register all generators as "generator.some-rule", not with "some-module.some-rule".)
54
+ IMPORT $(__name__) : register-fortran-compiler : : generators.register-fortran-compiler ;
55
+ IMPORT $(__name__) : register-fortran90-compiler : : generators.register-fortran90-compiler ;
mosesdecoder/jam-files/boost-build/tools/gettext.jam ADDED
@@ -0,0 +1,230 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2003, 2004, 2005, 2006 Vladimir Prus
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # This module support GNU gettext internationalization utilities.
6
+ #
7
+ # It provides two main target rules: 'gettext.catalog', used for
8
+ # creating machine-readable catalogs from translations files, and
9
+ # 'gettext.update', used for update translation files from modified
10
+ # sources.
11
+ #
12
+ # To add i18n support to your application you should follow these
13
+ # steps.
14
+ #
15
+ # - Decide on a file name which will contain translations and
16
+ # what main target name will be used to update it. For example::
17
+ #
18
+ # gettext.update update-russian : russian.po a.cpp my_app ;
19
+ #
20
+ # - Create the initial translation file by running::
21
+ #
22
+ # bjam update-russian
23
+ #
24
+ # - Edit russian.po. For example, you might change fields like LastTranslator.
25
+ #
26
+ # - Create a main target for final message catalog::
27
+ #
28
+ # gettext.catalog russian : russian.po ;
29
+ #
30
+ # The machine-readable catalog will be updated whenever you update
31
+ # "russian.po". The "russian.po" file will be updated only on explicit
32
+ # request. When you're ready to update translations, you should
33
+ #
34
+ # - Run::
35
+ #
36
+ # bjam update-russian
37
+ #
38
+ # - Edit "russian.po" in appropriate editor.
39
+ #
40
+ # The next bjam run will convert "russian.po" into machine-readable form.
41
+ #
42
+ # By default, translations are marked by 'i18n' call. The 'gettext.keyword'
43
+ # feature can be used to alter this.
44
+
45
+
46
+ import targets ;
47
+ import property-set ;
48
+ import virtual-target ;
49
+ import "class" : new ;
50
+ import project ;
51
+ import type ;
52
+ import generators ;
53
+ import errors ;
54
+ import feature : feature ;
55
+ import toolset : flags ;
56
+ import regex ;
57
+
58
+ .path = "" ;
59
+
60
+ # Initializes the gettext module.
61
+ rule init ( path ? # Path where all tools are located. If not specified,
62
+ # they should be in PATH.
63
+ )
64
+ {
65
+ if $(.initialized) && $(.path) != $(path)
66
+ {
67
+ errors.error "Attempt to reconfigure with different path" ;
68
+ }
69
+ .initialized = true ;
70
+ if $(path)
71
+ {
72
+ .path = $(path)/ ;
73
+ }
74
+ }
75
+
76
+ # Creates a main target 'name', which, when updated, will cause
77
+ # file 'existing-translation' to be updated with translations
78
+ # extracted from 'sources'. It's possible to specify main target
79
+ # in sources --- it which case all target from dependency graph
80
+ # of those main targets will be scanned, provided they are of
81
+ # appropricate type. The 'gettext.types' feature can be used to
82
+ # control the types.
83
+ #
84
+ # The target will be updated only if explicitly requested on the
85
+ # command line.
86
+ rule update ( name : existing-translation sources + : requirements * )
87
+ {
88
+ local project = [ project.current ] ;
89
+
90
+ targets.main-target-alternative
91
+ [ new typed-target $(name) : $(project) : gettext.UPDATE :
92
+ $(existing-translation) $(sources)
93
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
94
+ ] ;
95
+ $(project).mark-target-as-explicit $(name) ;
96
+ }
97
+
98
+
99
+ # The human editable source, containing translation.
100
+ type.register gettext.PO : po ;
101
+ # The machine readable message catalog.
102
+ type.register gettext.catalog : mo ;
103
+ # Intermediate type produce by extracting translations from
104
+ # sources.
105
+ type.register gettext.POT : pot ;
106
+ # Pseudo type used to invoke update-translations generator
107
+ type.register gettext.UPDATE ;
108
+
109
+ # Identifies the keyword that should be used when scanning sources.
110
+ # Default: i18n
111
+ feature gettext.keyword : : free ;
112
+ # Contains space-separated list of sources types which should be scanned.
113
+ # Default: "C CPP"
114
+ feature gettext.types : : free ;
115
+
116
+ generators.register-standard gettext.compile : gettext.PO : gettext.catalog ;
117
+
118
+ class update-translations-generator : generator
119
+ {
120
+ import regex : split ;
121
+ import property-set ;
122
+
123
+ rule __init__ ( * : * )
124
+ {
125
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
126
+ }
127
+
128
+ # The rule should be called with at least two sources. The first source
129
+ # is the translation (.po) file to update. The remaining sources are targets
130
+ # which should be scanned for new messages. All sources files for those targets
131
+ # will be found and passed to the 'xgettext' utility, which extracts the
132
+ # messages for localization. Those messages will be merged to the .po file.
133
+ rule run ( project name ? : property-set : sources * : multiple ? )
134
+ {
135
+ local types = [ $(property-set).get <gettext.types> ] ;
136
+ types ?= "C CPP" ;
137
+ types = [ regex.split $(types) " " ] ;
138
+
139
+ local keywords = [ $(property-set).get <gettext.keyword> ] ;
140
+ property-set = [ property-set.create $(keywords:G=<gettext.keyword>) ] ;
141
+
142
+ # First deterime the list of sources that must be scanned for
143
+ # messages.
144
+ local all-sources ;
145
+ # CONSIDER: I'm not sure if the logic should be the same as for 'stage':
146
+ # i.e. following dependency properties as well.
147
+ for local s in $(sources[2-])
148
+ {
149
+ all-sources += [ virtual-target.traverse $(s) : : include-sources ] ;
150
+ }
151
+ local right-sources ;
152
+ for local s in $(all-sources)
153
+ {
154
+ if [ $(s).type ] in $(types)
155
+ {
156
+ right-sources += $(s) ;
157
+ }
158
+ }
159
+
160
+ local .constructed ;
161
+ if $(right-sources)
162
+ {
163
+ # Create the POT file, which will contain list of messages extracted
164
+ # from the sources.
165
+ local extract =
166
+ [ new action $(right-sources) : gettext.extract : $(property-set) ] ;
167
+ local new-messages = [ new file-target $(name) : gettext.POT
168
+ : $(project) : $(extract) ] ;
169
+
170
+ # Create a notfile target which will update the existing translation file
171
+ # with new messages.
172
+ local a = [ new action $(sources[1]) $(new-messages)
173
+ : gettext.update-po-dispatch ] ;
174
+ local r = [ new notfile-target $(name) : $(project) : $(a) ] ;
175
+ .constructed = [ virtual-target.register $(r) ] ;
176
+ }
177
+ else
178
+ {
179
+ errors.error "No source could be scanned by gettext tools" ;
180
+ }
181
+ return $(.constructed) ;
182
+ }
183
+ }
184
+ generators.register [ new update-translations-generator gettext.update : : gettext.UPDATE ] ;
185
+
186
+ flags gettext.extract KEYWORD <gettext.keyword> ;
187
+ actions extract
188
+ {
189
+ $(.path)xgettext -k$(KEYWORD:E=i18n) -o $(<) $(>)
190
+ }
191
+
192
+ # Does realy updating of po file. The tricky part is that
193
+ # we're actually updating one of the sources:
194
+ # $(<) is the NOTFILE target we're updating
195
+ # $(>[1]) is the PO file to be really updated.
196
+ # $(>[2]) is the PO file created from sources.
197
+ #
198
+ # When file to be updated does not exist (during the
199
+ # first run), we need to copy the file created from sources.
200
+ # In all other cases, we need to update the file.
201
+ rule update-po-dispatch
202
+ {
203
+ NOCARE $(>[1]) ;
204
+ gettext.create-po $(<) : $(>) ;
205
+ gettext.update-po $(<) : $(>) ;
206
+ _ on $(<) = " " ;
207
+ ok on $(<) = "" ;
208
+ EXISTING_PO on $(<) = $(>[1]) ;
209
+ }
210
+
211
+ # Due to fancy interaction of existing and updated, this rule can be called with
212
+ # one source, in which case we copy the lonely source into EXISTING_PO, or with
213
+ # two sources, in which case the action body expands to nothing. I'd really like
214
+ # to have "missing" action modifier.
215
+ actions quietly existing updated create-po bind EXISTING_PO
216
+ {
217
+ cp$(_)"$(>[1])"$(_)"$(EXISTING_PO)"$($(>[2]:E=ok))
218
+ }
219
+
220
+ actions updated update-po bind EXISTING_PO
221
+ {
222
+ $(.path)msgmerge$(_)-U$(_)"$(EXISTING_PO)"$(_)"$(>[1])"
223
+ }
224
+
225
+ actions gettext.compile
226
+ {
227
+ $(.path)msgfmt -o $(<) $(>)
228
+ }
229
+
230
+ IMPORT $(__name__) : update : : gettext.update ;
mosesdecoder/jam-files/boost-build/tools/ifort.jam ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2004 Toon Knapen
2
+ #
3
+ # Use, modification and distribution is subject to the Boost Software
4
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5
+ # http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ import toolset : flags ;
8
+ import feature ;
9
+ import fortran ;
10
+
11
+ rule init ( version ? : command * : options * )
12
+ {
13
+ }
14
+
15
+ # Declare flags and action for compilation
16
+ flags ifort OPTIONS <fflags> ;
17
+
18
+ flags ifort OPTIONS <optimization>off : /Od ;
19
+ flags ifort OPTIONS <optimization>speed : /O3 ;
20
+ flags ifort OPTIONS <optimization>space : /O1 ;
21
+
22
+ flags ifort OPTIONS <debug-symbols>on : /debug:full ;
23
+ flags ifort OPTIONS <profiling>on : /Qprof_gen ;
24
+
25
+ flags ifort.compile FFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
26
+ flags ifort.compile FFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
27
+ flags ifort.compile FFLAGS <runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
28
+ flags ifort.compile FFLAGS <runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
29
+ flags ifort.compile FFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
30
+ flags ifort.compile FFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
31
+
32
+ flags ifort DEFINES <define> ;
33
+ flags ifort INCLUDES <include> ;
34
+
35
+ rule compile.fortran
36
+ {
37
+ }
38
+
39
+ actions compile.fortran
40
+ {
41
+ ifort $(FFLAGS) $(OPTIONS) /names:lowercase /D$(DEFINES) /I"$(INCLUDES)" /c /object:"$(<)" "$(>)"
42
+ }
43
+
44
+ generators.register-fortran-compiler ifort.compile.fortran : FORTRAN : OBJ ;
mosesdecoder/jam-files/boost-build/tools/intel-darwin.jam ADDED
@@ -0,0 +1,220 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2004.
2
+ # Copyright Noel Belcourt 2007.
3
+ # Distributed under the Boost Software License, Version 1.0.
4
+ # (See accompanying file LICENSE_1_0.txt
5
+ # or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ import intel ;
8
+ import feature : feature ;
9
+ import os ;
10
+ import toolset ;
11
+ import toolset : flags ;
12
+ import gcc ;
13
+ import common ;
14
+ import errors ;
15
+ import generators ;
16
+
17
+ feature.extend-subfeature toolset intel : platform : darwin ;
18
+
19
+ toolset.inherit-generators intel-darwin
20
+ <toolset>intel <toolset-intel:platform>darwin
21
+ : gcc
22
+ # Don't inherit PCH generators. They were not tested, and probably
23
+ # don't work for this compiler.
24
+ : gcc.mingw.link gcc.mingw.link.dll gcc.compile.c.pch gcc.compile.c++.pch
25
+ ;
26
+
27
+ generators.override intel-darwin.prebuilt : builtin.lib-generator ;
28
+ generators.override intel-darwin.prebuilt : builtin.prebuilt ;
29
+ generators.override intel-darwin.searched-lib-generator : searched-lib-generator ;
30
+
31
+ toolset.inherit-rules intel-darwin : gcc ;
32
+ toolset.inherit-flags intel-darwin : gcc
33
+ : <inlining>off <inlining>on <inlining>full <optimization>space
34
+ <warnings>off <warnings>all <warnings>on
35
+ <architecture>x86/<address-model>32
36
+ <architecture>x86/<address-model>64
37
+ ;
38
+
39
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
40
+ {
41
+ .debug-configuration = true ;
42
+ }
43
+
44
+ # vectorization diagnostics
45
+ feature vectorize : off on full ;
46
+
47
+ # Initializes the intel-darwin toolset
48
+ # version in mandatory
49
+ # name (default icc) is used to invoke the specified intel complier
50
+ # compile and link options allow you to specify addition command line options for each version
51
+ rule init ( version ? : command * : options * )
52
+ {
53
+ local condition = [ common.check-init-parameters intel-darwin
54
+ : version $(version) ] ;
55
+
56
+ command = [ common.get-invocation-command intel-darwin : icc
57
+ : $(command) : /opt/intel_cc_80/bin ] ;
58
+
59
+ common.handle-options intel-darwin : $(condition) : $(command) : $(options) ;
60
+
61
+ gcc.init-link-flags intel-darwin darwin $(condition) ;
62
+
63
+ # handle <library-path>
64
+ # local library-path = [ feature.get-values <library-path> : $(options) ] ;
65
+ # flags intel-darwin.link USER_OPTIONS $(condition) : [ feature.get-values <dll-path> : $(options) ] ;
66
+
67
+ local root = [ feature.get-values <root> : $(options) ] ;
68
+ local bin ;
69
+ if $(command) || $(root)
70
+ {
71
+ bin ?= [ common.get-absolute-tool-path $(command[-1]) ] ;
72
+ root ?= $(bin:D) ;
73
+
74
+ if $(root)
75
+ {
76
+ # Libraries required to run the executable may be in either
77
+ # $(root)/lib (10.1 and earlier)
78
+ # or
79
+ # $(root)/lib/architecture-name (11.0 and later:
80
+ local lib_path = $(root)/lib $(root:P)/lib/$(bin:B) ;
81
+ if $(.debug-configuration)
82
+ {
83
+ ECHO notice: using intel libraries :: $(condition) :: $(lib_path) ;
84
+ }
85
+ flags intel-darwin.link RUN_PATH $(condition) : $(lib_path) ;
86
+ }
87
+ }
88
+
89
+ local m = [ MATCH (..).* : $(version) ] ;
90
+ local n = [ MATCH (.)\\. : $(m) ] ;
91
+ if $(n) {
92
+ m = $(n) ;
93
+ }
94
+
95
+ local major = $(m) ;
96
+
97
+ if $(major) = "9" {
98
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>off : -Ob0 ;
99
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>on : -Ob1 ;
100
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>full : -Ob2 ;
101
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>off : -vec-report0 ;
102
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>on : -vec-report1 ;
103
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>full : -vec-report5 ;
104
+ flags intel-darwin.link OPTIONS $(condition)/<runtime-link>static : -static -static-libcxa -lstdc++ -lpthread ;
105
+ flags intel-darwin.link OPTIONS $(condition)/<runtime-link>shared : -shared-libcxa -lstdc++ -lpthread ;
106
+ }
107
+ else {
108
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>off : -inline-level=0 ;
109
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>on : -inline-level=1 ;
110
+ flags intel-darwin.compile OPTIONS $(condition)/<inlining>full : -inline-level=2 ;
111
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>off : -vec-report0 ;
112
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>on : -vec-report1 ;
113
+ flags intel-darwin.compile OPTIONS $(condition)/<vectorize>full : -vec-report5 ;
114
+ flags intel-darwin.link OPTIONS $(condition)/<runtime-link>static : -static -static-intel -lstdc++ -lpthread ;
115
+ flags intel-darwin.link OPTIONS $(condition)/<runtime-link>shared : -shared-intel -lstdc++ -lpthread ;
116
+ }
117
+
118
+ local minor = [ MATCH ".*\\.(.).*" : $(version) ] ;
119
+
120
+ # wchar_t char_traits workaround for compilers older than 10.2
121
+ if $(major) = "9" || ( $(major) = "10" && ( $(minor) = "0" || $(minor) = "1" ) ) {
122
+ flags intel-darwin.compile DEFINES $(condition) : __WINT_TYPE__=int : unchecked ;
123
+ }
124
+ }
125
+
126
+ SPACE = " " ;
127
+
128
+ flags intel-darwin.compile OPTIONS <cflags> ;
129
+ flags intel-darwin.compile OPTIONS <cxxflags> ;
130
+ # flags intel-darwin.compile INCLUDES <include> ;
131
+
132
+ flags intel-darwin.compile OPTIONS <optimization>space : -O1 ; # no specific space optimization flag in icc
133
+
134
+ #
135
+ cpu-type-em64t = prescott nocona ;
136
+ flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>32 : -m32 ; # -mcmodel=small ;
137
+ flags intel-darwin.compile OPTIONS <instruction-set>$(cpu-type-em64t)/<address-model>64 : -m64 ; # -mcmodel=large ;
138
+
139
+ flags intel-darwin.compile.c OPTIONS <warnings>off : -w0 ;
140
+ flags intel-darwin.compile.c OPTIONS <warnings>on : -w1 ;
141
+ flags intel-darwin.compile.c OPTIONS <warnings>all : -w2 ;
142
+
143
+ flags intel-darwin.compile.c++ OPTIONS <warnings>off : -w0 ;
144
+ flags intel-darwin.compile.c++ OPTIONS <warnings>on : -w1 ;
145
+ flags intel-darwin.compile.c++ OPTIONS <warnings>all : -w2 ;
146
+
147
+ actions compile.c
148
+ {
149
+ "$(CONFIG_COMMAND)" -xc $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
150
+ }
151
+
152
+ actions compile.c++
153
+ {
154
+ "$(CONFIG_COMMAND)" -xc++ $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
155
+ }
156
+
157
+ flags intel-darwin ARFLAGS <archiveflags> ;
158
+
159
+ # Default value. Mostly for the sake of intel-linux
160
+ # that inherits from gcc, but does not has the same
161
+ # logic to set the .AR variable. We can put the same
162
+ # logic in intel-linux, but that's hardly worth the trouble
163
+ # as on Linux, 'ar' is always available.
164
+ .AR = ar ;
165
+
166
+ rule archive ( targets * : sources * : properties * )
167
+ {
168
+ # Always remove archive and start again. Here's rationale from
169
+ # Andre Hentz:
170
+ #
171
+ # I had a file, say a1.c, that was included into liba.a.
172
+ # I moved a1.c to a2.c, updated my Jamfiles and rebuilt.
173
+ # My program was crashing with absurd errors.
174
+ # After some debugging I traced it back to the fact that a1.o was *still*
175
+ # in liba.a
176
+ #
177
+ # Rene Rivera:
178
+ #
179
+ # Originally removing the archive was done by splicing an RM
180
+ # onto the archive action. That makes archives fail to build on NT
181
+ # when they have many files because it will no longer execute the
182
+ # action directly and blow the line length limit. Instead we
183
+ # remove the file in a different action, just before the building
184
+ # of the archive.
185
+ #
186
+ local clean.a = $(targets[1])(clean) ;
187
+ TEMPORARY $(clean.a) ;
188
+ NOCARE $(clean.a) ;
189
+ LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ;
190
+ DEPENDS $(clean.a) : $(sources) ;
191
+ DEPENDS $(targets) : $(clean.a) ;
192
+ common.RmTemps $(clean.a) : $(targets) ;
193
+ }
194
+
195
+ actions piecemeal archive
196
+ {
197
+ "$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)"
198
+ "ranlib" -cs "$(<)"
199
+ }
200
+
201
+ flags intel-darwin.link USER_OPTIONS <linkflags> ;
202
+
203
+ # Declare actions for linking
204
+ rule link ( targets * : sources * : properties * )
205
+ {
206
+ SPACE on $(targets) = " " ;
207
+ # Serialize execution of the 'link' action, since
208
+ # running N links in parallel is just slower.
209
+ JAM_SEMAPHORE on $(targets) = <s>intel-darwin-link-semaphore ;
210
+ }
211
+
212
+ actions link bind LIBRARIES
213
+ {
214
+ "$(CONFIG_COMMAND)" $(USER_OPTIONS) -L"$(LINKPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(OPTIONS)
215
+ }
216
+
217
+ actions link.dll bind LIBRARIES
218
+ {
219
+ "$(CONFIG_COMMAND)" $(USER_OPTIONS) -L"$(LINKPATH)" -o "$(<)" -single_module -dynamiclib -install_name "$(<[1]:D=)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST) $(OPTIONS)
220
+ }
mosesdecoder/jam-files/boost-build/tools/intel-win.jam ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2004.
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt
4
+ # or copy at http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ # Importing common is needed because the rules we inherit here depend on it.
7
+ # That is nasty.
8
+ import common ;
9
+ import errors ;
10
+ import feature ;
11
+ import intel ;
12
+ import msvc ;
13
+ import os ;
14
+ import toolset ;
15
+ import generators ;
16
+ import type ;
17
+
18
+ feature.extend-subfeature toolset intel : platform : win ;
19
+
20
+ toolset.inherit-generators intel-win <toolset>intel <toolset-intel:platform>win : msvc ;
21
+ toolset.inherit-flags intel-win : msvc : : YLOPTION ;
22
+ toolset.inherit-rules intel-win : msvc ;
23
+
24
+ # Override default do-nothing generators.
25
+ generators.override intel-win.compile.c.pch : pch.default-c-pch-generator ;
26
+ generators.override intel-win.compile.c++.pch : pch.default-cpp-pch-generator ;
27
+ generators.override intel-win.compile.rc : rc.compile.resource ;
28
+ generators.override intel-win.compile.mc : mc.compile ;
29
+
30
+ toolset.flags intel-win.compile PCH_SOURCE <pch>on : <pch-source> ;
31
+
32
+ toolset.add-requirements <toolset>intel-win,<runtime-link>shared:<threading>multi ;
33
+
34
+ # Initializes the intel toolset for windows
35
+ rule init ( version ? : # the compiler version
36
+ command * : # the command to invoke the compiler itself
37
+ options * # Additional option: <compatibility>
38
+ # either 'vc6', 'vc7', 'vc7.1'
39
+ # or 'native'(default).
40
+ )
41
+ {
42
+ local compatibility =
43
+ [ feature.get-values <compatibility> : $(options) ] ;
44
+ local condition = [ common.check-init-parameters intel-win
45
+ : version $(version) : compatibility $(compatibility) ] ;
46
+
47
+ command = [ common.get-invocation-command intel-win : icl.exe :
48
+ $(command) ] ;
49
+
50
+ common.handle-options intel-win : $(condition) : $(command) : $(options) ;
51
+
52
+ local root ;
53
+ if $(command)
54
+ {
55
+ root = [ common.get-absolute-tool-path $(command[-1]) ] ;
56
+ root = $(root)/ ;
57
+ }
58
+
59
+ local setup ;
60
+ setup = [ GLOB $(root) : iclvars_*.bat ] ;
61
+ if ! $(setup)
62
+ {
63
+ setup = $(root)/iclvars.bat ;
64
+ }
65
+ setup = "call \""$(setup)"\" > nul " ;
66
+
67
+ if [ os.name ] = NT
68
+ {
69
+ setup = $(setup)"
70
+ " ;
71
+ }
72
+ else
73
+ {
74
+ setup = "cmd /S /C "$(setup)" \"&&\" " ;
75
+ }
76
+
77
+ toolset.flags intel-win.compile .CC $(condition) : $(setup)icl ;
78
+ toolset.flags intel-win.link .LD $(condition) : $(setup)xilink ;
79
+ toolset.flags intel-win.archive .LD $(condition) : $(setup)xilink /lib ;
80
+ toolset.flags intel-win.link .MT $(condition) : $(setup)mt -nologo ;
81
+ toolset.flags intel-win.compile .MC $(condition) : $(setup)mc ;
82
+ toolset.flags intel-win.compile .RC $(condition) : $(setup)rc ;
83
+
84
+ local m = [ MATCH (.).* : $(version) ] ;
85
+ local major = $(m[1]) ;
86
+
87
+ local C++FLAGS ;
88
+
89
+ C++FLAGS += /nologo ;
90
+
91
+ # Reduce the number of spurious error messages
92
+ C++FLAGS += /Qwn5 /Qwd985 ;
93
+
94
+ # Enable ADL
95
+ C++FLAGS += -Qoption,c,--arg_dep_lookup ; #"c" works for C++, too
96
+
97
+ # Disable Microsoft "secure" overloads in Dinkumware libraries since they
98
+ # cause compile errors with Intel versions 9 and 10.
99
+ C++FLAGS += -D_SECURE_SCL=0 ;
100
+
101
+ if $(major) > 5
102
+ {
103
+ C++FLAGS += /Zc:forScope ; # Add support for correct for loop scoping.
104
+ }
105
+
106
+ # Add options recognized only by intel7 and above.
107
+ if $(major) >= 7
108
+ {
109
+ C++FLAGS += /Qansi_alias ;
110
+ }
111
+
112
+ if $(compatibility) = vc6
113
+ {
114
+ C++FLAGS +=
115
+ # Emulate VC6
116
+ /Qvc6
117
+
118
+ # No wchar_t support in vc6 dinkum library. Furthermore, in vc6
119
+ # compatibility-mode, wchar_t is not a distinct type from unsigned
120
+ # short.
121
+ -DBOOST_NO_INTRINSIC_WCHAR_T
122
+ ;
123
+ }
124
+ else
125
+ {
126
+ if $(major) > 5
127
+ {
128
+ # Add support for wchar_t
129
+ C++FLAGS += /Zc:wchar_t
130
+ # Tell the dinkumware library about it.
131
+ -D_NATIVE_WCHAR_T_DEFINED
132
+ ;
133
+ }
134
+ }
135
+
136
+ if $(compatibility) && $(compatibility) != native
137
+ {
138
+ C++FLAGS += /Q$(base-vc) ;
139
+ }
140
+ else
141
+ {
142
+ C++FLAGS +=
143
+ -Qoption,cpp,--arg_dep_lookup
144
+ # The following options were intended to disable the Intel compiler's
145
+ # 'bug-emulation' mode, but were later reported to be causing ICE with
146
+ # Intel-Win 9.0. It is not yet clear which options can be safely used.
147
+ # -Qoption,cpp,--const_string_literals
148
+ # -Qoption,cpp,--new_for_init
149
+ # -Qoption,cpp,--no_implicit_typename
150
+ # -Qoption,cpp,--no_friend_injection
151
+ # -Qoption,cpp,--no_microsoft_bugs
152
+ ;
153
+ }
154
+
155
+ toolset.flags intel-win CFLAGS $(condition) : $(C++FLAGS) ;
156
+ # By default, when creating PCH, intel adds 'i' to the explicitly
157
+ # specified name of the PCH file. Of course, Boost.Build is not
158
+ # happy when compiler produces not the file it was asked for.
159
+ # The option below stops this behaviour.
160
+ toolset.flags intel-win CFLAGS : -Qpchi- ;
161
+
162
+ if ! $(compatibility)
163
+ {
164
+ # If there's no backend version, assume 10.
165
+ compatibility = vc10 ;
166
+ }
167
+
168
+ local extract-version = [ MATCH ^vc(.*) : $(compatibility) ] ;
169
+ if ! $(extract-version)
170
+ {
171
+ errors.user-error "Invalid value for compatibility option:"
172
+ $(compatibility) ;
173
+ }
174
+
175
+ # Depending on the settings, running of tests require some runtime DLLs.
176
+ toolset.flags intel-win RUN_PATH $(condition) : $(root) ;
177
+
178
+ msvc.configure-version-specific intel-win : $(extract-version[1]) : $(condition) ;
179
+ }
180
+
181
+ toolset.flags intel-win.link LIBRARY_OPTION <toolset>intel : "" ;
182
+
183
+ toolset.flags intel-win YLOPTION ;
184
+
mosesdecoder/jam-files/boost-build/tools/mpi.jam ADDED
@@ -0,0 +1,583 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Support for the Message Passing Interface (MPI)
2
+ #
3
+ # (C) Copyright 2005, 2006 Trustees of Indiana University
4
+ # (C) Copyright 2005 Douglas Gregor
5
+ #
6
+ # Distributed under the Boost Software License, Version 1.0. (See accompanying
7
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
8
+ #
9
+ # Authors: Douglas Gregor
10
+ # Andrew Lumsdaine
11
+ #
12
+ # ==== MPI Configuration ====
13
+ #
14
+ # For many users, MPI support can be enabled simply by adding the following
15
+ # line to your user-config.jam file:
16
+ #
17
+ # using mpi ;
18
+ #
19
+ # This should auto-detect MPI settings based on the MPI wrapper compiler in
20
+ # your path, e.g., "mpic++". If the wrapper compiler is not in your path, or
21
+ # has a different name, you can pass the name of the wrapper compiler as the
22
+ # first argument to the mpi module:
23
+ #
24
+ # using mpi : /opt/mpich2-1.0.4/bin/mpiCC ;
25
+ #
26
+ # If your MPI implementation does not have a wrapper compiler, or the MPI
27
+ # auto-detection code does not work with your MPI's wrapper compiler,
28
+ # you can pass MPI-related options explicitly via the second parameter to the
29
+ # mpi module:
30
+ #
31
+ # using mpi : : <find-shared-library>lammpio <find-shared-library>lammpi++
32
+ # <find-shared-library>mpi <find-shared-library>lam
33
+ # <find-shared-library>dl ;
34
+ #
35
+ # To see the results of MPI auto-detection, pass "--debug-configuration" on
36
+ # the bjam command line.
37
+ #
38
+ # The (optional) fourth argument configures Boost.MPI for running
39
+ # regression tests. These parameters specify the executable used to
40
+ # launch jobs (default: "mpirun") followed by any necessary arguments
41
+ # to this to run tests and tell the program to expect the number of
42
+ # processors to follow (default: "-np"). With the default parameters,
43
+ # for instance, the test harness will execute, e.g.,
44
+ #
45
+ # mpirun -np 4 all_gather_test
46
+ #
47
+ # ==== Linking Against the MPI Libraries ===
48
+ #
49
+ # To link against the MPI libraries, import the "mpi" module and add the
50
+ # following requirement to your target:
51
+ #
52
+ # <library>/mpi//mpi
53
+ #
54
+ # Since MPI support is not always available, you should check
55
+ # "mpi.configured" before trying to link against the MPI libraries.
56
+
57
+ import "class" : new ;
58
+ import common ;
59
+ import feature : feature ;
60
+ import generators ;
61
+ import os ;
62
+ import project ;
63
+ import property ;
64
+ import testing ;
65
+ import toolset ;
66
+ import type ;
67
+ import path ;
68
+
69
+ # Make this module a project
70
+ project.initialize $(__name__) ;
71
+ project mpi ;
72
+
73
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
74
+ {
75
+ .debug-configuration = true ;
76
+ }
77
+
78
+ # Assuming the first part of the command line is the given prefix
79
+ # followed by some non-empty value, remove the first argument. Returns
80
+ # either nothing (if there was no prefix or no value) or a pair
81
+ #
82
+ # <name>value rest-of-cmdline
83
+ #
84
+ # This is a subroutine of cmdline_to_features
85
+ rule add_feature ( prefix name cmdline )
86
+ {
87
+ local match = [ MATCH "^$(prefix)([^\" ]+|\"[^\"]+\") *(.*)$" : $(cmdline) ] ;
88
+
89
+ # If there was no value associated with the prefix, abort
90
+ if ! $(match) {
91
+ return ;
92
+ }
93
+
94
+ local value = $(match[1]) ;
95
+
96
+ if [ MATCH " +" : $(value) ] {
97
+ value = "\"$(value)\"" ;
98
+ }
99
+
100
+ return "<$(name)>$(value)" $(match[2]) ;
101
+ }
102
+
103
+ # Strip any end-of-line characters off the given string and return the
104
+ # result.
105
+ rule strip-eol ( string )
106
+ {
107
+ local match = [ MATCH "^(([A-Za-z0-9~`\.!@#$%^&*()_+={};:'\",.<>/?\\| -]|[|])*).*$" : $(string) ] ;
108
+
109
+ if $(match)
110
+ {
111
+ return $(match[1]) ;
112
+ }
113
+ else
114
+ {
115
+ return $(string) ;
116
+ }
117
+ }
118
+
119
+ # Split a command-line into a set of features. Certain kinds of
120
+ # compiler flags are recognized (e.g., -I, -D, -L, -l) and replaced
121
+ # with their Boost.Build equivalents (e.g., <include>, <define>,
122
+ # <library-path>, <find-library>). All other arguments are introduced
123
+ # using the features in the unknown-features parameter, because we
124
+ # don't know how to deal with them. For instance, if your compile and
125
+ # correct. The incoming command line should be a string starting with
126
+ # an executable (e.g., g++ -I/include/path") and may contain any
127
+ # number of command-line arguments thereafter. The result is a list of
128
+ # features corresponding to the given command line, ignoring the
129
+ # executable.
130
+ rule cmdline_to_features ( cmdline : unknown-features ? )
131
+ {
132
+ local executable ;
133
+ local features ;
134
+ local otherflags ;
135
+ local result ;
136
+
137
+ unknown-features ?= <cxxflags> <linkflags> ;
138
+
139
+ # Pull the executable out of the command line. At this point, the
140
+ # executable is just thrown away.
141
+ local match = [ MATCH "^([^\" ]+|\"[^\"]+\") *(.*)$" : $(cmdline) ] ;
142
+ executable = $(match[1]) ;
143
+ cmdline = $(match[2]) ;
144
+
145
+ # List the prefix/feature pairs that we will be able to transform.
146
+ # Every kind of parameter not mentioned here will be placed in both
147
+ # cxxflags and linkflags, because we don't know where they should go.
148
+ local feature_kinds-D = "define" ;
149
+ local feature_kinds-I = "include" ;
150
+ local feature_kinds-L = "library-path" ;
151
+ local feature_kinds-l = "find-shared-library" ;
152
+
153
+ while $(cmdline) {
154
+
155
+ # Check for one of the feature prefixes we know about. If we
156
+ # find one (and the associated value is nonempty), convert it
157
+ # into a feature.
158
+ local match = [ MATCH "^(-.)(.*)" : $(cmdline) ] ;
159
+ local matched ;
160
+ if $(match) && $(match[2]) {
161
+ local prefix = $(match[1]) ;
162
+ if $(feature_kinds$(prefix)) {
163
+ local name = $(feature_kinds$(prefix)) ;
164
+ local add = [ add_feature $(prefix) $(name) $(cmdline) ] ;
165
+
166
+ if $(add) {
167
+
168
+ if $(add[1]) = <find-shared-library>pthread
169
+ {
170
+ # Uhm. It's not really nice that this MPI implementation
171
+ # uses -lpthread as opposed to -pthread. We do want to
172
+ # set <threading>multi, instead of -lpthread.
173
+ result += "<threading>multi" ;
174
+ MPI_EXTRA_REQUIREMENTS += "<threading>multi" ;
175
+ }
176
+ else
177
+ {
178
+ result += $(add[1]) ;
179
+ }
180
+
181
+ cmdline = $(add[2]) ;
182
+ matched = yes ;
183
+ }
184
+ }
185
+ }
186
+
187
+ # If we haven't matched a feature prefix, just grab the command-line
188
+ # argument itself. If we can map this argument to a feature
189
+ # (e.g., -pthread -> <threading>multi), then do so; otherwise,
190
+ # and add it to the list of "other" flags that we don't
191
+ # understand.
192
+ if ! $(matched) {
193
+ match = [ MATCH "^([^\" ]+|\"[^\"]+\") *(.*)$" : $(cmdline) ] ;
194
+ local value = $(match[1]) ;
195
+ cmdline = $(match[2]) ;
196
+
197
+ # Check for multithreading support
198
+ if $(value) = "-pthread" || $(value) = "-pthreads"
199
+ {
200
+ result += "<threading>multi" ;
201
+
202
+ # DPG: This is a hack intended to work around a BBv2 bug where
203
+ # requirements propagated from libraries are not checked for
204
+ # conflicts when BBv2 determines which "common" properties to
205
+ # apply to a target. In our case, the <threading>single property
206
+ # gets propagated from the common properties to Boost.MPI
207
+ # targets, even though <threading>multi is in the usage
208
+ # requirements of <library>/mpi//mpi.
209
+ MPI_EXTRA_REQUIREMENTS += "<threading>multi" ;
210
+ }
211
+ else if [ MATCH "(.*[a-zA-Z0-9<>?-].*)" : $(value) ] {
212
+ otherflags += $(value) ;
213
+ }
214
+ }
215
+ }
216
+
217
+ # If there are other flags that we don't understand, add them to the
218
+ # result as both <cxxflags> and <linkflags>
219
+ if $(otherflags) {
220
+ for unknown in $(unknown-features)
221
+ {
222
+ result += "$(unknown)$(otherflags:J= )" ;
223
+ }
224
+ }
225
+
226
+ return $(result) ;
227
+ }
228
+
229
+ # Determine if it is safe to execute the given shell command by trying
230
+ # to execute it and determining whether the exit code is zero or
231
+ # not. Returns true for an exit code of zero, false otherwise.
232
+ local rule safe-shell-command ( cmdline )
233
+ {
234
+ local result = [ SHELL "$(cmdline) > /dev/null 2>/dev/null; if [ "$?" -eq "0" ]; then echo SSCOK; fi" ] ;
235
+ return [ MATCH ".*(SSCOK).*" : $(result) ] ;
236
+ }
237
+
238
+ # Initialize the MPI module.
239
+ rule init ( mpicxx ? : options * : mpirun-with-options * )
240
+ {
241
+ if ! $(options) && $(.debug-configuration)
242
+ {
243
+ ECHO "===============MPI Auto-configuration===============" ;
244
+ }
245
+
246
+ if ! $(mpicxx) && [ os.on-windows ]
247
+ {
248
+ # Try to auto-configure to the Microsoft Compute Cluster Pack
249
+ local cluster_pack_path_native = "C:\\Program Files\\Microsoft Compute Cluster Pack" ;
250
+ local cluster_pack_path = [ path.make $(cluster_pack_path_native) ] ;
251
+ if [ GLOB $(cluster_pack_path_native)\\Include : mpi.h ]
252
+ {
253
+ if $(.debug-configuration)
254
+ {
255
+ ECHO "Found Microsoft Compute Cluster Pack: $(cluster_pack_path_native)" ;
256
+ }
257
+
258
+ # Pick up either the 32-bit or 64-bit library, depending on which address
259
+ # model the user has selected. Default to 32-bit.
260
+ options = <include>$(cluster_pack_path)/Include
261
+ <address-model>64:<library-path>$(cluster_pack_path)/Lib/amd64
262
+ <library-path>$(cluster_pack_path)/Lib/i386
263
+ <find-static-library>msmpi
264
+ <toolset>msvc:<define>_SECURE_SCL=0
265
+ ;
266
+
267
+ # Setup the "mpirun" equivalent (mpiexec)
268
+ .mpirun = "\"$(cluster_pack_path_native)\\Bin\\mpiexec.exe"\" ;
269
+ .mpirun_flags = -n ;
270
+ }
271
+ else if $(.debug-configuration)
272
+ {
273
+ ECHO "Did not find Microsoft Compute Cluster Pack in $(cluster_pack_path_native)." ;
274
+ }
275
+ }
276
+
277
+ if ! $(options)
278
+ {
279
+ # Try to auto-detect options based on the wrapper compiler
280
+ local command = [ common.get-invocation-command mpi : mpic++ : $(mpicxx) ] ;
281
+
282
+ if ! $(mpicxx) && ! $(command)
283
+ {
284
+ # Try "mpiCC", which is used by MPICH
285
+ command = [ common.get-invocation-command mpi : mpiCC ] ;
286
+ }
287
+
288
+ if ! $(mpicxx) && ! $(command)
289
+ {
290
+ # Try "mpicxx", which is used by OpenMPI and MPICH2
291
+ command = [ common.get-invocation-command mpi : mpicxx ] ;
292
+ }
293
+
294
+ local result ;
295
+ local compile_flags ;
296
+ local link_flags ;
297
+
298
+ if ! $(command)
299
+ {
300
+ # Do nothing: we'll complain later
301
+ }
302
+ # OpenMPI and newer versions of LAM-MPI have -showme:compile and
303
+ # -showme:link.
304
+ else if [ safe-shell-command "$(command) -showme:compile" ] &&
305
+ [ safe-shell-command "$(command) -showme:link" ]
306
+ {
307
+ if $(.debug-configuration)
308
+ {
309
+ ECHO "Found recent LAM-MPI or Open MPI wrapper compiler: $(command)" ;
310
+ }
311
+
312
+ compile_flags = [ SHELL "$(command) -showme:compile" ] ;
313
+ link_flags = [ SHELL "$(command) -showme:link" ] ;
314
+
315
+ # Prepend COMPILER as the executable name, to match the format of
316
+ # other compilation commands.
317
+ compile_flags = "COMPILER $(compile_flags)" ;
318
+ link_flags = "COMPILER $(link_flags)" ;
319
+ }
320
+ # Look for LAM-MPI's -showme
321
+ else if [ safe-shell-command "$(command) -showme" ]
322
+ {
323
+ if $(.debug-configuration)
324
+ {
325
+ ECHO "Found older LAM-MPI wrapper compiler: $(command)" ;
326
+ }
327
+
328
+ result = [ SHELL "$(command) -showme" ] ;
329
+ }
330
+ # Look for MPICH
331
+ else if [ safe-shell-command "$(command) -show" ]
332
+ {
333
+ if $(.debug-configuration)
334
+ {
335
+ ECHO "Found MPICH wrapper compiler: $(command)" ;
336
+ }
337
+ compile_flags = [ SHELL "$(command) -compile_info" ] ;
338
+ link_flags = [ SHELL "$(command) -link_info" ] ;
339
+ }
340
+ # Sun HPC and Ibm POE
341
+ else if [ SHELL "$(command) -v 2>/dev/null" ]
342
+ {
343
+ compile_flags = [ SHELL "$(command) -c -v -xtarget=native64 2>/dev/null" ] ;
344
+
345
+ local back = [ MATCH "--------------------(.*)" : $(compile_flags) ] ;
346
+ if $(back)
347
+ {
348
+ # Sun HPC
349
+ if $(.debug-configuration)
350
+ {
351
+ ECHO "Found Sun MPI wrapper compiler: $(command)" ;
352
+ }
353
+
354
+ compile_flags = [ MATCH "(.*)--------------------" : $(back) ] ;
355
+ compile_flags = [ MATCH "(.*)-v" : $(compile_flags) ] ;
356
+ link_flags = [ SHELL "$(command) -v -xtarget=native64 2>/dev/null" ] ;
357
+ link_flags = [ MATCH "--------------------(.*)" : $(link_flags) ] ;
358
+ link_flags = [ MATCH "(.*)--------------------" : $(link_flags) ] ;
359
+
360
+ # strip out -v from compile options
361
+ local front = [ MATCH "(.*)-v" : $(link_flags) ] ;
362
+ local back = [ MATCH "-v(.*)" : $(link_flags) ] ;
363
+ link_flags = "$(front) $(back)" ;
364
+ front = [ MATCH "(.*)-xtarget=native64" : $(link_flags) ] ;
365
+ back = [ MATCH "-xtarget=native64(.*)" : $(link_flags) ] ;
366
+ link_flags = "$(front) $(back)" ;
367
+ }
368
+ else
369
+ {
370
+ # Ibm POE
371
+ if $(.debug-configuration)
372
+ {
373
+ ECHO "Found IBM MPI wrapper compiler: $(command)" ;
374
+ }
375
+
376
+ #
377
+ compile_flags = [ SHELL "$(command) -c -v 2>/dev/null" ] ;
378
+ compile_flags = [ MATCH "(.*)exec: export.*" : $(compile_flags) ] ;
379
+ local front = [ MATCH "(.*)-v" : $(compile_flags) ] ;
380
+ local back = [ MATCH "-v(.*)" : $(compile_flags) ] ;
381
+ compile_flags = "$(front) $(back)" ;
382
+ front = [ MATCH "(.*)-c" : $(compile_flags) ] ;
383
+ back = [ MATCH "-c(.*)" : $(compile_flags) ] ;
384
+ compile_flags = "$(front) $(back)" ;
385
+ link_flags = $(compile_flags) ;
386
+
387
+ # get location of mpif.h from mpxlf
388
+ local f_flags = [ SHELL "mpxlf -v 2>/dev/null" ] ;
389
+ f_flags = [ MATCH "(.*)exec: export.*" : $(f_flags) ] ;
390
+ front = [ MATCH "(.*)-v" : $(f_flags) ] ;
391
+ back = [ MATCH "-v(.*)" : $(f_flags) ] ;
392
+ f_flags = "$(front) $(back)" ;
393
+ f_flags = [ MATCH "xlf_r(.*)" : $(f_flags) ] ;
394
+ f_flags = [ MATCH "-F:mpxlf_r(.*)" : $(f_flags) ] ;
395
+ compile_flags = [ strip-eol $(compile_flags) ] ;
396
+ compile_flags = "$(compile_flags) $(f_flags)" ;
397
+ }
398
+ }
399
+
400
+ if $(result) || $(compile_flags) && $(link_flags)
401
+ {
402
+ if $(result)
403
+ {
404
+ result = [ strip-eol $(result) ] ;
405
+ options = [ cmdline_to_features $(result) ] ;
406
+ }
407
+ else
408
+ {
409
+ compile_flags = [ strip-eol $(compile_flags) ] ;
410
+ link_flags = [ strip-eol $(link_flags) ] ;
411
+
412
+ # Separately process compilation and link features, then combine
413
+ # them at the end.
414
+ local compile_features = [ cmdline_to_features $(compile_flags)
415
+ : "<cxxflags>" ] ;
416
+ local link_features = [ cmdline_to_features $(link_flags)
417
+ : "<linkflags>" ] ;
418
+ options = $(compile_features) $(link_features) ;
419
+ }
420
+
421
+ # If requested, display MPI configuration information.
422
+ if $(.debug-configuration)
423
+ {
424
+ if $(result)
425
+ {
426
+ ECHO " Wrapper compiler command line: $(result)" ;
427
+ }
428
+ else
429
+ {
430
+ local match = [ MATCH "^([^\" ]+|\"[^\"]+\") *(.*)$"
431
+ : $(compile_flags) ] ;
432
+ ECHO "MPI compilation flags: $(match[2])" ;
433
+ local match = [ MATCH "^([^\" ]+|\"[^\"]+\") *(.*)$"
434
+ : $(link_flags) ] ;
435
+ ECHO "MPI link flags: $(match[2])" ;
436
+ }
437
+ }
438
+ }
439
+ else
440
+ {
441
+ if $(command)
442
+ {
443
+ ECHO "MPI auto-detection failed: unknown wrapper compiler $(command)" ;
444
+ ECHO "Please report this error to the Boost mailing list: http://www.boost.org" ;
445
+ }
446
+ else if $(mpicxx)
447
+ {
448
+ ECHO "MPI auto-detection failed: unable to find wrapper compiler $(mpicxx)" ;
449
+ }
450
+ else
451
+ {
452
+ ECHO "MPI auto-detection failed: unable to find wrapper compiler `mpic++' or `mpiCC'" ;
453
+ }
454
+ ECHO "You will need to manually configure MPI support." ;
455
+ }
456
+
457
+ }
458
+
459
+ # Find mpirun (or its equivalent) and its flags
460
+ if ! $(.mpirun)
461
+ {
462
+ .mpirun =
463
+ [ common.get-invocation-command mpi : mpirun : $(mpirun-with-options[1]) ] ;
464
+ .mpirun_flags = $(mpirun-with-options[2-]) ;
465
+ .mpirun_flags ?= -np ;
466
+ }
467
+
468
+ if $(.debug-configuration)
469
+ {
470
+ if $(options)
471
+ {
472
+ echo "MPI build features: " ;
473
+ ECHO $(options) ;
474
+ }
475
+
476
+ if $(.mpirun)
477
+ {
478
+ echo "MPI launcher: $(.mpirun) $(.mpirun_flags)" ;
479
+ }
480
+
481
+ ECHO "====================================================" ;
482
+ }
483
+
484
+ if $(options)
485
+ {
486
+ .configured = true ;
487
+
488
+ # Set up the "mpi" alias
489
+ alias mpi : : : : $(options) ;
490
+ }
491
+ }
492
+
493
+ # States whether MPI has bee configured
494
+ rule configured ( )
495
+ {
496
+ return $(.configured) ;
497
+ }
498
+
499
+ # Returs the "extra" requirements needed to build MPI. These requirements are
500
+ # part of the /mpi//mpi library target, but they need to be added to anything
501
+ # that uses MPI directly to work around bugs in BBv2's propagation of
502
+ # requirements.
503
+ rule extra-requirements ( )
504
+ {
505
+ return $(MPI_EXTRA_REQUIREMENTS) ;
506
+ }
507
+
508
+ # Support for testing; borrowed from Python
509
+ type.register RUN_MPI_OUTPUT ;
510
+ type.register RUN_MPI : : TEST ;
511
+
512
+ class mpi-test-generator : generator
513
+ {
514
+ import property-set ;
515
+
516
+ rule __init__ ( * : * )
517
+ {
518
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
519
+ self.composing = true ;
520
+ }
521
+
522
+ rule run ( project name ? : property-set : sources * : multiple ? )
523
+ {
524
+ # Generate an executable from the sources. This is the executable we will run.
525
+ local executable =
526
+ [ generators.construct $(project) $(name) : EXE : $(property-set) : $(sources) ] ;
527
+
528
+ result =
529
+ [ construct-result $(executable[2-]) : $(project) $(name)-run : $(property-set) ] ;
530
+ }
531
+ }
532
+
533
+ # Use mpi-test-generator to generate MPI tests from sources
534
+ generators.register
535
+ [ new mpi-test-generator mpi.capture-output : : RUN_MPI_OUTPUT ] ;
536
+
537
+ generators.register-standard testing.expect-success
538
+ : RUN_MPI_OUTPUT : RUN_MPI ;
539
+
540
+ # The number of processes to spawn when executing an MPI test.
541
+ feature mpi:processes : : free incidental ;
542
+
543
+ # The flag settings on testing.capture-output do not
544
+ # apply to mpi.capture output at the moment.
545
+ # Redo this explicitly.
546
+ toolset.flags mpi.capture-output ARGS <testing.arg> ;
547
+ rule capture-output ( target : sources * : properties * )
548
+ {
549
+ # Use the standard capture-output rule to run the tests
550
+ testing.capture-output $(target) : $(sources[1]) : $(properties) ;
551
+
552
+ # Determine the number of processes we should run on.
553
+ local num_processes = [ property.select <mpi:processes> : $(properties) ] ;
554
+ num_processes = $(num_processes:G=) ;
555
+
556
+ # serialize the MPI tests to avoid overloading systems
557
+ JAM_SEMAPHORE on $(target) = <s>mpi-run-semaphore ;
558
+
559
+ # We launch MPI processes using the "mpirun" equivalent specified by the user.
560
+ LAUNCHER on $(target) =
561
+ [ on $(target) return $(.mpirun) $(.mpirun_flags) $(num_processes) ] ;
562
+ }
563
+
564
+ # Creates a set of test cases to be run through the MPI launcher. The name, sources,
565
+ # and requirements are the same as for any other test generator. However, schedule is
566
+ # a list of numbers, which indicates how many processes each test run will use. For
567
+ # example, passing 1 2 7 will run the test with 1 process, then 2 processes, then 7
568
+ # 7 processes. The name provided is just the base name: the actual tests will be
569
+ # the name followed by a hypen, then the number of processes.
570
+ rule mpi-test ( name : sources * : requirements * : schedule * )
571
+ {
572
+ sources ?= $(name).cpp ;
573
+ schedule ?= 1 2 3 4 7 8 13 17 ;
574
+
575
+ local result ;
576
+ for processes in $(schedule)
577
+ {
578
+ result += [ testing.make-test
579
+ run-mpi : $(sources) /boost/mpi//boost_mpi
580
+ : $(requirements) <toolset>msvc:<link>static <mpi:processes>$(processes) : $(name)-$(processes) ] ;
581
+ }
582
+ return $(result) ;
583
+ }
mosesdecoder/jam-files/boost-build/tools/msvc.jam ADDED
@@ -0,0 +1,1398 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2003 David Abrahams.
2
+ # Copyright (c) 2005 Vladimir Prus.
3
+ # Copyright (c) 2005 Alexey Pakhunov.
4
+ # Copyright (c) 2006 Bojan Resnik.
5
+ # Copyright (c) 2006 Ilya Sokolov.
6
+ # Copyright (c) 2007 Rene Rivera
7
+ # Copyright (c) 2008 Jurko Gospodnetic
8
+ #
9
+ # Use, modification and distribution is subject to the Boost Software
10
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
11
+ # http://www.boost.org/LICENSE_1_0.txt)
12
+
13
+ ################################################################################
14
+ #
15
+ # MSVC Boost Build toolset module.
16
+ # --------------------------------
17
+ #
18
+ # All toolset versions need to have their location either auto-detected or
19
+ # explicitly specified except for the special 'default' version that expects the
20
+ # environment to find the needed tools or report an error.
21
+ #
22
+ ################################################################################
23
+
24
+ import "class" : new ;
25
+ import common ;
26
+ import errors ;
27
+ import feature ;
28
+ import generators ;
29
+ import mc ;
30
+ import midl ;
31
+ import os ;
32
+ import path ;
33
+ import pch ;
34
+ import property ;
35
+ import rc ;
36
+ import toolset ;
37
+ import type ;
38
+
39
+
40
+ type.register MANIFEST : manifest ;
41
+ feature.feature embed-manifest : on off : incidental propagated ;
42
+
43
+ type.register PDB : pdb ;
44
+
45
+ ################################################################################
46
+ #
47
+ # Public rules.
48
+ #
49
+ ################################################################################
50
+
51
+ # Initialize a specific toolset version configuration. As the result, path to
52
+ # compiler and, possible, program names are set up, and will be used when that
53
+ # version of compiler is requested. For example, you might have:
54
+ #
55
+ # using msvc : 6.5 : cl.exe ;
56
+ # using msvc : 7.0 : Y:/foo/bar/cl.exe ;
57
+ #
58
+ # The version parameter may be ommited:
59
+ #
60
+ # using msvc : : Z:/foo/bar/cl.exe ;
61
+ #
62
+ # The following keywords have special meanings when specified as versions:
63
+ # - all - all detected but not yet used versions will be marked as used
64
+ # with their default options.
65
+ # - default - this is an equivalent to an empty version.
66
+ #
67
+ # Depending on a supplied version, detected configurations and presence 'cl.exe'
68
+ # in the path different results may be achieved. The following table describes
69
+ # the possible scenarios:
70
+ #
71
+ # Nothing "x.y"
72
+ # Passed Nothing "x.y" detected, detected,
73
+ # version detected detected cl.exe in path cl.exe in path
74
+ #
75
+ # default Error Use "x.y" Create "default" Use "x.y"
76
+ # all None Use all None Use all
77
+ # x.y - Use "x.y" - Use "x.y"
78
+ # a.b Error Error Create "a.b" Create "a.b"
79
+ #
80
+ # "x.y" - refers to a detected version;
81
+ # "a.b" - refers to an undetected version.
82
+ #
83
+ # FIXME: Currently the command parameter and the <compiler> property parameter
84
+ # seem to overlap in duties. Remove this duplication. This seems to be related
85
+ # to why someone started preparing to replace init with configure rules.
86
+ #
87
+ rule init (
88
+ # The msvc version being configured. When omitted the tools invoked when no
89
+ # explicit version is given will be configured.
90
+ version ?
91
+
92
+ # The command used to invoke the compiler. If not specified:
93
+ # - if version is given, default location for that version will be
94
+ # searched
95
+ #
96
+ # - if version is not given, default locations for MSVC 9.0, 8.0, 7.1, 7.0
97
+ # and 6.* will be searched
98
+ #
99
+ # - if compiler is not found in the default locations, PATH will be
100
+ # searched.
101
+ : command *
102
+
103
+ # Options may include:
104
+ #
105
+ # All options shared by multiple toolset types as handled by the
106
+ # common.handle-options() rule, e.g. <cflags>, <compileflags>, <cxxflags>,
107
+ # <fflags> & <linkflags>.
108
+ #
109
+ # <assembler>
110
+ # <compiler>
111
+ # <idl-compiler>
112
+ # <linker>
113
+ # <mc-compiler>
114
+ # <resource-compiler>
115
+ # Exact tool names to be used by this msvc toolset configuration.
116
+ #
117
+ # <compiler-filter>
118
+ # Command through which to pipe the output of running the compiler.
119
+ # For example to pass the output to STLfilt.
120
+ #
121
+ # <setup>
122
+ # Global setup command to invoke before running any of the msvc tools.
123
+ # It will be passed additional option parameters depending on the actual
124
+ # target platform.
125
+ #
126
+ # <setup-amd64>
127
+ # <setup-i386>
128
+ # <setup-ia64>
129
+ # Platform specific setup command to invoke before running any of the
130
+ # msvc tools used when builing a target for a specific platform, e.g.
131
+ # when building a 32 or 64 bit executable.
132
+ : options *
133
+ )
134
+ {
135
+ if $(command)
136
+ {
137
+ options += <command>$(command) ;
138
+ }
139
+ configure $(version) : $(options) ;
140
+ }
141
+
142
+
143
+ # 'configure' is a newer version of 'init'. The parameter 'command' is passed as
144
+ # a part of the 'options' list. See the 'init' rule comment for more detailed
145
+ # information.
146
+ #
147
+ rule configure ( version ? : options * )
148
+ {
149
+ switch $(version)
150
+ {
151
+ case "all" :
152
+ if $(options)
153
+ {
154
+ errors.error "MSVC toolset configuration: options should be"
155
+ "empty when '$(version)' is specified." ;
156
+ }
157
+
158
+ # Configure (i.e. mark as used) all registered versions.
159
+ local all-versions = [ $(.versions).all ] ;
160
+ if ! $(all-versions)
161
+ {
162
+ if $(.debug-configuration)
163
+ {
164
+ ECHO "notice: [msvc-cfg] Asked to configure all registered"
165
+ "msvc toolset versions when there are none currently"
166
+ "registered." ;
167
+ }
168
+ }
169
+ else
170
+ {
171
+ for local v in $(all-versions)
172
+ {
173
+ # Note that there is no need to skip already configured
174
+ # versions here as this will request configure-really rule
175
+ # to configure the version using default options which will
176
+ # in turn cause it to simply do nothing in case the version
177
+ # has already been configured.
178
+ configure-really $(v) ;
179
+ }
180
+ }
181
+
182
+ case "default" :
183
+ configure-really : $(options) ;
184
+
185
+ case * :
186
+ configure-really $(version) : $(options) ;
187
+ }
188
+ }
189
+
190
+
191
+ # Sets up flag definitions dependent on the compiler version used.
192
+ # - 'version' is the version of compiler in N.M format.
193
+ # - 'conditions' is the property set to be used as flag conditions.
194
+ # - 'toolset' is the toolset for which flag settings are to be defined.
195
+ # This makes the rule reusable for other msvc-option-compatible compilers.
196
+ #
197
+ rule configure-version-specific ( toolset : version : conditions )
198
+ {
199
+ toolset.push-checking-for-flags-module unchecked ;
200
+ # Starting with versions 7.0, the msvc compiler have the /Zc:forScope and
201
+ # /Zc:wchar_t options that improve C++ standard conformance, but those
202
+ # options are off by default. If we are sure that the msvc version is at
203
+ # 7.*, add those options explicitly. We can be sure either if user specified
204
+ # version 7.* explicitly or if we auto-detected the version ourselves.
205
+ if ! [ MATCH ^(6\\.) : $(version) ]
206
+ {
207
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Zc:forScope /Zc:wchar_t ;
208
+ toolset.flags $(toolset).compile.c++ C++FLAGS $(conditions) : /wd4675 ;
209
+
210
+ # Explicitly disable the 'function is deprecated' warning. Some msvc
211
+ # versions have a bug, causing them to emit the deprecation warning even
212
+ # with /W0.
213
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>off : /wd4996 ;
214
+
215
+ if [ MATCH ^([78]\\.) : $(version) ]
216
+ {
217
+ # 64-bit compatibility warning deprecated since 9.0, see
218
+ # http://msdn.microsoft.com/en-us/library/yt4xw8fh.aspx
219
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<warnings>all : /Wp64 ;
220
+ }
221
+ }
222
+
223
+ #
224
+ # Processor-specific optimization.
225
+ #
226
+
227
+ if [ MATCH ^([67]) : $(version) ]
228
+ {
229
+ # 8.0 deprecates some of the options.
230
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed $(conditions)/<optimization>space : /Ogiy /Gs ;
231
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>speed : /Ot ;
232
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<optimization>space : /Os ;
233
+
234
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set> : /GB ;
235
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i386 : /G3 ;
236
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>i486 : /G4 ;
237
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g5) : /G5 ;
238
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g6) : /G6 ;
239
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-i386)/<instruction-set>$(.cpu-type-g7) : /G7 ;
240
+
241
+ # Improve floating-point accuracy. Otherwise, some of C++ Boost's "math"
242
+ # tests will fail.
243
+ toolset.flags $(toolset).compile CFLAGS $(conditions) : /Op ;
244
+
245
+ # 7.1 and below have single-threaded static RTL.
246
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /ML ;
247
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MLd ;
248
+ }
249
+ else
250
+ {
251
+ # 8.0 and above adds some more options.
252
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set> : /favor:blend ;
253
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-em64t) : /favor:EM64T ;
254
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/$(.cpu-arch-amd64)/<instruction-set>$(.cpu-type-amd64) : /favor:AMD64 ;
255
+
256
+ # 8.0 and above only has multi-threaded static RTL.
257
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>off/<runtime-link>static/<threading>single : /MT ;
258
+ toolset.flags $(toolset).compile CFLAGS $(conditions)/<runtime-debugging>on/<runtime-link>static/<threading>single : /MTd ;
259
+
260
+ # Specify target machine type so the linker will not need to guess.
261
+ toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-amd64) : /MACHINE:X64 ;
262
+ toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-i386) : /MACHINE:X86 ;
263
+ toolset.flags $(toolset).link LINKFLAGS $(conditions)/$(.cpu-arch-ia64) : /MACHINE:IA64 ;
264
+
265
+ # Make sure that manifest will be generated even if there is no
266
+ # dependencies to put there.
267
+ toolset.flags $(toolset).link LINKFLAGS $(conditions)/<embed-manifest>off : /MANIFEST ;
268
+ }
269
+ toolset.pop-checking-for-flags-module ;
270
+ }
271
+
272
+
273
+ # Registers this toolset including all of its flags, features & generators. Does
274
+ # nothing on repeated calls.
275
+ #
276
+ rule register-toolset ( )
277
+ {
278
+ if ! msvc in [ feature.values toolset ]
279
+ {
280
+ register-toolset-really ;
281
+ }
282
+ }
283
+
284
+
285
+ # Declare action for creating static libraries. If library exists, remove it
286
+ # before adding files. See
287
+ # http://article.gmane.org/gmane.comp.lib.boost.build/4241 for rationale.
288
+ if [ os.name ] in NT
289
+ {
290
+ # The 'DEL' command would issue a message to stdout if the file does not
291
+ # exist, so need a check.
292
+ actions archive
293
+ {
294
+ if exist "$(<[1])" DEL "$(<[1])"
295
+ $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
296
+ }
297
+ }
298
+ else
299
+ {
300
+ actions archive
301
+ {
302
+ $(.RM) "$(<[1])"
303
+ $(.LD) $(AROPTIONS) /out:"$(<[1])" @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
304
+ }
305
+ }
306
+
307
+
308
+ # For the assembler the following options are turned on by default:
309
+ #
310
+ # -Zp4 align structures to 4 bytes
311
+ # -Cp preserve case of user identifiers
312
+ # -Cx preserve case in publics, externs
313
+ #
314
+ actions compile.asm
315
+ {
316
+ $(.ASM) -c -Zp4 -Cp -Cx -D$(DEFINES) $(ASMFLAGS) $(USER_ASMFLAGS) -Fo "$(<:W)" "$(>:W)"
317
+ }
318
+
319
+
320
+ rule compile.c ( targets + : sources * : properties * )
321
+ {
322
+ C++FLAGS on $(targets[1]) = ;
323
+ get-rspline $(targets) : -TC ;
324
+ compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
325
+ }
326
+
327
+
328
+ rule compile.c.preprocess ( targets + : sources * : properties * )
329
+ {
330
+ C++FLAGS on $(targets[1]) = ;
331
+ get-rspline $(targets) : -TC ;
332
+ preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
333
+ }
334
+
335
+
336
+ rule compile.c.pch ( targets + : sources * : properties * )
337
+ {
338
+ C++FLAGS on $(targets[1]) = ;
339
+ get-rspline $(targets[1]) : -TC ;
340
+ get-rspline $(targets[2]) : -TC ;
341
+ local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
342
+ if $(pch-source)
343
+ {
344
+ DEPENDS $(<) : $(pch-source) ;
345
+ compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
346
+ }
347
+ else
348
+ {
349
+ compile-c-c++-pch $(targets) : $(sources) ;
350
+ }
351
+ }
352
+
353
+ toolset.flags msvc YLOPTION : "-Yl" ;
354
+
355
+ # Action for running the C/C++ compiler without using precompiled headers.
356
+ #
357
+ # WARNING: Synchronize any changes this in action with intel-win
358
+ #
359
+ # Notes regarding PDB generation, for when we use <debug-symbols>on/<debug-store>database
360
+ #
361
+ # 1. PDB_CFLAG is only set for <debug-symbols>on/<debug-store>database, ensuring that the /Fd flag is dropped if PDB_CFLAG is empty
362
+ #
363
+ # 2. When compiling executables's source files, PDB_NAME is set on a per-source file basis by rule compile-c-c++.
364
+ # The linker will pull these into the executable's PDB
365
+ #
366
+ # 3. When compiling library's source files, PDB_NAME is updated to <libname>.pdb for each source file by rule archive,
367
+ # as in this case the compiler must be used to create a single PDB for our library.
368
+ #
369
+ actions compile-c-c++ bind PDB_NAME
370
+ {
371
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -Fo"$(<[1]:W)" $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
372
+ }
373
+
374
+ actions preprocess-c-c++ bind PDB_NAME
375
+ {
376
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[1]:W)" -E $(PDB_CFLAG)"$(PDB_NAME)" -Yu"$(>[3]:D=)" -Fp"$(>[2]:W)" $(CC_RSPLINE))" >"$(<[1]:W)"
377
+ }
378
+
379
+ rule compile-c-c++ ( targets + : sources * )
380
+ {
381
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
382
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
383
+ PDB_NAME on $(<) = $(<:S=.pdb) ;
384
+ }
385
+
386
+ rule preprocess-c-c++ ( targets + : sources * )
387
+ {
388
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_HEADER) ] ;
389
+ DEPENDS $(<[1]) : [ on $(<[1]) return $(PCH_FILE) ] ;
390
+ PDB_NAME on $(<) = $(<:S=.pdb) ;
391
+ }
392
+
393
+ # Action for running the C/C++ compiler using precompiled headers. In addition
394
+ # to whatever else it needs to compile, this action also adds a temporary source
395
+ # .cpp file used to compile the precompiled headers themselves.
396
+ #
397
+ # The global .escaped-double-quote variable is used to avoid messing up Emacs
398
+ # syntax highlighting in the messy N-quoted code below.
399
+ actions compile-c-c++-pch
400
+ {
401
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" "@($(<[1]:W).cpp:E=#include $(.escaped-double-quote)$(>[1]:D=)$(.escaped-double-quote)$(.nl))" $(.CC.FILTER)
402
+ }
403
+
404
+
405
+ # Action for running the C/C++ compiler using precompiled headers. An already
406
+ # built source file for compiling the precompiled headers is expected to be
407
+ # given as one of the source parameters.
408
+ actions compile-c-c++-pch-s
409
+ {
410
+ $(.CC) @"@($(<[1]:W).rsp:E="$(>[2]:W)" -Fo"$(<[2]:W)" -Yc"$(>[1]:D=)" $(YLOPTION)"__bjam_pch_symbol_$(>[1]:D=)" -Fp"$(<[1]:W)" $(CC_RSPLINE))" $(.CC.FILTER)
411
+ }
412
+
413
+
414
+ rule compile.c++ ( targets + : sources * : properties * )
415
+ {
416
+ get-rspline $(targets) : -TP ;
417
+ compile-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
418
+ }
419
+
420
+ rule compile.c++.preprocess ( targets + : sources * : properties * )
421
+ {
422
+ get-rspline $(targets) : -TP ;
423
+ preprocess-c-c++ $(<) : $(>) [ on $(<) return $(PCH_FILE) ] [ on $(<) return $(PCH_HEADER) ] ;
424
+ }
425
+
426
+
427
+ rule compile.c++.pch ( targets + : sources * : properties * )
428
+ {
429
+ get-rspline $(targets[1]) : -TP ;
430
+ get-rspline $(targets[2]) : -TP ;
431
+ local pch-source = [ on $(<) return $(PCH_SOURCE) ] ;
432
+ if $(pch-source)
433
+ {
434
+ DEPENDS $(<) : $(pch-source) ;
435
+ compile-c-c++-pch-s $(targets) : $(sources) $(pch-source) ;
436
+ }
437
+ else
438
+ {
439
+ compile-c-c++-pch $(targets) : $(sources) ;
440
+ }
441
+ }
442
+
443
+
444
+ # See midl.jam for details.
445
+ #
446
+ actions compile.idl
447
+ {
448
+ $(.IDL) /nologo @"@($(<[1]:W).rsp:E=$(.nl)"$(>:W)" $(.nl)-D$(DEFINES) $(.nl)"-I$(INCLUDES:W)" $(.nl)-U$(UNDEFS) $(.nl)$(MIDLFLAGS) $(.nl)/tlb "$(<[1]:W)" $(.nl)/h "$(<[2]:W)" $(.nl)/iid "$(<[3]:W)" $(.nl)/proxy "$(<[4]:W)" $(.nl)/dlldata "$(<[5]:W)")"
449
+ $(.TOUCH_FILE) "$(<[4]:W)"
450
+ $(.TOUCH_FILE) "$(<[5]:W)"
451
+ }
452
+
453
+
454
+ actions compile.mc
455
+ {
456
+ $(.MC) $(MCFLAGS) -h "$(<[1]:DW)" -r "$(<[2]:DW)" "$(>:W)"
457
+ }
458
+
459
+
460
+ actions compile.rc
461
+ {
462
+ $(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES:W)" -fo "$(<:W)" "$(>:W)"
463
+ }
464
+
465
+
466
+ rule link ( targets + : sources * : properties * )
467
+ {
468
+ if <embed-manifest>on in $(properties)
469
+ {
470
+ msvc.manifest $(targets) : $(sources) : $(properties) ;
471
+ }
472
+ }
473
+
474
+ rule link.dll ( targets + : sources * : properties * )
475
+ {
476
+ DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
477
+ if <embed-manifest>on in $(properties)
478
+ {
479
+ msvc.manifest.dll $(targets) : $(sources) : $(properties) ;
480
+ }
481
+ }
482
+
483
+ # Incremental linking a DLL causes no end of problems: if the actual exports do
484
+ # not change, the import .lib file is never updated. Therefore, the .lib is
485
+ # always out-of-date and gets rebuilt every time. I am not sure that incremental
486
+ # linking is such a great idea in general, but in this case I am sure we do not
487
+ # want it.
488
+
489
+ # Windows manifest is a new way to specify dependencies on managed DotNet
490
+ # assemblies and Windows native DLLs. The manifests are embedded as resources
491
+ # and are useful in any PE target (both DLL and EXE).
492
+
493
+ if [ os.name ] in NT
494
+ {
495
+ actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
496
+ {
497
+ $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
498
+ if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
499
+ }
500
+
501
+ actions manifest
502
+ {
503
+ if exist "$(<[1]).manifest" (
504
+ $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);1"
505
+ )
506
+ }
507
+
508
+ actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
509
+ {
510
+ $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
511
+ if %ERRORLEVEL% NEQ 0 EXIT %ERRORLEVEL%
512
+ }
513
+
514
+ actions manifest.dll
515
+ {
516
+ if exist "$(<[1]).manifest" (
517
+ $(.MT) -manifest "$(<[1]).manifest" "-outputresource:$(<[1]);2"
518
+ )
519
+ }
520
+ }
521
+ else
522
+ {
523
+ actions link bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
524
+ {
525
+ $(.LD) $(LINKFLAGS) /out:"$(<[1]:W)" /LIBPATH:"$(LINKPATH:W)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
526
+ }
527
+
528
+ actions manifest
529
+ {
530
+ if test -e "$(<[1]).manifest"; then
531
+ $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);1"
532
+ fi
533
+ }
534
+
535
+ actions link.dll bind DEF_FILE LIBRARIES_MENTIONED_BY_FILE
536
+ {
537
+ $(.LD) /DLL $(LINKFLAGS) /out:"$(<[1]:W)" /IMPLIB:"$(<[2]:W)" /LIBPATH:"$(LINKPATH:W)" /def:"$(DEF_FILE)" $(OPTIONS) @"@($(<[1]:W).rsp:E=$(.nl)"$(>)" $(.nl)$(LIBRARIES_MENTIONED_BY_FILE) $(.nl)$(LIBRARIES) $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_ST).lib" $(.nl)"$(LIBRARY_OPTION)$(FINDLIBS_SA).lib")"
538
+ }
539
+
540
+ actions manifest.dll
541
+ {
542
+ if test -e "$(<[1]).manifest"; then
543
+ $(.MT) -manifest "$(<[1]:W).manifest" "-outputresource:$(<[1]:W);2"
544
+ fi
545
+ }
546
+ }
547
+
548
+ # this rule sets up the pdb file that will be used when generating static
549
+ # libraries and the debug-store option is database, so that the compiler
550
+ # puts all debug info into a single .pdb file named after the library
551
+ #
552
+ # Poking at source targets this way is probably not clean, but it's the
553
+ # easiest approach.
554
+ rule archive ( targets + : sources * : properties * )
555
+ {
556
+ PDB_NAME on $(>) = $(<:S=.pdb) ;
557
+ }
558
+
559
+ ################################################################################
560
+ #
561
+ # Classes.
562
+ #
563
+ ################################################################################
564
+
565
+ class msvc-pch-generator : pch-generator
566
+ {
567
+ import property-set ;
568
+
569
+ rule run-pch ( project name ? : property-set : sources * )
570
+ {
571
+ # Searching for the header and source file in the sources.
572
+ local pch-header ;
573
+ local pch-source ;
574
+ for local s in $(sources)
575
+ {
576
+ if [ type.is-derived [ $(s).type ] H ]
577
+ {
578
+ pch-header = $(s) ;
579
+ }
580
+ else if
581
+ [ type.is-derived [ $(s).type ] CPP ] ||
582
+ [ type.is-derived [ $(s).type ] C ]
583
+ {
584
+ pch-source = $(s) ;
585
+ }
586
+ }
587
+
588
+ if ! $(pch-header)
589
+ {
590
+ errors.user-error "can not build pch without pch-header" ;
591
+ }
592
+
593
+ # If we do not have the PCH source - that is fine. We will just create a
594
+ # temporary .cpp file in the action.
595
+
596
+ local generated = [ generator.run $(project) $(name)
597
+ : [ property-set.create
598
+ # Passing of <pch-source> is a dirty trick, needed because
599
+ # non-composing generators with multiple inputs are subtly
600
+ # broken. For more detailed information see:
601
+ # https://zigzag.cs.msu.su:7813/boost.build/ticket/111
602
+ <pch-source>$(pch-source)
603
+ [ $(property-set).raw ] ]
604
+ : $(pch-header) ] ;
605
+
606
+ local pch-file ;
607
+ for local g in $(generated)
608
+ {
609
+ if [ type.is-derived [ $(g).type ] PCH ]
610
+ {
611
+ pch-file = $(g) ;
612
+ }
613
+ }
614
+
615
+ return [ property-set.create <pch-header>$(pch-header)
616
+ <pch-file>$(pch-file) ] $(generated) ;
617
+ }
618
+ }
619
+
620
+
621
+ ################################################################################
622
+ #
623
+ # Local rules.
624
+ #
625
+ ################################################################################
626
+
627
+ # Detects versions listed as '.known-versions' by checking registry information,
628
+ # environment variables & default paths. Supports both native Windows and
629
+ # Cygwin.
630
+ #
631
+ local rule auto-detect-toolset-versions ( )
632
+ {
633
+ if [ os.name ] in NT CYGWIN
634
+ {
635
+ # Get installation paths from the registry.
636
+ for local i in $(.known-versions)
637
+ {
638
+ if $(.version-$(i)-reg)
639
+ {
640
+ local vc-path ;
641
+ for local x in "" "Wow6432Node\\"
642
+ {
643
+ vc-path += [ W32_GETREG
644
+ "HKEY_LOCAL_MACHINE\\SOFTWARE\\"$(x)"\\Microsoft\\"$(.version-$(i)-reg)
645
+ : "ProductDir" ] ;
646
+ }
647
+
648
+ if $(vc-path)
649
+ {
650
+ vc-path = [ path.join [ path.make-NT $(vc-path[1]) ] "bin" ] ;
651
+ register-configuration $(i) : [ path.native $(vc-path[1]) ] ;
652
+ }
653
+ }
654
+ }
655
+ }
656
+
657
+ # Check environment and default installation paths.
658
+ for local i in $(.known-versions)
659
+ {
660
+ if ! $(i) in [ $(.versions).all ]
661
+ {
662
+ register-configuration $(i) : [ default-path $(i) ] ;
663
+ }
664
+ }
665
+ }
666
+
667
+
668
+ # Worker rule for toolset version configuration. Takes an explicit version id or
669
+ # nothing in case it should configure the default toolset version (the first
670
+ # registered one or a new 'default' one in case no toolset versions have been
671
+ # registered yet).
672
+ #
673
+ local rule configure-really ( version ? : options * )
674
+ {
675
+ local v = $(version) ;
676
+
677
+ # Decide what the 'default' version is.
678
+ if ! $(v)
679
+ {
680
+ # Take the first registered (i.e. auto-detected) version.
681
+ version = [ $(.versions).all ] ;
682
+ version = $(version[1]) ;
683
+ v = $(version) ;
684
+
685
+ # Note: 'version' can still be empty at this point if no versions have
686
+ # been auto-detected.
687
+ version ?= "default" ;
688
+ }
689
+
690
+ # Version alias -> real version number.
691
+ if $(.version-alias-$(version))
692
+ {
693
+ version = $(.version-alias-$(version)) ;
694
+ }
695
+
696
+ # Check whether the selected configuration is already in use.
697
+ if $(version) in [ $(.versions).used ]
698
+ {
699
+ # Allow multiple 'toolset.using' calls for the same configuration if the
700
+ # identical sets of options are used.
701
+ if $(options) && ( $(options) != [ $(.versions).get $(version) : options ] )
702
+ {
703
+ errors.error "MSVC toolset configuration: Toolset version"
704
+ "'$(version)' already configured." ;
705
+ }
706
+ }
707
+ else
708
+ {
709
+ # Register a new configuration.
710
+ $(.versions).register $(version) ;
711
+
712
+ # Add user-supplied to auto-detected options.
713
+ options = [ $(.versions).get $(version) : options ] $(options) ;
714
+
715
+ # Mark the configuration as 'used'.
716
+ $(.versions).use $(version) ;
717
+
718
+ # Generate conditions and save them.
719
+ local conditions = [ common.check-init-parameters msvc : version $(v) ]
720
+ ;
721
+
722
+ $(.versions).set $(version) : conditions : $(conditions) ;
723
+
724
+ local command = [ feature.get-values <command> : $(options) ] ;
725
+
726
+ # If version is specified, we try to search first in default paths, and
727
+ # only then in PATH.
728
+ command = [ common.get-invocation-command msvc : cl.exe : $(command) :
729
+ [ default-paths $(version) ] : $(version) ] ;
730
+
731
+ common.handle-options msvc : $(conditions) : $(command) : $(options) ;
732
+
733
+ if ! $(version)
734
+ {
735
+ # Even if version is not explicitly specified, try to detect the
736
+ # version from the path.
737
+ # FIXME: We currently detect both Microsoft Visual Studio 9.0 and
738
+ # 9.0express as 9.0 here.
739
+ if [ MATCH "(Microsoft Visual Studio 11)" : $(command) ]
740
+ {
741
+ version = 11.0 ;
742
+ }
743
+ else if [ MATCH "(Microsoft Visual Studio 10)" : $(command) ]
744
+ {
745
+ version = 10.0 ;
746
+ }
747
+ else if [ MATCH "(Microsoft Visual Studio 9)" : $(command) ]
748
+ {
749
+ version = 9.0 ;
750
+ }
751
+ else if [ MATCH "(Microsoft Visual Studio 8)" : $(command) ]
752
+ {
753
+ version = 8.0 ;
754
+ }
755
+ else if [ MATCH "(NET 2003[\/\\]VC7)" : $(command) ]
756
+ {
757
+ version = 7.1 ;
758
+ }
759
+ else if [ MATCH "(Microsoft Visual C\\+\\+ Toolkit 2003)" :
760
+ $(command) ]
761
+ {
762
+ version = 7.1toolkit ;
763
+ }
764
+ else if [ MATCH "(.NET[\/\\]VC7)" : $(command) ]
765
+ {
766
+ version = 7.0 ;
767
+ }
768
+ else
769
+ {
770
+ version = 6.0 ;
771
+ }
772
+ }
773
+
774
+ # Generate and register setup command.
775
+
776
+ local below-8.0 = [ MATCH ^([67]\\.) : $(version) ] ;
777
+
778
+ local cpu = i386 amd64 ia64 ;
779
+ if $(below-8.0)
780
+ {
781
+ cpu = i386 ;
782
+ }
783
+
784
+ local setup-amd64 ;
785
+ local setup-i386 ;
786
+ local setup-ia64 ;
787
+
788
+ if $(command)
789
+ {
790
+ # TODO: Note that if we specify a non-existant toolset version then
791
+ # this rule may find and use a corresponding compiler executable
792
+ # belonging to an incorrect toolset version. For example, if you
793
+ # have only MSVC 7.1 installed, have its executable on the path and
794
+ # specify you want Boost Build to use MSVC 9.0, then you want Boost
795
+ # Build to report an error but this may cause it to silently use the
796
+ # MSVC 7.1 compiler even though it thinks it is using the msvc-9.0
797
+ # toolset version.
798
+ command = [ common.get-absolute-tool-path $(command[-1]) ] ;
799
+ }
800
+
801
+ if $(command)
802
+ {
803
+ local parent = [ path.make $(command) ] ;
804
+ parent = [ path.parent $(parent) ] ;
805
+ parent = [ path.native $(parent) ] ;
806
+
807
+ # Setup will be used if the command name has been specified. If
808
+ # setup is not specified explicitly then a default setup script will
809
+ # be used instead. Setup scripts may be global or arhitecture/
810
+ # /platform/cpu specific. Setup options are used only in case of
811
+ # global setup scripts.
812
+
813
+ # Default setup scripts provided with different VC distributions:
814
+ #
815
+ # VC 7.1 had only the vcvars32.bat script specific to 32 bit i386
816
+ # builds. It was located in the bin folder for the regular version
817
+ # and in the root folder for the free VC 7.1 tools.
818
+ #
819
+ # Later 8.0 & 9.0 versions introduce separate platform specific
820
+ # vcvars*.bat scripts (e.g. 32 bit, 64 bit AMD or 64 bit Itanium)
821
+ # located in or under the bin folder. Most also include a global
822
+ # vcvarsall.bat helper script located in the root folder which runs
823
+ # one of the aforementioned vcvars*.bat scripts based on the options
824
+ # passed to it. So far only the version coming with some PlatformSDK
825
+ # distributions does not include this top level script but to
826
+ # support those we need to fall back to using the worker scripts
827
+ # directly in case the top level script can not be found.
828
+
829
+ local global-setup = [ feature.get-values <setup> : $(options) ] ;
830
+ global-setup = $(global-setup[1]) ;
831
+ if ! $(below-8.0)
832
+ {
833
+ global-setup ?= [ locate-default-setup $(command) : $(parent) :
834
+ vcvarsall.bat ] ;
835
+ }
836
+
837
+ local default-setup-amd64 = vcvarsx86_amd64.bat ;
838
+ local default-setup-i386 = vcvars32.bat ;
839
+ local default-setup-ia64 = vcvarsx86_ia64.bat ;
840
+
841
+ # http://msdn2.microsoft.com/en-us/library/x4d2c09s(VS.80).aspx and
842
+ # http://msdn2.microsoft.com/en-us/library/x4d2c09s(vs.90).aspx
843
+ # mention an x86_IPF option, that seems to be a documentation bug
844
+ # and x86_ia64 is the correct option.
845
+ local default-global-setup-options-amd64 = x86_amd64 ;
846
+ local default-global-setup-options-i386 = x86 ;
847
+ local default-global-setup-options-ia64 = x86_ia64 ;
848
+
849
+ # When using 64-bit Windows, and targeting 64-bit, it is possible to
850
+ # use a native 64-bit compiler, selected by the "amd64" & "ia64"
851
+ # parameters to vcvarsall.bat. There are two variables we can use --
852
+ # PROCESSOR_ARCHITECTURE and PROCESSOR_IDENTIFIER. The first is
853
+ # 'x86' when running 32-bit Windows, no matter which processor is
854
+ # used, and 'AMD64' on 64-bit windows on x86 (either AMD64 or EM64T)
855
+ # Windows.
856
+ #
857
+ if [ MATCH ^(AMD64) : [ os.environ PROCESSOR_ARCHITECTURE ] ]
858
+ {
859
+ default-global-setup-options-amd64 = amd64 ;
860
+ }
861
+ # TODO: The same 'native compiler usage' should be implemented for
862
+ # the Itanium platform by using the "ia64" parameter. For this
863
+ # though we need someone with access to this platform who can find
864
+ # out how to correctly detect this case.
865
+ else if $(somehow-detect-the-itanium-platform)
866
+ {
867
+ default-global-setup-options-ia64 = ia64 ;
868
+ }
869
+
870
+ local setup-prefix = "call " ;
871
+ local setup-suffix = " >nul"$(.nl) ;
872
+ if ! [ os.name ] in NT
873
+ {
874
+ setup-prefix = "cmd.exe /S /C call " ;
875
+ setup-suffix = " \">nul\" \"&&\" " ;
876
+ }
877
+
878
+ for local c in $(cpu)
879
+ {
880
+ local setup-options ;
881
+
882
+ setup-$(c) = [ feature.get-values <setup-$(c)> : $(options) ] ;
883
+
884
+ if ! $(setup-$(c))-is-not-empty
885
+ {
886
+ if $(global-setup)-is-not-empty
887
+ {
888
+ setup-$(c) = $(global-setup) ;
889
+
890
+ # If needed we can easily add using configuration flags
891
+ # here for overriding which options get passed to the
892
+ # global setup command for which target platform:
893
+ # setup-options = [ feature.get-values <setup-options-$(c)> : $(options) ] ;
894
+
895
+ setup-options ?= $(default-global-setup-options-$(c)) ;
896
+ }
897
+ else
898
+ {
899
+ setup-$(c) = [ locate-default-setup $(command) : $(parent) : $(default-setup-$(c)) ] ;
900
+ }
901
+ }
902
+
903
+ # Cygwin to Windows path translation.
904
+ setup-$(c) = "\""$(setup-$(c):W)"\"" ;
905
+
906
+ # Append setup options to the setup name and add the final setup
907
+ # prefix & suffix.
908
+ setup-options ?= "" ;
909
+ setup-$(c) = $(setup-prefix)$(setup-$(c):J=" ")" "$(setup-options:J=" ")$(setup-suffix) ;
910
+ }
911
+ }
912
+
913
+ # Get tool names (if any) and finish setup.
914
+
915
+ compiler = [ feature.get-values <compiler> : $(options) ] ;
916
+ compiler ?= cl ;
917
+
918
+ linker = [ feature.get-values <linker> : $(options) ] ;
919
+ linker ?= link ;
920
+
921
+ resource-compiler = [ feature.get-values <resource-compiler> : $(options) ] ;
922
+ resource-compiler ?= rc ;
923
+
924
+ # Turn on some options for i386 assembler
925
+ # -coff generate COFF format object file (compatible with cl.exe output)
926
+ local default-assembler-amd64 = ml64 ;
927
+ local default-assembler-i386 = "ml -coff" ;
928
+ local default-assembler-ia64 = ias ;
929
+
930
+ assembler = [ feature.get-values <assembler> : $(options) ] ;
931
+
932
+ idl-compiler = [ feature.get-values <idl-compiler> : $(options) ] ;
933
+ idl-compiler ?= midl ;
934
+
935
+ mc-compiler = [ feature.get-values <mc-compiler> : $(options) ] ;
936
+ mc-compiler ?= mc ;
937
+
938
+ manifest-tool = [ feature.get-values <manifest-tool> : $(options) ] ;
939
+ manifest-tool ?= mt ;
940
+
941
+ local cc-filter = [ feature.get-values <compiler-filter> : $(options) ] ;
942
+
943
+ for local c in $(cpu)
944
+ {
945
+ # Setup script is not required in some configurations.
946
+ setup-$(c) ?= "" ;
947
+
948
+ local cpu-conditions = $(conditions)/$(.cpu-arch-$(c)) ;
949
+
950
+ if $(.debug-configuration)
951
+ {
952
+ for local cpu-condition in $(cpu-conditions)
953
+ {
954
+ ECHO "notice: [msvc-cfg] condition: '$(cpu-condition)', setup: '$(setup-$(c))'" ;
955
+ }
956
+ }
957
+
958
+ local cpu-assembler = $(assembler) ;
959
+ cpu-assembler ?= $(default-assembler-$(c)) ;
960
+
961
+ toolset.flags msvc.compile .CC $(cpu-conditions) : $(setup-$(c))$(compiler) /Zm800 -nologo ;
962
+ toolset.flags msvc.compile .RC $(cpu-conditions) : $(setup-$(c))$(resource-compiler) ;
963
+ toolset.flags msvc.compile .ASM $(cpu-conditions) : $(setup-$(c))$(cpu-assembler) -nologo ;
964
+ toolset.flags msvc.link .LD $(cpu-conditions) : $(setup-$(c))$(linker) /NOLOGO /INCREMENTAL:NO ;
965
+ toolset.flags msvc.archive .LD $(cpu-conditions) : $(setup-$(c))$(linker) /lib /NOLOGO ;
966
+ toolset.flags msvc.compile .IDL $(cpu-conditions) : $(setup-$(c))$(idl-compiler) ;
967
+ toolset.flags msvc.compile .MC $(cpu-conditions) : $(setup-$(c))$(mc-compiler) ;
968
+
969
+ toolset.flags msvc.link .MT $(cpu-conditions) : $(setup-$(c))$(manifest-tool) -nologo ;
970
+
971
+ if $(cc-filter)
972
+ {
973
+ toolset.flags msvc .CC.FILTER $(cpu-conditions) : "|" $(cc-filter) ;
974
+ }
975
+ }
976
+
977
+ # Set version-specific flags.
978
+ configure-version-specific msvc : $(version) : $(conditions) ;
979
+ }
980
+ }
981
+
982
+
983
+ # Returns the default installation path for the given version.
984
+ #
985
+ local rule default-path ( version )
986
+ {
987
+ # Use auto-detected path if possible.
988
+ local path = [ feature.get-values <command> : [ $(.versions).get $(version)
989
+ : options ] ] ;
990
+
991
+ if $(path)
992
+ {
993
+ path = $(path:D) ;
994
+ }
995
+ else
996
+ {
997
+ # Check environment.
998
+ if $(.version-$(version)-env)
999
+ {
1000
+ local vc-path = [ os.environ $(.version-$(version)-env) ] ;
1001
+ if $(vc-path)
1002
+ {
1003
+ vc-path = [ path.make $(vc-path) ] ;
1004
+ vc-path = [ path.join $(vc-path) $(.version-$(version)-envpath) ] ;
1005
+ vc-path = [ path.native $(vc-path) ] ;
1006
+
1007
+ path = $(vc-path) ;
1008
+ }
1009
+ }
1010
+
1011
+ # Check default path.
1012
+ if ! $(path) && $(.version-$(version)-path)
1013
+ {
1014
+ path = [ path.native [ path.join $(.ProgramFiles) $(.version-$(version)-path) ] ] ;
1015
+ }
1016
+ }
1017
+
1018
+ return $(path) ;
1019
+ }
1020
+
1021
+
1022
+ # Returns either the default installation path (if 'version' is not empty) or
1023
+ # list of all known default paths (if no version is given)
1024
+ #
1025
+ local rule default-paths ( version ? )
1026
+ {
1027
+ local possible-paths ;
1028
+
1029
+ if $(version)
1030
+ {
1031
+ possible-paths += [ default-path $(version) ] ;
1032
+ }
1033
+ else
1034
+ {
1035
+ for local i in $(.known-versions)
1036
+ {
1037
+ possible-paths += [ default-path $(i) ] ;
1038
+ }
1039
+ }
1040
+
1041
+ return $(possible-paths) ;
1042
+ }
1043
+
1044
+
1045
+ rule get-rspline ( target : lang-opt )
1046
+ {
1047
+ CC_RSPLINE on $(target) = [ on $(target) return $(lang-opt) -U$(UNDEFS)
1048
+ $(CFLAGS) $(C++FLAGS) $(OPTIONS) -c $(.nl)-D$(DEFINES)
1049
+ $(.nl)\"-I$(INCLUDES:W)\" ] ;
1050
+ }
1051
+
1052
+ class msvc-linking-generator : linking-generator
1053
+ {
1054
+ # Calls the base version. If necessary, also create a target for the
1055
+ # manifest file.specifying source's name as the name of the created
1056
+ # target. As result, the PCH will be named whatever.hpp.gch, and not
1057
+ # whatever.gch.
1058
+ rule generated-targets ( sources + : property-set : project name ? )
1059
+ {
1060
+ local result = [ linking-generator.generated-targets $(sources)
1061
+ : $(property-set) : $(project) $(name) ] ;
1062
+
1063
+ if $(result)
1064
+ {
1065
+ local name-main = [ $(result[0]).name ] ;
1066
+ local action = [ $(result[0]).action ] ;
1067
+
1068
+ if [ $(property-set).get <debug-symbols> ] = "on"
1069
+ {
1070
+ # We force exact name on PDB. The reason is tagging -- the tag rule may
1071
+ # reasonably special case some target types, like SHARED_LIB. The tag rule
1072
+ # will not catch PDB, and it cannot even easily figure if PDB is paired with
1073
+ # SHARED_LIB or EXE or something else. Because PDB always get the
1074
+ # same name as the main target, with .pdb as extension, just force it.
1075
+ local target = [ class.new file-target $(name-main:S=.pdb) exact : PDB : $(project) : $(action) ] ;
1076
+ local registered-target = [ virtual-target.register $(target) ] ;
1077
+ if $(target) != $(registered-target)
1078
+ {
1079
+ $(action).replace-targets $(target) : $(registered-target) ;
1080
+ }
1081
+ result += $(registered-target) ;
1082
+ }
1083
+
1084
+ if [ $(property-set).get <embed-manifest> ] = "off"
1085
+ {
1086
+ # Manifest is evil target. It has .manifest appened to the name of
1087
+ # main target, including extension. E.g. a.exe.manifest. We use 'exact'
1088
+ # name because to achieve this effect.
1089
+ local target = [ class.new file-target $(name-main).manifest exact : MANIFEST : $(project) : $(action) ] ;
1090
+ local registered-target = [ virtual-target.register $(target) ] ;
1091
+ if $(target) != $(registered-target)
1092
+ {
1093
+ $(action).replace-targets $(target) : $(registered-target) ;
1094
+ }
1095
+ result += $(registered-target) ;
1096
+ }
1097
+ }
1098
+ return $(result) ;
1099
+ }
1100
+ }
1101
+
1102
+
1103
+
1104
+ # Unsafe worker rule for the register-toolset() rule. Must not be called
1105
+ # multiple times.
1106
+ #
1107
+ local rule register-toolset-really ( )
1108
+ {
1109
+ feature.extend toolset : msvc ;
1110
+
1111
+ # Intel and msvc supposedly have link-compatible objects.
1112
+ feature.subfeature toolset msvc : vendor : intel : propagated optional ;
1113
+
1114
+ # Inherit MIDL flags.
1115
+ toolset.inherit-flags msvc : midl ;
1116
+
1117
+ # Inherit MC flags.
1118
+ toolset.inherit-flags msvc : mc ;
1119
+
1120
+ # Dynamic runtime comes only in MT flavour.
1121
+ toolset.add-requirements
1122
+ <toolset>msvc,<runtime-link>shared:<threading>multi ;
1123
+
1124
+ # Declare msvc toolset specific features.
1125
+ {
1126
+ feature.feature debug-store : object database : propagated ;
1127
+ feature.feature pch-source : : dependency free ;
1128
+ }
1129
+
1130
+ # Declare generators.
1131
+ {
1132
+ # TODO: Is it possible to combine these? Make the generators
1133
+ # non-composing so that they do not convert each source into a separate
1134
+ # .rsp file.
1135
+ generators.register [ new msvc-linking-generator
1136
+ msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE : <toolset>msvc ] ;
1137
+ generators.register [ new msvc-linking-generator
1138
+ msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB : <toolset>msvc ] ;
1139
+
1140
+ generators.register-archiver msvc.archive : OBJ : STATIC_LIB : <toolset>msvc ;
1141
+ generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
1142
+ generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
1143
+ generators.register-c-compiler msvc.compile.c++.preprocess : CPP : PREPROCESSED_CPP : <toolset>msvc ;
1144
+ generators.register-c-compiler msvc.compile.c.preprocess : C : PREPROCESSED_C : <toolset>msvc ;
1145
+
1146
+ # Using 'register-c-compiler' adds the build directory to INCLUDES.
1147
+ generators.register-c-compiler msvc.compile.rc : RC : OBJ(%_res) : <toolset>msvc ;
1148
+ generators.override msvc.compile.rc : rc.compile.resource ;
1149
+ generators.register-standard msvc.compile.asm : ASM : OBJ : <toolset>msvc ;
1150
+
1151
+ generators.register-c-compiler msvc.compile.idl : IDL : MSTYPELIB H C(%_i) C(%_proxy) C(%_dlldata) : <toolset>msvc ;
1152
+ generators.override msvc.compile.idl : midl.compile.idl ;
1153
+
1154
+ generators.register-standard msvc.compile.mc : MC : H RC : <toolset>msvc ;
1155
+ generators.override msvc.compile.mc : mc.compile ;
1156
+
1157
+ # Note: the 'H' source type will catch both '.h' and '.hpp' headers as
1158
+ # the latter have their HPP type derived from H. The type of compilation
1159
+ # is determined entirely by the destination type.
1160
+ generators.register [ new msvc-pch-generator msvc.compile.c.pch : H : C_PCH OBJ : <pch>on <toolset>msvc ] ;
1161
+ generators.register [ new msvc-pch-generator msvc.compile.c++.pch : H : CPP_PCH OBJ : <pch>on <toolset>msvc ] ;
1162
+
1163
+ generators.override msvc.compile.c.pch : pch.default-c-pch-generator ;
1164
+ generators.override msvc.compile.c++.pch : pch.default-cpp-pch-generator ;
1165
+ }
1166
+
1167
+ toolset.flags msvc.compile PCH_FILE <pch>on : <pch-file> ;
1168
+ toolset.flags msvc.compile PCH_SOURCE <pch>on : <pch-source> ;
1169
+ toolset.flags msvc.compile PCH_HEADER <pch>on : <pch-header> ;
1170
+
1171
+ #
1172
+ # Declare flags for compilation.
1173
+ #
1174
+
1175
+ toolset.flags msvc.compile CFLAGS <optimization>speed : /O2 ;
1176
+ toolset.flags msvc.compile CFLAGS <optimization>space : /O1 ;
1177
+
1178
+ toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium) : /G1 ;
1179
+ toolset.flags msvc.compile CFLAGS $(.cpu-arch-ia64)/<instruction-set>$(.cpu-type-itanium2) : /G2 ;
1180
+
1181
+ toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>object : /Z7 ;
1182
+ toolset.flags msvc.compile CFLAGS <debug-symbols>on/<debug-store>database : /Zi ;
1183
+ toolset.flags msvc.compile CFLAGS <optimization>off : /Od ;
1184
+ toolset.flags msvc.compile CFLAGS <inlining>off : /Ob0 ;
1185
+ toolset.flags msvc.compile CFLAGS <inlining>on : /Ob1 ;
1186
+ toolset.flags msvc.compile CFLAGS <inlining>full : /Ob2 ;
1187
+
1188
+ toolset.flags msvc.compile CFLAGS <warnings>on : /W3 ;
1189
+ toolset.flags msvc.compile CFLAGS <warnings>off : /W0 ;
1190
+ toolset.flags msvc.compile CFLAGS <warnings>all : /W4 ;
1191
+ toolset.flags msvc.compile CFLAGS <warnings-as-errors>on : /WX ;
1192
+
1193
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>off : /EHs ;
1194
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>off/<extern-c-nothrow>on : /EHsc ;
1195
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>off : /EHa ;
1196
+ toolset.flags msvc.compile C++FLAGS <exception-handling>on/<asynch-exceptions>on/<extern-c-nothrow>on : /EHac ;
1197
+
1198
+ # By default 8.0 enables rtti support while prior versions disabled it. We
1199
+ # simply enable or disable it explicitly so we do not have to depend on this
1200
+ # default behaviour.
1201
+ toolset.flags msvc.compile CFLAGS <rtti>on : /GR ;
1202
+ toolset.flags msvc.compile CFLAGS <rtti>off : /GR- ;
1203
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>shared : /MD ;
1204
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>shared : /MDd ;
1205
+
1206
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>off/<runtime-link>static/<threading>multi : /MT ;
1207
+ toolset.flags msvc.compile CFLAGS <runtime-debugging>on/<runtime-link>static/<threading>multi : /MTd ;
1208
+
1209
+ toolset.flags msvc.compile OPTIONS <cflags> : ;
1210
+ toolset.flags msvc.compile.c++ OPTIONS <cxxflags> : ;
1211
+
1212
+ toolset.flags msvc.compile PDB_CFLAG <debug-symbols>on/<debug-store>database : /Fd ;
1213
+
1214
+ toolset.flags msvc.compile DEFINES <define> ;
1215
+ toolset.flags msvc.compile UNDEFS <undef> ;
1216
+ toolset.flags msvc.compile INCLUDES <include> ;
1217
+
1218
+ # Declare flags for the assembler.
1219
+ toolset.flags msvc.compile.asm USER_ASMFLAGS <asmflags> ;
1220
+
1221
+ toolset.flags msvc.compile.asm ASMFLAGS <debug-symbols>on : "/Zi /Zd" ;
1222
+
1223
+ toolset.flags msvc.compile.asm ASMFLAGS <warnings>on : /W3 ;
1224
+ toolset.flags msvc.compile.asm ASMFLAGS <warnings>off : /W0 ;
1225
+ toolset.flags msvc.compile.asm ASMFLAGS <warnings>all : /W4 ;
1226
+ toolset.flags msvc.compile.asm ASMFLAGS <warnings-as-errors>on : /WX ;
1227
+
1228
+ toolset.flags msvc.compile.asm DEFINES <define> ;
1229
+
1230
+ # Declare flags for linking.
1231
+ {
1232
+ toolset.flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet
1233
+ toolset.flags msvc.link LINKFLAGS <debug-symbols>on : /DEBUG ;
1234
+ toolset.flags msvc.link DEF_FILE <def-file> ;
1235
+
1236
+ # The linker disables the default optimizations when using /DEBUG so we
1237
+ # have to enable them manually for release builds with debug symbols.
1238
+ toolset.flags msvc LINKFLAGS <debug-symbols>on/<runtime-debugging>off : /OPT:REF,ICF ;
1239
+
1240
+ toolset.flags msvc LINKFLAGS <user-interface>console : /subsystem:console ;
1241
+ toolset.flags msvc LINKFLAGS <user-interface>gui : /subsystem:windows ;
1242
+ toolset.flags msvc LINKFLAGS <user-interface>wince : /subsystem:windowsce ;
1243
+ toolset.flags msvc LINKFLAGS <user-interface>native : /subsystem:native ;
1244
+ toolset.flags msvc LINKFLAGS <user-interface>auto : /subsystem:posix ;
1245
+
1246
+ toolset.flags msvc.link OPTIONS <linkflags> ;
1247
+ toolset.flags msvc.link LINKPATH <library-path> ;
1248
+
1249
+ toolset.flags msvc.link FINDLIBS_ST <find-static-library> ;
1250
+ toolset.flags msvc.link FINDLIBS_SA <find-shared-library> ;
1251
+ toolset.flags msvc.link LIBRARY_OPTION <toolset>msvc : "" : unchecked ;
1252
+ toolset.flags msvc.link LIBRARIES_MENTIONED_BY_FILE : <library-file> ;
1253
+ }
1254
+
1255
+ toolset.flags msvc.archive AROPTIONS <archiveflags> ;
1256
+ }
1257
+
1258
+
1259
+ # Locates the requested setup script under the given folder and returns its full
1260
+ # path or nothing in case the script can not be found. In case multiple scripts
1261
+ # are found only the first one is returned.
1262
+ #
1263
+ # TODO: There used to exist a code comment for the msvc.init rule stating that
1264
+ # we do not correctly detect the location of the vcvars32.bat setup script for
1265
+ # the free VC7.1 tools in case user explicitly provides a path. This should be
1266
+ # tested or simply remove this whole comment in case this toolset version is no
1267
+ # longer important.
1268
+ #
1269
+ local rule locate-default-setup ( command : parent : setup-name )
1270
+ {
1271
+ local result = [ GLOB $(command) $(parent) : $(setup-name) ] ;
1272
+ if $(result[1])
1273
+ {
1274
+ return $(result[1]) ;
1275
+ }
1276
+ }
1277
+
1278
+
1279
+ # Validates given path, registers found configuration and prints debug
1280
+ # information about it.
1281
+ #
1282
+ local rule register-configuration ( version : path ? )
1283
+ {
1284
+ if $(path)
1285
+ {
1286
+ local command = [ GLOB $(path) : cl.exe ] ;
1287
+
1288
+ if $(command)
1289
+ {
1290
+ if $(.debug-configuration)
1291
+ {
1292
+ ECHO "notice: [msvc-cfg] msvc-$(version) detected, command: '$(command)'" ;
1293
+ }
1294
+
1295
+ $(.versions).register $(version) ;
1296
+ $(.versions).set $(version) : options : <command>$(command) ;
1297
+ }
1298
+ }
1299
+ }
1300
+
1301
+
1302
+ ################################################################################
1303
+ #
1304
+ # Startup code executed when loading this module.
1305
+ #
1306
+ ################################################################################
1307
+
1308
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
1309
+ {
1310
+ .debug-configuration = true ;
1311
+ }
1312
+
1313
+ # Miscellaneous constants.
1314
+ .RM = [ common.rm-command ] ;
1315
+ .nl = "
1316
+ " ;
1317
+ .ProgramFiles = [ path.make [ common.get-program-files-dir ] ] ;
1318
+ .escaped-double-quote = "\"" ;
1319
+ .TOUCH_FILE = [ common.file-touch-command ] ;
1320
+
1321
+ # List of all registered configurations.
1322
+ .versions = [ new configurations ] ;
1323
+
1324
+ # Supported CPU architectures.
1325
+ .cpu-arch-i386 =
1326
+ <architecture>/<address-model>
1327
+ <architecture>/<address-model>32
1328
+ <architecture>x86/<address-model>
1329
+ <architecture>x86/<address-model>32 ;
1330
+
1331
+ .cpu-arch-amd64 =
1332
+ <architecture>/<address-model>64
1333
+ <architecture>x86/<address-model>64 ;
1334
+
1335
+ .cpu-arch-ia64 =
1336
+ <architecture>ia64/<address-model>
1337
+ <architecture>ia64/<address-model>64 ;
1338
+
1339
+
1340
+ # Supported CPU types (only Itanium optimization options are supported from
1341
+ # VC++ 2005 on). See
1342
+ # http://msdn2.microsoft.com/en-us/library/h66s5s0e(vs.90).aspx for more
1343
+ # detailed information.
1344
+ .cpu-type-g5 = i586 pentium pentium-mmx ;
1345
+ .cpu-type-g6 = i686 pentiumpro pentium2 pentium3 pentium3m pentium-m k6
1346
+ k6-2 k6-3 winchip-c6 winchip2 c3 c3-2 ;
1347
+ .cpu-type-em64t = prescott nocona conroe conroe-xe conroe-l allendale mermon
1348
+ mermon-xe kentsfield kentsfield-xe penryn wolfdale
1349
+ yorksfield nehalem ;
1350
+ .cpu-type-amd64 = k8 opteron athlon64 athlon-fx ;
1351
+ .cpu-type-g7 = pentium4 pentium4m athlon athlon-tbird athlon-4 athlon-xp
1352
+ athlon-mp $(.cpu-type-em64t) $(.cpu-type-amd64) ;
1353
+ .cpu-type-itanium = itanium itanium1 merced ;
1354
+ .cpu-type-itanium2 = itanium2 mckinley ;
1355
+
1356
+
1357
+ # Known toolset versions, in order of preference.
1358
+ .known-versions = 11.0 10.0 10.0express 9.0 9.0express 8.0 8.0express 7.1 7.1toolkit 7.0 6.0 ;
1359
+
1360
+ # Version aliases.
1361
+ .version-alias-6 = 6.0 ;
1362
+ .version-alias-6.5 = 6.0 ;
1363
+ .version-alias-7 = 7.0 ;
1364
+ .version-alias-8 = 8.0 ;
1365
+ .version-alias-9 = 9.0 ;
1366
+ .version-alias-10 = 10.0 ;
1367
+ .version-alias-11 = 11.0 ;
1368
+
1369
+ # Names of registry keys containing the Visual C++ installation path (relative
1370
+ # to "HKEY_LOCAL_MACHINE\SOFTWARE\\Microsoft").
1371
+ .version-6.0-reg = "VisualStudio\\6.0\\Setup\\Microsoft Visual C++" ;
1372
+ .version-7.0-reg = "VisualStudio\\7.0\\Setup\\VC" ;
1373
+ .version-7.1-reg = "VisualStudio\\7.1\\Setup\\VC" ;
1374
+ .version-8.0-reg = "VisualStudio\\8.0\\Setup\\VC" ;
1375
+ .version-8.0express-reg = "VCExpress\\8.0\\Setup\\VC" ;
1376
+ .version-9.0-reg = "VisualStudio\\9.0\\Setup\\VC" ;
1377
+ .version-9.0express-reg = "VCExpress\\9.0\\Setup\\VC" ;
1378
+ .version-10.0-reg = "VisualStudio\\10.0\\Setup\\VC" ;
1379
+ .version-10.0express-reg = "VCExpress\\10.0\\Setup\\VC" ;
1380
+ .version-11.0-reg = "VisualStudio\\11.0\\Setup\\VC" ;
1381
+
1382
+ # Visual C++ Toolkit 2003 does not store its installation path in the registry.
1383
+ # The environment variable 'VCToolkitInstallDir' and the default installation
1384
+ # path will be checked instead.
1385
+ .version-7.1toolkit-path = "Microsoft Visual C++ Toolkit 2003" "bin" ;
1386
+ .version-7.1toolkit-env = VCToolkitInstallDir ;
1387
+
1388
+ # Path to the folder containing "cl.exe" relative to the value of the
1389
+ # corresponding environment variable.
1390
+ .version-7.1toolkit-envpath = "bin" ;
1391
+
1392
+
1393
+ # Auto-detect all the available msvc installations on the system.
1394
+ auto-detect-toolset-versions ;
1395
+
1396
+
1397
+ # And finally trigger the actual Boost Build toolset registration.
1398
+ register-toolset ;
mosesdecoder/jam-files/boost-build/tools/notfile.jam ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2005 Vladimir Prus.
2
+ #
3
+ # Use, modification and distribution is subject to the Boost Software
4
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5
+ # http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ import "class" : new ;
8
+ import generators ;
9
+ import project ;
10
+ import targets ;
11
+ import toolset ;
12
+ import type ;
13
+
14
+
15
+ type.register NOTFILE_MAIN ;
16
+
17
+
18
+ class notfile-generator : generator
19
+ {
20
+ rule __init__ ( * : * )
21
+ {
22
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
23
+ }
24
+
25
+ rule run ( project name ? : property-set : sources * : multiple ? )
26
+ {
27
+ local action ;
28
+ local action-name = [ $(property-set).get <action> ] ;
29
+
30
+ local m = [ MATCH ^@(.*) : $(action-name) ] ;
31
+
32
+ if $(m)
33
+ {
34
+ action = [ new action $(sources) : $(m[1])
35
+ : $(property-set) ] ;
36
+ }
37
+ else
38
+ {
39
+ action = [ new action $(sources) : notfile.run
40
+ : $(property-set) ] ;
41
+ }
42
+ return [ virtual-target.register
43
+ [ new notfile-target $(name) : $(project) : $(action) ] ] ;
44
+ }
45
+ }
46
+
47
+
48
+ generators.register [ new notfile-generator notfile.main : : NOTFILE_MAIN ] ;
49
+
50
+
51
+ toolset.flags notfile.run ACTION : <action> ;
52
+
53
+
54
+ actions run
55
+ {
56
+ $(ACTION)
57
+ }
58
+
59
+
60
+ rule notfile ( target-name : action + : sources * : requirements * : default-build * )
61
+ {
62
+ local project = [ project.current ] ;
63
+
64
+ requirements += <action>$(action) ;
65
+
66
+ targets.main-target-alternative
67
+ [ new typed-target $(target-name) : $(project) : NOTFILE_MAIN
68
+ : [ targets.main-target-sources $(sources) : $(target-name) ]
69
+ : [ targets.main-target-requirements $(requirements) : $(project) ]
70
+ : [ targets.main-target-default-build $(default-build) : $(project) ]
71
+ ] ;
72
+ }
73
+
74
+ IMPORT $(__name__) : notfile : : notfile ;
mosesdecoder/jam-files/boost-build/tools/pathscale.jam ADDED
@@ -0,0 +1,168 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2006 Noel Belcourt
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or copy at
4
+ # http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ import property ;
7
+ import generators ;
8
+ import toolset : flags ;
9
+ import feature ;
10
+ import type ;
11
+ import common ;
12
+ import fortran ;
13
+
14
+ feature.extend toolset : pathscale ;
15
+ toolset.inherit pathscale : unix ;
16
+ generators.override pathscale.prebuilt : builtin.prebuilt ;
17
+ generators.override pathscale.searched-lib-generator : searched-lib-generator ;
18
+
19
+ # Documentation and toolchain description located
20
+ # http://www.pathscale.com/docs.html
21
+
22
+ rule init ( version ? : command * : options * )
23
+ {
24
+ command = [ common.get-invocation-command pathscale : pathCC : $(command)
25
+ : /opt/ekopath/bin ] ;
26
+
27
+ # Determine the version
28
+ local command-string = $(command:J=" ") ;
29
+ if $(command)
30
+ {
31
+ version ?= [ MATCH "^([0-9.]+)"
32
+ : [ SHELL "$(command-string) -dumpversion" ] ] ;
33
+ }
34
+
35
+ local condition = [ common.check-init-parameters pathscale
36
+ : version $(version) ] ;
37
+
38
+ common.handle-options pathscale : $(condition) : $(command) : $(options) ;
39
+
40
+ toolset.flags pathscale.compile.fortran90 OPTIONS $(condition) :
41
+ [ feature.get-values <fflags> : $(options) ] : unchecked ;
42
+
43
+ command_c = $(command_c[1--2]) $(command[-1]:B=pathcc) ;
44
+
45
+ toolset.flags pathscale CONFIG_C_COMMAND $(condition) : $(command_c) ;
46
+
47
+ # fortran support
48
+ local f-command = [ common.get-invocation-command pathscale : pathf90 : $(command) ] ;
49
+ local command_f = $(command_f[1--2]) $(f-command[-1]:B=pathf90) ;
50
+ local command_f90 = $(command_f[1--2]) $(f-command[-1]:B=pathf90) ;
51
+
52
+ toolset.flags pathscale CONFIG_F_COMMAND $(condition) : $(command_f) ;
53
+ toolset.flags pathscale CONFIG_F90_COMMAND $(condition) : $(command_f90) ;
54
+
55
+ # always link lib rt to resolve clock_gettime()
56
+ flags pathscale.link FINDLIBS-SA : rt : unchecked ;
57
+ }
58
+
59
+ # Declare generators
60
+ generators.register-c-compiler pathscale.compile.c : C : OBJ : <toolset>pathscale ;
61
+ generators.register-c-compiler pathscale.compile.c++ : CPP : OBJ : <toolset>pathscale ;
62
+ generators.register-fortran-compiler pathscale.compile.fortran : FORTRAN : OBJ : <toolset>pathscale ;
63
+ generators.register-fortran90-compiler pathscale.compile.fortran90 : FORTRAN90 : OBJ : <toolset>pathscale ;
64
+
65
+ # Declare flags and actions for compilation
66
+ flags pathscale.compile OPTIONS <optimization>off : -O0 ;
67
+ flags pathscale.compile OPTIONS <optimization>speed : -O3 ;
68
+ flags pathscale.compile OPTIONS <optimization>space : -Os ;
69
+
70
+ flags pathscale.compile OPTIONS <inlining>off : -noinline ;
71
+ flags pathscale.compile OPTIONS <inlining>on : -inline ;
72
+ flags pathscale.compile OPTIONS <inlining>full : -inline ;
73
+
74
+ flags pathscale.compile OPTIONS <warnings>off : -woffall ;
75
+ flags pathscale.compile OPTIONS <warnings>on : -Wall ;
76
+ flags pathscale.compile OPTIONS <warnings>all : -Wall -pedantic ;
77
+ flags pathscale.compile OPTIONS <warnings-as-errors>on : -Werror ;
78
+
79
+ flags pathscale.compile OPTIONS <debug-symbols>on : -ggdb ;
80
+ flags pathscale.compile OPTIONS <profiling>on : -pg ;
81
+ flags pathscale.compile OPTIONS <link>shared : -fPIC ;
82
+ flags pathscale.compile OPTIONS <address-model>32 : -m32 ;
83
+ flags pathscale.compile OPTIONS <address-model>64 : -m64 ;
84
+
85
+ flags pathscale.compile USER_OPTIONS <cflags> ;
86
+ flags pathscale.compile.c++ USER_OPTIONS <cxxflags> ;
87
+ flags pathscale.compile DEFINES <define> ;
88
+ flags pathscale.compile INCLUDES <include> ;
89
+
90
+ flags pathscale.compile.fortran USER_OPTIONS <fflags> ;
91
+ flags pathscale.compile.fortran90 USER_OPTIONS <fflags> ;
92
+
93
+ actions compile.c
94
+ {
95
+ "$(CONFIG_C_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
96
+ }
97
+
98
+ actions compile.c++
99
+ {
100
+ "$(CONFIG_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
101
+ }
102
+
103
+ actions compile.fortran
104
+ {
105
+ "$(CONFIG_F_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
106
+ }
107
+
108
+ rule compile.fortran90 ( targets * : sources * : properties * )
109
+ {
110
+ # the space rule inserts spaces between targets and it's necessary
111
+ SPACE on $(targets) = " " ;
112
+ # Serialize execution of the compile.fortran90 action
113
+ # F90 source must be compiled in a particular order so we
114
+ # serialize the build as a parallel F90 compile might fail
115
+ JAM_SEMAPHORE on $(targets) = <s>pathscale-f90-semaphore ;
116
+ }
117
+
118
+ actions compile.fortran90
119
+ {
120
+ "$(CONFIG_F90_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -module $(<[1]:D) -c -o "$(<)" "$(>)"
121
+ }
122
+
123
+ # Declare flags and actions for linking
124
+ flags pathscale.link OPTIONS <debug-symbols>on : -ggdb -rdynamic ;
125
+ # Strip the binary when no debugging is needed
126
+ flags pathscale.link OPTIONS <debug-symbols>off : -g0 ;
127
+ flags pathscale.link OPTIONS <profiling>on : -pg ;
128
+ flags pathscale.link USER_OPTIONS <linkflags> ;
129
+ flags pathscale.link LINKPATH <library-path> ;
130
+ flags pathscale.link FINDLIBS-ST <find-static-library> ;
131
+ flags pathscale.link FINDLIBS-SA <find-shared-library> ;
132
+ flags pathscale.link FINDLIBS-SA <threading>multi : pthread ;
133
+ flags pathscale.link LIBRARIES <library-file> ;
134
+ flags pathscale.link LINK-RUNTIME <runtime-link>static : static ;
135
+ flags pathscale.link LINK-RUNTIME <runtime-link>shared : dynamic ;
136
+ flags pathscale.link RPATH <dll-path> ;
137
+ # On gcc, there are separate options for dll path at runtime and
138
+ # link time. On Solaris, there's only one: -R, so we have to use
139
+ # it, even though it's bad idea.
140
+ flags pathscale.link RPATH <xdll-path> ;
141
+
142
+ rule link ( targets * : sources * : properties * )
143
+ {
144
+ SPACE on $(targets) = " " ;
145
+ }
146
+
147
+ actions link bind LIBRARIES
148
+ {
149
+ "$(CONFIG_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST)
150
+ }
151
+
152
+ # Slight mods for dlls
153
+ rule link.dll ( targets * : sources * : properties * )
154
+ {
155
+ SPACE on $(targets) = " " ;
156
+ }
157
+
158
+ actions link.dll bind LIBRARIES
159
+ {
160
+ "$(CONFIG_COMMAND)" $(OPTIONS) $(USER_OPTIONS) -L"$(LINKPATH)" -Wl,$(RPATH_OPTION:E=-R)$(SPACE)-Wl,"$(RPATH)" -o "$(<)" -Wl,-soname$(SPACE)-Wl,$(<[1]:D=) -shared "$(>)" "$(LIBRARIES)" -l$(FINDLIBS-SA) -l$(FINDLIBS-ST)
161
+ }
162
+
163
+ # Declare action for creating static libraries
164
+ # "$(CONFIG_COMMAND)" -ar -o "$(<)" "$(>)"
165
+ actions piecemeal archive
166
+ {
167
+ ar $(ARFLAGS) ru "$(<)" "$(>)"
168
+ }
mosesdecoder/jam-files/boost-build/tools/pch.jam ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2005 Reece H. Dunn.
2
+ # Copyright 2006 Ilya Sokolov
3
+ #
4
+ # Use, modification and distribution is subject to the Boost Software
5
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
6
+ # http://www.boost.org/LICENSE_1_0.txt)
7
+
8
+ ##### Using Precompiled Headers (Quick Guide) #####
9
+ #
10
+ # Make precompiled mypch.hpp:
11
+ #
12
+ # import pch ;
13
+ #
14
+ # cpp-pch mypch
15
+ # : # sources
16
+ # mypch.hpp
17
+ # : # requiremnts
18
+ # <toolset>msvc:<source>mypch.cpp
19
+ # ;
20
+ #
21
+ # Add cpp-pch to sources:
22
+ #
23
+ # exe hello
24
+ # : main.cpp hello.cpp mypch
25
+ # ;
26
+
27
+ import "class" : new ;
28
+ import type ;
29
+ import feature ;
30
+ import generators ;
31
+
32
+ type.register PCH : pch ;
33
+
34
+ type.register C_PCH : : PCH ;
35
+ type.register CPP_PCH : : PCH ;
36
+
37
+ # Control precompiled header (PCH) generation.
38
+ feature.feature pch :
39
+ on
40
+ off
41
+ : propagated ;
42
+
43
+
44
+ feature.feature pch-header : : free dependency ;
45
+ feature.feature pch-file : : free dependency ;
46
+
47
+ # Base PCH generator. The 'run' method has the logic to prevent this generator
48
+ # from being run unless it's being used for a top-level PCH target.
49
+ class pch-generator : generator
50
+ {
51
+ import property-set ;
52
+
53
+ rule action-class ( )
54
+ {
55
+ return compile-action ;
56
+ }
57
+
58
+ rule run ( project name ? : property-set : sources + )
59
+ {
60
+ if ! $(name)
61
+ {
62
+ # Unless this generator is invoked as the top-most generator for a
63
+ # main target, fail. This allows using 'H' type as input type for
64
+ # this generator, while preventing Boost.Build to try this generator
65
+ # when not explicitly asked for.
66
+ #
67
+ # One bad example is msvc, where pch generator produces both PCH
68
+ # target and OBJ target, so if there's any header generated (like by
69
+ # bison, or by msidl), we'd try to use pch generator to get OBJ from
70
+ # that H, which is completely wrong. By restricting this generator
71
+ # only to pch main target, such problem is solved.
72
+ }
73
+ else
74
+ {
75
+ local r = [ run-pch $(project) $(name)
76
+ : [ $(property-set).add-raw <define>BOOST_BUILD_PCH_ENABLED ]
77
+ : $(sources) ] ;
78
+ return [ generators.add-usage-requirements $(r)
79
+ : <define>BOOST_BUILD_PCH_ENABLED ] ;
80
+ }
81
+ }
82
+
83
+ # This rule must be overridden by the derived classes.
84
+ rule run-pch ( project name ? : property-set : sources + )
85
+ {
86
+ }
87
+ }
88
+
89
+
90
+ # NOTE: requirements are empty, default pch generator can be applied when
91
+ # pch=off.
92
+ generators.register
93
+ [ new dummy-generator pch.default-c-pch-generator : : C_PCH ] ;
94
+ generators.register
95
+ [ new dummy-generator pch.default-cpp-pch-generator : : CPP_PCH ] ;
mosesdecoder/jam-files/boost-build/tools/qt.jam ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2006 Vladimir Prus.
2
+ #
3
+ # Use, modification and distribution is subject to the Boost Software
4
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5
+ # http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ # Forwarning toolset file to Qt GUI library. Forwards to the toolset file
8
+ # for the current version of Qt.
9
+
10
+ import qt4 ;
11
+
12
+ rule init ( prefix : full_bin ? : full_inc ? : full_lib ? : version ? : condition * )
13
+ {
14
+ qt4.init $(prefix) : $(full_bin) : $(full_inc) : $(full_lib) : $(version) : $(condition) ;
15
+ }
16
+
17
+
mosesdecoder/jam-files/boost-build/tools/qt3.jam ADDED
@@ -0,0 +1,209 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2006 Vladimir Prus
2
+ # Distributed under the Boost Software License, Version 1.0.
3
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # Support for the Qt GUI library version 3
6
+ # (http://www.trolltech.com/products/qt3/index.html).
7
+ # For new developments, it is recommended to use Qt4 via the qt4 Boost.Build
8
+ # module.
9
+
10
+ import modules ;
11
+ import feature ;
12
+ import errors ;
13
+ import type ;
14
+ import "class" : new ;
15
+ import generators ;
16
+ import project ;
17
+ import toolset : flags ;
18
+
19
+ # Convert this module into a project, so that we can declare targets here.
20
+ project.initialize $(__name__) ;
21
+ project qt3 ;
22
+
23
+
24
+ # Initialized the QT support module. The 'prefix' parameter tells where QT is
25
+ # installed. When not given, environmental variable QTDIR should be set.
26
+ #
27
+ rule init ( prefix ? )
28
+ {
29
+ if ! $(prefix)
30
+ {
31
+ prefix = [ modules.peek : QTDIR ] ;
32
+ if ! $(prefix)
33
+ {
34
+ errors.error
35
+ "QT installation prefix not given and QTDIR variable is empty" ;
36
+ }
37
+ }
38
+
39
+ if $(.initialized)
40
+ {
41
+ if $(prefix) != $(.prefix)
42
+ {
43
+ errors.error
44
+ "Attempt the reinitialize QT with different installation prefix" ;
45
+ }
46
+ }
47
+ else
48
+ {
49
+ .initialized = true ;
50
+ .prefix = $(prefix) ;
51
+
52
+ generators.register-standard qt3.moc : H : CPP(moc_%) : <allow>qt3 ;
53
+ # Note: the OBJ target type here is fake, take a look at
54
+ # qt4.jam/uic-h-generator for explanations that apply in this case as
55
+ # well.
56
+ generators.register [ new moc-h-generator-qt3
57
+ qt3.moc.cpp : MOCCABLE_CPP : OBJ : <allow>qt3 ] ;
58
+
59
+ # The UI type is defined in types/qt.jam, and UIC_H is only used in
60
+ # qt.jam, but not in qt4.jam, so define it here.
61
+ type.register UIC_H : : H ;
62
+
63
+ generators.register-standard qt3.uic-h : UI : UIC_H : <allow>qt3 ;
64
+
65
+ # The following generator is used to convert UI files to CPP. It creates
66
+ # UIC_H from UI, and constructs CPP from UI/UIC_H. In addition, it also
67
+ # returns UIC_H target, so that it can be mocced.
68
+ class qt::uic-cpp-generator : generator
69
+ {
70
+ rule __init__ ( )
71
+ {
72
+ generator.__init__ qt3.uic-cpp : UI UIC_H : CPP : <allow>qt3 ;
73
+ }
74
+
75
+ rule run ( project name ? : properties * : sources + )
76
+ {
77
+ # Consider this:
78
+ # obj test : test_a.cpp : <optimization>off ;
79
+ #
80
+ # This generator will somehow be called in this case, and,
81
+ # will fail -- which is okay. However, if there are <library>
82
+ # properties they will be converted to sources, so the size of
83
+ # 'sources' will be more than 1. In this case, the base generator
84
+ # will just crash -- and that's not good. Just use a quick test
85
+ # here.
86
+
87
+ local result ;
88
+ if ! $(sources[2])
89
+ {
90
+ # Construct CPP as usual
91
+ result = [ generator.run $(project) $(name)
92
+ : $(properties) : $(sources) ] ;
93
+
94
+ # If OK, process UIC_H with moc. It's pretty clear that
95
+ # the object generated with UIC will have Q_OBJECT macro.
96
+ if $(result)
97
+ {
98
+ local action = [ $(result[1]).action ] ;
99
+ local sources = [ $(action).sources ] ;
100
+ local mocced = [ generators.construct $(project) $(name)
101
+ : CPP : $(properties) : $(sources[2]) ] ;
102
+ result += $(mocced[2-]) ;
103
+ }
104
+ }
105
+
106
+ return $(result) ;
107
+ }
108
+ }
109
+
110
+ generators.register [ new qt::uic-cpp-generator ] ;
111
+
112
+ # Finally, declare prebuilt target for QT library.
113
+ local usage-requirements =
114
+ <include>$(.prefix)/include
115
+ <dll-path>$(.prefix)/lib
116
+ <library-path>$(.prefix)/lib
117
+ <allow>qt3
118
+ ;
119
+ lib qt : : <name>qt-mt <threading>multi : : $(usage-requirements) ;
120
+ lib qt : : <name>qt <threading>single : : $(usage-requirements) ;
121
+ }
122
+ }
123
+
124
+ class moc-h-generator-qt3 : generator
125
+ {
126
+ rule __init__ ( * : * )
127
+ {
128
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
129
+ }
130
+
131
+ rule run ( project name ? : property-set : sources * )
132
+ {
133
+ if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
134
+ {
135
+ name = [ $(sources[1]).name ] ;
136
+ name = $(name:B) ;
137
+
138
+ local a = [ new action $(sources[1]) : qt3.moc.cpp :
139
+ $(property-set) ] ;
140
+
141
+ local target = [
142
+ new file-target $(name) : MOC : $(project) : $(a) ] ;
143
+
144
+ local r = [ virtual-target.register $(target) ] ;
145
+
146
+ # Since this generator will return a H target, the linking generator
147
+ # won't use it at all, and won't set any dependency on it. However,
148
+ # we need the target to be seen by bjam, so that the dependency from
149
+ # sources to this generated header is detected -- if Jam does not
150
+ # know about this target, it won't do anything.
151
+ DEPENDS all : [ $(r).actualize ] ;
152
+
153
+ return $(r) ;
154
+ }
155
+ }
156
+ }
157
+
158
+
159
+ # Query the installation directory. This is needed in at least two scenarios.
160
+ # First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
161
+ # plugins to the Qt-Tree.
162
+ #
163
+ rule directory
164
+ {
165
+ return $(.prefix) ;
166
+ }
167
+
168
+ # -f forces moc to include the processed source file. Without it, it would think
169
+ # that .qpp is not a header and would not include it from the generated file.
170
+ #
171
+ actions moc
172
+ {
173
+ $(.prefix)/bin/moc -f $(>) -o $(<)
174
+ }
175
+
176
+ # When moccing .cpp files, we don't need -f, otherwise generated code will
177
+ # include .cpp and we'll get duplicated symbols.
178
+ #
179
+ actions moc.cpp
180
+ {
181
+ $(.prefix)/bin/moc $(>) -o $(<)
182
+ }
183
+
184
+
185
+ space = " " ;
186
+
187
+ # Sometimes it's required to make 'plugins' available during uic invocation. To
188
+ # help with this we add paths to all dependency libraries to uic commane line.
189
+ # The intention is that it's possible to write
190
+ #
191
+ # exe a : ... a.ui ... : <uses>some_plugin ;
192
+ #
193
+ # and have everything work. We'd add quite a bunch of unrelated paths but it
194
+ # won't hurt.
195
+ #
196
+ flags qt3.uic-h LIBRARY_PATH <xdll-path> ;
197
+ actions uic-h
198
+ {
199
+ $(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
200
+ }
201
+
202
+
203
+ flags qt3.uic-cpp LIBRARY_PATH <xdll-path> ;
204
+ # The second target is uic-generated header name. It's placed in build dir, but
205
+ # we want to include it using only basename.
206
+ actions uic-cpp
207
+ {
208
+ $(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
209
+ }
mosesdecoder/jam-files/boost-build/tools/qt4.jam ADDED
@@ -0,0 +1,724 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2002-2006 Vladimir Prus
2
+ # Copyright 2005 Alo Sarv
3
+ # Copyright 2005-2009 Juergen Hunold
4
+ #
5
+ # Distributed under the Boost Software License, Version 1.0. (See
6
+ # accompanying file LICENSE_1_0.txt or copy at
7
+ # http://www.boost.org/LICENSE_1_0.txt)
8
+
9
+ # Qt4 library support module
10
+ #
11
+ # The module attempts to auto-detect QT installation location from QTDIR
12
+ # environment variable; failing that, installation location can be passed as
13
+ # argument:
14
+ #
15
+ # toolset.using qt4 : /usr/local/Trolltech/Qt-4.0.0 ;
16
+ #
17
+ # The module supports code generation from .ui and .qrc files, as well as
18
+ # running the moc preprocessor on headers. Note that you must list all your
19
+ # moc-able headers in sources.
20
+ #
21
+ # Example:
22
+ #
23
+ # exe myapp : myapp.cpp myapp.h myapp.ui myapp.qrc
24
+ # /qt4//QtGui /qt4//QtNetwork ;
25
+ #
26
+ # It's also possible to run moc on cpp sources:
27
+ #
28
+ # import cast ;
29
+ #
30
+ # exe myapp : myapp.cpp [ cast _ moccable-cpp : myapp.cpp ] /qt4//QtGui ;
31
+ #
32
+ # When moccing source file myapp.cpp you need to include "myapp.moc" from
33
+ # myapp.cpp. When moccing .h files, the output of moc will be automatically
34
+ # compiled and linked in, you don't need any includes.
35
+ #
36
+ # This is consistent with Qt guidelines:
37
+ # http://doc.trolltech.com/4.0/moc.html
38
+
39
+ import modules ;
40
+ import feature ;
41
+ import errors ;
42
+ import type ;
43
+ import "class" : new ;
44
+ import generators ;
45
+ import project ;
46
+ import toolset : flags ;
47
+ import os ;
48
+ import virtual-target ;
49
+ import scanner ;
50
+
51
+ # Qt3Support control feature
52
+ #
53
+ # Qt4 configure defaults to build Qt4 libraries with Qt3Support.
54
+ # The autodetection is missing, so we default to disable Qt3Support.
55
+ # This prevents the user from inadvertedly using a deprecated API.
56
+ #
57
+ # The Qt3Support library can be activated by adding
58
+ # "<qt3support>on" to requirements
59
+ #
60
+ # Use "<qt3support>on:<define>QT3_SUPPORT_WARNINGS"
61
+ # to get warnings about deprecated Qt3 support funtions and classes.
62
+ # Files ported by the "qt3to4" conversion tool contain _tons_ of
63
+ # warnings, so this define is not set as default.
64
+ #
65
+ # Todo: Detect Qt3Support from Qt's configure data.
66
+ # Or add more auto-configuration (like python).
67
+ feature.feature qt3support : off on : propagated link-incompatible ;
68
+
69
+ # The Qt version used for requirements
70
+ # Valid are <qt>4.4 or <qt>4.5.0
71
+ # Auto-detection via qmake sets '<qt>major.minor.patch'
72
+ feature.feature qt : : propagated ;
73
+
74
+ project.initialize $(__name__) ;
75
+ project qt ;
76
+
77
+ # Save the project so that we tolerate 'import + using' combo.
78
+ .project = [ project.current ] ;
79
+
80
+ # Helper utils for easy debug output
81
+ if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
82
+ {
83
+ .debug-configuration = TRUE ;
84
+ }
85
+
86
+ local rule debug-message ( message * )
87
+ {
88
+ if $(.debug-configuration) = TRUE
89
+ {
90
+ ECHO notice: [qt4-cfg] $(message) ;
91
+ }
92
+ }
93
+
94
+ # Capture qmake output line by line
95
+ local rule read-output ( content )
96
+ {
97
+ local lines ;
98
+ local nl = "
99
+ " ;
100
+ local << = "([^$(nl)]*)[$(nl)](.*)" ;
101
+ local line+ = [ MATCH "$(<<)" : "$(content)" ] ;
102
+ while $(line+)
103
+ {
104
+ lines += $(line+[1]) ;
105
+ line+ = [ MATCH "$(<<)" : "$(line+[2])" ] ;
106
+ }
107
+ return $(lines) ;
108
+ }
109
+
110
+ # Capture Qt version from qmake
111
+ local rule check-version ( bin_prefix )
112
+ {
113
+ full-cmd = $(bin_prefix)"/qmake -v" ;
114
+ debug-message Running '$(full-cmd)' ;
115
+ local output = [ SHELL $(full-cmd) ] ;
116
+ for line in [ read-output $(output) ]
117
+ {
118
+ # Parse the output to get all the results.
119
+ if [ MATCH "QMake" : $(line) ]
120
+ {
121
+ # Skip first line of output
122
+ }
123
+ else
124
+ {
125
+ temp = [ MATCH "([0-9]*)\\.([0-9]*)\\.([0-9]*)" : $(line) ] ;
126
+ }
127
+ }
128
+ return $(temp) ;
129
+ }
130
+
131
+ # Validate the version string and extract the major/minor part we care about.
132
+ #
133
+ local rule split-version ( version )
134
+ {
135
+ local major-minor = [ MATCH ^([0-9]+)\.([0-9]+)(.*)$ : $(version) : 1 2 3 ] ;
136
+ if ! $(major-minor[2]) || $(major-minor[3])
137
+ {
138
+ ECHO "Warning: 'using qt' expects a two part (major, minor) version number; got" $(version) instead ;
139
+
140
+ # Add a zero to account for the missing digit if necessary.
141
+ major-minor += 0 ;
142
+ }
143
+
144
+ return $(major-minor[1]) $(major-minor[2]) ;
145
+ }
146
+
147
+ # Initialize the QT support module.
148
+ # Parameters:
149
+ # - 'prefix' parameter tells where Qt is installed.
150
+ # - 'full_bin' optional full path to Qt binaries (qmake,moc,uic,rcc)
151
+ # - 'full_inc' optional full path to Qt top-level include directory
152
+ # - 'full_lib' optional full path to Qt library directory
153
+ # - 'version' optional version of Qt, else autodetected via 'qmake -v'
154
+ # - 'condition' optional requirements
155
+ rule init ( prefix : full_bin ? : full_inc ? : full_lib ? : version ? : condition * )
156
+ {
157
+ project.push-current $(.project) ;
158
+
159
+ debug-message "==== Configuring Qt ... ====" ;
160
+ for local v in version cmd-or-prefix includes libraries condition
161
+ {
162
+ if $($(v))
163
+ {
164
+ debug-message " user-specified "$(v): '$($(v))' ;
165
+ }
166
+ }
167
+
168
+ # Needed as default value
169
+ .prefix = $(prefix) ;
170
+
171
+ # pre-build paths to detect reinitializations changes
172
+ local inc_prefix lib_prefix bin_prefix ;
173
+ if $(full_inc)
174
+ {
175
+ inc_prefix = $(full_inc) ;
176
+ }
177
+ else
178
+ {
179
+ inc_prefix = $(prefix)/include ;
180
+ }
181
+ if $(full_lib)
182
+ {
183
+ lib_prefix = $(full_lib) ;
184
+ }
185
+ else
186
+ {
187
+ lib_prefix = $(prefix)/lib ;
188
+ }
189
+ if $(full_bin)
190
+ {
191
+ bin_prefix = $(full_bin) ;
192
+ }
193
+ else
194
+ {
195
+ bin_prefix = $(prefix)/bin ;
196
+ }
197
+
198
+ # Globally needed variables
199
+ .incprefix = $(inc_prefix) ;
200
+ .libprefix = $(lib_prefix) ;
201
+ .binprefix = $(bin_prefix) ;
202
+
203
+ if ! $(.initialized)
204
+ {
205
+ # Make sure this is initialised only once
206
+ .initialized = true ;
207
+
208
+ # Generates cpp files from header files using "moc" tool
209
+ generators.register-standard qt4.moc : H : CPP(moc_%) : <allow>qt4 ;
210
+
211
+ # The OBJ result type is a fake, 'H' will be really produced. See
212
+ # comments on the generator class, defined below the 'init' function.
213
+ generators.register [ new uic-generator qt4.uic : UI : OBJ :
214
+ <allow>qt4 ] ;
215
+
216
+ # The OBJ result type is a fake here too.
217
+ generators.register [ new moc-h-generator
218
+ qt4.moc.inc : MOCCABLE_CPP : OBJ : <allow>qt4 ] ;
219
+
220
+ generators.register [ new moc-inc-generator
221
+ qt4.moc.inc : MOCCABLE_H : OBJ : <allow>qt4 ] ;
222
+
223
+ # Generates .cpp files from .qrc files.
224
+ generators.register-standard qt4.rcc : QRC : CPP(qrc_%) ;
225
+
226
+ # dependency scanner for wrapped files.
227
+ type.set-scanner QRC : qrc-scanner ;
228
+
229
+ # Save value of first occuring prefix
230
+ .PREFIX = $(prefix) ;
231
+ }
232
+
233
+ if $(version)
234
+ {
235
+ major-minor = [ split-version $(version) ] ;
236
+ version = $(major-minor:J=.) ;
237
+ }
238
+ else
239
+ {
240
+ version = [ check-version $(bin_prefix) ] ;
241
+ if $(version)
242
+ {
243
+ version = $(version:J=.) ;
244
+ }
245
+ debug-message Detected version '$(version)' ;
246
+ }
247
+
248
+ local target-requirements = $(condition) ;
249
+
250
+ # Add the version, if any, to the target requirements.
251
+ if $(version)
252
+ {
253
+ if ! $(version) in [ feature.values qt ]
254
+ {
255
+ feature.extend qt : $(version) ;
256
+ }
257
+ target-requirements += <qt>$(version:E=default) ;
258
+ }
259
+
260
+ local target-os = [ feature.get-values target-os : $(condition) ] ;
261
+ if ! $(target-os)
262
+ {
263
+ target-os ?= [ feature.defaults target-os ] ;
264
+ target-os = $(target-os:G=) ;
265
+ target-requirements += <target-os>$(target-os) ;
266
+ }
267
+
268
+ # Build exact requirements for the tools
269
+ local tools-requirements = $(target-requirements:J=/) ;
270
+
271
+ debug-message "Details of this Qt configuration:" ;
272
+ debug-message " prefix: " '$(prefix:E=<empty>)' ;
273
+ debug-message " binary path: " '$(bin_prefix:E=<empty>)' ;
274
+ debug-message " include path:" '$(inc_prefix:E=<empty>)' ;
275
+ debug-message " library path:" '$(lib_prefix:E=<empty>)' ;
276
+ debug-message " target requirements:" '$(target-requirements)' ;
277
+ debug-message " tool requirements: " '$(tools-requirements)' ;
278
+
279
+ # setup the paths for the tools
280
+ toolset.flags qt4.moc .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
281
+ toolset.flags qt4.rcc .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
282
+ toolset.flags qt4.uic .BINPREFIX $(tools-requirements) : $(bin_prefix) ;
283
+
284
+ # TODO: 2009-02-12: Better support for directories
285
+ # Most likely needed are separate getters for: include,libraries,binaries and sources.
286
+ toolset.flags qt4.directory .PREFIX $(tools-requirements) : $(prefix) ;
287
+
288
+ # Test for a buildable Qt.
289
+ if [ glob $(.prefix)/Jamroot ]
290
+ {
291
+ .bjam-qt = true
292
+
293
+ # this will declare QtCore (and qtmain on <target-os>windows)
294
+ add-shared-library QtCore ;
295
+ }
296
+ else
297
+ # Setup common pre-built Qt.
298
+ # Special setup for QtCore on which everything depends
299
+ {
300
+ local usage-requirements =
301
+ <include>$(.incprefix)
302
+ <library-path>$(.libprefix)
303
+ <dll-path>$(.libprefix)
304
+ <threading>multi
305
+ <allow>qt4 ;
306
+
307
+ local suffix ;
308
+
309
+ # Since Qt-4.2, debug versions on unix have to be built
310
+ # separately and therefore have no suffix.
311
+ .suffix_version = "" ;
312
+ .suffix_debug = "" ;
313
+
314
+ # Control flag for auto-configuration of the debug libraries.
315
+ # This setup requires Qt 'configure -debug-and-release'.
316
+ # Only available on some platforms.
317
+ # ToDo: 2009-02-12: Maybe throw this away and
318
+ # require separate setup with <variant>debug as condition.
319
+ .have_separate_debug = FALSE ;
320
+
321
+ # Setup other platforms
322
+ if $(target-os) in windows cygwin
323
+ {
324
+ .have_separate_debug = TRUE ;
325
+
326
+ # On NT, the libs have "4" suffix, and "d" suffix in debug builds.
327
+ .suffix_version = "4" ;
328
+ .suffix_debug = "d" ;
329
+
330
+ # On Windows we must link against the qtmain library
331
+ lib qtmain
332
+ : # sources
333
+ : # requirements
334
+ <name>qtmain$(.suffix_debug)
335
+ <variant>debug
336
+ $(target-requirements)
337
+ ;
338
+
339
+ lib qtmain
340
+ : # sources
341
+ : # requirements
342
+ <name>qtmain
343
+ $(target-requirements)
344
+ ;
345
+ }
346
+ else if $(target-os) = darwin
347
+ {
348
+ # On MacOS X, both debug and release libraries are available.
349
+ .suffix_debug = "_debug" ;
350
+
351
+ .have_separate_debug = TRUE ;
352
+
353
+ alias qtmain ;
354
+ }
355
+ else
356
+ {
357
+ alias qtmain : : $(target-requirements) ;
358
+ }
359
+
360
+ lib QtCore : qtmain
361
+ : # requirements
362
+ <name>QtCore$(.suffix_version)
363
+ $(target-requirements)
364
+ : # default-build
365
+ : # usage-requirements
366
+ <define>QT_CORE_LIB
367
+ <define>QT_NO_DEBUG
368
+ <include>$(.incprefix)/QtCore
369
+ $(usage-requirements)
370
+ ;
371
+
372
+ if $(.have_separate_debug) = TRUE
373
+ {
374
+ debug-message Configure debug libraries with suffix '$(.suffix_debug)' ;
375
+
376
+ lib QtCore : $(main)
377
+ : # requirements
378
+ <name>QtCore$(.suffix_debug)$(.suffix_version)
379
+ <variant>debug
380
+ $(target-requirements)
381
+ : # default-build
382
+ : # usage-requirements
383
+ <define>QT_CORE_LIB
384
+ <include>$(.incprefix)/QtCore
385
+ $(usage-requirements)
386
+ ;
387
+ }
388
+ }
389
+
390
+ # Initialising the remaining libraries is canonical
391
+ # parameters 'module' : 'depends-on' : 'usage-define' : 'requirements' : 'include'
392
+ # 'include' only for non-canonical include paths.
393
+ add-shared-library QtGui : QtCore : QT_GUI_LIB : $(target-requirements) ;
394
+ add-shared-library QtNetwork : QtCore : QT_NETWORK_LIB : $(target-requirements) ;
395
+ add-shared-library QtSql : QtCore : QT_SQL_LIB : $(target-requirements) ;
396
+ add-shared-library QtXml : QtCore : QT_XML_LIB : $(target-requirements) ;
397
+
398
+ add-shared-library Qt3Support : QtGui QtNetwork QtXml QtSql
399
+ : QT_QT3SUPPORT_LIB QT3_SUPPORT
400
+ : <qt3support>on $(target-requirements) ;
401
+
402
+ # Dummy target to enable "<qt3support>off" and
403
+ # "<library>/qt//Qt3Support" at the same time. This enables quick
404
+ # switching from one to the other for test/porting purposes.
405
+ alias Qt3Support : : <qt3support>off $(target-requirements) ;
406
+
407
+ # OpenGl Support
408
+ add-shared-library QtOpenGL : QtGui : QT_OPENGL_LIB : $(target-requirements) ;
409
+
410
+ # SVG-Support (Qt 4.1)
411
+ add-shared-library QtSvg : QtXml QtOpenGL : QT_SVG_LIB : $(target-requirements) ;
412
+
413
+ # Test-Support (Qt 4.1)
414
+ add-shared-library QtTest : QtCore : : $(target-requirements) ;
415
+
416
+ # Qt designer library
417
+ add-shared-library QtDesigner : QtGui QtXml : : $(target-requirements) ;
418
+ add-shared-library QtDesignerComponents : QtGui QtXml : : $(target-requirements) ;
419
+
420
+ # Support for dynamic Widgets (Qt 4.1)
421
+ add-static-library QtUiTools : QtGui QtXml : $(target-requirements) ;
422
+
423
+ # DBus-Support (Qt 4.2)
424
+ add-shared-library QtDBus : QtXml : : $(target-requirements) ;
425
+
426
+ # Script-Engine (Qt 4.3)
427
+ add-shared-library QtScript : QtGui QtXml : QT_SCRIPT_LIB : $(target-requirements) ;
428
+
429
+ # Tools for the Script-Engine (Qt 4.5)
430
+ add-shared-library QtScriptTools : QtScript : QT_SCRIPTTOOLS_LIB : $(target-requirements) ;
431
+
432
+ # WebKit (Qt 4.4)
433
+ add-shared-library QtWebKit : QtGui : QT_WEBKIT_LIB : $(target-requirements) ;
434
+
435
+ # Phonon Multimedia (Qt 4.4)
436
+ add-shared-library phonon : QtGui QtXml : QT_PHONON_LIB : $(target-requirements) ;
437
+
438
+ # Multimedia engine (Qt 4.6)
439
+ add-shared-library QtMultimedia : QtGui : QT_MULTIMEDIA_LIB : $(target-requirements) ;
440
+
441
+ # XmlPatterns-Engine (Qt 4.4)
442
+ add-shared-library QtXmlPatterns : QtNetwork : QT_XMLPATTERNS_LIB : $(target-requirements) ;
443
+
444
+ # Help-Engine (Qt 4.4)
445
+ add-shared-library QtHelp : QtGui QtSql QtXml : : $(target-requirements) ;
446
+ add-shared-library QtCLucene : QCore QtSql QtXml : : $(target-requirements) ;
447
+
448
+ # QML-Engine (Qt 4.7)
449
+ add-shared-library QtDeclarative : QtGui QtXml : : $(target-requirements) ;
450
+
451
+ # AssistantClient Support
452
+ # Compat library removed in 4.7.0
453
+ # Pre-4.4 help system, use QtHelp for new programs
454
+ if $(version) < "4.7"
455
+ {
456
+ add-shared-library QtAssistantClient : QtGui : : $(target-requirements) : QtAssistant ;
457
+ }
458
+ debug-message "==== Configured Qt-$(version) ====" ;
459
+
460
+ project.pop-current ;
461
+ }
462
+
463
+ rule initialized ( )
464
+ {
465
+ return $(.initialized) ;
466
+ }
467
+
468
+
469
+
470
+ # This custom generator is needed because in QT4, UI files are translated only
471
+ # into H files, and no C++ files are created. Further, the H files need not be
472
+ # passed via MOC. The header is used only via inclusion. If we define a standard
473
+ # UI -> H generator, Boost.Build will run MOC on H, and then compile the
474
+ # resulting cpp. It will give a warning, since output from moc will be empty.
475
+ #
476
+ # This generator is declared with a UI -> OBJ signature, so it gets invoked when
477
+ # linking generator tries to convert sources to OBJ, but it produces target of
478
+ # type H. This is non-standard, but allowed. That header won't be mocced.
479
+ #
480
+ class uic-generator : generator
481
+ {
482
+ rule __init__ ( * : * )
483
+ {
484
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
485
+ }
486
+
487
+ rule run ( project name ? : property-set : sources * )
488
+ {
489
+ if ! $(name)
490
+ {
491
+ name = [ $(sources[0]).name ] ;
492
+ name = $(name:B) ;
493
+ }
494
+
495
+ local a = [ new action $(sources[1]) : qt4.uic : $(property-set) ] ;
496
+
497
+ # The 'ui_' prefix is to match qmake's default behavior.
498
+ local target = [ new file-target ui_$(name) : H : $(project) : $(a) ] ;
499
+
500
+ local r = [ virtual-target.register $(target) ] ;
501
+
502
+ # Since this generator will return a H target, the linking generator
503
+ # won't use it at all, and won't set any dependency on it. However, we
504
+ # need the target to be seen by bjam, so that dependency from sources to
505
+ # this generated header is detected -- if jam does not know about this
506
+ # target, it won't do anything.
507
+ DEPENDS all : [ $(r).actualize ] ;
508
+
509
+ return $(r) ;
510
+ }
511
+ }
512
+
513
+
514
+ class moc-h-generator : generator
515
+ {
516
+ rule __init__ ( * : * )
517
+ {
518
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
519
+ }
520
+
521
+ rule run ( project name ? : property-set : sources * )
522
+ {
523
+ if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
524
+ {
525
+ name = [ $(sources[0]).name ] ;
526
+ name = $(name:B) ;
527
+
528
+ local a = [ new action $(sources[1]) : qt4.moc.inc :
529
+ $(property-set) ] ;
530
+
531
+ local target = [ new file-target $(name) : MOC : $(project) : $(a)
532
+ ] ;
533
+
534
+ local r = [ virtual-target.register $(target) ] ;
535
+
536
+ # Since this generator will return a H target, the linking generator
537
+ # won't use it at all, and won't set any dependency on it. However,
538
+ # we need the target to be seen by bjam, so that dependency from
539
+ # sources to this generated header is detected -- if jam does not
540
+ # know about this target, it won't do anything.
541
+ DEPENDS all : [ $(r).actualize ] ;
542
+
543
+ return $(r) ;
544
+ }
545
+ }
546
+ }
547
+
548
+
549
+ class moc-inc-generator : generator
550
+ {
551
+ rule __init__ ( * : * )
552
+ {
553
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
554
+ }
555
+
556
+ rule run ( project name ? : property-set : sources * )
557
+ {
558
+ if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_H
559
+ {
560
+ name = [ $(sources[0]).name ] ;
561
+ name = $(name:B) ;
562
+
563
+ local a = [ new action $(sources[1]) : qt4.moc.inc :
564
+ $(property-set) ] ;
565
+
566
+ local target = [ new file-target moc_$(name) : CPP : $(project) :
567
+ $(a) ] ;
568
+
569
+ # Since this generator will return a H target, the linking generator
570
+ # won't use it at all, and won't set any dependency on it. However,
571
+ # we need the target to be seen by bjam, so that dependency from
572
+ # sources to this generated header is detected -- if jam does not
573
+ # know about this target, it won't do anything.
574
+ DEPENDS all : [ $(target).actualize ] ;
575
+
576
+ return [ virtual-target.register $(target) ] ;
577
+ }
578
+ }
579
+ }
580
+
581
+
582
+ # Query the installation directory. This is needed in at least two scenarios.
583
+ # First, when re-using sources from the Qt-Tree. Second, to "install" custom Qt
584
+ # plugins to the Qt-Tree.
585
+ #
586
+ rule directory
587
+ {
588
+ return $(.PREFIX) ;
589
+ }
590
+
591
+ # Add a shared Qt library.
592
+ rule add-shared-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? )
593
+ {
594
+ add-library $(lib-name) : $(.suffix_version) : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
595
+ }
596
+
597
+ # Add a static Qt library.
598
+ rule add-static-library ( lib-name : depends-on * : usage-defines * : requirements * : include ? )
599
+ {
600
+ add-library $(lib-name) : : $(depends-on) : $(usage-defines) : $(requirements) : $(include) ;
601
+ }
602
+
603
+ # Add a Qt library.
604
+ # Static libs are unversioned, whereas shared libs have the major number as suffix.
605
+ # Creates both release and debug versions on platforms where both are enabled by Qt configure.
606
+ # Flags:
607
+ # - lib-name Qt library Name
608
+ # - version Qt major number used as shared library suffix (QtCore4.so)
609
+ # - depends-on other Qt libraries
610
+ # - usage-defines those are set by qmake, so set them when using this library
611
+ # - requirements addional requirements
612
+ # - include non-canonical include path. The canonical path is $(.incprefix)/$(lib-name).
613
+ rule add-library ( lib-name : version ? : depends-on * : usage-defines * : requirements * : include ? )
614
+ {
615
+ if $(.bjam-qt)
616
+ {
617
+ # Import Qt module
618
+ # Eveything will be setup there
619
+ alias $(lib-name)
620
+ : $(.prefix)//$(lib-name)
621
+ :
622
+ :
623
+ : <allow>qt4 ;
624
+ }
625
+ else
626
+ {
627
+ local real_include ;
628
+ real_include ?= $(include) ;
629
+ real_include ?= $(lib-name) ;
630
+
631
+ lib $(lib-name)
632
+ : # sources
633
+ $(depends-on)
634
+ : # requirements
635
+ <name>$(lib-name)$(version)
636
+ $(requirements)
637
+ : # default-build
638
+ : # usage-requirements
639
+ <define>$(usage-defines)
640
+ <include>$(.incprefix)/$(real_include)
641
+ ;
642
+
643
+ if $(.have_separate_debug) = TRUE
644
+ {
645
+ lib $(lib-name)
646
+ : # sources
647
+ $(depends-on)
648
+ : # requirements
649
+ <name>$(lib-name)$(.suffix_debug)$(version)
650
+ $(requirements)
651
+ <variant>debug
652
+ : # default-build
653
+ : # usage-requirements
654
+ <define>$(usage-defines)
655
+ <include>$(.incprefix)/$(real_include)
656
+ ;
657
+ }
658
+ }
659
+
660
+ # Make library explicit so that a simple <use>qt4 will not bring in everything.
661
+ # And some components like QtDBus/Phonon may not be available on all platforms.
662
+ explicit $(lib-name) ;
663
+ }
664
+
665
+ # Use $(.BINPREFIX[-1]) for the paths as several tools-requirements can match.
666
+ # The exact match is the last one.
667
+
668
+ # Get <include> and <defines> from current toolset.
669
+ flags qt4.moc INCLUDES <include> ;
670
+ flags qt4.moc DEFINES <define> ;
671
+
672
+ # need a newline for expansion of DEFINES and INCLUDES in the response file.
673
+ .nl = "
674
+ " ;
675
+
676
+ # Processes headers to create Qt MetaObject information. Qt4-moc has its
677
+ # c++-parser, so pass INCLUDES and DEFINES.
678
+ # We use response file with one INCLUDE/DEFINE per line
679
+ #
680
+ actions moc
681
+ {
682
+ $(.BINPREFIX[-1])/moc -f $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
683
+ }
684
+
685
+ # When moccing files for include only, we don't need -f, otherwise the generated
686
+ # code will include the .cpp and we'll get duplicated symbols.
687
+ #
688
+ actions moc.inc
689
+ {
690
+ $(.BINPREFIX[-1])/moc $(>) -o $(<) @"@($(<).rsp:E=-D$(DEFINES)$(.nl) -I$(INCLUDES:T)$(.nl))"
691
+ }
692
+
693
+
694
+ # Generates source files from resource files.
695
+ #
696
+ actions rcc
697
+ {
698
+ $(.BINPREFIX[-1])/rcc $(>) -name $(>:B) -o $(<)
699
+ }
700
+
701
+
702
+ # Generates user-interface source from .ui files.
703
+ #
704
+ actions uic
705
+ {
706
+ $(.BINPREFIX[-1])/uic $(>) -o $(<)
707
+ }
708
+
709
+
710
+ # Scanner for .qrc files. Look for the CDATA section of the <file> tag. Ignore
711
+ # the "alias" attribute. See http://doc.trolltech.com/qt/resources.html for
712
+ # detailed documentation of the Qt Resource System.
713
+ #
714
+ class qrc-scanner : common-scanner
715
+ {
716
+ rule pattern ( )
717
+ {
718
+ return "<file.*>(.*)</file>" ;
719
+ }
720
+ }
721
+
722
+
723
+ # Wrapped files are "included".
724
+ scanner.register qrc-scanner : include ;
mosesdecoder/jam-files/boost-build/tools/sun.jam ADDED
@@ -0,0 +1,142 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) Christopher Currie 2003. Permission to copy, use,
2
+ # modify, sell and distribute this software is granted provided this
3
+ # copyright notice appears in all copies. This software is provided
4
+ # "as is" without express or implied warranty, and with no claim as
5
+ # to its suitability for any purpose.
6
+
7
+ import property ;
8
+ import generators ;
9
+ import os ;
10
+ import toolset : flags ;
11
+ import feature ;
12
+ import type ;
13
+ import common ;
14
+
15
+ feature.extend toolset : sun ;
16
+ toolset.inherit sun : unix ;
17
+ generators.override sun.prebuilt : builtin.lib-generator ;
18
+ generators.override sun.prebuilt : builtin.prebuilt ;
19
+ generators.override sun.searched-lib-generator : searched-lib-generator ;
20
+
21
+ feature.extend stdlib : sun-stlport ;
22
+ feature.compose <stdlib>sun-stlport
23
+ : <cxxflags>-library=stlport4 <linkflags>-library=stlport4
24
+ ;
25
+
26
+ rule init ( version ? : command * : options * )
27
+ {
28
+ local condition = [
29
+ common.check-init-parameters sun : version $(version) ] ;
30
+
31
+ command = [ common.get-invocation-command sun : CC
32
+ : $(command) : "/opt/SUNWspro/bin" ] ;
33
+
34
+ # Even if the real compiler is not found, put CC to
35
+ # command line so that user see command line that would have being executed.
36
+ command ?= CC ;
37
+
38
+ common.handle-options sun : $(condition) : $(command) : $(options) ;
39
+
40
+ command_c = $(command[1--2]) $(command[-1]:B=cc) ;
41
+
42
+ toolset.flags sun CONFIG_C_COMMAND $(condition) : $(command_c) ;
43
+ }
44
+
45
+ # Declare generators
46
+ generators.register-c-compiler sun.compile.c : C : OBJ : <toolset>sun ;
47
+ generators.register-c-compiler sun.compile.c++ : CPP : OBJ : <toolset>sun ;
48
+
49
+ # Declare flags and actions for compilation
50
+ flags sun.compile OPTIONS <debug-symbols>on : -g ;
51
+ flags sun.compile OPTIONS <profiling>on : -xprofile=tcov ;
52
+ flags sun.compile OPTIONS <optimization>speed : -xO4 ;
53
+ flags sun.compile OPTIONS <optimization>space : -xO2 -xspace ;
54
+ flags sun.compile OPTIONS <threading>multi : -mt ;
55
+ flags sun.compile OPTIONS <warnings>off : -erroff ;
56
+ flags sun.compile OPTIONS <warnings>on : -erroff=%none ;
57
+ flags sun.compile OPTIONS <warnings>all : -erroff=%none ;
58
+ flags sun.compile OPTIONS <warnings-as-errors>on : -errwarn ;
59
+
60
+ flags sun.compile.c++ OPTIONS <inlining>off : +d ;
61
+
62
+ # The -m32 and -m64 options are supported starting
63
+ # with Sun Studio 12. On earlier compilers, the
64
+ # 'address-model' feature is not supported and should not
65
+ # be used. Instead, use -xarch=generic64 command line
66
+ # option.
67
+ # See http://svn.boost.org/trac/boost/ticket/1186
68
+ # for details.
69
+ flags sun OPTIONS <address-model>32 : -m32 ;
70
+ flags sun OPTIONS <address-model>64 : -m64 ;
71
+ # On sparc, there's a difference between -Kpic
72
+ # and -KPIC. The first is slightly more efficient,
73
+ # but has the limits on the size of GOT table.
74
+ # For minimal fuss on user side, we use -KPIC here.
75
+ # See http://svn.boost.org/trac/boost/ticket/1186#comment:6
76
+ # for detailed explanation.
77
+ flags sun OPTIONS <link>shared : -KPIC ;
78
+
79
+ flags sun.compile OPTIONS <cflags> ;
80
+ flags sun.compile.c++ OPTIONS <cxxflags> ;
81
+ flags sun.compile DEFINES <define> ;
82
+ flags sun.compile INCLUDES <include> ;
83
+
84
+ actions compile.c
85
+ {
86
+ "$(CONFIG_C_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
87
+ }
88
+
89
+ actions compile.c++
90
+ {
91
+ "$(CONFIG_COMMAND)" $(OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -o "$(<)" "$(>)"
92
+ }
93
+
94
+ # Declare flags and actions for linking
95
+ flags sun.link OPTIONS <debug-symbols>on : -g ;
96
+ # Strip the binary when no debugging is needed
97
+ flags sun.link OPTIONS <debug-symbols>off : -s ;
98
+ flags sun.link OPTIONS <profiling>on : -xprofile=tcov ;
99
+ flags sun.link OPTIONS <threading>multi : -mt ;
100
+ flags sun.link OPTIONS <linkflags> ;
101
+ flags sun.link LINKPATH <library-path> ;
102
+ flags sun.link FINDLIBS-ST <find-static-library> ;
103
+ flags sun.link FINDLIBS-SA <find-shared-library> ;
104
+ flags sun.link LIBRARIES <library-file> ;
105
+ flags sun.link LINK-RUNTIME <runtime-link>static : static ;
106
+ flags sun.link LINK-RUNTIME <runtime-link>shared : dynamic ;
107
+ flags sun.link RPATH <dll-path> ;
108
+ # On gcc, there are separate options for dll path at runtime and
109
+ # link time. On Solaris, there's only one: -R, so we have to use
110
+ # it, even though it's bad idea.
111
+ flags sun.link RPATH <xdll-path> ;
112
+
113
+ # The POSIX real-time library is always needed (nanosleep, clock_gettime etc.)
114
+ flags sun.link FINDLIBS-SA : rt ;
115
+
116
+ rule link ( targets * : sources * : properties * )
117
+ {
118
+ SPACE on $(targets) = " " ;
119
+ }
120
+
121
+ actions link bind LIBRARIES
122
+ {
123
+ "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
124
+ }
125
+
126
+ # Slight mods for dlls
127
+ rule link.dll ( targets * : sources * : properties * )
128
+ {
129
+ SPACE on $(targets) = " " ;
130
+ }
131
+
132
+ actions link.dll bind LIBRARIES
133
+ {
134
+ "$(CONFIG_COMMAND)" $(OPTIONS) -L"$(LINKPATH)" -R"$(RPATH)" -o "$(<)" -h$(<[1]:D=) -G "$(>)" "$(LIBRARIES)" -Bdynamic -l$(FINDLIBS-SA) -Bstatic -l$(FINDLIBS-ST) -B$(LINK-RUNTIME)
135
+ }
136
+
137
+ # Declare action for creating static libraries
138
+ actions piecemeal archive
139
+ {
140
+ "$(CONFIG_COMMAND)" -xar -o "$(<)" "$(>)"
141
+ }
142
+
mosesdecoder/jam-files/boost-build/tools/testing.jam ADDED
@@ -0,0 +1,581 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2005 Dave Abrahams
2
+ # Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
3
+ # Distributed under the Boost Software License, Version 1.0.
4
+ # (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ # This module implements regression testing framework. It declares a number of
7
+ # main target rules which perform some action and, if the results are OK,
8
+ # creates an output file.
9
+ #
10
+ # The exact list of rules is:
11
+ # 'compile' -- creates .test file if compilation of sources was
12
+ # successful.
13
+ # 'compile-fail' -- creates .test file if compilation of sources failed.
14
+ # 'run' -- creates .test file is running of executable produced from
15
+ # sources was successful. Also leaves behind .output file
16
+ # with the output from program run.
17
+ # 'run-fail' -- same as above, but .test file is created if running fails.
18
+ #
19
+ # In all cases, presence of .test file is an indication that the test passed.
20
+ # For more convenient reporting, you might want to use C++ Boost regression
21
+ # testing utilities (see http://www.boost.org/more/regression.html).
22
+ #
23
+ # For historical reason, a 'unit-test' rule is available which has the same
24
+ # syntax as 'exe' and behaves just like 'run'.
25
+
26
+ # Things to do:
27
+ # - Teach compiler_status handle Jamfile.v2.
28
+ # Notes:
29
+ # - <no-warn> is not implemented, since it is Como-specific, and it is not
30
+ # clear how to implement it
31
+ # - std::locale-support is not implemented (it is used in one test).
32
+
33
+
34
+ import alias ;
35
+ import "class" ;
36
+ import common ;
37
+ import errors ;
38
+ import feature ;
39
+ import generators ;
40
+ import os ;
41
+ import path ;
42
+ import project ;
43
+ import property ;
44
+ import property-set ;
45
+ import regex ;
46
+ import sequence ;
47
+ import targets ;
48
+ import toolset ;
49
+ import type ;
50
+ import virtual-target ;
51
+
52
+
53
+ rule init ( )
54
+ {
55
+ }
56
+
57
+
58
+ # Feature controling the command used to lanch test programs.
59
+ feature.feature testing.launcher : : free optional ;
60
+
61
+ feature.feature test-info : : free incidental ;
62
+ feature.feature testing.arg : : free incidental ;
63
+ feature.feature testing.input-file : : free dependency ;
64
+
65
+ feature.feature preserve-test-targets : on off : incidental propagated ;
66
+
67
+ # Register target types.
68
+ type.register TEST : test ;
69
+ type.register COMPILE : : TEST ;
70
+ type.register COMPILE_FAIL : : TEST ;
71
+ type.register RUN_OUTPUT : run ;
72
+ type.register RUN : : TEST ;
73
+ type.register RUN_FAIL : : TEST ;
74
+ type.register LINK_FAIL : : TEST ;
75
+ type.register LINK : : TEST ;
76
+ type.register UNIT_TEST : passed : TEST ;
77
+
78
+
79
+ # Declare the rules which create main targets. While the 'type' module already
80
+ # creates rules with the same names for us, we need extra convenience: default
81
+ # name of main target, so write our own versions.
82
+
83
+ # Helper rule. Create a test target, using basename of first source if no target
84
+ # name is explicitly passed. Remembers the created target in a global variable.
85
+ #
86
+ rule make-test ( target-type : sources + : requirements * : target-name ? )
87
+ {
88
+ target-name ?= $(sources[1]:D=:S=) ;
89
+
90
+ # Having periods (".") in the target name is problematic because the typed
91
+ # generator will strip the suffix and use the bare name for the file
92
+ # targets. Even though the location-prefix averts problems most times it
93
+ # does not prevent ambiguity issues when referring to the test targets. For
94
+ # example when using the XML log output. So we rename the target to remove
95
+ # the periods, and provide an alias for users.
96
+ local real-name = [ regex.replace $(target-name) "[.]" "~" ] ;
97
+
98
+ local project = [ project.current ] ;
99
+ # The <location-prefix> forces the build system for generate paths in the
100
+ # form '$build_dir/array1.test/gcc/debug'. This is necessary to allow
101
+ # post-processing tools to work.
102
+ local t = [ targets.create-typed-target [ type.type-from-rule-name
103
+ $(target-type) ] : $(project) : $(real-name) : $(sources) :
104
+ $(requirements) <location-prefix>$(real-name).test ] ;
105
+
106
+ # The alias to the real target, per period replacement above.
107
+ if $(real-name) != $(target-name)
108
+ {
109
+ alias $(target-name) : $(t) ;
110
+ }
111
+
112
+ # Remember the test (for --dump-tests). A good way would be to collect all
113
+ # given a project. This has some technical problems: e.g. we can not call
114
+ # this dump from a Jamfile since projects referred by 'build-project' are
115
+ # not available until the whole Jamfile has been loaded.
116
+ .all-tests += $(t) ;
117
+ return $(t) ;
118
+ }
119
+
120
+
121
+ # Note: passing more that one cpp file here is known to fail. Passing a cpp file
122
+ # and a library target works.
123
+ #
124
+ rule compile ( sources + : requirements * : target-name ? )
125
+ {
126
+ return [ make-test compile : $(sources) : $(requirements) : $(target-name) ]
127
+ ;
128
+ }
129
+
130
+
131
+ rule compile-fail ( sources + : requirements * : target-name ? )
132
+ {
133
+ return [ make-test compile-fail : $(sources) : $(requirements) :
134
+ $(target-name) ] ;
135
+ }
136
+
137
+
138
+ rule link ( sources + : requirements * : target-name ? )
139
+ {
140
+ return [ make-test link : $(sources) : $(requirements) : $(target-name) ] ;
141
+ }
142
+
143
+
144
+ rule link-fail ( sources + : requirements * : target-name ? )
145
+ {
146
+ return [ make-test link-fail : $(sources) : $(requirements) : $(target-name)
147
+ ] ;
148
+ }
149
+
150
+
151
+ rule handle-input-files ( input-files * )
152
+ {
153
+ if $(input-files[2])
154
+ {
155
+ # Check that sorting made when creating property-set instance will not
156
+ # change the ordering.
157
+ if [ sequence.insertion-sort $(input-files) ] != $(input-files)
158
+ {
159
+ errors.user-error "Names of input files must be sorted alphabetically"
160
+ : "due to internal limitations" ;
161
+ }
162
+ }
163
+ return <testing.input-file>$(input-files) ;
164
+ }
165
+
166
+
167
+ rule run ( sources + : args * : input-files * : requirements * : target-name ? :
168
+ default-build * )
169
+ {
170
+ requirements += <testing.arg>$(args:J=" ") ;
171
+ requirements += [ handle-input-files $(input-files) ] ;
172
+ return [ make-test run : $(sources) : $(requirements) : $(target-name) ] ;
173
+ }
174
+
175
+
176
+ rule run-fail ( sources + : args * : input-files * : requirements * :
177
+ target-name ? : default-build * )
178
+ {
179
+ requirements += <testing.arg>$(args:J=" ") ;
180
+ requirements += [ handle-input-files $(input-files) ] ;
181
+ return [ make-test run-fail : $(sources) : $(requirements) : $(target-name)
182
+ ] ;
183
+ }
184
+
185
+
186
+ # Use 'test-suite' as a synonym for 'alias', for backward compatibility.
187
+ IMPORT : alias : : test-suite ;
188
+
189
+
190
+ # For all main targets in 'project-module', which are typed targets with type
191
+ # derived from 'TEST', produce some interesting information.
192
+ #
193
+ rule dump-tests
194
+ {
195
+ for local t in $(.all-tests)
196
+ {
197
+ dump-test $(t) ;
198
+ }
199
+ }
200
+
201
+
202
+ # Given a project location in normalized form (slashes are forward), compute the
203
+ # name of the Boost library.
204
+ #
205
+ local rule get-library-name ( path )
206
+ {
207
+ # Path is in normalized form, so all slashes are forward.
208
+ local match1 = [ MATCH /(tools|libs)/(.*)/(test|example) : $(path) ] ;
209
+ local match2 = [ MATCH /(tools|libs)/(.*)$ : $(path) ] ;
210
+ local match3 = [ MATCH (/status$) : $(path) ] ;
211
+
212
+ if $(match1) { return $(match1[2]) ; }
213
+ else if $(match2) { return $(match2[2]) ; }
214
+ else if $(match3) { return "" ; }
215
+ else if --dump-tests in [ modules.peek : ARGV ]
216
+ {
217
+ # The 'run' rule and others might be used outside boost. In that case,
218
+ # just return the path, since the 'library name' makes no sense.
219
+ return $(path) ;
220
+ }
221
+ }
222
+
223
+
224
+ # Was an XML dump requested?
225
+ .out-xml = [ MATCH --out-xml=(.*) : [ modules.peek : ARGV ] ] ;
226
+
227
+
228
+ # Takes a target (instance of 'basic-target') and prints
229
+ # - its type
230
+ # - its name
231
+ # - comments specified via the <test-info> property
232
+ # - relative location of all source from the project root.
233
+ #
234
+ rule dump-test ( target )
235
+ {
236
+ local type = [ $(target).type ] ;
237
+ local name = [ $(target).name ] ;
238
+ local project = [ $(target).project ] ;
239
+
240
+ local project-root = [ $(project).get project-root ] ;
241
+ local library = [ get-library-name [ path.root [ $(project).get location ]
242
+ [ path.pwd ] ] ] ;
243
+ if $(library)
244
+ {
245
+ name = $(library)/$(name) ;
246
+ }
247
+
248
+ local sources = [ $(target).sources ] ;
249
+ local source-files ;
250
+ for local s in $(sources)
251
+ {
252
+ if [ class.is-a $(s) : file-reference ]
253
+ {
254
+ local location = [ path.root [ path.root [ $(s).name ]
255
+ [ $(s).location ] ] [ path.pwd ] ] ;
256
+
257
+ source-files += [ path.relative-to [ path.root $(project-root)
258
+ [ path.pwd ] ] $(location) ] ;
259
+ }
260
+ }
261
+
262
+ local target-name = [ $(project).get location ] // [ $(target).name ] .test
263
+ ;
264
+ target-name = $(target-name:J=) ;
265
+
266
+ local r = [ $(target).requirements ] ;
267
+ # Extract values of the <test-info> feature.
268
+ local test-info = [ $(r).get <test-info> ] ;
269
+
270
+ # If the user requested XML output on the command-line, add the test info to
271
+ # that XML file rather than dumping them to stdout.
272
+ if $(.out-xml)
273
+ {
274
+ local nl = "
275
+ " ;
276
+ .contents on $(.out-xml) +=
277
+ "$(nl) <test type=\"$(type)\" name=\"$(name)\">"
278
+ "$(nl) <target><![CDATA[$(target-name)]]></target>"
279
+ "$(nl) <info><![CDATA[$(test-info)]]></info>"
280
+ "$(nl) <source><![CDATA[$(source-files)]]></source>"
281
+ "$(nl) </test>"
282
+ ;
283
+ }
284
+ else
285
+ {
286
+ # Format them into a single string of quoted strings.
287
+ test-info = \"$(test-info:J=\"\ \")\" ;
288
+
289
+ ECHO boost-test($(type)) \"$(name)\" [$(test-info)] ":"
290
+ \"$(source-files)\" ;
291
+ }
292
+ }
293
+
294
+
295
+ # Register generators. Depending on target type, either 'expect-success' or
296
+ # 'expect-failure' rule will be used.
297
+ generators.register-standard testing.expect-success : OBJ : COMPILE ;
298
+ generators.register-standard testing.expect-failure : OBJ : COMPILE_FAIL ;
299
+ generators.register-standard testing.expect-success : RUN_OUTPUT : RUN ;
300
+ generators.register-standard testing.expect-failure : RUN_OUTPUT : RUN_FAIL ;
301
+ generators.register-standard testing.expect-failure : EXE : LINK_FAIL ;
302
+ generators.register-standard testing.expect-success : EXE : LINK ;
303
+
304
+ # Generator which runs an EXE and captures output.
305
+ generators.register-standard testing.capture-output : EXE : RUN_OUTPUT ;
306
+
307
+ # Generator which creates a target if sources run successfully. Differs from RUN
308
+ # in that run output is not captured. The reason why it exists is that the 'run'
309
+ # rule is much better for automated testing, but is not user-friendly (see
310
+ # http://article.gmane.org/gmane.comp.lib.boost.build/6353).
311
+ generators.register-standard testing.unit-test : EXE : UNIT_TEST ;
312
+
313
+
314
+ # The action rules called by generators.
315
+
316
+ # Causes the 'target' to exist after bjam invocation if and only if all the
317
+ # dependencies were successfully built.
318
+ #
319
+ rule expect-success ( target : dependency + : requirements * )
320
+ {
321
+ **passed** $(target) : $(sources) ;
322
+ }
323
+
324
+
325
+ # Causes the 'target' to exist after bjam invocation if and only if all some of
326
+ # the dependencies were not successfully built.
327
+ #
328
+ rule expect-failure ( target : dependency + : properties * )
329
+ {
330
+ local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
331
+ local marker = $(dependency:G=$(grist)*fail) ;
332
+ (failed-as-expected) $(marker) ;
333
+ FAIL_EXPECTED $(dependency) ;
334
+ LOCATE on $(marker) = [ on $(dependency) return $(LOCATE) ] ;
335
+ RMOLD $(marker) ;
336
+ DEPENDS $(marker) : $(dependency) ;
337
+ DEPENDS $(target) : $(marker) ;
338
+ **passed** $(target) : $(marker) ;
339
+ }
340
+
341
+
342
+ # The rule/action combination used to report successful passing of a test.
343
+ #
344
+ rule **passed**
345
+ {
346
+ # Dump all the tests, if needed. We do it here, since dump should happen
347
+ # only after all Jamfiles have been read, and there is no such place
348
+ # currently defined (but there should be).
349
+ if ! $(.dumped-tests) && ( --dump-tests in [ modules.peek : ARGV ] )
350
+ {
351
+ .dumped-tests = true ;
352
+ dump-tests ;
353
+ }
354
+
355
+ # Force deletion of the target, in case any dependencies failed to build.
356
+ RMOLD $(<) ;
357
+ }
358
+
359
+
360
+ # Used to create test files signifying passed tests.
361
+ #
362
+ actions **passed**
363
+ {
364
+ echo passed > "$(<)"
365
+ }
366
+
367
+
368
+ # Used to create replacement object files that do not get created during tests
369
+ # that are expected to fail.
370
+ #
371
+ actions (failed-as-expected)
372
+ {
373
+ echo failed as expected > "$(<)"
374
+ }
375
+
376
+
377
+ rule run-path-setup ( target : source : properties * )
378
+ {
379
+ # For testing, we need to make sure that all dynamic libraries needed by the
380
+ # test are found. So, we collect all paths from dependency libraries (via
381
+ # xdll-path property) and add whatever explicit dll-path user has specified.
382
+ # The resulting paths are added to the environment on each test invocation.
383
+ local dll-paths = [ feature.get-values <dll-path> : $(properties) ] ;
384
+ dll-paths += [ feature.get-values <xdll-path> : $(properties) ] ;
385
+ dll-paths += [ on $(source) return $(RUN_PATH) ] ;
386
+ dll-paths = [ sequence.unique $(dll-paths) ] ;
387
+ if $(dll-paths)
388
+ {
389
+ dll-paths = [ sequence.transform path.native : $(dll-paths) ] ;
390
+ PATH_SETUP on $(target) = [ common.prepend-path-variable-command
391
+ [ os.shared-library-path-variable ] : $(dll-paths) ] ;
392
+ }
393
+ }
394
+
395
+
396
+ local argv = [ modules.peek : ARGV ] ;
397
+
398
+ toolset.flags testing.capture-output ARGS <testing.arg> ;
399
+ toolset.flags testing.capture-output INPUT_FILES <testing.input-file> ;
400
+ toolset.flags testing.capture-output LAUNCHER <testing.launcher> ;
401
+
402
+
403
+ # Runs executable 'sources' and stores stdout in file 'target'. Unless
404
+ # --preserve-test-targets command line option has been specified, removes the
405
+ # executable. The 'target-to-remove' parameter controls what should be removed:
406
+ # - if 'none', does not remove anything, ever
407
+ # - if empty, removes 'source'
408
+ # - if non-empty and not 'none', contains a list of sources to remove.
409
+ #
410
+ rule capture-output ( target : source : properties * : targets-to-remove * )
411
+ {
412
+ output-file on $(target) = $(target:S=.output) ;
413
+ LOCATE on $(target:S=.output) = [ on $(target) return $(LOCATE) ] ;
414
+
415
+ # The INCLUDES kill a warning about independent target...
416
+ INCLUDES $(target) : $(target:S=.output) ;
417
+ # but it also puts .output into dependency graph, so we must tell jam it is
418
+ # OK if it cannot find the target or updating rule.
419
+ NOCARE $(target:S=.output) ;
420
+
421
+ # This has two-fold effect. First it adds input files to the dependendency
422
+ # graph, preventing a warning. Second, it causes input files to be bound
423
+ # before target is created. Therefore, they are bound using SEARCH setting
424
+ # on them and not LOCATE setting of $(target), as in other case (due to jam
425
+ # bug).
426
+ DEPENDS $(target) : [ on $(target) return $(INPUT_FILES) ] ;
427
+
428
+ if $(targets-to-remove) = none
429
+ {
430
+ targets-to-remove = ;
431
+ }
432
+ else if ! $(targets-to-remove)
433
+ {
434
+ targets-to-remove = $(source) ;
435
+ }
436
+
437
+ run-path-setup $(target) : $(source) : $(properties) ;
438
+
439
+ if [ feature.get-values preserve-test-targets : $(properties) ] = off
440
+ {
441
+ TEMPORARY $(targets-to-remove) ;
442
+ # Set a second action on target that will be executed after capture
443
+ # output action. The 'RmTemps' rule has the 'ignore' modifier so it is
444
+ # always considered succeeded. This is needed for 'run-fail' test. For
445
+ # that test the target will be marked with FAIL_EXPECTED, and without
446
+ # 'ignore' successful execution will be negated and be reported as
447
+ # failure. With 'ignore' we do not detect a case where removing files
448
+ # fails, but it is not likely to happen.
449
+ RmTemps $(target) : $(targets-to-remove) ;
450
+ }
451
+ }
452
+
453
+
454
+ if [ os.name ] = NT
455
+ {
456
+ .STATUS = %status% ;
457
+ .SET_STATUS = "set status=%ERRORLEVEL%" ;
458
+ .RUN_OUTPUT_NL = "echo." ;
459
+ .STATUS_0 = "%status% EQU 0 (" ;
460
+ .STATUS_NOT_0 = "%status% NEQ 0 (" ;
461
+ .VERBOSE = "%verbose% EQU 1 (" ;
462
+ .ENDIF = ")" ;
463
+ .SHELL_SET = "set " ;
464
+ .CATENATE = type ;
465
+ .CP = copy ;
466
+ }
467
+ else
468
+ {
469
+ .STATUS = "$status" ;
470
+ .SET_STATUS = "status=$?" ;
471
+ .RUN_OUTPUT_NL = "echo" ;
472
+ .STATUS_0 = "test $status -eq 0 ; then" ;
473
+ .STATUS_NOT_0 = "test $status -ne 0 ; then" ;
474
+ .VERBOSE = "test $verbose -eq 1 ; then" ;
475
+ .ENDIF = "fi" ;
476
+ .SHELL_SET = "" ;
477
+ .CATENATE = cat ;
478
+ .CP = cp ;
479
+ }
480
+
481
+
482
+ .VERBOSE_TEST = 0 ;
483
+ if --verbose-test in [ modules.peek : ARGV ]
484
+ {
485
+ .VERBOSE_TEST = 1 ;
486
+ }
487
+
488
+
489
+ .RM = [ common.rm-command ] ;
490
+
491
+
492
+ actions capture-output bind INPUT_FILES output-file
493
+ {
494
+ $(PATH_SETUP)
495
+ $(LAUNCHER) "$(>)" $(ARGS) "$(INPUT_FILES)" > "$(output-file)" 2>&1
496
+ $(.SET_STATUS)
497
+ $(.RUN_OUTPUT_NL) >> "$(output-file)"
498
+ echo EXIT STATUS: $(.STATUS) >> "$(output-file)"
499
+ if $(.STATUS_0)
500
+ $(.CP) "$(output-file)" "$(<)"
501
+ $(.ENDIF)
502
+ $(.SHELL_SET)verbose=$(.VERBOSE_TEST)
503
+ if $(.STATUS_NOT_0)
504
+ $(.SHELL_SET)verbose=1
505
+ $(.ENDIF)
506
+ if $(.VERBOSE)
507
+ echo ====== BEGIN OUTPUT ======
508
+ $(.CATENATE) "$(output-file)"
509
+ echo ====== END OUTPUT ======
510
+ $(.ENDIF)
511
+ exit $(.STATUS)
512
+ }
513
+
514
+
515
+ actions quietly updated ignore piecemeal together RmTemps
516
+ {
517
+ $(.RM) "$(>)"
518
+ }
519
+
520
+
521
+ .MAKE_FILE = [ common.file-creation-command ] ;
522
+
523
+ toolset.flags testing.unit-test LAUNCHER <testing.launcher> ;
524
+ toolset.flags testing.unit-test ARGS <testing.arg> ;
525
+
526
+
527
+ rule unit-test ( target : source : properties * )
528
+ {
529
+ run-path-setup $(target) : $(source) : $(properties) ;
530
+ }
531
+
532
+
533
+ actions unit-test
534
+ {
535
+ $(PATH_SETUP)
536
+ $(LAUNCHER) $(>) $(ARGS) && $(.MAKE_FILE) $(<)
537
+ }
538
+
539
+
540
+ IMPORT $(__name__) : compile compile-fail run run-fail link link-fail
541
+ : : compile compile-fail run run-fail link link-fail ;
542
+
543
+
544
+ type.register TIME : time ;
545
+ generators.register-standard testing.time : : TIME ;
546
+
547
+
548
+ rule record-time ( target : source : start end user system )
549
+ {
550
+ local src-string = [$(source:G=:J=",")"] " ;
551
+ USER_TIME on $(target) += $(src-string)$(user) ;
552
+ SYSTEM_TIME on $(target) += $(src-string)$(system) ;
553
+ }
554
+
555
+
556
+ IMPORT testing : record-time : : testing.record-time ;
557
+
558
+
559
+ # Calling this rule requests that Boost Build time how long it taks to build the
560
+ # 'source' target and display the results both on the standard output and in the
561
+ # 'target' file.
562
+ #
563
+ rule time ( target : source : properties * )
564
+ {
565
+ # Set up rule for recording timing information.
566
+ __TIMING_RULE__ on $(source) = testing.record-time $(target) ;
567
+
568
+ # Make sure that the source is rebuilt any time we need to retrieve that
569
+ # information.
570
+ REBUILDS $(target) : $(source) ;
571
+ }
572
+
573
+
574
+ actions time
575
+ {
576
+ echo user: $(USER_TIME)
577
+ echo system: $(SYSTEM_TIME)
578
+
579
+ echo user: $(USER_TIME)" seconds" > "$(<)"
580
+ echo system: $(SYSTEM_TIME)" seconds" >> "$(<)"
581
+ }
mosesdecoder/jam-files/boost-build/tools/types/html.jam ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ # Copyright David Abrahams 2004. Distributed under the Boost
2
+ # Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+ type HTML : html ;
mosesdecoder/jam-files/boost-build/tools/types/obj.jam ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright David Abrahams 2004. Distributed under the Boost
2
+ # Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ import type ;
6
+
7
+ type.register OBJ : o obj ;
8
+ type.set-generated-target-suffix OBJ : <target-os>windows : obj ;
9
+ type.set-generated-target-suffix OBJ : <target-os>cygwin : obj ;
mosesdecoder/jam-files/boost-build/tools/types/objc.jam ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Rene Rivera 2008, 2010.
2
+ # Distributed under the Boost Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+ import type ;
5
+ import scanner ;
6
+ import types/cpp ;
7
+
8
+ class objc-scanner : c-scanner
9
+ {
10
+ rule __init__ ( includes * )
11
+ {
12
+ c-scanner.__init__ $(includes) ;
13
+ }
14
+
15
+ rule pattern ( )
16
+ {
17
+ return "#[ \t]*include|import[ ]*(<(.*)>|\"(.*)\")" ;
18
+ }
19
+ }
20
+
21
+ scanner.register objc-scanner : include ;
22
+
23
+ type.register OBJECTIVE_C : m ;
24
+ type.register OBJECTIVE_CPP : mm ;
25
+ type.set-scanner OBJECTIVE_C : objc-scanner ;
26
+ type.set-scanner OBJECTIVE_CPP : objc-scanner ;
mosesdecoder/jam-files/boost-build/tools/types/preprocessed.jam ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Steven Watanabe 2011
2
+ # Distributed under the Boost Software License Version 1.0. (See
3
+ # accompanying file LICENSE_1_0.txt or copy at
4
+ # http://www.boost.org/LICENSE_1_0.txt)
5
+
6
+ import type ;
7
+
8
+ type.register PREPROCESSED_C : i : C ;
9
+ type.register PREPROCESSED_CPP : ii : CPP ;
mosesdecoder/jam-files/boost-build/tools/types/qt.jam ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright Vladimir Prus 2005. Distributed under the Boost
2
+ # Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ type UI : ui ;
6
+ type QRC : qrc ;
7
+ type MOCCABLE_CPP ;
8
+ type MOCCABLE_H ;
9
+ # Result of running moc.
10
+ type MOC : moc : H ;
mosesdecoder/jam-files/boost-build/tools/types/register.jam ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright David Abrahams 2004. Distributed under the Boost
2
+ # Software License, Version 1.0. (See accompanying
3
+ # file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
4
+
5
+ # This module's job is to automatically import all the type
6
+ # registration modules in its directory.
7
+ import type os path modules ;
8
+
9
+ # Register the given type on the specified OSes, or on remaining OSes
10
+ # if os is not specified. This rule is injected into each of the type
11
+ # modules for the sake of convenience.
12
+ local rule type ( type : suffixes * : base-type ? : os * )
13
+ {
14
+ if ! [ type.registered $(type) ]
15
+ {
16
+ if ( ! $(os) ) || [ os.name ] in $(os)
17
+ {
18
+ type.register $(type) : $(suffixes) : $(base-type) ;
19
+ }
20
+ }
21
+ }
22
+
23
+ .this-module's-file = [ modules.binding $(__name__) ] ;
24
+ .this-module's-dir = [ path.parent $(.this-module's-file) ] ;
25
+ .sibling-jamfiles = [ path.glob $(.this-module's-dir) : *.jam ] ;
26
+ .sibling-modules = [ MATCH ^(.*)\.jam$ : $(.sibling-jamfiles) ] ;
27
+
28
+ # A loop over all modules in this directory
29
+ for m in $(.sibling-modules)
30
+ {
31
+ m = [ path.basename $(m) ] ;
32
+ m = types/$(m) ;
33
+
34
+ # Inject the type rule into the new module
35
+ IMPORT $(__name__) : type : $(m) : type ;
36
+ import $(m) ;
37
+ }
38
+
39
+
mosesdecoder/jam-files/boost-build/tools/unix.jam ADDED
@@ -0,0 +1,224 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) 2004 Vladimir Prus.
2
+ #
3
+ # Use, modification and distribution is subject to the Boost Software
4
+ # License Version 1.0. (See accompanying file LICENSE_1_0.txt or
5
+ # http://www.boost.org/LICENSE_1_0.txt)
6
+
7
+ # This file implements linking semantic common to all unixes. On unix, static
8
+ # libraries must be specified in a fixed order on the linker command line. Generators
9
+ # declared there store information about the order and use it property.
10
+
11
+ import feature ;
12
+ import "class" : new ;
13
+ import generators ;
14
+ import type ;
15
+ import set ;
16
+ import order ;
17
+ import builtin ;
18
+
19
+ class unix-linking-generator : linking-generator
20
+ {
21
+ import property-set ;
22
+ import type ;
23
+ import unix ;
24
+
25
+ rule __init__ ( id
26
+ composing ? : # Specify if generator is composing. The generator will be
27
+ # composing if non-empty string is passed, or parameter is
28
+ # not given. To make generator non-composing, pass empty
29
+ # string ("")
30
+ source-types + : target-types + :
31
+ requirements * )
32
+ {
33
+ composing ?= true ;
34
+ generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
35
+ $(requirements) ;
36
+ }
37
+
38
+ rule run ( project name ? : property-set : sources + )
39
+ {
40
+ local result = [ linking-generator.run $(project) $(name) : $(property-set)
41
+ : $(sources) ] ;
42
+
43
+ unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ;
44
+
45
+ return $(result) ;
46
+ }
47
+
48
+ rule generated-targets ( sources + : property-set : project name ? )
49
+ {
50
+ local sources2 ;
51
+ local libraries ;
52
+ for local l in $(sources)
53
+ {
54
+ if [ type.is-derived [ $(l).type ] LIB ]
55
+ {
56
+ libraries += $(l) ;
57
+ }
58
+ else
59
+ {
60
+ sources2 += $(l) ;
61
+ }
62
+ }
63
+
64
+ sources = $(sources2) [ unix.order-libraries $(libraries) ] ;
65
+
66
+ return [ linking-generator.generated-targets $(sources) : $(property-set)
67
+ : $(project) $(name) ] ;
68
+ }
69
+
70
+ }
71
+
72
+ class unix-archive-generator : archive-generator
73
+ {
74
+ import unix ;
75
+
76
+ rule __init__ ( id composing ? : source-types + : target-types + :
77
+ requirements * )
78
+ {
79
+ composing ?= true ;
80
+ archive-generator.__init__ $(id) $(composing) : $(source-types) : $(target-types) :
81
+ $(requirements) ;
82
+ }
83
+
84
+ rule run ( project name ? : property-set : sources + )
85
+ {
86
+ local result = [ archive-generator.run $(project) $(name) : $(property-set)
87
+ : $(sources) ] ;
88
+
89
+ unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ;
90
+
91
+ return $(result) ;
92
+
93
+ }
94
+ }
95
+
96
+ class unix-searched-lib-generator : searched-lib-generator
97
+ {
98
+ import unix ;
99
+ rule __init__ ( * : * )
100
+ {
101
+ generator.__init__
102
+ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
103
+ }
104
+
105
+ rule optional-properties ( )
106
+ {
107
+ return $(self.requirements) ;
108
+ }
109
+
110
+ rule run ( project name ? : property-set : sources * )
111
+ {
112
+ local result = [ searched-lib-generator.run $(project) $(name)
113
+ : $(property-set) : $(sources) ] ;
114
+
115
+ unix.set-library-order $(sources) : $(property-set) : $(result[2-]) ;
116
+
117
+ return $(result) ;
118
+ }
119
+ }
120
+
121
+ class unix-prebuilt-lib-generator : generator
122
+ {
123
+ import unix ;
124
+ rule __init__ ( * : * )
125
+ {
126
+ generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
127
+ }
128
+
129
+ rule run ( project name ? : property-set : sources * )
130
+ {
131
+ local f = [ $(property-set).get <file> ] ;
132
+ unix.set-library-order-aux $(f) : $(sources) ;
133
+ return $(f) $(sources) ;
134
+ }
135
+ }
136
+
137
+ generators.register
138
+ [ new unix-prebuilt-lib-generator unix.prebuilt : : LIB
139
+ : <file> <toolset>unix ] ;
140
+
141
+ generators.override unix.prebuilt : builtin.lib-generator ;
142
+
143
+
144
+ # Declare generators
145
+ generators.register [ new unix-linking-generator unix.link : LIB OBJ : EXE
146
+ : <toolset>unix ] ;
147
+
148
+ generators.register [ new unix-archive-generator unix.archive : OBJ : STATIC_LIB
149
+ : <toolset>unix ] ;
150
+
151
+ generators.register [ new unix-linking-generator unix.link.dll : LIB OBJ : SHARED_LIB
152
+ : <toolset>unix ] ;
153
+
154
+ generators.register [ new unix-searched-lib-generator
155
+ unix.searched-lib-generator : : SEARCHED_LIB : <toolset>unix ] ;
156
+
157
+
158
+ # The derived toolset must specify their own actions.
159
+ actions link {
160
+ }
161
+
162
+ actions link.dll {
163
+ }
164
+
165
+ actions archive {
166
+ }
167
+
168
+ actions searched-lib-generator {
169
+ }
170
+
171
+ actions prebuilt {
172
+ }
173
+
174
+
175
+
176
+
177
+
178
+ .order = [ new order ] ;
179
+
180
+ rule set-library-order-aux ( from * : to * )
181
+ {
182
+ for local f in $(from)
183
+ {
184
+ for local t in $(to)
185
+ {
186
+ if $(f) != $(t)
187
+ {
188
+ $(.order).add-pair $(f) $(t) ;
189
+ }
190
+ }
191
+ }
192
+ }
193
+
194
+ rule set-library-order ( sources * : property-set : result * )
195
+ {
196
+ local used-libraries ;
197
+ local deps = [ $(property-set).dependency ] ;
198
+ for local l in $(sources) $(deps:G=)
199
+ {
200
+ if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ]
201
+ {
202
+ used-libraries += $(l) ;
203
+ }
204
+ }
205
+
206
+ local created-libraries ;
207
+ for local l in $(result)
208
+ {
209
+ if [ $(l).type ] && [ type.is-derived [ $(l).type ] LIB ]
210
+ {
211
+ created-libraries += $(l) ;
212
+ }
213
+ }
214
+
215
+ created-libraries = [ set.difference $(created-libraries) : $(used-libraries) ] ;
216
+ set-library-order-aux $(created-libraries) : $(used-libraries) ;
217
+ }
218
+
219
+ rule order-libraries ( libraries * )
220
+ {
221
+ local r = [ $(.order).order $(libraries) ] ;
222
+ return $(r) ;
223
+ }
224
+
mosesdecoder/jam-files/boost-build/tools/xsltproc.jam ADDED
@@ -0,0 +1,194 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (C) 2003 Doug Gregor. Permission to copy, use, modify, sell and
2
+ # distribute this software is granted provided this copyright notice appears in
3
+ # all copies. This software is provided "as is" without express or implied
4
+ # warranty, and with no claim as to its suitability for any purpose.
5
+
6
+ # This module defines rules to apply an XSLT stylesheet to an XML file using the
7
+ # xsltproc driver, part of libxslt.
8
+ #
9
+ # Note: except for 'init', this modules does not provide any rules for end
10
+ # users.
11
+
12
+ import feature ;
13
+ import regex ;
14
+ import sequence ;
15
+ import common ;
16
+ import os ;
17
+ import modules ;
18
+ import path ;
19
+ import errors ;
20
+
21
+ feature.feature xsl:param : : free ;
22
+ feature.feature xsl:path : : free ;
23
+ feature.feature catalog : : free ;
24
+
25
+
26
+ # Initialize xsltproc support. The parameters are:
27
+ # xsltproc: The xsltproc executable
28
+ #
29
+ rule init ( xsltproc ? )
30
+ {
31
+ if $(xsltproc)
32
+ {
33
+ modify-config ;
34
+ .xsltproc = $(xsltproc) ;
35
+ check-xsltproc ;
36
+ }
37
+ }
38
+
39
+ rule freeze-config ( )
40
+ {
41
+ if ! $(.config-frozen)
42
+ {
43
+ .config-frozen = true ;
44
+ .xsltproc ?= [ modules.peek : XSLTPROC ] ;
45
+ .xsltproc ?= xsltproc ;
46
+ check-xsltproc ;
47
+ .is-cygwin = [ .is-cygwin $(.xsltproc) ] ;
48
+ }
49
+ }
50
+
51
+ rule modify-config
52
+ {
53
+ if $(.config-frozen)
54
+ {
55
+ errors.user-error "xsltproc: Cannot change xsltproc command after it has been used." ;
56
+ }
57
+ }
58
+
59
+ rule check-xsltproc ( )
60
+ {
61
+ if $(.xsltproc)
62
+ {
63
+ local status = [ SHELL "\"$(.xsltproc)\" -V" : no-output : exit-status ] ;
64
+ if $(status[2]) != "0"
65
+ {
66
+ errors.user-error "xsltproc: Could not run \"$(.xsltproc)\" -V." ;
67
+ }
68
+ }
69
+ }
70
+
71
+ # Returns a non-empty string if a cygwin xsltproc binary was specified.
72
+ rule is-cygwin ( )
73
+ {
74
+ freeze-config ;
75
+ return $(.is-cygwin) ;
76
+ }
77
+
78
+ rule .is-cygwin ( xsltproc )
79
+ {
80
+ if [ os.on-windows ]
81
+ {
82
+ local file = [ path.make [ modules.binding $(__name__) ] ] ;
83
+ local dir = [ path.native
84
+ [ path.join [ path.parent $(file) ] xsltproc ] ] ;
85
+ if [ os.name ] = CYGWIN
86
+ {
87
+ dir = $(dir:W) ;
88
+ }
89
+ local command =
90
+ "\"$(xsltproc)\" \"$(dir)\\test.xsl\" \"$(dir)\\test.xml\" 2>&1" ;
91
+ local status = [ SHELL $(command) : no-output : exit-status ] ;
92
+ if $(status[2]) != "0"
93
+ {
94
+ return true ;
95
+ }
96
+ }
97
+ }
98
+
99
+ rule compute-xslt-flags ( target : properties * )
100
+ {
101
+ local flags ;
102
+
103
+ # Raw flags.
104
+ flags += [ feature.get-values <flags> : $(properties) ] ;
105
+
106
+ # Translate <xsl:param> into command line flags.
107
+ for local param in [ feature.get-values <xsl:param> : $(properties) ]
108
+ {
109
+ local namevalue = [ regex.split $(param) "=" ] ;
110
+ flags += --stringparam $(namevalue[1]) \"$(namevalue[2])\" ;
111
+ }
112
+
113
+ # Translate <xsl:path>.
114
+ for local path in [ feature.get-values <xsl:path> : $(properties) ]
115
+ {
116
+ flags += --path \"$(path:G=)\" ;
117
+ }
118
+
119
+ # Take care of implicit dependencies.
120
+ local other-deps ;
121
+ for local dep in [ feature.get-values <implicit-dependency> : $(properties) ]
122
+ {
123
+ other-deps += [ $(dep:G=).creating-subvariant ] ;
124
+ }
125
+
126
+ local implicit-target-directories ;
127
+ for local dep in [ sequence.unique $(other-deps) ]
128
+ {
129
+ implicit-target-directories += [ $(dep).all-target-directories ] ;
130
+ }
131
+
132
+ for local dir in $(implicit-target-directories)
133
+ {
134
+ flags += --path \"$(dir:T)\" ;
135
+ }
136
+
137
+ return $(flags) ;
138
+ }
139
+
140
+
141
+ local rule .xsltproc ( target : source stylesheet : properties * : dirname ? : action )
142
+ {
143
+ freeze-config ;
144
+ STYLESHEET on $(target) = $(stylesheet) ;
145
+ FLAGS on $(target) += [ compute-xslt-flags $(target) : $(properties) ] ;
146
+ NAME on $(target) = $(.xsltproc) ;
147
+
148
+ for local catalog in [ feature.get-values <catalog> : $(properties) ]
149
+ {
150
+ CATALOG = [ common.variable-setting-command XML_CATALOG_FILES : $(catalog:T) ] ;
151
+ }
152
+
153
+ if [ os.on-windows ] && ! [ is-cygwin ]
154
+ {
155
+ action = $(action).windows ;
156
+ }
157
+
158
+ $(action) $(target) : $(source) ;
159
+ }
160
+
161
+
162
+ rule xslt ( target : source stylesheet : properties * )
163
+ {
164
+ return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) : : xslt-xsltproc ] ;
165
+ }
166
+
167
+
168
+ rule xslt-dir ( target : source stylesheet : properties * : dirname )
169
+ {
170
+ return [ .xsltproc $(target) : $(source) $(stylesheet) : $(properties) : $(dirname) : xslt-xsltproc-dir ] ;
171
+ }
172
+
173
+ actions xslt-xsltproc.windows
174
+ {
175
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:W)" "$(>:W)"
176
+ }
177
+
178
+
179
+ actions xslt-xsltproc bind STYLESHEET
180
+ {
181
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<)" "$(STYLESHEET:T)" "$(>:T)"
182
+ }
183
+
184
+
185
+ actions xslt-xsltproc-dir.windows bind STYLESHEET
186
+ {
187
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:W)" "$(>:W)"
188
+ }
189
+
190
+
191
+ actions xslt-xsltproc-dir bind STYLESHEET
192
+ {
193
+ $(CATALOG) "$(NAME:E=xsltproc)" $(FLAGS) --xinclude -o "$(<:D)/" "$(STYLESHEET:T)" "$(>:T)"
194
+ }
mosesdecoder/jam-files/empty_test_main.cc ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ /* Program to verify compilation against the unit test framework */
2
+
3
+ #define BOOST_TEST_MODULE EmptyTest
4
+ #include <boost/test/unit_test.hpp>
5
+
6
+ namespace {
7
+ BOOST_AUTO_TEST_CASE(Empty) {}
8
+ } // namespace
mosesdecoder/jam-files/engine/class.h ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Copyright Vladimir Prus 2003. Distributed under the Boost */
2
+ /* Software License, Version 1.0. (See accompanying */
3
+ /* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) */
4
+
5
+ #ifndef CLASS_H_VP_2003_08_01
6
+ #define CLASS_H_VP_2003_08_01
7
+
8
+ #include "lists.h"
9
+ #include "frames.h"
10
+
11
+ OBJECT * make_class_module( LIST * xname, LIST * bases, FRAME * frame );
12
+ void class_done( void );
13
+
14
+ #endif
mosesdecoder/jam-files/engine/command.c ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 1995 Christopher Seiwald.
3
+ *
4
+ * This file is part of Jam - see jam.c for Copyright information.
5
+ */
6
+
7
+ /* This file is ALSO:
8
+ * Copyright 2001-2004 David Abrahams.
9
+ * Distributed under the Boost Software License, Version 1.0.
10
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11
+ */
12
+
13
+ /*
14
+ * command.c - maintain lists of commands
15
+ */
16
+
17
+ #include "jam.h"
18
+ #include "command.h"
19
+
20
+ #include "lists.h"
21
+ #include "rules.h"
22
+
23
+ #include <assert.h>
24
+
25
+
26
+ /*
27
+ * cmd_new() - return a new CMD.
28
+ */
29
+
30
+ CMD * cmd_new( RULE * rule, LIST * targets, LIST * sources, LIST * shell )
31
+ {
32
+ CMD * cmd = (CMD *)BJAM_MALLOC( sizeof( CMD ) );
33
+ FRAME frame[ 1 ];
34
+
35
+ assert( cmd );
36
+ cmd->rule = rule;
37
+ cmd->shell = shell;
38
+ cmd->next = 0;
39
+ cmd->noop = 0;
40
+
41
+ lol_init( &cmd->args );
42
+ lol_add( &cmd->args, targets );
43
+ lol_add( &cmd->args, sources );
44
+ string_new( cmd->buf );
45
+
46
+ frame_init( frame );
47
+ frame->module = rule->module;
48
+ lol_init( frame->args );
49
+ lol_add( frame->args, list_copy( targets ) );
50
+ lol_add( frame->args, list_copy( sources ) );
51
+ function_run_actions( rule->actions->command, frame, stack_global(),
52
+ cmd->buf );
53
+ frame_free( frame );
54
+
55
+ return cmd;
56
+ }
57
+
58
+
59
+ /*
60
+ * cmd_free() - free a CMD
61
+ */
62
+
63
+ void cmd_free( CMD * cmd )
64
+ {
65
+ lol_free( &cmd->args );
66
+ list_free( cmd->shell );
67
+ string_free( cmd->buf );
68
+ BJAM_FREE( (void *)cmd );
69
+ }
70
+
71
+
72
+ /*
73
+ * cmd_release_targets_and_shell()
74
+ *
75
+ * Makes the CMD release its hold on its targets & shell lists and forget
76
+ * about them. Useful in case caller still has references to those lists and
77
+ * wants to reuse them after freeing the CMD object.
78
+ */
79
+
80
+ void cmd_release_targets_and_shell( CMD * cmd )
81
+ {
82
+ cmd->args.list[ 0 ] = L0; /* targets */
83
+ cmd->shell = L0; /* shell */
84
+ }
mosesdecoder/jam-files/engine/compile.c ADDED
@@ -0,0 +1,271 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 2000 Christopher Seiwald.
3
+ *
4
+ * This file is part of Jam - see jam.c for Copyright information.
5
+ */
6
+
7
+ /* This file is ALSO:
8
+ * Copyright 2001-2004 David Abrahams.
9
+ * Distributed under the Boost Software License, Version 1.0.
10
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11
+ */
12
+
13
+ /*
14
+ * compile.c - compile parsed jam statements
15
+ *
16
+ * External routines:
17
+ * evaluate_rule() - execute a rule invocation
18
+ *
19
+ * Internal routines:
20
+ * debug_compile() - printf with indent to show rule expansion
21
+ */
22
+
23
+ #include "jam.h"
24
+ #include "compile.h"
25
+
26
+ #include "builtins.h"
27
+ #include "class.h"
28
+ #include "constants.h"
29
+ #include "hash.h"
30
+ #include "hdrmacro.h"
31
+ #include "make.h"
32
+ #include "modules.h"
33
+ #include "parse.h"
34
+ #include "rules.h"
35
+ #include "search.h"
36
+ #include "strings.h"
37
+ #include "variable.h"
38
+
39
+ #include <assert.h>
40
+ #include <stdarg.h>
41
+ #include <string.h>
42
+
43
+
44
+ static void debug_compile( int which, char const * s, FRAME * );
45
+
46
+ /* Internal functions from builtins.c */
47
+ void backtrace( FRAME * );
48
+ void backtrace_line( FRAME * );
49
+ void print_source_line( FRAME * );
50
+ void unknown_rule( FRAME *, char const * key, module_t *, OBJECT * rule_name );
51
+
52
+
53
+ /*
54
+ * evaluate_rule() - execute a rule invocation
55
+ */
56
+
57
+ LIST * evaluate_rule( RULE * rule, OBJECT * rulename, FRAME * frame )
58
+ {
59
+ LIST * result = L0;
60
+ profile_frame prof[ 1 ];
61
+ module_t * prev_module = frame->module;
62
+
63
+ if ( DEBUG_COMPILE )
64
+ {
65
+ /* Try hard to indicate in which module the rule is going to execute. */
66
+ char buf[ 256 ] = "";
67
+ if ( rule->module->name )
68
+ {
69
+ strncat( buf, object_str( rule->module->name ), sizeof( buf ) -
70
+ 1 );
71
+ strncat( buf, ".", sizeof( buf ) - 1 );
72
+ if ( strncmp( buf, object_str( rule->name ), strlen( buf ) ) == 0 )
73
+ {
74
+ buf[ 0 ] = 0;
75
+ }
76
+ }
77
+ strncat( buf, object_str( rule->name ), sizeof( buf ) - 1 );
78
+ debug_compile( 1, buf, frame );
79
+
80
+ lol_print( frame->args );
81
+ printf( "\n" );
82
+ }
83
+
84
+ if ( rule->procedure && rule->module != prev_module )
85
+ {
86
+ /* Propagate current module to nested rule invocations. */
87
+ frame->module = rule->module;
88
+ }
89
+
90
+ /* Record current rule name in frame. */
91
+ if ( rule->procedure )
92
+ {
93
+ frame->rulename = object_str( rulename );
94
+ /* And enter record profile info. */
95
+ if ( DEBUG_PROFILE )
96
+ profile_enter( function_rulename( rule->procedure ), prof );
97
+ }
98
+
99
+ /* Check traditional targets $(<) and sources $(>). */
100
+ if ( !rule->actions && !rule->procedure )
101
+ unknown_rule( frame, NULL, frame->module, rule->name );
102
+
103
+ /* If this rule will be executed for updating the targets then construct the
104
+ * action for make().
105
+ */
106
+ if ( rule->actions )
107
+ {
108
+ TARGETS * t;
109
+
110
+ /* The action is associated with this instance of this rule. */
111
+ ACTION * const action = (ACTION *)BJAM_MALLOC( sizeof( ACTION ) );
112
+ memset( (char *)action, '\0', sizeof( *action ) );
113
+
114
+ action->rule = rule;
115
+ action->targets = targetlist( (TARGETS *)0, lol_get( frame->args, 0 ) );
116
+ action->sources = targetlist( (TARGETS *)0, lol_get( frame->args, 1 ) );
117
+ action->refs = 1;
118
+
119
+ /* If we have a group of targets all being built using the same action
120
+ * then we must not allow any of them to be used as sources unless they
121
+ * are all up to date and their action does not need to be run or their
122
+ * action has had a chance to finish its work and build all of them
123
+ * anew.
124
+ *
125
+ * Without this it might be possible, in case of a multi-process build,
126
+ * for their action, triggered to building one of the targets, to still
127
+ * be running when another target in the group reports as done in order
128
+ * to avoid triggering the same action again and gets used prematurely.
129
+ *
130
+ * As a quick-fix to achieve this effect we make all the targets list
131
+ * each other as 'included targets'. More precisely, we mark the first
132
+ * listed target as including all the other targets in the list and vice
133
+ * versa. This makes anyone depending on any of those targets implicitly
134
+ * depend on all of them, thus making sure none of those targets can be
135
+ * used as sources until all of them have been built. Note that direct
136
+ * dependencies could not have been used due to the 'circular
137
+ * dependency' issue.
138
+ *
139
+ * TODO: Although the current implementation solves the problem of one
140
+ * of the targets getting used before its action completes its work, it
141
+ * also forces the action to run whenever any of the targets in the
142
+ * group is not up to date even though some of them might not actually
143
+ * be used by the targets being built. We should see how we can
144
+ * correctly recognize such cases and use that to avoid running the
145
+ * action if possible and not rebuild targets not actually depending on
146
+ * targets that are not up to date.
147
+ *
148
+ * TODO: Current solution using fake INCLUDES relations may cause
149
+ * actions to be run when the affected targets are built by multiple
150
+ * actions. E.g. if we have the following actions registered in the
151
+ * order specified:
152
+ * (I) builds targets A & B
153
+ * (II) builds target B
154
+ * and we want to build a target depending on target A, then both
155
+ * actions (I) & (II) will be run, even though the second one does not
156
+ * have any direct relationship to target A. Consider whether this is
157
+ * desired behaviour or not. It could be that Boost Build should (or
158
+ * possibly already does) run all actions registered for a given target
159
+ * if any of them needs to be run in which case our INCLUDES relations
160
+ * are not actually causing any actions to be run that would not have
161
+ * been run without them.
162
+ */
163
+ if ( action->targets )
164
+ {
165
+ TARGET * const t0 = action->targets->target;
166
+ for ( t = action->targets->next; t; t = t->next )
167
+ {
168
+ target_include( t->target, t0 );
169
+ target_include( t0, t->target );
170
+ }
171
+ }
172
+
173
+ /* Append this action to the actions of each target. */
174
+ for ( t = action->targets; t; t = t->next )
175
+ t->target->actions = actionlist( t->target->actions, action );
176
+
177
+ action_free( action );
178
+ }
179
+
180
+ /* Now recursively compile any parse tree associated with this rule.
181
+ * function_refer()/function_free() call pair added to ensure the rule does
182
+ * not get freed while in use.
183
+ */
184
+ if ( rule->procedure )
185
+ {
186
+ FUNCTION * const function = rule->procedure;
187
+ function_refer( function );
188
+ result = function_run( function, frame, stack_global() );
189
+ function_free( function );
190
+ }
191
+
192
+ if ( DEBUG_PROFILE && rule->procedure )
193
+ profile_exit( prof );
194
+
195
+ if ( DEBUG_COMPILE )
196
+ debug_compile( -1, 0, frame );
197
+
198
+ return result;
199
+ }
200
+
201
+
202
+ /*
203
+ * Call the given rule with the specified parameters. The parameters should be
204
+ * of type LIST* and end with a NULL pointer. This differs from 'evaluate_rule'
205
+ * in that frame for the called rule is prepared inside 'call_rule'.
206
+ *
207
+ * This function is useful when a builtin rule (in C) wants to call another rule
208
+ * which might be implemented in Jam.
209
+ */
210
+
211
+ LIST * call_rule( OBJECT * rulename, FRAME * caller_frame, ... )
212
+ {
213
+ va_list va;
214
+ LIST * result;
215
+
216
+ FRAME inner[ 1 ];
217
+ frame_init( inner );
218
+ inner->prev = caller_frame;
219
+ inner->prev_user = caller_frame->module->user_module
220
+ ? caller_frame
221
+ : caller_frame->prev_user;
222
+ inner->module = caller_frame->module;
223
+
224
+ va_start( va, caller_frame );
225
+ for ( ; ; )
226
+ {
227
+ LIST * const l = va_arg( va, LIST * );
228
+ if ( !l )
229
+ break;
230
+ lol_add( inner->args, l );
231
+ }
232
+ va_end( va );
233
+
234
+ result = evaluate_rule( bindrule( rulename, inner->module ), rulename, inner );
235
+
236
+ frame_free( inner );
237
+
238
+ return result;
239
+ }
240
+
241
+
242
+ /*
243
+ * debug_compile() - printf with indent to show rule expansion
244
+ */
245
+
246
+ static void debug_compile( int which, char const * s, FRAME * frame )
247
+ {
248
+ static int level = 0;
249
+ static char indent[ 36 ] = ">>>>|>>>>|>>>>|>>>>|>>>>|>>>>|>>>>|";
250
+
251
+ if ( which >= 0 )
252
+ {
253
+ int i;
254
+
255
+ print_source_line( frame );
256
+
257
+ i = ( level + 1 ) * 2;
258
+ while ( i > 35 )
259
+ {
260
+ fputs( indent, stdout );
261
+ i -= 35;
262
+ }
263
+
264
+ printf( "%*.*s ", i, i, indent );
265
+ }
266
+
267
+ if ( s )
268
+ printf( "%s ", s );
269
+
270
+ level += which;
271
+ }
mosesdecoder/jam-files/engine/cwd.h ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2002. Vladimir Prus
3
+ * Distributed under the Boost Software License, Version 1.0.
4
+ * (See accompanying file LICENSE_1_0.txt or copy at
5
+ * http://www.boost.org/LICENSE_1_0.txt)
6
+ */
7
+
8
+ /*
9
+ * cwd.h - manages the current working folder information
10
+ */
11
+
12
+ #ifndef CWD_H
13
+ #define CWD_H
14
+
15
+ #include "object.h"
16
+
17
+
18
+ /* cwd() - returns the current working folder */
19
+ OBJECT * cwd( void );
20
+
21
+ /* cwd_init() - initialize the cwd module functionality
22
+ *
23
+ * The current working folder can not change in Boost Jam so this function
24
+ * gets the current working folder information from the OS and stores it
25
+ * internally.
26
+ *
27
+ * Expected to be called at program startup before the program's current
28
+ * working folder has been changed
29
+ */
30
+ void cwd_init( void );
31
+
32
+ /* cwd_done() - cleans up the cwd module functionality */
33
+ void cwd_done( void );
34
+
35
+ #endif
mosesdecoder/jam-files/engine/debug.c ADDED
@@ -0,0 +1,145 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2005. Rene Rivera
3
+ * Distributed under the Boost Software License, Version 1.0.
4
+ * (See accompanying file LICENSE_1_0.txt or copy at
5
+ * http://www.boost.org/LICENSE_1_0.txt)
6
+ */
7
+
8
+ #include "jam.h"
9
+ #include "debug.h"
10
+
11
+ #include "hash.h"
12
+
13
+
14
+ static profile_frame * profile_stack = 0;
15
+ static struct hash * profile_hash = 0;
16
+ static profile_info profile_other = { 0 };
17
+ static profile_info profile_total = { 0 };
18
+
19
+
20
+ profile_frame * profile_init( OBJECT * rulename, profile_frame * frame )
21
+ {
22
+ if ( DEBUG_PROFILE ) profile_enter( rulename, frame );
23
+ return frame;
24
+ }
25
+
26
+
27
+ void profile_enter( OBJECT * rulename, profile_frame * frame )
28
+ {
29
+ if ( DEBUG_PROFILE )
30
+ {
31
+ clock_t start = clock();
32
+ profile_info * p;
33
+
34
+ if ( !profile_hash && rulename )
35
+ profile_hash = hashinit( sizeof( profile_info ), "profile" );
36
+
37
+ if ( rulename )
38
+ {
39
+ int found;
40
+ p = (profile_info *)hash_insert( profile_hash, rulename, &found );
41
+ if ( !found )
42
+ {
43
+ p->name = rulename;
44
+ p->cumulative = 0;
45
+ p->net = 0;
46
+ p->num_entries = 0;
47
+ p->stack_count = 0;
48
+ p->memory = 0;
49
+ }
50
+ }
51
+ else
52
+ {
53
+ p = &profile_other;
54
+ }
55
+
56
+ ++p->num_entries;
57
+ ++p->stack_count;
58
+
59
+ frame->info = p;
60
+
61
+ frame->caller = profile_stack;
62
+ profile_stack = frame;
63
+
64
+ frame->entry_time = clock();
65
+ frame->overhead = 0;
66
+ frame->subrules = 0;
67
+
68
+ /* caller pays for the time it takes to play with the hash table */
69
+ if ( frame->caller )
70
+ frame->caller->overhead += frame->entry_time - start;
71
+ }
72
+ }
73
+
74
+
75
+ void profile_memory( long mem )
76
+ {
77
+ if ( DEBUG_PROFILE )
78
+ if ( profile_stack && profile_stack->info )
79
+ profile_stack->info->memory += mem;
80
+ }
81
+
82
+
83
+ void profile_exit( profile_frame * frame )
84
+ {
85
+ if ( DEBUG_PROFILE )
86
+ {
87
+ /* Cumulative time for this call. */
88
+ clock_t const t = clock() - frame->entry_time - frame->overhead;
89
+ /* If this rule is already present on the stack, do not add the time for
90
+ * this instance.
91
+ */
92
+ if ( frame->info->stack_count == 1 )
93
+ frame->info->cumulative += t;
94
+ /* Net time does not depend on presense of the same rule in call stack.
95
+ */
96
+ frame->info->net += t - frame->subrules;
97
+
98
+ if ( frame->caller )
99
+ {
100
+ /* Caller's cumulative time must account for this overhead. */
101
+ frame->caller->overhead += frame->overhead;
102
+ frame->caller->subrules += t;
103
+ }
104
+ /* Pop this stack frame. */
105
+ --frame->info->stack_count;
106
+ profile_stack = frame->caller;
107
+ }
108
+ }
109
+
110
+
111
+ static void dump_profile_entry( void * p_, void * ignored )
112
+ {
113
+ profile_info * p = (profile_info *)p_;
114
+ unsigned long mem_each = ( p->memory / ( p->num_entries ? p->num_entries : 1
115
+ ) );
116
+ double cumulative = p->cumulative;
117
+ double net = p->net;
118
+ double q = p->net;
119
+ q /= ( p->num_entries ? p->num_entries : 1 );
120
+ cumulative /= CLOCKS_PER_SEC;
121
+ net /= CLOCKS_PER_SEC;
122
+ q /= CLOCKS_PER_SEC;
123
+ if ( !ignored )
124
+ {
125
+ profile_total.cumulative += p->net;
126
+ profile_total.memory += p->memory;
127
+ }
128
+ printf( "%10ld %12.6f %12.6f %12.8f %10ld %10ld %s\n", p->num_entries,
129
+ cumulative, net, q, p->memory, mem_each, object_str( p->name ) );
130
+ }
131
+
132
+
133
+ void profile_dump()
134
+ {
135
+ if ( profile_hash )
136
+ {
137
+ printf( "%10s %12s %12s %12s %10s %10s %s\n", "--count--", "--gross--",
138
+ "--net--", "--each--", "--mem--", "--each--", "--name--" );
139
+ hashenumerate( profile_hash, dump_profile_entry, 0 );
140
+ profile_other.name = constant_other;
141
+ dump_profile_entry( &profile_other, 0 );
142
+ profile_total.name = constant_total;
143
+ dump_profile_entry( &profile_total, (void *)1 );
144
+ }
145
+ }
mosesdecoder/jam-files/engine/debug.h ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2005. Rene Rivera
3
+ * Distributed under the Boost Software License, Version 1.0.
4
+ * (See accompanying file LICENSE_1_0.txt or copy at
5
+ * http://www.boost.org/LICENSE_1_0.txt)
6
+ */
7
+
8
+ #ifndef BJAM_DEBUG_H
9
+ #define BJAM_DEBUG_H
10
+
11
+ #include "constants.h"
12
+ #include "object.h"
13
+ #include <time.h>
14
+
15
+
16
+ typedef struct profile_info
17
+ {
18
+ /* name of rule being called */
19
+ OBJECT * name;
20
+ /* cumulative time spent in rule */
21
+ clock_t cumulative;
22
+ /* time spent in rule proper */
23
+ clock_t net;
24
+ /* number of time rule was entered */
25
+ unsigned long num_entries;
26
+ /* number of the times this function is present in stack */
27
+ unsigned long stack_count;
28
+ /* bytes of memory allocated by the call */
29
+ unsigned long memory;
30
+ } profile_info;
31
+
32
+ typedef struct profile_frame
33
+ {
34
+ /* permanent storage where data accumulates */
35
+ profile_info * info;
36
+ /* overhead for profiling in this call */
37
+ clock_t overhead;
38
+ /* time of last entry to rule */
39
+ clock_t entry_time;
40
+ /* stack frame of caller */
41
+ struct profile_frame * caller;
42
+ /* time spent in subrules */
43
+ clock_t subrules;
44
+ } profile_frame;
45
+
46
+ profile_frame * profile_init( OBJECT * rulename, profile_frame * );
47
+ void profile_enter( OBJECT * rulename, profile_frame * );
48
+ void profile_memory( long mem );
49
+ void profile_exit( profile_frame * );
50
+ void profile_dump();
51
+
52
+ #define PROFILE_ENTER( scope ) profile_frame PROF_ ## scope, *PROF_ ## scope ## _p = profile_init( constant_ ## scope, &PROF_ ## scope )
53
+ #define PROFILE_EXIT( scope ) profile_exit( PROF_ ## scope ## _p )
54
+
55
+ #endif
mosesdecoder/jam-files/engine/execcmd.c ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 1995 Christopher Seiwald.
3
+ * Copyright 2007 Noel Belcourt.
4
+ *
5
+ * Utility functions shared between different exec*.c platform specific
6
+ * implementation modules.
7
+ *
8
+ * This file is part of Jam - see jam.c for Copyright information.
9
+ */
10
+
11
+ #include "jam.h"
12
+ #include "execcmd.h"
13
+
14
+ #include <assert.h>
15
+ #include <stdio.h>
16
+ #include <string.h>
17
+
18
+
19
+ /* Internal interrupt counter. */
20
+ static int intr;
21
+
22
+
23
+ /* Constructs a list of command-line elements using the format specified by the
24
+ * given shell list.
25
+ *
26
+ * Given argv array should have at least MAXARGC + 1 elements.
27
+ * Slot numbers may be between 0 and 998 (inclusive).
28
+ *
29
+ * Constructed argv list will be zero terminated. Character arrays referenced by
30
+ * the argv structure elements will be either elements from the give shell list,
31
+ * internal static buffers or the given command string and should thus not
32
+ * considered owned by or released via the argv structure and should be
33
+ * considered invalidated by the next argv_from_shell() call.
34
+ *
35
+ * Shell list elements:
36
+ * - Starting with '%' - represent the command string.
37
+ * - Starting with '!' - represent the slot number (increased by one).
38
+ * - Anything else - used as a literal.
39
+ * - If no '%' element is found, the command string is appended as an extra.
40
+ */
41
+
42
+ void argv_from_shell( char const * * argv, LIST * shell, char const * command,
43
+ int const slot )
44
+ {
45
+ static char jobno[ 4 ];
46
+
47
+ int i;
48
+ int gotpercent = 0;
49
+ LISTITER iter = list_begin( shell );
50
+ LISTITER end = list_end( shell );
51
+
52
+ assert( 0 <= slot );
53
+ assert( slot < 999 );
54
+ sprintf( jobno, "%d", slot + 1 );
55
+
56
+ for ( i = 0; iter != end && i < MAXARGC; ++i, iter = list_next( iter ) )
57
+ {
58
+ switch ( object_str( list_item( iter ) )[ 0 ] )
59
+ {
60
+ case '%': argv[ i ] = command; ++gotpercent; break;
61
+ case '!': argv[ i ] = jobno; break;
62
+ default : argv[ i ] = object_str( list_item( iter ) );
63
+ }
64
+ }
65
+
66
+ if ( !gotpercent )
67
+ argv[ i++ ] = command;
68
+
69
+ argv[ i ] = NULL;
70
+ }
71
+
72
+
73
+ /* Returns whether the given command string contains lines longer than the given
74
+ * maximum.
75
+ */
76
+ int check_cmd_for_too_long_lines( char const * command, int const max,
77
+ int * const error_length, int * const error_max_length )
78
+ {
79
+ while ( *command )
80
+ {
81
+ size_t const l = strcspn( command, "\n" );
82
+ if ( l > max )
83
+ {
84
+ *error_length = l;
85
+ *error_max_length = max;
86
+ return EXEC_CHECK_LINE_TOO_LONG;
87
+ }
88
+ command += l;
89
+ if ( *command )
90
+ ++command;
91
+ }
92
+ return EXEC_CHECK_OK;
93
+ }
94
+
95
+
96
+ /* Checks whether the given shell list is actually a request to execute raw
97
+ * commands without an external shell.
98
+ */
99
+ int is_raw_command_request( LIST * shell )
100
+ {
101
+ return !list_empty( shell ) &&
102
+ !strcmp( object_str( list_front( shell ) ), "%" ) &&
103
+ list_next( list_begin( shell ) ) == list_end( shell );
104
+ }
105
+
106
+
107
+ /* Returns whether an interrupt has been detected so far. */
108
+
109
+ int interrupted( void )
110
+ {
111
+ return intr != 0;
112
+ }
113
+
114
+
115
+ /* Internal interrupt handler. */
116
+
117
+ void onintr( int disp )
118
+ {
119
+ ++intr;
120
+ printf( "...interrupted\n" );
121
+ }
mosesdecoder/jam-files/engine/execnt.c ADDED
@@ -0,0 +1,1232 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 1995 Christopher Seiwald.
3
+ *
4
+ * This file is part of Jam - see jam.c for Copyright information.
5
+ */
6
+
7
+ /* This file is ALSO:
8
+ * Copyright 2001-2004 David Abrahams.
9
+ * Copyright 2007 Rene Rivera.
10
+ * Distributed under the Boost Software License, Version 1.0.
11
+ * (See accompanying file LICENSE_1_0.txt or copy at
12
+ * http://www.boost.org/LICENSE_1_0.txt)
13
+ */
14
+
15
+ /*
16
+ * execnt.c - execute a shell command on Windows NT
17
+ *
18
+ * If $(JAMSHELL) is defined, uses that to formulate the actual command. The
19
+ * default is: cmd.exe /Q/C
20
+ *
21
+ * In $(JAMSHELL), % expands to the command string and ! expands to the slot
22
+ * number (starting at 1) for multiprocess (-j) invocations. If $(JAMSHELL) does
23
+ * not include a %, it is tacked on as the last argument.
24
+ *
25
+ * Each $(JAMSHELL) placeholder must be specified as a separate individual
26
+ * element in a jam variable value.
27
+ *
28
+ * Do not just set JAMSHELL to cmd.exe - it will not work!
29
+ *
30
+ * External routines:
31
+ * exec_check() - preprocess and validate the command
32
+ * exec_cmd() - launch an async command execution
33
+ * exec_wait() - wait for any of the async command processes to terminate
34
+ *
35
+ * Internal routines:
36
+ * filetime_to_seconds() - Windows FILETIME --> number of seconds conversion
37
+ */
38
+
39
+ #include "jam.h"
40
+ #ifdef USE_EXECNT
41
+ #include "execcmd.h"
42
+
43
+ #include "lists.h"
44
+ #include "output.h"
45
+ #include "pathsys.h"
46
+ #include "string.h"
47
+
48
+ #include <assert.h>
49
+ #include <ctype.h>
50
+ #include <errno.h>
51
+ #include <time.h>
52
+
53
+ #define WIN32_LEAN_AND_MEAN
54
+ #include <windows.h>
55
+ #include <process.h>
56
+ #include <tlhelp32.h>
57
+
58
+
59
+ /* get the maximum shell command line length according to the OS */
60
+ static int maxline();
61
+ /* valid raw command string length */
62
+ static long raw_command_length( char const * command );
63
+ /* add two 64-bit unsigned numbers, h1l1 and h2l2 */
64
+ static FILETIME add_64(
65
+ unsigned long h1, unsigned long l1,
66
+ unsigned long h2, unsigned long l2 );
67
+ /* */
68
+ static FILETIME add_FILETIME( FILETIME t1, FILETIME t2 );
69
+ /* */
70
+ static FILETIME negate_FILETIME( FILETIME t );
71
+ /* record the timing info for the process */
72
+ static void record_times( HANDLE const, timing_info * const );
73
+ /* calc the current running time of an *active* process */
74
+ static double running_time( HANDLE const );
75
+ /* terminate the given process, after terminating all its children first */
76
+ static void kill_process_tree( DWORD const procesdId, HANDLE const );
77
+ /* waits for a command to complete or time out */
78
+ static int try_wait( int const timeoutMillis );
79
+ /* reads any pending output for running commands */
80
+ static void read_output();
81
+ /* checks if a command ran out of time, and kills it */
82
+ static int try_kill_one();
83
+ /* is the first process a parent (direct or indirect) to the second one */
84
+ static int is_parent_child( DWORD const parent, DWORD const child );
85
+ /* */
86
+ static void close_alert( PROCESS_INFORMATION const * const );
87
+ /* close any alerts hanging around */
88
+ static void close_alerts();
89
+ /* prepare a command file to be executed using an external shell */
90
+ static char const * prepare_command_file( string const * command, int slot );
91
+ /* invoke the actual external process using the given command line */
92
+ static void invoke_cmd( char const * const command, int const slot );
93
+ /* find a free slot in the running commands table */
94
+ static int get_free_cmdtab_slot();
95
+ /* put together the final command string we are to run */
96
+ static void string_new_from_argv( string * result, char const * const * argv );
97
+ /* frees and renews the given string */
98
+ static void string_renew( string * const );
99
+ /* reports the last failed Windows API related error message */
100
+ static void reportWindowsError( char const * const apiName );
101
+ /* closes a Windows HANDLE and resets its variable to 0. */
102
+ static void closeWinHandle( HANDLE * const handle );
103
+
104
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
105
+
106
+ /* CreateProcessA() Windows API places a limit of 32768 characters (bytes) on
107
+ * the allowed command-line length, including a trailing Unicode (2-byte)
108
+ * nul-terminator character.
109
+ */
110
+ #define MAX_RAW_COMMAND_LENGTH 32766
111
+
112
+ /* We hold handles for pipes used to communicate with child processes in two
113
+ * element arrays indexed as follows.
114
+ */
115
+ #define EXECCMD_PIPE_READ 0
116
+ #define EXECCMD_PIPE_WRITE 1
117
+
118
+ static int intr_installed;
119
+
120
+
121
+ /* The list of commands we run. */
122
+ static struct
123
+ {
124
+ /* Temporary command file used to execute the action when needed. */
125
+ string command_file[ 1 ];
126
+
127
+ /* Pipes for communicating with the child process. Parent reads from (0),
128
+ * child writes to (1).
129
+ */
130
+ HANDLE pipe_out[ 2 ];
131
+ HANDLE pipe_err[ 2 ];
132
+
133
+ string buffer_out[ 1 ]; /* buffer to hold stdout, if any */
134
+ string buffer_err[ 1 ]; /* buffer to hold stderr, if any */
135
+
136
+ PROCESS_INFORMATION pi; /* running process information */
137
+
138
+ /* Function called when the command completes. */
139
+ ExecCmdCallback func;
140
+
141
+ /* Opaque data passed back to the 'func' callback. */
142
+ void * closure;
143
+ }
144
+ cmdtab[ MAXJOBS ] = { { 0 } };
145
+
146
+
147
+ /*
148
+ * Execution unit tests.
149
+ */
150
+
151
+ void execnt_unit_test()
152
+ {
153
+ #if !defined( NDEBUG )
154
+ /* vc6 preprocessor is broken, so assert with these strings gets confused.
155
+ * Use a table instead.
156
+ */
157
+ {
158
+ typedef struct test { char * command; int result; } test;
159
+ test tests[] = {
160
+ { "", 0 },
161
+ { " ", 0 },
162
+ { "x", 1 },
163
+ { "\nx", 1 },
164
+ { "x\n", 1 },
165
+ { "\nx\n", 1 },
166
+ { "\nx \n", 2 },
167
+ { "\nx \n ", 2 },
168
+ { " \n\t\t\v\r\r\n \t x \v \t\t\r\n\n\n \n\n\v\t", 8 },
169
+ { "x\ny", -1 },
170
+ { "x\n\n y", -1 },
171
+ { "echo x > foo.bar", -1 },
172
+ { "echo x < foo.bar", -1 },
173
+ { "echo x | foo.bar", -1 },
174
+ { "echo x \">\" foo.bar", 18 },
175
+ { "echo x '<' foo.bar", 18 },
176
+ { "echo x \"|\" foo.bar", 18 },
177
+ { "echo x \\\">\\\" foo.bar", -1 },
178
+ { "echo x \\\"<\\\" foo.bar", -1 },
179
+ { "echo x \\\"|\\\" foo.bar", -1 },
180
+ { "\"echo x > foo.bar\"", 18 },
181
+ { "echo x \"'\"<' foo.bar", -1 },
182
+ { "echo x \\\\\"<\\\\\" foo.bar", 22 },
183
+ { "echo x \\x\\\"<\\\\\" foo.bar", -1 },
184
+ { 0 } };
185
+ test const * t;
186
+ for ( t = tests; t->command; ++t )
187
+ assert( raw_command_length( t->command ) == t->result );
188
+ }
189
+
190
+ {
191
+ int const length = maxline() + 9;
192
+ char * const cmd = (char *)BJAM_MALLOC_ATOMIC( length + 1 );
193
+ memset( cmd, 'x', length );
194
+ cmd[ length ] = 0;
195
+ assert( raw_command_length( cmd ) == length );
196
+ BJAM_FREE( cmd );
197
+ }
198
+ #endif
199
+ }
200
+
201
+
202
+ /*
203
+ * exec_check() - preprocess and validate the command
204
+ */
205
+
206
+ int exec_check
207
+ (
208
+ string const * command,
209
+ LIST * * pShell,
210
+ int * error_length,
211
+ int * error_max_length
212
+ )
213
+ {
214
+ /* Default shell does nothing when triggered with an empty or a
215
+ * whitespace-only command so we simply skip running it in that case. We
216
+ * still pass them on to non-default shells as we do not really know what
217
+ * they are going to do with such commands.
218
+ */
219
+ if ( list_empty( *pShell ) )
220
+ {
221
+ char const * s = command->value;
222
+ while ( isspace( *s ) ) ++s;
223
+ if ( !*s )
224
+ return EXEC_CHECK_NOOP;
225
+ }
226
+
227
+ /* Check prerequisites for executing raw commands. */
228
+ if ( is_raw_command_request( *pShell ) )
229
+ {
230
+ int const raw_cmd_length = raw_command_length( command->value );
231
+ if ( raw_cmd_length < 0 )
232
+ {
233
+ /* Invalid characters detected - fallback to default shell. */
234
+ list_free( *pShell );
235
+ *pShell = L0;
236
+ }
237
+ else if ( raw_cmd_length > MAX_RAW_COMMAND_LENGTH )
238
+ {
239
+ *error_length = raw_cmd_length;
240
+ *error_max_length = MAX_RAW_COMMAND_LENGTH;
241
+ return EXEC_CHECK_TOO_LONG;
242
+ }
243
+ else
244
+ return raw_cmd_length ? EXEC_CHECK_OK : EXEC_CHECK_NOOP;
245
+ }
246
+
247
+ /* Now we know we are using an external shell. Note that there is no need to
248
+ * check for too long command strings when using an external shell since we
249
+ * use a command file and assume no one is going to set up a JAMSHELL format
250
+ * string longer than a few hundred bytes at most which should be well under
251
+ * the total command string limit. Should someone actually construct such a
252
+ * JAMSHELL value it will get reported as an 'invalid parameter'
253
+ * CreateProcessA() Windows API failure which seems like a good enough
254
+ * result for such intentional mischief.
255
+ */
256
+
257
+ /* Check for too long command lines. */
258
+ return check_cmd_for_too_long_lines( command->value, maxline(),
259
+ error_length, error_max_length );
260
+ }
261
+
262
+
263
+ /*
264
+ * exec_cmd() - launch an async command execution
265
+ *
266
+ * We assume exec_check() already verified that the given command can have its
267
+ * command string constructed as requested.
268
+ */
269
+
270
+ void exec_cmd
271
+ (
272
+ string const * cmd_orig,
273
+ ExecCmdCallback func,
274
+ void * closure,
275
+ LIST * shell
276
+ )
277
+ {
278
+ int const slot = get_free_cmdtab_slot();
279
+ int const is_raw_cmd = is_raw_command_request( shell );
280
+ string cmd_local[ 1 ];
281
+
282
+ /* Initialize default shell - anything more than /Q/C is non-portable. */
283
+ static LIST * default_shell;
284
+ if ( !default_shell )
285
+ default_shell = list_new( object_new( "cmd.exe /Q/C" ) );
286
+
287
+ /* Specifying no shell means requesting the default shell. */
288
+ if ( list_empty( shell ) )
289
+ shell = default_shell;
290
+
291
+ if ( DEBUG_EXECCMD )
292
+ if ( is_raw_cmd )
293
+ printf( "Executing raw command directly\n" );
294
+ else
295
+ {
296
+ printf( "Executing using a command file and the shell: " );
297
+ list_print( shell );
298
+ printf( "\n" );
299
+ }
300
+
301
+ /* If we are running a raw command directly - trim its leading whitespaces
302
+ * as well as any trailing all-whitespace lines but keep any trailing
303
+ * whitespace in the final/only line containing something other than
304
+ * whitespace).
305
+ */
306
+ if ( is_raw_cmd )
307
+ {
308
+ char const * start = cmd_orig->value;
309
+ char const * p = cmd_orig->value + cmd_orig->size;
310
+ char const * end = p;
311
+ while ( isspace( *start ) ) ++start;
312
+ while ( p > start && isspace( p[ -1 ] ) )
313
+ if ( *--p == '\n' )
314
+ end = p;
315
+ string_new( cmd_local );
316
+ string_append_range( cmd_local, start, end );
317
+ assert( cmd_local->size == raw_command_length( cmd_orig->value ) );
318
+ }
319
+ /* If we are not running a raw command directly, prepare a command file to
320
+ * be executed using an external shell and the actual command string using
321
+ * that command file.
322
+ */
323
+ else
324
+ {
325
+ char const * const cmd_file = prepare_command_file( cmd_orig, slot );
326
+ char const * argv[ MAXARGC + 1 ]; /* +1 for NULL */
327
+ argv_from_shell( argv, shell, cmd_file, slot );
328
+ string_new_from_argv( cmd_local, argv );
329
+ }
330
+
331
+ /* Catch interrupts whenever commands are running. */
332
+ if ( !intr_installed )
333
+ {
334
+ intr_installed = 1;
335
+ signal( SIGINT, onintr );
336
+ }
337
+
338
+ /* Save input data into the selected running commands table slot. */
339
+ cmdtab[ slot ].func = func;
340
+ cmdtab[ slot ].closure = closure;
341
+
342
+ /* Invoke the actual external process using the constructed command line. */
343
+ invoke_cmd( cmd_local->value, slot );
344
+
345
+ /* Free our local command string copy. */
346
+ string_free( cmd_local );
347
+ }
348
+
349
+
350
+ /*
351
+ * exec_wait() - wait for any of the async command processes to terminate
352
+ *
353
+ * Wait and drive at most one execution completion, while processing the I/O for
354
+ * all ongoing commands.
355
+ */
356
+
357
+ void exec_wait()
358
+ {
359
+ int i = -1;
360
+ int exit_reason; /* reason why a command completed */
361
+
362
+ /* Wait for a command to complete, while snarfing up any output. */
363
+ while ( 1 )
364
+ {
365
+ /* Check for a complete command, briefly. */
366
+ i = try_wait( 500 );
367
+ /* Read in the output of all running commands. */
368
+ read_output();
369
+ /* Close out pending debug style dialogs. */
370
+ close_alerts();
371
+ /* Process the completed command we found. */
372
+ if ( i >= 0 ) { exit_reason = EXIT_OK; break; }
373
+ /* Check if a command ran out of time. */
374
+ i = try_kill_one();
375
+ if ( i >= 0 ) { exit_reason = EXIT_TIMEOUT; break; }
376
+ }
377
+
378
+ /* We have a command... process it. */
379
+ {
380
+ DWORD exit_code;
381
+ timing_info time;
382
+ int rstat;
383
+
384
+ /* The time data for the command. */
385
+ record_times( cmdtab[ i ].pi.hProcess, &time );
386
+
387
+ /* Removed the used temporary command file. */
388
+ if ( cmdtab[ i ].command_file->size )
389
+ unlink( cmdtab[ i ].command_file->value );
390
+
391
+ /* Find out the process exit code. */
392
+ GetExitCodeProcess( cmdtab[ i ].pi.hProcess, &exit_code );
393
+
394
+ /* The dispossition of the command. */
395
+ if ( interrupted() )
396
+ rstat = EXEC_CMD_INTR;
397
+ else if ( exit_code )
398
+ rstat = EXEC_CMD_FAIL;
399
+ else
400
+ rstat = EXEC_CMD_OK;
401
+
402
+ /* Call the callback, may call back to jam rule land. */
403
+ (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time,
404
+ cmdtab[ i ].buffer_out->value, cmdtab[ i ].buffer_err->value,
405
+ exit_reason );
406
+
407
+ /* Clean up our child process tracking data. No need to clear the
408
+ * temporary command file name as it gets reused.
409
+ */
410
+ closeWinHandle( &cmdtab[ i ].pi.hProcess );
411
+ closeWinHandle( &cmdtab[ i ].pi.hThread );
412
+ closeWinHandle( &cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ] );
413
+ closeWinHandle( &cmdtab[ i ].pipe_out[ EXECCMD_PIPE_WRITE ] );
414
+ closeWinHandle( &cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ] );
415
+ closeWinHandle( &cmdtab[ i ].pipe_err[ EXECCMD_PIPE_WRITE ] );
416
+ string_renew( cmdtab[ i ].buffer_out );
417
+ string_renew( cmdtab[ i ].buffer_err );
418
+ }
419
+ }
420
+
421
+
422
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
423
+
424
+ /*
425
+ * Invoke the actual external process using the given command line. Track the
426
+ * process in our running commands table.
427
+ */
428
+
429
+ static void invoke_cmd( char const * const command, int const slot )
430
+ {
431
+ SECURITY_ATTRIBUTES sa = { sizeof( SECURITY_ATTRIBUTES ), 0, 0 };
432
+ SECURITY_DESCRIPTOR sd;
433
+ STARTUPINFO si = { sizeof( STARTUPINFO ), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
434
+ 0, 0, 0, 0, 0, 0 };
435
+
436
+ /* Init the security data. */
437
+ InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION );
438
+ SetSecurityDescriptorDacl( &sd, TRUE, NULL, FALSE );
439
+ sa.lpSecurityDescriptor = &sd;
440
+ sa.bInheritHandle = TRUE;
441
+
442
+ /* Create pipes for communicating with the child process. */
443
+ if ( !CreatePipe( &cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_READ ],
444
+ &cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_WRITE ], &sa, 0 ) )
445
+ {
446
+ reportWindowsError( "CreatePipe" );
447
+ exit( EXITBAD );
448
+ }
449
+ if ( globs.pipe_action && !CreatePipe( &cmdtab[ slot ].pipe_err[
450
+ EXECCMD_PIPE_READ ], &cmdtab[ slot ].pipe_err[ EXECCMD_PIPE_WRITE ],
451
+ &sa, 0 ) )
452
+ {
453
+ reportWindowsError( "CreatePipe" );
454
+ exit( EXITBAD );
455
+ }
456
+
457
+ /* Set handle inheritance off for the pipe ends the parent reads from. */
458
+ SetHandleInformation( cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_READ ],
459
+ HANDLE_FLAG_INHERIT, 0 );
460
+ if ( globs.pipe_action )
461
+ SetHandleInformation( cmdtab[ slot ].pipe_err[ EXECCMD_PIPE_READ ],
462
+ HANDLE_FLAG_INHERIT, 0 );
463
+
464
+ /* Hide the child window, if any. */
465
+ si.dwFlags |= STARTF_USESHOWWINDOW;
466
+ si.wShowWindow = SW_HIDE;
467
+
468
+ /* Redirect the child's output streams to our pipes. */
469
+ si.dwFlags |= STARTF_USESTDHANDLES;
470
+ si.hStdOutput = cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_WRITE ];
471
+ si.hStdError = globs.pipe_action
472
+ ? cmdtab[ slot ].pipe_err[ EXECCMD_PIPE_WRITE ]
473
+ : cmdtab[ slot ].pipe_out[ EXECCMD_PIPE_WRITE ];
474
+
475
+ /* Let the child inherit stdin, as some commands assume it is available. */
476
+ si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
477
+
478
+ /* Create output buffers. */
479
+ string_new( cmdtab[ slot ].buffer_out );
480
+ string_new( cmdtab[ slot ].buffer_err );
481
+
482
+ if ( DEBUG_EXECCMD )
483
+ printf( "Command string for CreateProcessA(): '%s'\n", command );
484
+
485
+ /* Run the command by creating a sub-process for it. */
486
+ if ( !CreateProcessA(
487
+ NULL , /* application name */
488
+ (char *)command , /* command line */
489
+ NULL , /* process attributes */
490
+ NULL , /* thread attributes */
491
+ TRUE , /* inherit handles */
492
+ CREATE_NEW_PROCESS_GROUP, /* create flags */
493
+ NULL , /* env vars, null inherits env */
494
+ NULL , /* current dir, null is our current dir */
495
+ &si , /* startup info */
496
+ &cmdtab[ slot ].pi ) ) /* child process info, if created */
497
+ {
498
+ reportWindowsError( "CreateProcessA" );
499
+ exit( EXITBAD );
500
+ }
501
+ }
502
+
503
+
504
+ /*
505
+ * For more details on Windows cmd.exe shell command-line length limitations see
506
+ * the following MSDN article:
507
+ * http://support.microsoft.com/default.aspx?scid=kb;en-us;830473
508
+ */
509
+
510
+ static int raw_maxline()
511
+ {
512
+ OSVERSIONINFO os_info;
513
+ os_info.dwOSVersionInfoSize = sizeof( os_info );
514
+ GetVersionEx( &os_info );
515
+
516
+ if ( os_info.dwMajorVersion >= 5 ) return 8191; /* XP */
517
+ if ( os_info.dwMajorVersion == 4 ) return 2047; /* NT 4.x */
518
+ return 996; /* NT 3.5.1 */
519
+ }
520
+
521
+ static int maxline()
522
+ {
523
+ static result;
524
+ if ( !result ) result = raw_maxline();
525
+ return result;
526
+ }
527
+
528
+
529
+ /*
530
+ * Closes a Windows HANDLE and resets its variable to 0.
531
+ */
532
+
533
+ static void closeWinHandle( HANDLE * const handle )
534
+ {
535
+ if ( *handle )
536
+ {
537
+ CloseHandle( *handle );
538
+ *handle = 0;
539
+ }
540
+ }
541
+
542
+
543
+ /*
544
+ * Frees and renews the given string.
545
+ */
546
+
547
+ static void string_renew( string * const s )
548
+ {
549
+ string_free( s );
550
+ string_new( s );
551
+ }
552
+
553
+
554
+ /*
555
+ * raw_command_length() - valid raw command string length
556
+ *
557
+ * Checks whether the given command may be executed as a raw command. If yes,
558
+ * returns the corresponding command string length. If not, returns -1.
559
+ *
560
+ * Rules for constructing raw command strings:
561
+ * - Command may not contain unquoted shell I/O redirection characters.
562
+ * - May have at most one command line with non-whitespace content.
563
+ * - Leading whitespace trimmed.
564
+ * - Trailing all-whitespace lines trimmed.
565
+ * - Trailing whitespace on the sole command line kept (may theoretically
566
+ * affect the executed command).
567
+ */
568
+
569
+ static long raw_command_length( char const * command )
570
+ {
571
+ char const * p;
572
+ char const * escape = 0;
573
+ char inquote = 0;
574
+ char const * newline = 0;
575
+
576
+ /* Skip leading whitespace. */
577
+ while ( isspace( *command ) )
578
+ ++command;
579
+
580
+ p = command;
581
+
582
+ /* Look for newlines and unquoted I/O redirection. */
583
+ do
584
+ {
585
+ p += strcspn( p, "\n\"'<>|\\" );
586
+ switch ( *p )
587
+ {
588
+ case '\n':
589
+ /* If our command contains non-whitespace content split over
590
+ * multiple lines we can not execute it directly.
591
+ */
592
+ newline = p;
593
+ while ( isspace( *++p ) );
594
+ if ( *p ) return -1;
595
+ break;
596
+
597
+ case '\\':
598
+ escape = escape && escape == p - 1 ? 0 : p;
599
+ ++p;
600
+ break;
601
+
602
+ case '"':
603
+ case '\'':
604
+ if ( escape && escape == p - 1 )
605
+ escape = 0;
606
+ else if ( inquote == *p )
607
+ inquote = 0;
608
+ else if ( !inquote )
609
+ inquote = *p;
610
+ ++p;
611
+ break;
612
+
613
+ case '<':
614
+ case '>':
615
+ case '|':
616
+ if ( !inquote )
617
+ return -1;
618
+ ++p;
619
+ break;
620
+ }
621
+ }
622
+ while ( *p );
623
+
624
+ /* Return the number of characters the command will occupy. */
625
+ return ( newline ? newline : p ) - command;
626
+ }
627
+
628
+
629
+ /* 64-bit arithmetic helpers. */
630
+
631
+ /* Compute the carry bit from the addition of two 32-bit unsigned numbers. */
632
+ #define add_carry_bit( a, b ) ((((a) | (b)) >> 31) & (~((a) + (b)) >> 31) & 0x1)
633
+
634
+ /* Compute the high 32 bits of the addition of two 64-bit unsigned numbers, h1l1
635
+ * and h2l2.
636
+ */
637
+ #define add_64_hi( h1, l1, h2, l2 ) ((h1) + (h2) + add_carry_bit(l1, l2))
638
+
639
+
640
+ /*
641
+ * Add two 64-bit unsigned numbers, h1l1 and h2l2.
642
+ */
643
+
644
+ static FILETIME add_64
645
+ (
646
+ unsigned long h1, unsigned long l1,
647
+ unsigned long h2, unsigned long l2
648
+ )
649
+ {
650
+ FILETIME result;
651
+ result.dwLowDateTime = l1 + l2;
652
+ result.dwHighDateTime = add_64_hi( h1, l1, h2, l2 );
653
+ return result;
654
+ }
655
+
656
+
657
+ static FILETIME add_FILETIME( FILETIME t1, FILETIME t2 )
658
+ {
659
+ return add_64( t1.dwHighDateTime, t1.dwLowDateTime, t2.dwHighDateTime,
660
+ t2.dwLowDateTime );
661
+ }
662
+
663
+
664
+ static FILETIME negate_FILETIME( FILETIME t )
665
+ {
666
+ /* 2s complement negation */
667
+ return add_64( ~t.dwHighDateTime, ~t.dwLowDateTime, 0, 1 );
668
+ }
669
+
670
+
671
+ /*
672
+ * filetime_to_seconds() - Windows FILETIME --> number of seconds conversion
673
+ */
674
+
675
+ static double filetime_to_seconds( FILETIME const ft )
676
+ {
677
+ return ft.dwHighDateTime * ( (double)( 1UL << 31 ) * 2.0 * 1.0e-7 ) +
678
+ ft.dwLowDateTime * 1.0e-7;
679
+ }
680
+
681
+
682
+ static void record_times( HANDLE const process, timing_info * const time )
683
+ {
684
+ FILETIME creation;
685
+ FILETIME exit;
686
+ FILETIME kernel;
687
+ FILETIME user;
688
+ if ( GetProcessTimes( process, &creation, &exit, &kernel, &user ) )
689
+ {
690
+ time->system = filetime_to_seconds( kernel );
691
+ time->user = filetime_to_seconds( user );
692
+ timestamp_from_filetime( &time->start, &creation );
693
+ timestamp_from_filetime( &time->end, &exit );
694
+ }
695
+ }
696
+
697
+
698
+ #define IO_BUFFER_SIZE ( 16 * 1024 )
699
+
700
+ static char ioBuffer[ IO_BUFFER_SIZE + 1 ];
701
+
702
+
703
+ static void read_pipe
704
+ (
705
+ HANDLE in, /* the pipe to read from */
706
+ string * out
707
+ )
708
+ {
709
+ DWORD bytesInBuffer = 0;
710
+ DWORD bytesAvailable = 0;
711
+
712
+ do
713
+ {
714
+ /* check if we have any data to read */
715
+ if ( !PeekNamedPipe( in, ioBuffer, IO_BUFFER_SIZE, &bytesInBuffer,
716
+ &bytesAvailable, NULL ) )
717
+ bytesAvailable = 0;
718
+
719
+ /* read in the available data */
720
+ if ( bytesAvailable > 0 )
721
+ {
722
+ /* we only read in the available bytes, to avoid blocking */
723
+ if ( ReadFile( in, ioBuffer, bytesAvailable <= IO_BUFFER_SIZE ?
724
+ bytesAvailable : IO_BUFFER_SIZE, &bytesInBuffer, NULL ) )
725
+ {
726
+ if ( bytesInBuffer > 0 )
727
+ {
728
+ /* Clean up some illegal chars. */
729
+ int i;
730
+ for ( i = 0; i < bytesInBuffer; ++i )
731
+ {
732
+ if ( ( (unsigned char)ioBuffer[ i ] < 1 ) )
733
+ ioBuffer[ i ] = '?';
734
+ }
735
+ /* Null, terminate. */
736
+ ioBuffer[ bytesInBuffer ] = '\0';
737
+ /* Append to the output. */
738
+ string_append( out, ioBuffer );
739
+ /* Subtract what we read in. */
740
+ bytesAvailable -= bytesInBuffer;
741
+ }
742
+ else
743
+ {
744
+ /* Likely read a error, bail out. */
745
+ bytesAvailable = 0;
746
+ }
747
+ }
748
+ else
749
+ {
750
+ /* Definitely read a error, bail out. */
751
+ bytesAvailable = 0;
752
+ }
753
+ }
754
+ }
755
+ while ( bytesAvailable > 0 );
756
+ }
757
+
758
+
759
+ static void read_output()
760
+ {
761
+ int i;
762
+ for ( i = 0; i < globs.jobs; ++i )
763
+ if ( cmdtab[ i ].pi.hProcess )
764
+ {
765
+ /* Read stdout data. */
766
+ if ( cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ] )
767
+ read_pipe( cmdtab[ i ].pipe_out[ EXECCMD_PIPE_READ ],
768
+ cmdtab[ i ].buffer_out );
769
+ /* Read stderr data. */
770
+ if ( cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ] )
771
+ read_pipe( cmdtab[ i ].pipe_err[ EXECCMD_PIPE_READ ],
772
+ cmdtab[ i ].buffer_err );
773
+ }
774
+ }
775
+
776
+
777
+ /*
778
+ * Waits for a single child process command to complete, or the timeout,
779
+ * whichever comes first. Returns the index of the completed command in the
780
+ * cmdtab array, or -1.
781
+ */
782
+
783
+ static int try_wait( int const timeoutMillis )
784
+ {
785
+ int i;
786
+ int num_active;
787
+ int wait_api_result;
788
+ HANDLE active_handles[ MAXJOBS ];
789
+ int active_procs[ MAXJOBS ];
790
+
791
+ /* Prepare a list of all active processes to wait for. */
792
+ for ( num_active = 0, i = 0; i < globs.jobs; ++i )
793
+ if ( cmdtab[ i ].pi.hProcess )
794
+ {
795
+ active_handles[ num_active ] = cmdtab[ i ].pi.hProcess;
796
+ active_procs[ num_active ] = i;
797
+ ++num_active;
798
+ }
799
+
800
+ /* Wait for a child to complete, or for our timeout window to expire. */
801
+ wait_api_result = WaitForMultipleObjects( num_active, active_handles,
802
+ FALSE, timeoutMillis );
803
+ if ( ( WAIT_OBJECT_0 <= wait_api_result ) &&
804
+ ( wait_api_result < WAIT_OBJECT_0 + num_active ) )
805
+ {
806
+ /* Terminated process detected - return its index. */
807
+ return active_procs[ wait_api_result - WAIT_OBJECT_0 ];
808
+ }
809
+
810
+ /* Timeout. */
811
+ return -1;
812
+ }
813
+
814
+
815
+ static int try_kill_one()
816
+ {
817
+ /* Only need to check if a timeout was specified with the -l option. */
818
+ if ( globs.timeout > 0 )
819
+ {
820
+ int i;
821
+ for ( i = 0; i < globs.jobs; ++i )
822
+ if ( cmdtab[ i ].pi.hProcess )
823
+ {
824
+ double const t = running_time( cmdtab[ i ].pi.hProcess );
825
+ if ( t > (double)globs.timeout )
826
+ {
827
+ /* The job may have left an alert dialog around, try and get
828
+ * rid of it before killing the job itself.
829
+ */
830
+ close_alert( &cmdtab[ i ].pi );
831
+ /* We have a "runaway" job, kill it. */
832
+ kill_process_tree( cmdtab[ i ].pi.dwProcessId,
833
+ cmdtab[ i ].pi.hProcess );
834
+ /* And return its running commands table slot. */
835
+ return i;
836
+ }
837
+ }
838
+ }
839
+ return -1;
840
+ }
841
+
842
+
843
+ static void close_alerts()
844
+ {
845
+ /* We only attempt this every 5 seconds or so, because it is not a cheap
846
+ * operation, and we will catch the alerts eventually. This check uses
847
+ * floats as some compilers define CLOCKS_PER_SEC as a float or double.
848
+ */
849
+ if ( ( (float)clock() / (float)( CLOCKS_PER_SEC * 5 ) ) < ( 1.0 / 5.0 ) )
850
+ {
851
+ int i;
852
+ for ( i = 0; i < globs.jobs; ++i )
853
+ if ( cmdtab[ i ].pi.hProcess )
854
+ close_alert( &cmdtab[ i ].pi );
855
+ }
856
+ }
857
+
858
+
859
+ /*
860
+ * Calc the current running time of an *active* process.
861
+ */
862
+
863
+ static double running_time( HANDLE const process )
864
+ {
865
+ FILETIME creation;
866
+ FILETIME exit;
867
+ FILETIME kernel;
868
+ FILETIME user;
869
+ if ( GetProcessTimes( process, &creation, &exit, &kernel, &user ) )
870
+ {
871
+ /* Compute the elapsed time. */
872
+ FILETIME current;
873
+ GetSystemTimeAsFileTime( &current );
874
+ return filetime_to_seconds( add_FILETIME( current,
875
+ negate_FILETIME( creation ) ) );
876
+ }
877
+ return 0.0;
878
+ }
879
+
880
+
881
+ /*
882
+ * Not really optimal, or efficient, but it is easier this way, and it is not
883
+ * like we are going to be killing thousands, or even tens of processes.
884
+ */
885
+
886
+ static void kill_process_tree( DWORD const pid, HANDLE const process )
887
+ {
888
+ HANDLE const process_snapshot_h = CreateToolhelp32Snapshot(
889
+ TH32CS_SNAPPROCESS, 0 );
890
+ if ( INVALID_HANDLE_VALUE != process_snapshot_h )
891
+ {
892
+ BOOL ok = TRUE;
893
+ PROCESSENTRY32 pinfo;
894
+ pinfo.dwSize = sizeof( PROCESSENTRY32 );
895
+ for (
896
+ ok = Process32First( process_snapshot_h, &pinfo );
897
+ ok == TRUE;
898
+ ok = Process32Next( process_snapshot_h, &pinfo ) )
899
+ {
900
+ if ( pinfo.th32ParentProcessID == pid )
901
+ {
902
+ /* Found a child, recurse to kill it and anything else below it.
903
+ */
904
+ HANDLE const ph = OpenProcess( PROCESS_ALL_ACCESS, FALSE,
905
+ pinfo.th32ProcessID );
906
+ if ( ph )
907
+ {
908
+ kill_process_tree( pinfo.th32ProcessID, ph );
909
+ CloseHandle( ph );
910
+ }
911
+ }
912
+ }
913
+ CloseHandle( process_snapshot_h );
914
+ }
915
+ /* Now that the children are all dead, kill the root. */
916
+ TerminateProcess( process, -2 );
917
+ }
918
+
919
+
920
+ static double creation_time( HANDLE const process )
921
+ {
922
+ FILETIME creation;
923
+ FILETIME exit;
924
+ FILETIME kernel;
925
+ FILETIME user;
926
+ return GetProcessTimes( process, &creation, &exit, &kernel, &user )
927
+ ? filetime_to_seconds( creation )
928
+ : 0.0;
929
+ }
930
+
931
+
932
+ /*
933
+ * Recursive check if first process is parent (directly or indirectly) of the
934
+ * second one. Both processes are passed as process ids, not handles. Special
935
+ * return value 2 means that the second process is smss.exe and its parent
936
+ * process is System (first argument is ignored).
937
+ */
938
+
939
+ static int is_parent_child( DWORD const parent, DWORD const child )
940
+ {
941
+ HANDLE process_snapshot_h = INVALID_HANDLE_VALUE;
942
+
943
+ if ( !child )
944
+ return 0;
945
+ if ( parent == child )
946
+ return 1;
947
+
948
+ process_snapshot_h = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
949
+ if ( INVALID_HANDLE_VALUE != process_snapshot_h )
950
+ {
951
+ BOOL ok = TRUE;
952
+ PROCESSENTRY32 pinfo;
953
+ pinfo.dwSize = sizeof( PROCESSENTRY32 );
954
+ for (
955
+ ok = Process32First( process_snapshot_h, &pinfo );
956
+ ok == TRUE;
957
+ ok = Process32Next( process_snapshot_h, &pinfo ) )
958
+ {
959
+ if ( pinfo.th32ProcessID == child )
960
+ {
961
+ /* Unfortunately, process ids are not really unique. There might
962
+ * be spurious "parent and child" relationship match between two
963
+ * non-related processes if real parent process of a given
964
+ * process has exited (while child process kept running as an
965
+ * "orphan") and the process id of such parent process has been
966
+ * reused by internals of the operating system when creating
967
+ * another process.
968
+ *
969
+ * Thus an additional check is needed - process creation time.
970
+ * This check may fail (i.e. return 0) for system processes due
971
+ * to insufficient privileges, and that is OK.
972
+ */
973
+ double tchild = 0.0;
974
+ double tparent = 0.0;
975
+ HANDLE const hchild = OpenProcess( PROCESS_QUERY_INFORMATION,
976
+ FALSE, pinfo.th32ProcessID );
977
+ CloseHandle( process_snapshot_h );
978
+
979
+ /* csrss.exe may display message box like following:
980
+ * xyz.exe - Unable To Locate Component
981
+ * This application has failed to start because
982
+ * boost_foo-bar.dll was not found. Re-installing the
983
+ * application may fix the problem
984
+ * This actually happens when starting a test process that
985
+ * depends on a dynamic library which failed to build. We want
986
+ * to automatically close these message boxes even though
987
+ * csrss.exe is not our child process. We may depend on the fact
988
+ * that (in all current versions of Windows) csrss.exe is a
989
+ * direct child of the smss.exe process, which in turn is a
990
+ * direct child of the System process, which always has process
991
+ * id == 4. This check must be performed before comparing
992
+ * process creation times.
993
+ */
994
+ if ( !stricmp( pinfo.szExeFile, "csrss.exe" ) &&
995
+ is_parent_child( parent, pinfo.th32ParentProcessID ) == 2 )
996
+ return 1;
997
+ if ( !stricmp( pinfo.szExeFile, "smss.exe" ) &&
998
+ ( pinfo.th32ParentProcessID == 4 ) )
999
+ return 2;
1000
+
1001
+ if ( hchild )
1002
+ {
1003
+ HANDLE hparent = OpenProcess( PROCESS_QUERY_INFORMATION,
1004
+ FALSE, pinfo.th32ParentProcessID );
1005
+ if ( hparent )
1006
+ {
1007
+ tchild = creation_time( hchild );
1008
+ tparent = creation_time( hparent );
1009
+ CloseHandle( hparent );
1010
+ }
1011
+ CloseHandle( hchild );
1012
+ }
1013
+
1014
+ /* Return 0 if one of the following is true:
1015
+ * 1. we failed to read process creation time
1016
+ * 2. child was created before alleged parent
1017
+ */
1018
+ if ( ( tchild == 0.0 ) || ( tparent == 0.0 ) ||
1019
+ ( tchild < tparent ) )
1020
+ return 0;
1021
+
1022
+ return is_parent_child( parent, pinfo.th32ParentProcessID ) & 1;
1023
+ }
1024
+ }
1025
+
1026
+ CloseHandle( process_snapshot_h );
1027
+ }
1028
+
1029
+ return 0;
1030
+ }
1031
+
1032
+
1033
+ /*
1034
+ * Called by the OS for each topmost window.
1035
+ */
1036
+
1037
+ BOOL CALLBACK close_alert_window_enum( HWND hwnd, LPARAM lParam )
1038
+ {
1039
+ char buf[ 7 ] = { 0 };
1040
+ PROCESS_INFORMATION const * const pi = (PROCESS_INFORMATION *)lParam;
1041
+ DWORD pid;
1042
+ DWORD tid;
1043
+
1044
+ /* We want to find and close any window that:
1045
+ * 1. is visible and
1046
+ * 2. is a dialog and
1047
+ * 3. is displayed by any of our child processes
1048
+ */
1049
+ if (
1050
+ /* We assume hidden windows do not require user interaction. */
1051
+ !IsWindowVisible( hwnd )
1052
+ /* Failed to read class name; presume it is not a dialog. */
1053
+ || !GetClassNameA( hwnd, buf, sizeof( buf ) )
1054
+ /* All Windows system dialogs use the same Window class name. */
1055
+ || strcmp( buf, "#32770" ) )
1056
+ return TRUE;
1057
+
1058
+ /* GetWindowThreadProcessId() returns 0 on error, otherwise thread id of
1059
+ * the window's message pump thread.
1060
+ */
1061
+ tid = GetWindowThreadProcessId( hwnd, &pid );
1062
+ if ( !tid || !is_parent_child( pi->dwProcessId, pid ) )
1063
+ return TRUE;
1064
+
1065
+ /* Ask real nice. */
1066
+ PostMessageA( hwnd, WM_CLOSE, 0, 0 );
1067
+
1068
+ /* Wait and see if it worked. If not, insist. */
1069
+ if ( WaitForSingleObject( pi->hProcess, 200 ) == WAIT_TIMEOUT )
1070
+ {
1071
+ PostThreadMessageA( tid, WM_QUIT, 0, 0 );
1072
+ WaitForSingleObject( pi->hProcess, 300 );
1073
+ }
1074
+
1075
+ /* Done, we do not want to check any other windows now. */
1076
+ return FALSE;
1077
+ }
1078
+
1079
+
1080
+ static void close_alert( PROCESS_INFORMATION const * const pi )
1081
+ {
1082
+ EnumWindows( &close_alert_window_enum, (LPARAM)pi );
1083
+ }
1084
+
1085
+
1086
+ /*
1087
+ * Open a command file to store the command into for executing using an external
1088
+ * shell. Returns a pointer to a FILE open for writing or 0 in case such a file
1089
+ * could not be opened. The file name used is stored back in the corresponding
1090
+ * running commands table slot.
1091
+ *
1092
+ * Expects the running commands table slot's command_file attribute to contain
1093
+ * either a zeroed out string object or one prepared previously by this same
1094
+ * function.
1095
+ */
1096
+
1097
+ static FILE * open_command_file( int const slot )
1098
+ {
1099
+ string * const command_file = cmdtab[ slot ].command_file;
1100
+
1101
+ /* If the temporary command file name has not already been prepared for this
1102
+ * slot number, prepare a new one containing a '##' place holder that will
1103
+ * be changed later and needs to be located at a fixed distance from the
1104
+ * end.
1105
+ */
1106
+ if ( !command_file->value )
1107
+ {
1108
+ DWORD const procID = GetCurrentProcessId();
1109
+ string const * const tmpdir = path_tmpdir();
1110
+ string_new( command_file );
1111
+ string_reserve( command_file, tmpdir->size + 64 );
1112
+ command_file->size = sprintf( command_file->value,
1113
+ "%s\\jam%d-%02d-##.bat", tmpdir->value, procID, slot );
1114
+ }
1115
+
1116
+ /* For some reason opening a command file can fail intermittently. But doing
1117
+ * some retries works. Most likely this is due to a previously existing file
1118
+ * of the same name that happens to still be opened by an active virus
1119
+ * scanner. Originally pointed out and fixed by Bronek Kozicki.
1120
+ *
1121
+ * We first try to open several differently named files to avoid having to
1122
+ * wait idly if not absolutely necessary. Our temporary command file names
1123
+ * contain a fixed position place holder we use for generating different
1124
+ * file names.
1125
+ */
1126
+ {
1127
+ char * const index1 = command_file->value + command_file->size - 6;
1128
+ char * const index2 = index1 + 1;
1129
+ int waits_remaining;
1130
+ assert( command_file->value < index1 );
1131
+ assert( index2 + 1 < command_file->value + command_file->size );
1132
+ assert( index2[ 1 ] == '.' );
1133
+ for ( waits_remaining = 3; ; --waits_remaining )
1134
+ {
1135
+ int index;
1136
+ for ( index = 0; index != 20; ++index )
1137
+ {
1138
+ FILE * f;
1139
+ *index1 = '0' + index / 10;
1140
+ *index2 = '0' + index % 10;
1141
+ f = fopen( command_file->value, "w" );
1142
+ if ( f ) return f;
1143
+ }
1144
+ if ( !waits_remaining ) break;
1145
+ Sleep( 250 );
1146
+ }
1147
+ }
1148
+
1149
+ return 0;
1150
+ }
1151
+
1152
+
1153
+ /*
1154
+ * Prepare a command file to be executed using an external shell.
1155
+ */
1156
+
1157
+ static char const * prepare_command_file( string const * command, int slot )
1158
+ {
1159
+ FILE * const f = open_command_file( slot );
1160
+ if ( !f )
1161
+ {
1162
+ printf( "failed to write command file!\n" );
1163
+ exit( EXITBAD );
1164
+ }
1165
+ fputs( command->value, f );
1166
+ fclose( f );
1167
+ return cmdtab[ slot ].command_file->value;
1168
+ }
1169
+
1170
+
1171
+ /*
1172
+ * Find a free slot in the running commands table.
1173
+ */
1174
+
1175
+ static int get_free_cmdtab_slot()
1176
+ {
1177
+ int slot;
1178
+ for ( slot = 0; slot < MAXJOBS; ++slot )
1179
+ if ( !cmdtab[ slot ].pi.hProcess )
1180
+ return slot;
1181
+ printf( "no slots for child!\n" );
1182
+ exit( EXITBAD );
1183
+ }
1184
+
1185
+
1186
+ /*
1187
+ * Put together the final command string we are to run.
1188
+ */
1189
+
1190
+ static void string_new_from_argv( string * result, char const * const * argv )
1191
+ {
1192
+ assert( argv );
1193
+ assert( argv[ 0 ] );
1194
+ string_copy( result, *(argv++) );
1195
+ while ( *argv )
1196
+ {
1197
+ string_push_back( result, ' ' );
1198
+ string_append( result, *(argv++) );
1199
+ }
1200
+ }
1201
+
1202
+
1203
+ /*
1204
+ * Reports the last failed Windows API related error message.
1205
+ */
1206
+
1207
+ static void reportWindowsError( char const * const apiName )
1208
+ {
1209
+ char * errorMessage;
1210
+ DWORD const errorCode = GetLastError();
1211
+ DWORD apiResult = FormatMessageA(
1212
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | /* __in DWORD dwFlags */
1213
+ FORMAT_MESSAGE_FROM_SYSTEM |
1214
+ FORMAT_MESSAGE_IGNORE_INSERTS,
1215
+ NULL, /* __in_opt LPCVOID lpSource */
1216
+ errorCode, /* __in DWORD dwMessageId */
1217
+ 0, /* __in DWORD dwLanguageId */
1218
+ (LPSTR)&errorMessage, /* __out LPTSTR lpBuffer */
1219
+ 0, /* __in DWORD nSize */
1220
+ 0 ); /* __in_opt va_list * Arguments */
1221
+ if ( !apiResult )
1222
+ printf( "%s() Windows API failed: %d.\n", apiName, errorCode );
1223
+ else
1224
+ {
1225
+ printf( "%s() Windows API failed: %d - %s\n", apiName, errorCode,
1226
+ errorMessage );
1227
+ LocalFree( errorMessage );
1228
+ }
1229
+ }
1230
+
1231
+
1232
+ #endif /* USE_EXECNT */
mosesdecoder/jam-files/engine/execunix.c ADDED
@@ -0,0 +1,559 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 1995 Christopher Seiwald.
3
+ * Copyright 2007 Noel Belcourt.
4
+ *
5
+ * This file is part of Jam - see jam.c for Copyright information.
6
+ */
7
+
8
+ #include "jam.h"
9
+ #include "execcmd.h"
10
+
11
+ #include "lists.h"
12
+ #include "output.h"
13
+ #include "strings.h"
14
+
15
+ #include <errno.h>
16
+ #include <signal.h>
17
+ #include <stdio.h>
18
+ #include <time.h>
19
+ #include <unistd.h> /* vfork(), _exit(), STDOUT_FILENO and such */
20
+ #include <sys/resource.h>
21
+ #include <sys/times.h>
22
+ #include <sys/wait.h>
23
+
24
+ #if defined(sun) || defined(__sun)
25
+ #include <wait.h>
26
+ #endif
27
+
28
+ #ifdef USE_EXECUNIX
29
+
30
+ #include <sys/times.h>
31
+
32
+ #if defined(__APPLE__)
33
+ #define NO_VFORK
34
+ #endif
35
+
36
+ #ifdef NO_VFORK
37
+ #define vfork() fork()
38
+ #endif
39
+
40
+
41
+ /*
42
+ * execunix.c - execute a shell script on UNIX/OS2/AmigaOS
43
+ *
44
+ * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp(). The
45
+ * default is: /bin/sh -c
46
+ *
47
+ * In $(JAMSHELL), % expands to the command string and ! expands to the slot
48
+ * number (starting at 1) for multiprocess (-j) invocations. If $(JAMSHELL) does
49
+ * not include a %, it is tacked on as the last argument.
50
+ *
51
+ * Each word must be an individual element in a jam variable value.
52
+ *
53
+ * Do not just set JAMSHELL to /bin/sh - it will not work!
54
+ *
55
+ * External routines:
56
+ * exec_check() - preprocess and validate the command.
57
+ * exec_cmd() - launch an async command execution.
58
+ * exec_wait() - wait for any of the async command processes to terminate.
59
+ */
60
+
61
+ /* find a free slot in the running commands table */
62
+ static int get_free_cmdtab_slot();
63
+
64
+ /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
65
+
66
+ static clock_t tps;
67
+ static int old_time_initialized;
68
+ static struct tms old_time;
69
+
70
+ /* We hold stdout & stderr child process information in two element arrays
71
+ * indexed as follows.
72
+ */
73
+ #define OUT 0
74
+ #define ERR 1
75
+
76
+ static struct
77
+ {
78
+ int pid; /* on win32, a real process handle */
79
+ int fd[ 2 ]; /* file descriptors for stdout and stderr */
80
+ FILE * stream[ 2 ]; /* child's stdout and stderr file streams */
81
+ clock_t start_time; /* start time of child process */
82
+ int exit_reason; /* termination status */
83
+ char * buffer[ 2 ]; /* buffers to hold stdout and stderr, if any */
84
+ int buf_size[ 2 ]; /* buffer sizes in bytes */
85
+ timestamp start_dt; /* start of command timestamp */
86
+
87
+ /* Function called when the command completes. */
88
+ ExecCmdCallback func;
89
+
90
+ /* Opaque data passed back to the 'func' callback. */
91
+ void * closure;
92
+ } cmdtab[ MAXJOBS ] = { { 0 } };
93
+
94
+
95
+ /*
96
+ * exec_check() - preprocess and validate the command.
97
+ */
98
+
99
+ int exec_check
100
+ (
101
+ string const * command,
102
+ LIST * * pShell,
103
+ int * error_length,
104
+ int * error_max_length
105
+ )
106
+ {
107
+ int const is_raw_cmd = is_raw_command_request( *pShell );
108
+
109
+ /* We allow empty commands for non-default shells since we do not really
110
+ * know what they are going to do with such commands.
111
+ */
112
+ if ( !command->size && ( is_raw_cmd || list_empty( *pShell ) ) )
113
+ return EXEC_CHECK_NOOP;
114
+
115
+ return is_raw_cmd
116
+ ? EXEC_CHECK_OK
117
+ : check_cmd_for_too_long_lines( command->value, MAXLINE, error_length,
118
+ error_max_length );
119
+ }
120
+
121
+
122
+ /*
123
+ * exec_cmd() - launch an async command execution.
124
+ */
125
+
126
+ /* We hold file descriptors for pipes used to communicate with child processes
127
+ * in two element arrays indexed as follows.
128
+ */
129
+ #define EXECCMD_PIPE_READ 0
130
+ #define EXECCMD_PIPE_WRITE 1
131
+
132
+ void exec_cmd
133
+ (
134
+ string const * command,
135
+ ExecCmdCallback func,
136
+ void * closure,
137
+ LIST * shell
138
+ )
139
+ {
140
+ int const slot = get_free_cmdtab_slot();
141
+ int out[ 2 ];
142
+ int err[ 2 ];
143
+ int len;
144
+ char const * argv[ MAXARGC + 1 ]; /* +1 for NULL */
145
+
146
+ /* Initialize default shell. */
147
+ static LIST * default_shell;
148
+ if ( !default_shell )
149
+ default_shell = list_push_back( list_new(
150
+ object_new( "/bin/sh" ) ),
151
+ object_new( "-c" ) );
152
+
153
+ if ( list_empty( shell ) )
154
+ shell = default_shell;
155
+
156
+ /* Forumulate argv. If shell was defined, be prepared for % and ! subs.
157
+ * Otherwise, use stock /bin/sh.
158
+ */
159
+ argv_from_shell( argv, shell, command->value, slot );
160
+
161
+ if ( DEBUG_EXECCMD )
162
+ {
163
+ int i;
164
+ printf( "Using shell: " );
165
+ list_print( shell );
166
+ printf( "\n" );
167
+ for ( i = 0; argv[ i ]; ++i )
168
+ printf( " argv[%d] = '%s'\n", i, argv[ i ] );
169
+ }
170
+
171
+ /* Create pipes for collecting child output. */
172
+ if ( pipe( out ) < 0 || ( globs.pipe_action && pipe( err ) < 0 ) )
173
+ {
174
+ perror( "pipe" );
175
+ exit( EXITBAD );
176
+ }
177
+
178
+ /* Initialize old_time only once. */
179
+ if ( !old_time_initialized )
180
+ {
181
+ times( &old_time );
182
+ old_time_initialized = 1;
183
+ }
184
+
185
+ /* Start the command */
186
+
187
+ timestamp_current( &cmdtab[ slot ].start_dt );
188
+
189
+ if ( 0 < globs.timeout )
190
+ {
191
+ /* Handle hung processes by manually tracking elapsed time and signal
192
+ * process when time limit expires.
193
+ */
194
+ struct tms buf;
195
+ cmdtab[ slot ].start_time = times( &buf );
196
+
197
+ /* Make a global, only do this once. */
198
+ if ( !tps ) tps = sysconf( _SC_CLK_TCK );
199
+ }
200
+
201
+ /* Child does not need the read pipe ends used by the parent. */
202
+ fcntl( out[ EXECCMD_PIPE_READ ], F_SETFD, FD_CLOEXEC );
203
+ if ( globs.pipe_action )
204
+ fcntl( err[ EXECCMD_PIPE_READ ], F_SETFD, FD_CLOEXEC );
205
+
206
+ if ( ( cmdtab[ slot ].pid = vfork() ) == -1 )
207
+ {
208
+ perror( "vfork" );
209
+ exit( EXITBAD );
210
+ }
211
+
212
+ if ( cmdtab[ slot ].pid == 0 )
213
+ {
214
+ /*****************/
215
+ /* Child process */
216
+ /*****************/
217
+ int const pid = getpid();
218
+
219
+ /* Redirect stdout and stderr to pipes inherited from the parent. */
220
+ dup2( out[ EXECCMD_PIPE_WRITE ], STDOUT_FILENO );
221
+ dup2( globs.pipe_action ? err[ EXECCMD_PIPE_WRITE ] :
222
+ out[ EXECCMD_PIPE_WRITE ], STDERR_FILENO );
223
+ close( out[ EXECCMD_PIPE_WRITE ] );
224
+ if ( globs.pipe_action )
225
+ close( err[ EXECCMD_PIPE_WRITE ] );
226
+
227
+ /* Make this process a process group leader so that when we kill it, all
228
+ * child processes of this process are terminated as well. We use
229
+ * killpg( pid, SIGKILL ) to kill the process group leader and all its
230
+ * children.
231
+ */
232
+ if ( 0 < globs.timeout )
233
+ {
234
+ struct rlimit r_limit;
235
+ r_limit.rlim_cur = globs.timeout;
236
+ r_limit.rlim_max = globs.timeout;
237
+ setrlimit( RLIMIT_CPU, &r_limit );
238
+ }
239
+ setpgid( pid, pid );
240
+ execvp( argv[ 0 ], (char * *)argv );
241
+ perror( "execvp" );
242
+ _exit( 127 );
243
+ }
244
+
245
+ /******************/
246
+ /* Parent process */
247
+ /******************/
248
+ setpgid( cmdtab[ slot ].pid, cmdtab[ slot ].pid );
249
+
250
+ /* Parent not need the write pipe ends used by the child. */
251
+ close( out[ EXECCMD_PIPE_WRITE ] );
252
+ if ( globs.pipe_action )
253
+ close( err[ EXECCMD_PIPE_WRITE ] );
254
+
255
+ /* Set both pipe read file descriptors to non-blocking. */
256
+ fcntl( out[ EXECCMD_PIPE_READ ], F_SETFL, O_NONBLOCK );
257
+ if ( globs.pipe_action )
258
+ fcntl( err[ EXECCMD_PIPE_READ ], F_SETFL, O_NONBLOCK );
259
+
260
+ /* Parent reads from out[ EXECCMD_PIPE_READ ]. */
261
+ cmdtab[ slot ].fd[ OUT ] = out[ EXECCMD_PIPE_READ ];
262
+ cmdtab[ slot ].stream[ OUT ] = fdopen( cmdtab[ slot ].fd[ OUT ], "rb" );
263
+ if ( !cmdtab[ slot ].stream[ OUT ] )
264
+ {
265
+ perror( "fdopen" );
266
+ exit( EXITBAD );
267
+ }
268
+
269
+ /* Parent reads from err[ EXECCMD_PIPE_READ ]. */
270
+ if ( globs.pipe_action )
271
+ {
272
+ cmdtab[ slot ].fd[ ERR ] = err[ EXECCMD_PIPE_READ ];
273
+ cmdtab[ slot ].stream[ ERR ] = fdopen( cmdtab[ slot ].fd[ ERR ], "rb" );
274
+ if ( !cmdtab[ slot ].stream[ ERR ] )
275
+ {
276
+ perror( "fdopen" );
277
+ exit( EXITBAD );
278
+ }
279
+ }
280
+
281
+ /* Save input data into the selected running commands table slot. */
282
+ cmdtab[ slot ].func = func;
283
+ cmdtab[ slot ].closure = closure;
284
+ }
285
+
286
+ #undef EXECCMD_PIPE_READ
287
+ #undef EXECCMD_PIPE_WRITE
288
+
289
+
290
+ /* Returns 1 if file descriptor is closed, or 0 if it is still alive.
291
+ *
292
+ * i is index into cmdtab
293
+ *
294
+ * s (stream) indexes:
295
+ * - cmdtab[ i ].stream[ s ]
296
+ * - cmdtab[ i ].buffer[ s ]
297
+ * - cmdtab[ i ].fd [ s ]
298
+ */
299
+
300
+ static int read_descriptor( int i, int s )
301
+ {
302
+ int ret;
303
+ char buffer[ BUFSIZ ];
304
+
305
+ while ( 0 < ( ret = fread( buffer, sizeof( char ), BUFSIZ - 1,
306
+ cmdtab[ i ].stream[ s ] ) ) )
307
+ {
308
+ buffer[ ret ] = 0;
309
+ if ( !cmdtab[ i ].buffer[ s ] )
310
+ {
311
+ /* Never been allocated. */
312
+ if ( globs.max_buf && ret > globs.max_buf )
313
+ {
314
+ ret = globs.max_buf;
315
+ buffer[ ret ] = 0;
316
+ }
317
+ cmdtab[ i ].buf_size[ s ] = ret + 1;
318
+ cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( ret + 1 );
319
+ memcpy( cmdtab[ i ].buffer[ s ], buffer, ret + 1 );
320
+ }
321
+ else
322
+ {
323
+ /* Previously allocated. */
324
+ if ( cmdtab[ i ].buf_size[ s ] < globs.max_buf || !globs.max_buf )
325
+ {
326
+ char * tmp = cmdtab[ i ].buffer[ s ];
327
+ int const old_len = cmdtab[ i ].buf_size[ s ] - 1;
328
+ int const new_len = old_len + ret + 1;
329
+ cmdtab[ i ].buf_size[ s ] = new_len;
330
+ cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( new_len );
331
+ memcpy( cmdtab[ i ].buffer[ s ], tmp, old_len );
332
+ memcpy( cmdtab[ i ].buffer[ s ] + old_len, buffer, ret + 1 );
333
+ BJAM_FREE( tmp );
334
+ }
335
+ }
336
+ }
337
+
338
+ /* If buffer full, ensure last buffer char is newline so that jam log
339
+ * contains the command status at beginning of it own line instead of
340
+ * appended to end of the previous output.
341
+ */
342
+ if ( globs.max_buf && globs.max_buf <= cmdtab[ i ].buf_size[ s ] )
343
+ cmdtab[ i ].buffer[ s ][ cmdtab[ i ].buf_size[ s ] - 2 ] = '\n';
344
+
345
+ return feof( cmdtab[ i ].stream[ s ] );
346
+ }
347
+
348
+
349
+ /*
350
+ * close_streams() - Close the stream and pipe descriptor.
351
+ */
352
+
353
+ static void close_streams( int const i, int const s )
354
+ {
355
+ fclose( cmdtab[ i ].stream[ s ] );
356
+ cmdtab[ i ].stream[ s ] = 0;
357
+
358
+ close( cmdtab[ i ].fd[ s ] );
359
+ cmdtab[ i ].fd[ s ] = 0;
360
+ }
361
+
362
+
363
+ /*
364
+ * Populate the file descriptors collection for use in select() and return the
365
+ * maximal included file descriptor value.
366
+ */
367
+
368
+ static int populate_file_descriptors( fd_set * const fds )
369
+ {
370
+ int i;
371
+ int fd_max = 0;
372
+
373
+ FD_ZERO( fds );
374
+ for ( i = 0; i < globs.jobs; ++i )
375
+ {
376
+ int fd;
377
+ if ( ( fd = cmdtab[ i ].fd[ OUT ] ) > 0 )
378
+ {
379
+ if ( fd > fd_max ) fd_max = fd;
380
+ FD_SET( fd, fds );
381
+ }
382
+ if ( globs.pipe_action )
383
+ {
384
+ if ( ( fd = cmdtab[ i ].fd[ ERR ] ) > 0 )
385
+ {
386
+ if ( fd > fd_max ) fd_max = fd;
387
+ FD_SET( fd, fds );
388
+ }
389
+ }
390
+ }
391
+ return fd_max;
392
+ }
393
+
394
+
395
+ /*
396
+ * exec_wait() - wait for any of the async command processes to terminate.
397
+ *
398
+ * May register more than one terminated child process but will exit as soon as
399
+ * at least one has been registered.
400
+ */
401
+
402
+ void exec_wait()
403
+ {
404
+ int finished = 0;
405
+
406
+ /* Process children that signaled. */
407
+ while ( !finished )
408
+ {
409
+ int i;
410
+ struct timeval tv;
411
+ struct timeval * ptv = NULL;
412
+ int select_timeout = globs.timeout;
413
+
414
+ /* Prepare file descriptor information for use in select(). */
415
+ fd_set fds;
416
+ int const fd_max = populate_file_descriptors( &fds );
417
+
418
+ /* Check for timeouts:
419
+ * - kill children that already timed out
420
+ * - decide how long until the next one times out
421
+ */
422
+ if ( globs.timeout > 0 )
423
+ {
424
+ struct tms buf;
425
+ clock_t const current = times( &buf );
426
+ for ( i = 0; i < globs.jobs; ++i )
427
+ if ( cmdtab[ i ].pid )
428
+ {
429
+ clock_t const consumed =
430
+ ( current - cmdtab[ i ].start_time ) / tps;
431
+ if ( consumed >= globs.timeout )
432
+ {
433
+ killpg( cmdtab[ i ].pid, SIGKILL );
434
+ cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
435
+ }
436
+ else if ( globs.timeout - consumed < select_timeout )
437
+ select_timeout = globs.timeout - consumed;
438
+ }
439
+
440
+ /* If nothing else causes our select() call to exit, force it after
441
+ * however long it takes for the next one of our child processes to
442
+ * crossed its alloted processing time so we can terminate it.
443
+ */
444
+ tv.tv_sec = select_timeout;
445
+ tv.tv_usec = 0;
446
+ ptv = &tv;
447
+ }
448
+
449
+ /* select() will wait for I/O on a descriptor, a signal, or timeout. */
450
+ {
451
+ int ret;
452
+ while ( ( ret = select( fd_max + 1, &fds, 0, 0, ptv ) ) == -1 )
453
+ if ( errno != EINTR )
454
+ break;
455
+ if ( ret <= 0 )
456
+ continue;
457
+ }
458
+
459
+ for ( i = 0; i < globs.jobs; ++i )
460
+ {
461
+ int out_done = 0;
462
+ int err_done = 0;
463
+ if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) )
464
+ out_done = read_descriptor( i, OUT );
465
+
466
+ if ( globs.pipe_action && FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) )
467
+ err_done = read_descriptor( i, ERR );
468
+
469
+ /* If feof on either descriptor, we are done. */
470
+ if ( out_done || err_done )
471
+ {
472
+ int pid;
473
+ int status;
474
+ int rstat;
475
+ timing_info time_info;
476
+
477
+ /* We found a terminated child process - our search is done. */
478
+ finished = 1;
479
+
480
+ /* Close the stream and pipe descriptors. */
481
+ close_streams( i, OUT );
482
+ if ( globs.pipe_action )
483
+ close_streams( i, ERR );
484
+
485
+ /* Reap the child and release resources. */
486
+ while ( ( pid = waitpid( cmdtab[ i ].pid, &status, 0 ) ) == -1 )
487
+ if ( errno != EINTR )
488
+ break;
489
+ if ( pid != cmdtab[ i ].pid )
490
+ {
491
+ printf( "unknown pid %d with errno = %d\n", pid, errno );
492
+ exit( EXITBAD );
493
+ }
494
+
495
+ /* Set reason for exit if not timed out. */
496
+ if ( WIFEXITED( status ) )
497
+ cmdtab[ i ].exit_reason = WEXITSTATUS( status )
498
+ ? EXIT_FAIL
499
+ : EXIT_OK;
500
+
501
+ {
502
+ struct tms new_time;
503
+ times( &new_time );
504
+ time_info.system = (double)( new_time.tms_cstime -
505
+ old_time.tms_cstime ) / CLOCKS_PER_SEC;
506
+ time_info.user = (double)( new_time.tms_cutime -
507
+ old_time.tms_cutime ) / CLOCKS_PER_SEC;
508
+ timestamp_copy( &time_info.start, &cmdtab[ i ].start_dt );
509
+ timestamp_current( &time_info.end );
510
+ old_time = new_time;
511
+ }
512
+
513
+ /* Drive the completion. */
514
+ if ( interrupted() )
515
+ rstat = EXEC_CMD_INTR;
516
+ else if ( status )
517
+ rstat = EXEC_CMD_FAIL;
518
+ else
519
+ rstat = EXEC_CMD_OK;
520
+
521
+ /* Call the callback, may call back to jam rule land. */
522
+ (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat, &time_info,
523
+ cmdtab[ i ].buffer[ OUT ], cmdtab[ i ].buffer[ ERR ],
524
+ cmdtab[ i ].exit_reason );
525
+
526
+ /* Clean up the command's running commands table slot. */
527
+ BJAM_FREE( cmdtab[ i ].buffer[ OUT ] );
528
+ cmdtab[ i ].buffer[ OUT ] = 0;
529
+ cmdtab[ i ].buf_size[ OUT ] = 0;
530
+
531
+ BJAM_FREE( cmdtab[ i ].buffer[ ERR ] );
532
+ cmdtab[ i ].buffer[ ERR ] = 0;
533
+ cmdtab[ i ].buf_size[ ERR ] = 0;
534
+
535
+ cmdtab[ i ].pid = 0;
536
+ cmdtab[ i ].func = 0;
537
+ cmdtab[ i ].closure = 0;
538
+ cmdtab[ i ].start_time = 0;
539
+ }
540
+ }
541
+ }
542
+ }
543
+
544
+
545
+ /*
546
+ * Find a free slot in the running commands table.
547
+ */
548
+
549
+ static int get_free_cmdtab_slot()
550
+ {
551
+ int slot;
552
+ for ( slot = 0; slot < MAXJOBS; ++slot )
553
+ if ( !cmdtab[ slot ].pid )
554
+ return slot;
555
+ printf( "no slots for child!\n" );
556
+ exit( EXITBAD );
557
+ }
558
+
559
+ # endif /* USE_EXECUNIX */
mosesdecoder/jam-files/engine/filesys.h ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993-2002 Christopher Seiwald and Perforce Software, Inc.
3
+ *
4
+ * This file is part of Jam - see jam.c for Copyright information.
5
+ */
6
+
7
+ /* This file is ALSO:
8
+ * Copyright 2001-2004 David Abrahams.
9
+ * Distributed under the Boost Software License, Version 1.0.
10
+ * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
11
+ */
12
+
13
+ /*
14
+ * filesys.h - OS specific file routines
15
+ */
16
+
17
+ #ifndef FILESYS_DWA20011025_H
18
+ #define FILESYS_DWA20011025_H
19
+
20
+ #include "hash.h"
21
+ #include "lists.h"
22
+ #include "object.h"
23
+ #include "pathsys.h"
24
+ #include "timestamp.h"
25
+
26
+
27
+ typedef struct file_info_t
28
+ {
29
+ OBJECT * name;
30
+ char is_file;
31
+ char is_dir;
32
+ char exists;
33
+ timestamp time;
34
+ LIST * files;
35
+ } file_info_t;
36
+
37
+ typedef void (*scanback)( void * closure, OBJECT * path, int found,
38
+ timestamp const * const );
39
+
40
+
41
+ void file_build1( PATHNAME * const f, string * file ) ;
42
+ void file_dirscan( OBJECT * dir, scanback func, void * closure );
43
+ file_info_t * file_info( OBJECT * const path, int * found );
44
+ int file_is_file( OBJECT * const path );
45
+ int file_mkdir( char const * const path );
46
+ file_info_t * file_query( OBJECT * const path );
47
+ void file_remove_atexit( OBJECT * const path );
48
+ void file_supported_fmt_resolution( timestamp * const );
49
+ int file_time( OBJECT * const path, timestamp * const );
50
+
51
+ /* Internal utility worker functions. */
52
+ void file_query_posix_( file_info_t * const );
53
+
54
+ void file_done();
55
+
56
+ #endif
mosesdecoder/jam-files/engine/frames.h ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 2001-2004 David Abrahams.
3
+ * Distributed under the Boost Software License, Version 1.0.
4
+ * (See accompanying file LICENSE_1_0.txt or copy at
5
+ * http://www.boost.org/LICENSE_1_0.txt)
6
+ */
7
+
8
+ #ifndef FRAMES_DWA20011021_H
9
+ #define FRAMES_DWA20011021_H
10
+
11
+ #include "lists.h"
12
+ #include "modules.h"
13
+ #include "object.h"
14
+
15
+
16
+ typedef struct frame FRAME;
17
+
18
+ struct frame
19
+ {
20
+ FRAME * prev;
21
+ FRAME * prev_user; /* The nearest enclosing frame for which
22
+ module->user_module is true. */
23
+ LOL args[ 1 ];
24
+ module_t * module;
25
+ OBJECT * file;
26
+ int line;
27
+ char const * rulename;
28
+ };
29
+
30
+
31
+ /* When a call into Python is in progress, this variable points to the bjam
32
+ * frame that was current at the moment of the call. When the call completes,
33
+ * the variable is not defined. Furthermore, if Jam calls Python which calls Jam
34
+ * and so on, this variable only keeps the most recent Jam frame.
35
+ */
36
+ extern FRAME * frame_before_python_call;
37
+
38
+
39
+ void frame_init( FRAME * );
40
+ void frame_free( FRAME * );
41
+
42
+ #endif
mosesdecoder/jam-files/engine/hash.c ADDED
@@ -0,0 +1,387 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ * Copyright 1993, 1995 Christopher Seiwald.
3
+ *
4
+ * This file is part of Jam - see jam.c for Copyright information.
5
+ */
6
+
7
+ /*
8
+ * hash.c - simple in-memory hashing routines
9
+ *
10
+ * External routines:
11
+ * hashinit() - initialize a hash table, returning a handle
12
+ * hashitem() - find a record in the table, and optionally enter a new one
13
+ * hashdone() - free a hash table, given its handle
14
+ *
15
+ * Internal routines:
16
+ * hashrehash() - resize and rebuild hp->tab, the hash table
17
+ */
18
+
19
+ #include "jam.h"
20
+ #include "hash.h"
21
+
22
+ #include "compile.h"
23
+
24
+ #include <assert.h>
25
+
26
+ /* */
27
+ #define HASH_DEBUG_PROFILE 1
28
+ /* */
29
+
30
+ /* Header attached to all hash table data items. */
31
+
32
+ typedef struct item ITEM;
33
+ struct item
34
+ {
35
+ ITEM * next;
36
+ };
37
+
38
+ #define MAX_LISTS 32
39
+
40
+ struct hash
41
+ {
42
+ /*
43
+ * the hash table, just an array of item pointers
44
+ */
45
+ struct
46
+ {
47
+ int nel;
48
+ ITEM * * base;
49
+ } tab;
50
+
51
+ int bloat; /* tab.nel / items.nel */
52
+ int inel; /* initial number of elements */
53
+
54
+ /*
55
+ * the array of records, maintained by these routines - essentially a
56
+ * microallocator
57
+ */
58
+ struct
59
+ {
60
+ int more; /* how many more ITEMs fit in lists[ list ] */
61
+ ITEM * free; /* free list of items */
62
+ char * next; /* where to put more ITEMs in lists[ list ] */
63
+ int size; /* sizeof( ITEM ) + aligned datalen */
64
+ int nel; /* total ITEMs held by all lists[] */
65
+ int list; /* index into lists[] */
66
+
67
+ struct
68
+ {
69
+ int nel; /* total ITEMs held by this list */
70
+ char * base; /* base of ITEMs array */
71
+ } lists[ MAX_LISTS ];
72
+ } items;
73
+
74
+ char const * name; /* just for hashstats() */
75
+ };
76
+
77
+ static void hashrehash( struct hash * );
78
+ static void hashstat( struct hash * );
79
+
80
+ static unsigned int hash_keyval( OBJECT * key )
81
+ {
82
+ return object_hash( key );
83
+ }
84
+
85
+ #define hash_bucket(hp, keyval) ((hp)->tab.base + ((keyval) % (hp)->tab.nel))
86
+
87
+ #define hash_data_key(data) (*(OBJECT * *)(data))
88
+ #define hash_item_data(item) ((HASHDATA *)((char *)item + sizeof(ITEM)))
89
+ #define hash_item_key(item) (hash_data_key(hash_item_data(item)))
90
+
91
+
92
+ #define ALIGNED(x) ((x + sizeof(ITEM) - 1) & ~(sizeof(ITEM) - 1))
93
+
94
+ /*
95
+ * hashinit() - initialize a hash table, returning a handle
96
+ */
97
+
98
+ struct hash * hashinit( int datalen, char const * name )
99
+ {
100
+ struct hash * hp = (struct hash *)BJAM_MALLOC( sizeof( *hp ) );
101
+
102
+ hp->bloat = 3;
103
+ hp->tab.nel = 0;
104
+ hp->tab.base = 0;
105
+ hp->items.more = 0;
106
+ hp->items.free = 0;
107
+ hp->items.size = sizeof( ITEM ) + ALIGNED( datalen );
108
+ hp->items.list = -1;
109
+ hp->items.nel = 0;
110
+ hp->inel = 11; /* 47 */
111
+ hp->name = name;
112
+
113
+ return hp;
114
+ }
115
+
116
+
117
+ /*
118
+ * hash_search() - Find the hash item for the given data.
119
+ *
120
+ * Returns a pointer to a hashed item with the given key. If given a 'previous'
121
+ * pointer, makes it point to the item prior to the found item in the same
122
+ * bucket or to 0 if our item is the first item in its bucket.
123
+ */
124
+
125
+ static ITEM * hash_search( struct hash * hp, unsigned int keyval,
126
+ OBJECT * keydata, ITEM * * previous )
127
+ {
128
+ ITEM * i = *hash_bucket( hp, keyval );
129
+ ITEM * p = 0;
130
+ for ( ; i; i = i->next )
131
+ {
132
+ if ( object_equal( hash_item_key( i ), keydata ) )
133
+ {
134
+ if ( previous )
135
+ *previous = p;
136
+ return i;
137
+ }
138
+ p = i;
139
+ }
140
+ return 0;
141
+ }
142
+
143
+
144
+ /*
145
+ * hash_insert() - insert a record in the table or return the existing one
146
+ */
147
+
148
+ HASHDATA * hash_insert( struct hash * hp, OBJECT * key, int * found )
149
+ {
150
+ ITEM * i;
151
+ unsigned int keyval = hash_keyval( key );
152
+
153
+ #ifdef HASH_DEBUG_PROFILE
154
+ profile_frame prof[ 1 ];
155
+ if ( DEBUG_PROFILE )
156
+ profile_enter( 0, prof );
157
+ #endif
158
+
159
+ if ( !hp->items.more )
160
+ hashrehash( hp );
161
+
162
+ i = hash_search( hp, keyval, key, 0 );
163
+ if ( i )
164
+ *found = 1;
165
+ else
166
+ {
167
+ ITEM * * base = hash_bucket( hp, keyval );
168
+
169
+ /* Try to grab one from the free list. */
170
+ if ( hp->items.free )
171
+ {
172
+ i = hp->items.free;
173
+ hp->items.free = i->next;
174
+ assert( !hash_item_key( i ) );
175
+ }
176
+ else
177
+ {
178
+ i = (ITEM *)hp->items.next;
179
+ hp->items.next += hp->items.size;
180
+ }
181
+ --hp->items.more;
182
+ i->next = *base;
183
+ *base = i;
184
+ *found = 0;
185
+ }
186
+
187
+ #ifdef HASH_DEBUG_PROFILE
188
+ if ( DEBUG_PROFILE )
189
+ profile_exit( prof );
190
+ #endif
191
+
192
+ return hash_item_data( i );
193
+ }
194
+
195
+
196
+ /*
197
+ * hash_find() - find a record in the table or NULL if none exists
198
+ */
199
+
200
+ HASHDATA * hash_find( struct hash * hp, OBJECT * key )
201
+ {
202
+ ITEM * i;
203
+ unsigned int keyval = hash_keyval( key );
204
+
205
+ #ifdef HASH_DEBUG_PROFILE
206
+ profile_frame prof[ 1 ];
207
+ if ( DEBUG_PROFILE )
208
+ profile_enter( 0, prof );
209
+ #endif
210
+
211
+ if ( !hp->items.nel )
212
+ {
213
+ #ifdef HASH_DEBUG_PROFILE
214
+ if ( DEBUG_PROFILE )
215
+ profile_exit( prof );
216
+ #endif
217
+ return 0;
218
+ }
219
+
220
+ i = hash_search( hp, keyval, key, 0 );
221
+
222
+ #ifdef HASH_DEBUG_PROFILE
223
+ if ( DEBUG_PROFILE )
224
+ profile_exit( prof );
225
+ #endif
226
+
227
+ return i ? hash_item_data( i ) : 0;
228
+ }
229
+
230
+
231
+ /*
232
+ * hashrehash() - resize and rebuild hp->tab, the hash table
233
+ */
234
+
235
+ static void hashrehash( struct hash * hp )
236
+ {
237
+ int i = ++hp->items.list;
238
+ hp->items.more = i ? 2 * hp->items.nel : hp->inel;
239
+ hp->items.next = (char *)BJAM_MALLOC( hp->items.more * hp->items.size );
240
+ hp->items.free = 0;
241
+
242
+ hp->items.lists[ i ].nel = hp->items.more;
243
+ hp->items.lists[ i ].base = hp->items.next;
244
+ hp->items.nel += hp->items.more;
245
+
246
+ if ( hp->tab.base )
247
+ BJAM_FREE( (char *)hp->tab.base );
248
+
249
+ hp->tab.nel = hp->items.nel * hp->bloat;
250
+ hp->tab.base = (ITEM * *)BJAM_MALLOC( hp->tab.nel * sizeof( ITEM * * ) );
251
+
252
+ memset( (char *)hp->tab.base, '\0', hp->tab.nel * sizeof( ITEM * ) );
253
+
254
+ for ( i = 0; i < hp->items.list; ++i )
255
+ {
256
+ int nel = hp->items.lists[ i ].nel;
257
+ char * next = hp->items.lists[ i ].base;
258
+
259
+ for ( ; nel--; next += hp->items.size )
260
+ {
261
+ ITEM * i = (ITEM *)next;
262
+ ITEM * * ip = hp->tab.base + object_hash( hash_item_key( i ) ) %
263
+ hp->tab.nel;
264
+ /* code currently assumes rehashing only when there are no free
265
+ * items
266
+ */
267
+ assert( hash_item_key( i ) );
268
+
269
+ i->next = *ip;
270
+ *ip = i;
271
+ }
272
+ }
273
+ }
274
+
275
+
276
+ void hashenumerate( struct hash * hp, void (* f)( void *, void * ), void * data
277
+ )
278
+ {
279
+ int i;
280
+ for ( i = 0; i <= hp->items.list; ++i )
281
+ {
282
+ char * next = hp->items.lists[ i ].base;
283
+ int nel = hp->items.lists[ i ].nel;
284
+ if ( i == hp->items.list )
285
+ nel -= hp->items.more;
286
+
287
+ for ( ; nel--; next += hp->items.size )
288
+ {
289
+ ITEM * const i = (ITEM *)next;
290
+ if ( hash_item_key( i ) != 0 ) /* Do not enumerate freed items. */
291
+ f( hash_item_data( i ), data );
292
+ }
293
+ }
294
+ }
295
+
296
+
297
+ /*
298
+ * hash_free() - free a hash table, given its handle
299
+ */
300
+
301
+ void hash_free( struct hash * hp )
302
+ {
303
+ int i;
304
+ if ( !hp )
305
+ return;
306
+ if ( hp->tab.base )
307
+ BJAM_FREE( (char *)hp->tab.base );
308
+ for ( i = 0; i <= hp->items.list; ++i )
309
+ BJAM_FREE( hp->items.lists[ i ].base );
310
+ BJAM_FREE( (char *)hp );
311
+ }
312
+
313
+
314
+ static void hashstat( struct hash * hp )
315
+ {
316
+ struct hashstats stats[ 1 ];
317
+ hashstats_init( stats );
318
+ hashstats_add( stats, hp );
319
+ hashstats_print( stats, hp->name );
320
+ }
321
+
322
+
323
+ void hashstats_init( struct hashstats * stats )
324
+ {
325
+ stats->count = 0;
326
+ stats->num_items = 0;
327
+ stats->tab_size = 0;
328
+ stats->item_size = 0;
329
+ stats->sets = 0;
330
+ stats->num_hashes = 0;
331
+ }
332
+
333
+
334
+ void hashstats_add( struct hashstats * stats, struct hash * hp )
335
+ {
336
+ if ( hp )
337
+ {
338
+ ITEM * * tab = hp->tab.base;
339
+ int nel = hp->tab.nel;
340
+ int count = 0;
341
+ int sets = 0;
342
+ int i;
343
+
344
+ for ( i = 0; i < nel; ++i )
345
+ {
346
+ ITEM * item;
347
+ int here = 0;
348
+ for ( item = tab[ i ]; item; item = item->next )
349
+ ++here;
350
+
351
+ count += here;
352
+ if ( here > 0 )
353
+ ++sets;
354
+ }
355
+
356
+ stats->count += count;
357
+ stats->sets += sets;
358
+ stats->num_items += hp->items.nel;
359
+ stats->tab_size += hp->tab.nel;
360
+ stats->item_size = hp->items.size;
361
+ ++stats->num_hashes;
362
+ }
363
+ }
364
+
365
+
366
+ void hashstats_print( struct hashstats * stats, char const * name )
367
+ {
368
+ printf( "%s table: %d+%d+%d (%dK+%luK+%luK) items+table+hash, %f density\n",
369
+ name,
370
+ stats->count,
371
+ stats->num_items,
372
+ stats->tab_size,
373
+ stats->num_items * stats->item_size / 1024,
374
+ (long unsigned)stats->tab_size * sizeof( ITEM * * ) / 1024,
375
+ (long unsigned)stats->num_hashes * sizeof( struct hash ) / 1024,
376
+ (float)stats->count / (float)stats->sets );
377
+ }
378
+
379
+
380
+ void hashdone( struct hash * hp )
381
+ {
382
+ if ( !hp )
383
+ return;
384
+ if ( DEBUG_MEM || DEBUG_PROFILE )
385
+ hashstat( hp );
386
+ hash_free( hp );
387
+ }