mirror of
https://github.com/boostorg/build.git
synced 2026-02-16 13:22:11 +00:00
virtual-target.jam.
- Added the missing explicit imports, now that we don't dump
everything into the global module with qualification
- stopped using the feature-space hack for temporary testing states of
the feature module. Instead we move its global variable definitions
to a temporary module.
- the way feature.action was invoking the rule it was being passed was
evil. Now you pass (even local) rules without qualification and
they are invoked in the source module context.
- module __test__ rules are always executed in a separate module, so
that their import dependencies can be separated from those of the
module being tested.
- better reporting of circular module-loading dependencies
implemented.
- minor changes:
property-set.jam: moved .empty initialization to avert circular
load dependency .
symlink.jam: fixed global variable naming.
[SVN r18407]
126 lines
4.2 KiB
Plaintext
126 lines
4.2 KiB
Plaintext
# Copyright (C) Vladimir Prus 2002. Permission to copy, use, modify, sell and
|
|
# distribute this software is granted provided this copyright notice appears in
|
|
# all copies. This software is provided "as is" without express or implied
|
|
# warranty, and with no claim as to its suitability for any purpose.
|
|
|
|
# Implements scanners: objects that compute implicit dependencies for
|
|
# files, such as includes in C++.
|
|
#
|
|
# Scanner has a regular expression used to find dependencies, some
|
|
# data needed to interpret those dependencies (for example, include
|
|
# paths), and a code which actually established needed relationship
|
|
# between actual jam targets.
|
|
#
|
|
# Scanner objects are created by actions, when they try to actualize
|
|
# virtual targets, passed to 'virtual-target.actualize' method and are
|
|
# then associated with actual targets. It is possible to use
|
|
# several scanners for a virtual-target. For example, a single source
|
|
# might be used by to compile actions, with different include paths.
|
|
# In this case, two different actual targets will be created, each
|
|
# having scanner of its own.
|
|
#
|
|
# Typically, scanners are created from target type and action's
|
|
# properties, using the rule 'get' in this module. Directly creating
|
|
# scanners is not recommended, because it might create many equvivalent
|
|
# but different instances, and lead in unneeded duplication of
|
|
# actual targets. However, actions can also create scanners in a special
|
|
# way, instead of relying on just target type.
|
|
|
|
import class : class new ;
|
|
import property virtual-target ;
|
|
|
|
# Base scanner class.
|
|
rule scanner ( )
|
|
{
|
|
# Returns a pattern to use for scanning
|
|
rule pattern ( )
|
|
{
|
|
error "method must be overriden" ;
|
|
}
|
|
|
|
# Establish necessary relationship between targets,
|
|
# given actual target beeing scanned, and a list of
|
|
# pattern matches in that file.
|
|
rule process ( target : matches * )
|
|
{
|
|
error "method must be overriden" ;
|
|
}
|
|
}
|
|
|
|
class scanner ;
|
|
|
|
# Registers a new generator class, specifying a set of
|
|
# properties relevant to this scanner. Ctor for that class
|
|
# should have one parameter: list of properties.
|
|
rule register ( scanner-class : relevant-properties * )
|
|
{
|
|
.registered += $(scanner-class) ;
|
|
.relevant-properties.$(scanner-class) = $(relevant-properties) ;
|
|
}
|
|
|
|
# Returns an instance of previously registered scanner,
|
|
# with the specified properties.
|
|
rule get ( scanner-class : properties * )
|
|
{
|
|
if ! $(scanner-class) in $(.registered)
|
|
{
|
|
error "attempt to get unregisted scanner" ;
|
|
}
|
|
local r = [ property.select $(.relevant-properties.$(scanner-class)) :
|
|
$(properties) ] ;
|
|
if ! $(r)
|
|
{
|
|
r = "" ;
|
|
}
|
|
if ! $(scanner.$(scanner-class).$(r:J=-))
|
|
{
|
|
scanner.$(scanner-class).$(r:J=-) = [ new $(scanner-class) $(r) ] ;
|
|
}
|
|
return $(scanner.$(scanner-class).$(r:J=-)) ;
|
|
}
|
|
|
|
|
|
# Installs the specified scanner on 'target'. If 'vtarget' is given
|
|
# it means installation is result of actualizing 'vtarget'. Otherwise
|
|
# installation is due to including of 'target' from 'including-target'
|
|
# which must be specified.
|
|
rule install ( scanner : target vtarget ? : including-target ? )
|
|
{
|
|
HDRSCAN on $(target) = [ $(scanner).pattern ] ;
|
|
SCANNER on $(target) = $(scanner) ;
|
|
HDRRULE on $(target) = scanner.hdrrule ;
|
|
if $(vtarget) && $(including-target)
|
|
|| ! $(vtarget) && ! $(including-target)
|
|
{
|
|
error "precondition failed" ;
|
|
}
|
|
if $(vtarget)
|
|
{
|
|
# scanner reflects difference in properties affecting
|
|
# binding of 'target', which will be known when processing
|
|
# includes for it, will give information on how to
|
|
# interpret quoted includes.
|
|
HDRGRIST on $(target) = $(scanner) ;
|
|
}
|
|
else
|
|
{
|
|
local hg = [ on $(including-target) return $(HDRGRIST) ] ;
|
|
local b = [ virtual-target.binding $(including-target) ] ;
|
|
HDRGRIST on $(target) = $(hg) ;
|
|
|
|
}
|
|
}
|
|
|
|
rule hdrrule ( target : matches * )
|
|
{
|
|
local scanner = [ on $(target) return $(SCANNER) ] ;
|
|
$(scanner).process $(target) : $(matches) ;
|
|
}
|
|
# hdrrule must be available at global scope so that it can be invoked
|
|
# by header scanning
|
|
IMPORT scanner : hdrrule : : scanner.hdrrule ;
|
|
|
|
|
|
|
|
|