2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-13 00:12:11 +00:00

Some cleanups. At the same time, allowed several suffixes to target types

(e.g. "cpp" and "cxx").


[SVN r15262]
This commit is contained in:
Vladimir Prus
2002-09-11 14:18:52 +00:00
parent 3fbc22a8c1
commit 021c2e550d
5 changed files with 30 additions and 284 deletions

View File

@@ -4,12 +4,7 @@
# warranty, and with no claim as to its suitability for any purpose.
# There are three kinds of targets: "abstract", which correspond to
# targets explicitly defined in Jamfile; "virtual", which correspond
# to possible build product with defined properties and "actual", which
# are targets in Jam sense. The "virtual" targets are generated during
# search for the best transformation sequence, and some of them can be
# later 'actualized'.
# Supports 'abstact' targets, which are targets explicitly defined in Jamfile.
#
# Abstract targets are represented by classes derived from 'abstract-target' class.
# The first abstract target is 'project-target', which is created for each
@@ -252,6 +247,7 @@ rule basic-target ( name : project
: sources * : requirements * : default-build * )
{
import build-request ;
import virtual-target ;
abstract-target.__init__ $(name) : $(project) ;
@@ -309,9 +305,7 @@ rule basic-target ( name : project
else
{
# Just a source file
# FIXME: break an import cycle in a rude way
import type ;
source-targets += [ type.from-file $(s) : $(self.project) ] ;
source-targets += [ virtual-target.from-file $(s) : $(self.project) ] ;
}
}
self.generated.$(property-path) =
@@ -426,231 +420,22 @@ rule main-target-alternative ( target-name project class-name
: $(a4) : $(a5) : $(a6) : $(a7) : $(a8) : $(a9) ] ;
}
# Class which represents a virtual target
rule virtual-target ( name : type ? : project
: subvariant * # Property sets which define this subvariant
)
rule typed-target ( name : project : type
: sources * : requirements * : default-build * )
{
self.name = $(name) ;
ECHO "Typed target: type is " $(type) ;
basic-target.__init__ $(name) : $(project)
: $(sources) : $(requirements) : $(defailt-build) ;
self.type = $(type) ;
self.subvariant = $(subvariant) ;
self.project = $(project) ;
self.includes = ;
self.dependencies = ;
self.action = ;
self.actual-name = ;
# Name of the target
rule name ( ) { return $(self.name) ; }
rule type ( ) { return $(self.type) ; }
# Property set that distinguished different variants of a target.
# May be a subset of the property set that is used for building.
# Determines the location of target, in an unspecified way.
rule subvariant ( ) { return $(self.subvariant) ; }
# Project where this target was declared
rule project ( ) { return $(self.project) ; }
rule includes ( ) { return $(self.includes) ; }
rule add_includes ( i + )
rule construct ( source-targets * : properties * )
{
self.includes = [ sequence.merge $(self.includes)
: [ sequence.insertion-sort $(i) ] ] ;
}
rule dependencies ( ) { return $(self.dependencies) ; }
rule depends ( d + )
{
self.dependencies = [ sequence.merge $(self.dependencies)
: [ sequence.insertion-sort $(d) ] ] ;
}
# If 'a' is supplied, sets action to 'a'.
# Returns the action currently set.
rule action ( a ? )
{
if $(a) {
self.action = $(a) ;
}
return $(self.action) ;
}
# Specified an extra element to be added to the target path.
rule extra-path ( p )
{
self.extra-path = $(p) ;
}
# Generates all the actual targets and build instructions needed to build
# this target. Returns the actual target name. Can be called several times.
# Does no processing for other targets that 'action' will generate.
# Rationale: we might need only one file from the set created by an
# action, and there's no need to run the action if the file is up-to-date,
# only because some other file in set is out-of-date.
rule actualize ( )
{
if ! $(self.actual-name) {
self.actual-name = [ actual-name ] ;
for local i in $(dependencies) {
DEPENDS $(name) : [ $(i).actualize ] ;
}
for local i in $(includes) {
INCLUDES $(name) : [ $(i).actualize ] ;
}
local a = [ action ] ;
if $(a) {
$(a).actualize ;
local path = [ path.join [ project.attribute $(self.project) location ]
"bin" [ property.as-path [ subvariant ] ]
$(self.extra-path) ] ;
path = [ path.native $(path) ] ;
LOCATE on $(self.actual-name) = $(path) ;
DEPENDS $(self.actual-name) : $(path) ;
common.MkDir $(path) ;
common.Clean clean : $(self.actual-name) ;
} else {
SEARCH on $(self.actual-name) =
[ path.native [ project.attribute $(self.project) source-location ] ] ;
}
}
return $(self.actual-name) ;
}
rule str ( )
{
local action = [ action ] ;
local filename = [ sequence.join $(self.name) "." $(self.type) ] ;
if $(action)
{
local sources = [ $(action).sources ] ;
local ss ;
for local s in $(sources)
{
ss += [ $(s).str ] ;
}
local name = [ $(action).action_name ] ;
return "{" $(name)-$(filename) $(ss) "}" ;
}
else
{
return "{" $(filename) "}" ;
}
}
rule less ( a )
{
if [ str ] < [ $(a).str ]
{
return true ;
}
}
rule equal ( a )
{
if [ str ] = [ $(a).str ]
{
return true ;
}
}
# private:
rule actual-name ( )
{
if ! $(self.actual-name)
{
local project-location = [ project.attribute $(self.project) location ] ;
local location-grist =
[ sequence.join [ regex.split $(project-location) "/" ] : "!" ] ;
local property-grist =
[ property.as-path $(self.subvariant) ] ;
# Set empty value to avoid eating adjacent text
local grist = $(location-grist)/$(property-grist) ;
if ! $(self.subvariant) {
grist = $(location-grist) ;
}
if $(self.type)
{
self.actual-name = [ sequence.join <$(grist)>$(self.name) [ type.suffix $(self.type) ] : "." ] ;
}
else
{
self.actual-name = <$(grist)>$(self.name) ;
}
}
return $(self.actual-name) ;
}
local r = [ generators.construct-dbg $(self.project) $(self.name) : $(self.type)
: $(properties) <main-target-type>$(self.type) : $(source-targets) ] ;
return [ $(r).get-at 1 ] [ $(r).get-at 2 ] ;
}
}
class virtual-target ;
# Class which represents an action.
# Both 'targets' and 'sources' should list instances of 'virtual-target'.
# Action name should name a rule with this prototype
# rule action_name ( targets + : sources * : properties * )
# Targets and sources are passed as actual jam targets. The rule may
# not establish dependency relationship, but should do everything else.
rule action ( targets + : sources * : action_name : properties * )
{
self.targets = $(targets) ;
self.sources = $(sources) ;
self.action_name = $(action_name) ;
self.properties = $(properties) ;
rule targets ( )
{
return $(self.targets) ;
}
rule sources ( )
{
return $(self.sources) ;
}
rule action_name ( )
{
return $(self.action_name) ;
}
rule properties ( )
{
return $(self.properties) ;
}
# Generates actual build instructions.
rule actualize ( )
{
if ! $(self.actualized)
{
self.actualized = true ;
local actual_targets ;
for local i in [ targets ]
{
actual_targets += [ $(i).actualize ] ;
}
local actual_sources ;
for local i in [ sources ]
{
actual_sources += [ $(i).actualize ] ;
}
DEPENDS $(actual_targets) : $(actual_sources) ;
$(self.action_name)
$(actual_targets) : $(actual_sources) : [ properties ] ;
}
}
}
class action ;
class typed-target : basic-target ;

