Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- mosesdecoder/jam-files/LICENSE_1_0.txt +23 -0
- mosesdecoder/jam-files/boost-build/tools/auto-index.jam +212 -0
- mosesdecoder/jam-files/boost-build/tools/bison.jam +32 -0
- mosesdecoder/jam-files/boost-build/tools/boostbook-config.jam +13 -0
- mosesdecoder/jam-files/boost-build/tools/borland.jam +220 -0
- mosesdecoder/jam-files/boost-build/tools/builtin.jam +960 -0
- mosesdecoder/jam-files/boost-build/tools/cast.jam +91 -0
- mosesdecoder/jam-files/boost-build/tools/common.jam +983 -0
- mosesdecoder/jam-files/boost-build/tools/como.jam +29 -0
- mosesdecoder/jam-files/boost-build/tools/cray.jam +112 -0
- mosesdecoder/jam-files/boost-build/tools/cw.jam +246 -0
- mosesdecoder/jam-files/boost-build/tools/darwin.jam +583 -0
- mosesdecoder/jam-files/boost-build/tools/docutils.jam +85 -0
- mosesdecoder/jam-files/boost-build/tools/doxygen-config.jam +11 -0
- mosesdecoder/jam-files/boost-build/tools/fortran.jam +55 -0
- mosesdecoder/jam-files/boost-build/tools/gettext.jam +230 -0
- mosesdecoder/jam-files/boost-build/tools/ifort.jam +44 -0
- mosesdecoder/jam-files/boost-build/tools/intel-darwin.jam +220 -0
- mosesdecoder/jam-files/boost-build/tools/intel-win.jam +184 -0
- mosesdecoder/jam-files/boost-build/tools/mpi.jam +583 -0
- mosesdecoder/jam-files/boost-build/tools/msvc.jam +1398 -0
- mosesdecoder/jam-files/boost-build/tools/notfile.jam +74 -0
- mosesdecoder/jam-files/boost-build/tools/pathscale.jam +168 -0
- mosesdecoder/jam-files/boost-build/tools/pch.jam +95 -0
- mosesdecoder/jam-files/boost-build/tools/qt.jam +17 -0
- mosesdecoder/jam-files/boost-build/tools/qt3.jam +209 -0
- mosesdecoder/jam-files/boost-build/tools/qt4.jam +724 -0
- mosesdecoder/jam-files/boost-build/tools/sun.jam +142 -0
- mosesdecoder/jam-files/boost-build/tools/testing.jam +581 -0
- mosesdecoder/jam-files/boost-build/tools/types/html.jam +4 -0
- mosesdecoder/jam-files/boost-build/tools/types/obj.jam +9 -0
- mosesdecoder/jam-files/boost-build/tools/types/objc.jam +26 -0
- mosesdecoder/jam-files/boost-build/tools/types/preprocessed.jam +9 -0
- mosesdecoder/jam-files/boost-build/tools/types/qt.jam +10 -0
- mosesdecoder/jam-files/boost-build/tools/types/register.jam +39 -0
- mosesdecoder/jam-files/boost-build/tools/unix.jam +224 -0
- mosesdecoder/jam-files/boost-build/tools/xsltproc.jam +194 -0
- mosesdecoder/jam-files/empty_test_main.cc +8 -0
- mosesdecoder/jam-files/engine/class.h +14 -0
- mosesdecoder/jam-files/engine/command.c +84 -0
- mosesdecoder/jam-files/engine/compile.c +271 -0
- mosesdecoder/jam-files/engine/cwd.h +35 -0
- mosesdecoder/jam-files/engine/debug.c +145 -0
- mosesdecoder/jam-files/engine/debug.h +55 -0
- mosesdecoder/jam-files/engine/execcmd.c +121 -0
- mosesdecoder/jam-files/engine/execnt.c +1232 -0
- mosesdecoder/jam-files/engine/execunix.c +559 -0
- mosesdecoder/jam-files/engine/filesys.h +56 -0
- mosesdecoder/jam-files/engine/frames.h +42 -0
- 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( ¤t );
|
| 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 |
+
}
|