1# Status: ported 2# Base revision: 64432. 3# Copyright 2005-2010 Vladimir Prus. 4# Distributed under the Boost Software License, Version 1.0. (See 5# accompanying file LICENSE_1_0.txt or copy at 6# http://www.boost.org/LICENSE_1_0.txt) 7 8# Defines main target 'cast', used to change type for target. For example, in Qt 9# library one wants two kinds of CPP files -- those that just compiled and those 10# that are passed via the MOC tool. 11# 12# This is done with: 13# 14# exe main : main.cpp [ cast _ moccable-cpp : widget.cpp ] ; 15# 16# Boost.Build will assign target type CPP to both main.cpp and widget.cpp. Then, 17# the cast rule will change target type of widget.cpp to MOCCABLE-CPP, and Qt 18# support will run the MOC tool as part of the build process. 19# 20# At the moment, the 'cast' rule only works for non-derived (source) targets. 21# 22# TODO: The following comment is unclear or incorrect. Clean it up. 23# > Another solution would be to add a separate main target 'moc-them' that 24# > would moc all the passed sources, no matter what their type is, but I prefer 25# > cast, as defining a new target type + generator for that type is somewhat 26# > simpler than defining a main target rule. 27 28from b2.build import targets, virtual_target, property_set, type as type_ 29 30from b2.manager import get_manager 31from b2.util import bjam_signature, is_iterable_typed 32 33 34class CastTargetClass(targets.TypedTarget): 35 36 def construct(self, name, source_targets, ps): 37 assert isinstance(name, basestring) 38 assert is_iterable_typed(source_targets, virtual_target.VirtualTarget) 39 assert isinstance(ps, property_set.PropertySet) 40 41 result = [] 42 for s in source_targets: 43 if not isinstance(s, virtual_target.FileTarget): 44 get_manager().errors()("Source to the 'cast' metatager is not a file") 45 46 if s.action(): 47 get_manager().errors()("Only non-derived targets allowed as sources for 'cast'.") 48 49 50 r = s.clone_with_different_type(self.type()) 51 result.append(get_manager().virtual_targets().register(r)) 52 53 return property_set.empty(), result 54 55 56@bjam_signature((["name", "type"], ["sources", "*"], ["requirements", "*"], 57 ["default_build", "*"], ["usage_requirements", "*"])) 58def cast(name, type, sources, requirements, default_build, usage_requirements): 59 60 from b2.manager import get_manager 61 t = get_manager().targets() 62 63 project = get_manager().projects().current() 64 65 real_type = type_.type_from_rule_name(type) 66 if not real_type: 67 real_type = type 68 return t.main_target_alternative( 69 CastTargetClass(name, project, real_type, 70 t.main_target_sources(sources, name), 71 t.main_target_requirements(requirements, project), 72 t.main_target_default_build(default_build, project), 73 t.main_target_usage_requirements(usage_requirements, project))) 74 75 76get_manager().projects().add_rule("cast", cast) 77