View File

@@ -7,7 +7,6 @@
# typed targets.
import feature ;
import targets ;
import generators : * ;
import class : class new ;
@@ -17,12 +16,14 @@ feature.feature base-target-type : : composite optional ;
feature.feature main-target-type : : optional incidental ;
# Registers a target type, possible derived from a 'base-type'.
# If 'suffix' is provided, it is associated with this target type.
# If 'suffixes' are provided, they given all the suffixes that mean a file is of 'type'.
# Also, the first element gives the suffix to be used when constructing and object of
# 'type'.
# If 'main' is given, a rule with the same name as the target type
# and signature
# rule target-type ( name : sources * : requirements * : default-build )
# will be added to the global scope.
rule register ( type : suffix ? : base-type ? : main ? )
rule register ( type : suffixes * : base-type ? : main ? )
{
if $(type) in $(.types)
{
@@ -31,8 +32,8 @@ rule register ( type : suffix ? : base-type ? : main ? )
else
{
.types += $(type) ;
.suffix.$(type) = $(suffix) ;
.type.$(suffix) = $(type) ;
.suffix.$(type) = $(suffixes[1]) ;
.type.$(suffixes) = $(type) ;
feature.extend target-type : $(type) ;
feature.compose <target-type>$(type) : $(base-type:G=<base-target-type>) ;
feature.compose <base-target-type>$(type) : $(base-type:G=<base-target-type>) ;
@@ -44,49 +45,19 @@ rule register ( type : suffix ? : base-type ? : main ? )
}
}
# Returns suffix to the 'type'.
rule suffix ( type )
# Returns suffix that should be used when generating target of 'type'.
rule generated-target-suffix ( type )
{
return $(.suffix.$(type)) ;
}
# Creates a virtual target with approariate name and type from 'file'.
# TODO: passing project with all virtual targets starts to be annoying.
rule from-file ( file : project )
# Returns file type given its suffix.
rule type ( suffix )
{
local name = $(file:S=) ;
local type = $(.type$(file:S)) ;
if ! $(type)
{
# warning "cannot determine type for file $(file)" ;
return [ new virtual-target $(file) : : $(project) ] ;
}
else
{
return [ new virtual-target $(name) : $(type) : $(project) ] ;
}
return $(.type$(suffix)) ;
}
rule typed-target ( name : project : type
: sources * : requirements * : default-build * )
{
ECHO "Typed target: type is " $(type) ;
basic-target.__init__ $(name) : $(project)
: $(sources) : $(requirements) : $(defailt-build) ;
self.type = $(type) ;
rule construct ( source-targets * : properties * )
{
local r = [ generators.construct-dbg $(self.project) $(self.name) : $(self.type)
: $(properties) <main-target-type>$(self.type) : $(source-targets) ] ;
return [ $(r).get-at 1 ] [ $(r).get-at 2 ] ;
}
}
class typed-target : basic-target ;
rule main-target-rule ( name : sources * : requirements * : default-build ? )
{
# First find requuired target type, which is equal to the name used to
@@ -99,13 +70,3 @@ rule main-target-rule ( name : sources * : requirements * : default-build ? )
;
}
rule construct-dbg-x ( target-types + : properties * : source-files + )
{
local sources ;
for local s in $(source-files)
{
sources += [ from-file $(s) : "some project" ] ;
}
return [ construct-dbg "result" : $(target-types) : $(properties) :
$(sources) ] ;
}

View File

@@ -1,5 +1,5 @@
exe a : a.cpp b.cpp c.ui d.wd x.l y.x_pro lib/aux ;
exe a : a.cpp b.cxx c.ui d.wd x.l y.x_pro lib/aux ;
#exe a : a.cpp b.cpp c.ui d.wd x.l y.x_pro ;
nm_exe e : e.cpp ;

View File

@@ -10,7 +10,7 @@ import type ;
type.register EXE : : : main ;
type.register LIB : : : main ;
type.register CPP : cpp ;
type.register CPP : cpp cxx ;
type.register C : c ;
type.register OBJ : o ;
type.register LEX : l ;