2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-16 01:12:13 +00:00
Files
build/new/scanner.jam
Dave Abrahams 5eb7ea1192 Note: there is currently a circular dependency between type.jam and
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]
2003-05-15 22:22:13 +00:00

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 ;