From f08f43810da08dcdd63b9249f090e02c2004ccd5 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 13 Sep 2005 09:19:54 +0000 Subject: [PATCH] New 'cast' main target rule. [SVN r30940] --- src/tools/cast.jam | 80 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 src/tools/cast.jam diff --git a/src/tools/cast.jam b/src/tools/cast.jam new file mode 100644 index 000000000..709181d5c --- /dev/null +++ b/src/tools/cast.jam @@ -0,0 +1,80 @@ +# Copyright 2005 Vladimir Prus. +# Distributed under the Boost Software License, Version 1.0. (See +# accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +# Defines main target 'cast', used to change type for target. For example, +# in Qt library one wants two kinds of CPP files -- those that just compiled +# and those that are passed via the MOC tool. +# +# This is done with: +# +# exe main : main.cpp [ cast _ moccable-cpp : widget.cpp ] ; +# +# Boost.Build will assing target type CPP to both main.cpp and widget.cpp. +# Then, the cast rule will change target type of widget.cpp to +# MOCCABLE-CPP, and Qt support will run MOC tool as part of build process. +# +# At the moment, the 'cast' rule only works for non-derived (source) targets. +# +# Another solution would be to add separate main target 'moc-them' that +# will moc all the passed sources, not matter what's the type, but I prefer +# cast, as defining new target type + generator for that type is somewhat +# simpler then defining main target rule. + +import project type targets ; +import "class" : new ; +import errors ; +import property-set ; + +class cast-target-class : typed-target +{ + import type ; + + rule __init__ ( name : project : type + : sources * : requirements * : default-build * : usage-requirements * ) + { + typed-target.__init__ $(name) : $(project) : $(type) + : $(sources) : $(requirements) : $(default-build) : $(usage-requirements) ; + } + + rule construct ( name : source-targets * : property-set ) + { + local result ; + for local s in $(source-targets) + { + if ! [ class.is-a $(s) : file-target ] + { + ECHO "error: source to the 'cast' rule is not a file!" ; + EXIT ; + } + if [ $(s).action ] + { + ECHO "error: only non-derived target are allowed for 'cast'." ; + ECHO "error: when building " [ full-name ] ; + EXIT ; + } + result += [ $(s).clone-with-different-type $(self.type) ] ; + } + + return [ property-set.empty ] $(result) ; + } + +} + +rule cast ( name type : sources * : requirements * : default-build * + : usage-requirements * ) +{ + local project = [ project.current ] ; + + # This is a circular module dependency, so it must be imported here + import targets ; + targets.main-target-alternative + [ new cast-target-class $(name) : $(project) : [ type.type-from-rule-name $(type) ] + : [ targets.main-target-sources $(sources) : $(name) ] + : [ targets.main-target-requirements $(requirements) : $(project) ] + : [ targets.main-target-default-build $(default-build) : $(project) ] + : [ targets.main-target-usage-requirements $(usage-requirements) : $(project) ] + ] ; +} +IMPORT $(__name__) : cast : : cast ;