/usr/share/boost-build/src/build/type.jam is in libboost1.62-tools-dev 1.62.0+dfsg-5.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 | # Copyright 2002, 2003 Dave Abrahams
# Copyright 2002, 2003, 2004, 2005, 2006 Vladimir Prus
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
# Deals with target type declaration and defines target class which supports
# typed targets.
import "class" : new ;
import feature ;
import generators : * ;
import os ;
import project ;
import property ;
import scanner ;
# The following import would create a circular dependency:
# project -> project-root -> builtin -> type -> targets -> project
# import targets ;
# The feature is optional so it would never get added implicitly. It is used
# only for internal purposes and in all cases we want to use it explicitly.
feature.feature target-type : : composite optional ;
feature.feature main-target-type : : optional incidental ;
feature.feature base-target-type : : composite optional free ;
# Registers a target type, possible derived from a 'base-type'. Providing a list
# of 'suffixes' here is a shortcut for separately calling the register-suffixes
# rule with the given suffixes and the set-generated-target-suffix rule with the
# first given suffix.
#
rule register ( type : suffixes * : base-type ? )
{
# Type names cannot contain hyphens, because when used as feature-values
# they would be interpreted as composite features which need to be
# decomposed.
switch $(type)
{
case *-* :
import errors ;
errors.error "type name \"$(type)\" contains a hyphen" ;
}
if $(type) in $(.types)
{
import errors ;
errors.error "Type $(type) is already registered." ;
}
{
.types += $(type) ;
.base.$(type) = $(base-type) ;
.derived.$(base-type) += $(type) ;
.bases.$(type) = $(type) $(.bases.$(base-type)) ;
# Store suffixes for generated targets.
.suffixes.$(type) = [ new property-map ] ;
# Store prefixes for generated targets (e.g. "lib" for library).
.prefixes.$(type) = [ new property-map ] ;
if $(suffixes)-is-defined
{
# Specify mapping from suffixes to type.
register-suffixes $(suffixes) : $(type) ;
# By default generated targets of 'type' will use the first of
#'suffixes'. This may be overriden.
set-generated-target-suffix $(type) : : $(suffixes[1]) ;
}
feature.extend target-type : $(type) ;
feature.extend main-target-type : $(type) ;
feature.extend base-target-type : $(type) ;
feature.compose <target-type>$(type) : $(base-type:G=<base-target-type>) ;
feature.compose <base-target-type>$(type) : <base-target-type>$(base-type) ;
# We used to declare the main target rule only when a 'main' parameter
# has been specified. However, it is hard to decide that a type will
# *never* need a main target rule and so from time to time we needed to
# make yet another type 'main'. So now a main target rule is defined for
# each type.
main-rule-name = [ type-to-rule-name $(type) ] ;
.main-target-type.$(main-rule-name) = $(type) ;
IMPORT $(__name__) : main-target-rule : : $(main-rule-name) ;
# Adding a new derived type affects generator selection so we need to
# make the generator selection module update any of its cached
# information related to a new derived type being defined.
generators.update-cached-information-with-a-new-type $(type) ;
}
}
# Given a type, returns the name of the main target rule which creates targets
# of that type.
#
rule type-to-rule-name ( type )
{
# Lowercase everything. Convert underscores to dashes.
import regex ;
local n = [ regex.split $(type:L) "_" ] ;
return $(n:J=-) ;
}
# Given a main target rule name, returns the type for which it creates targets.
#
rule type-from-rule-name ( rule-name )
{
return $(.main-target-type.$(rule-name)) ;
}
# Specifies that files with suffix from 'suffixes' be recognized as targets of
# type 'type'. Issues an error if a different type is already specified for any
# of the suffixes.
#
rule register-suffixes ( suffixes + : type )
{
for local s in $(suffixes)
{
if ! $(.type.$(s))
{
.type.$(s) = $(type) ;
}
else if $(.type.$(s)) != $(type)
{
import errors ;
errors.error Attempting to specify multiple types for suffix
\"$(s)\" : "Old type $(.type.$(s)), New type $(type)" ;
}
}
}
# Returns true iff type has been registered.
#
rule registered ( type )
{
if $(type) in $(.types)
{
return true ;
}
}
# Issues an error if 'type' is unknown.
#
rule validate ( type )
{
if ! [ registered $(type) ]
{
import errors ;
errors.error "Unknown target type $(type)" ;
}
}
# Sets a scanner class that will be used for this 'type'.
#
rule set-scanner ( type : scanner )
{
validate $(type) ;
.scanner.$(type) = $(scanner) ;
}
# Returns a scanner instance appropriate to 'type' and 'properties'.
#
rule get-scanner ( type : property-set )
{
if $(.scanner.$(type))
{
return [ scanner.get $(.scanner.$(type)) : $(property-set) ] ;
}
}
# Returns a base type for the given type or nothing in case the given type is
# not derived.
#
rule base ( type )
{
return $(.base.$(type)) ;
}
# Returns the given type and all of its base types in order of their distance
# from type.
#
rule all-bases ( type )
{
return $(.bases.$(type)) ;
}
# Returns the given type and all of its derived types in order of their distance
# from type.
#
rule all-derived ( type )
{
local result = $(type) ;
for local d in $(.derived.$(type))
{
result += [ all-derived $(d) ] ;
}
return $(result) ;
}
# Returns true if 'type' is equal to 'base' or has 'base' as its direct or
# indirect base.
#
rule is-derived ( type base )
{
if $(base) in $(.bases.$(type))
{
return true ;
}
}
# Returns true if 'type' is either derived from or is equal to 'base'.
#
# TODO: It might be that is-derived and is-subtype were meant to be different
# rules - one returning true for type = base and one not, but as currently
# implemented they are actually the same. Clean this up.
#
rule is-subtype ( type base )
{
return [ is-derived $(type) $(base) ] ;
}
# Sets a file suffix to be used when generating a target of 'type' with the
# specified properties. Can be called with no properties if no suffix has
# already been specified for the 'type'. The 'suffix' parameter can be an empty
# string ("") to indicate that no suffix should be used.
#
# Note that this does not cause files with 'suffix' to be automatically
# recognized as being of 'type'. Two different types can use the same suffix for
# their generated files but only one type can be auto-detected for a file with
# that suffix. User should explicitly specify which one using the
# register-suffixes rule.
#
rule set-generated-target-suffix ( type : properties * : suffix )
{
set-generated-target-ps suffix : $(type) : $(properties) : $(suffix) ;
}
# Change the suffix previously registered for this type/properties combination.
# If suffix is not yet specified, sets it.
#
rule change-generated-target-suffix ( type : properties * : suffix )
{
change-generated-target-ps suffix : $(type) : $(properties) : $(suffix) ;
}
# Returns the suffix used when generating a file of 'type' with the given
# properties.
#
rule generated-target-suffix ( type : property-set )
{
return [ generated-target-ps suffix : $(type) : $(property-set) ] ;
}
# Sets a target prefix that should be used when generating targets of 'type'
# with the specified properties. Can be called with empty properties if no
# prefix for 'type' has been specified yet.
#
# The 'prefix' parameter can be empty string ("") to indicate that no prefix
# should be used.
#
# Usage example: library names use the "lib" prefix on unix.
#
rule set-generated-target-prefix ( type : properties * : prefix )
{
set-generated-target-ps prefix : $(type) : $(properties) : $(prefix) ;
}
# Change the prefix previously registered for this type/properties combination.
# If prefix is not yet specified, sets it.
#
rule change-generated-target-prefix ( type : properties * : prefix )
{
change-generated-target-ps prefix : $(type) : $(properties) : $(prefix) ;
}
rule generated-target-prefix ( type : property-set )
{
return [ generated-target-ps prefix : $(type) : $(property-set) ] ;
}
# Common rules for prefix/suffix provisioning follow.
local rule set-generated-target-ps ( ps : type : properties * : psval )
{
$(.$(ps)es.$(type)).insert $(properties) : $(psval) ;
}
local rule change-generated-target-ps ( ps : type : properties * : psval )
{
local prev = [ $(.$(ps)es.$(type)).find-replace $(properties) : $(psval) ] ;
if ! $(prev)
{
set-generated-target-ps $(ps) : $(type) : $(properties) : $(psval) ;
}
}
# Returns either prefix or suffix (as indicated by 'ps') that should be used
# when generating a target of 'type' with the specified properties. Parameter
# 'ps' can be either "prefix" or "suffix". If no prefix/suffix is specified for
# 'type', returns prefix/suffix for base type, if any.
#
local rule generated-target-ps ( ps : type : property-set )
{
local result ;
local found ;
while $(type) && ! $(found)
{
result = [ $(.$(ps)es.$(type)).find $(property-set) ] ;
# If the prefix/suffix is explicitly set to an empty string, we consider
# prefix/suffix to be found. If we were not to compare with "", there
# would be no way to specify an empty prefix/suffix.
if $(result)-is-defined
{
found = true ;
}
type = $(.base.$(type)) ;
}
if $(result) = ""
{
result = ;
}
return $(result) ;
}
# Returns file type given its name. If there are several dots in filename, tries
# each suffix. E.g. for name of "file.so.1.2" suffixes "2", "1", and "so" will
# be tried.
#
rule type ( filename )
{
if [ os.name ] in NT CYGWIN
{
filename = $(filename:L) ;
}
local type ;
while ! $(type) && $(filename:S)
{
local suffix = $(filename:S) ;
type = $(.type$(suffix)) ;
filename = $(filename:S=) ;
}
return $(type) ;
}
# Rule used to construct all main targets. Note that this rule gets imported
# into the global namespace under different alias names and the exact target
# type to construct is selected based on the alias used to actually invoke this
# rule.
#
rule main-target-rule ( name : sources * : requirements * : default-build * :
usage-requirements * )
{
# First discover the required target type based on the exact alias used to
# invoke this rule.
local bt = [ BACKTRACE 1 ] ;
local rulename = $(bt[4]) ;
local target-type = [ type-from-rule-name $(rulename) ] ;
# This is a circular module dependency and so must be imported here.
import targets ;
return [ targets.create-typed-target $(target-type) : [ project.current ] :
$(name) : $(sources) : $(requirements) : $(default-build) :
$(usage-requirements) ] ;
}
rule __test__ ( )
{
import assert ;
# TODO: Add tests for all the is-derived, is-base & related type relation
# checking rules.
}
|