From 57ea500e02a10bca19d291b2b7d081fd855a40a8 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Tue, 27 Jul 2010 10:56:38 +0000 Subject: [PATCH] Use Property, not string, in more places [SVN r64382] --- v2/build/feature.py | 25 +++++++++++++------------ v2/build/generators.py | 13 +++++++------ v2/build/property.py | 3 +++ v2/build/property_set.py | 15 +++++++++------ v2/build/targets.py | 38 ++++++++++++++++---------------------- v2/build/virtual_target.py | 5 ++++- v2/build_system.py | 13 ++----------- v2/tools/gcc.py | 9 ++++----- 8 files changed, 58 insertions(+), 63 deletions(-) diff --git a/v2/build/feature.py b/v2/build/feature.py index 3d071c8bc..3f09d9da5 100644 --- a/v2/build/feature.py +++ b/v2/build/feature.py @@ -835,27 +835,28 @@ def compress_subproperties (properties): purposes and it needs help """ result = [] - matched_subs = [] + matched_subs = set() + all_subs = set() for p in properties: - pg = get_grist (p) - if not pg: - raise BaseException ("Gristed variable exppected. Got '%s'." % p) + f = p.feature() - if not __all_features [pg].subfeature(): + if not f.subfeature(): subs = __select_subproperties (p, properties) + if subs: - matched_subs.extend (subs) + matched_subs.update(subs) - subvalues = '-'.join (get_value (subs)) - if subvalues: subvalues = '-' + subvalues - - result.append (p + subvalues) + subvalues = '-'.join (sub.value() for sub in subs) + result.append(Property(p.feature(), p.value + '-' + subvalues, + p.condition())) + else: + result.append(p) else: - all_subs.append (p) + all_subs.add(p) # TODO: this variables are used just for debugging. What's the overhead? - assert (b2.util.set.equal (all_subs, matched_subs)) + assert all_subs == matched_subs return result diff --git a/v2/build/generators.py b/v2/build/generators.py index bae7e54d9..ab461f984 100644 --- a/v2/build/generators.py +++ b/v2/build/generators.py @@ -238,7 +238,7 @@ class Generator: """ return self.requirements_ - def match_rank (self, property_set_to_match): + def match_rank (self, ps): """ Returns true if the generator can be run with the specified properties. """ @@ -250,17 +250,18 @@ class Generator: property_requirements = [] feature_requirements = [] + # This uses strings because genenator requirements allow + # the '' syntax without value and regular validation + # is not happy about that. for r in all_requirements: if get_value (r): property_requirements.append (r) else: feature_requirements.append (r) - - properties_to_match = property_set_to_match.raw () - - return set.contains (property_requirements, properties_to_match) \ - and set.contains (feature_requirements, get_grist (properties_to_match)) + + return all(ps.get(get_grist(s)) == [get_value(s)] for s in property_requirements) \ + and all(ps.get(get_grist(s)) for s in feature_requirements) def run (self, project, name, prop_set, sources): """ Tries to invoke this generator on the given sources. Returns a diff --git a/v2/build/property.py b/v2/build/property.py index ddbd50c46..5eeea1a8a 100644 --- a/v2/build/property.py +++ b/v2/build/property.py @@ -64,6 +64,9 @@ class Property(object): def create_from_string(s, allow_condition = False): condition = [] + import types + if not isinstance(s, types.StringType): + print type(s) if __re_has_condition.search(s): if not allow_condition: diff --git a/v2/build/property_set.py b/v2/build/property_set.py index 4f7a0afcc..dc3dcc32d 100644 --- a/v2/build/property_set.py +++ b/v2/build/property_set.py @@ -142,6 +142,7 @@ class PropertySet: self.all_ = properties self.all_raw_ = raw_properties + self.all_set_ = set(properties) self.incidental_ = [] self.free_ = [] @@ -238,7 +239,7 @@ class PropertySet: return self.all_raw_ def __str__(self): - return string.join(self.all_raw_) + return ' '.join(str(p) for p in self.all_) def base (self): """ Returns properties that are neither incidental nor free. @@ -295,11 +296,6 @@ class PropertySet: self.expanded_ = create(expanded) return self.expanded_ - def expand_componsite(self): - if not self.componsites_: - self.composites_ = create(feature.expand_composires(self.all_raw_)) - return self.composites_ - def expand_subfeatures(self): if not self.subfeatures_: self.subfeatures_ = create(feature.expand_subfeatures(self.all_)) @@ -431,4 +427,11 @@ class PropertySet: self.feature_map_[v.feature()].append(v.value()) return self.feature_map_.get(feature, []) + + def __contains__(self, item): + for p in self.all_set_: + if p.feature().name() == "toolset": + print "EXISTING", hash(p), hash(p._feature), hash(p._value), "--", hash(item._feature), has(item._value) + print self.all_set_ + return item in self.all_set_ diff --git a/v2/build/targets.py b/v2/build/targets.py index 94d7f33bb..39b127a5c 100644 --- a/v2/build/targets.py +++ b/v2/build/targets.py @@ -388,7 +388,7 @@ class ProjectTarget (AbstractTarget): """ Generates all possible targets contained in this project. """ self.manager_.targets().log( - "Building project '%s' with '%s'" % (self.name (), ps.raw ())) + "Building project '%s' with '%s'" % (self.name (), str(ps))) self.manager_.targets().increase_indent () result = GenerateResult () @@ -656,14 +656,13 @@ class MainTarget (AbstractTarget): def apply_default_build (self, property_set): # 1. First, see what properties from default_build # are already present in property_set. - - raw = property_set.raw () - specified_features = get_grist (raw) + + specified_features = set(p.feature() for p in property_set.all()) defaults_to_apply = [] - for d in self.default_build_.raw (): - if not get_grist (d) in specified_features: - defaults_to_apply.append (d) + for d in self.default_build_.all(): + if not d.feature() in specified_features: + defaults_to_apply.append(d) # 2. If there's any defaults to be applied, form the new # build request. Pass it throw 'expand-no-defaults', since @@ -686,16 +685,9 @@ class MainTarget (AbstractTarget): # be an indication that # build_request.expand-no-defaults is the wrong rule # to use here. - compressed = feature.compress_subproperties (raw) + compressed = feature.compress_subproperties(property_set.all()) - properties = build_request.expand_no_defaults (compressed, defaults_to_apply) - - if properties: - for p in properties: - result.append (property_set.create (feature.expand (feature.split (p)))) - - else: - result .append (property_set.empty ()) + result = build_request.expand_no_defaults (compressed, defaults_to_apply) else: result.append (property_set) @@ -1042,8 +1034,8 @@ class BasicTarget (AbstractTarget): # is the object itself. This won't work in python. targets = [ self.manager_.register_object (x) for x in result.targets () ] - result_var += replace_grist (targets, grist) - usage_requirements += result.usage_requirements ().raw () + result_var += replace_grist(targets, grist) + usage_requirements += result.usage_requirements().all() return (result_var, usage_requirements) @@ -1078,7 +1070,7 @@ class BasicTarget (AbstractTarget): rproperties = self.common_properties (ps, self.requirements_) self.manager().targets().log( - "Common properties are '%s'" % str (rproperties.raw ())) + "Common properties are '%s'" % str (rproperties)) if rproperties.get("") != ["no"]: @@ -1096,11 +1088,13 @@ class BasicTarget (AbstractTarget): self.manager_.targets().log( "Usage requirements for '%s' are '%s'" % (self.name_, usage_requirements)) - rproperties = property_set.create (properties + usage_requirements) + # FIXME: + + rproperties = property_set.create(properties + [p.to_raw() for p in usage_requirements]) usage_requirements = property_set.create (usage_requirements) self.manager_.targets().log( - "Build properties: '%s'" % str(rproperties.raw())) + "Build properties: '%s'" % str(rproperties)) extra = rproperties.get ('') source_targets += replace_grist (extra, '') @@ -1251,7 +1245,7 @@ class TypedTarget (BasicTarget): def construct (self, name, source_targets, prop_set): r = generators.construct (self.project_, name, self.type_, - property_set.create (prop_set.raw () + ['' + self.type_]), + prop_set.add_raw(['' + self.type_]), source_targets) if not r: diff --git a/v2/build/virtual_target.py b/v2/build/virtual_target.py index 5ef3a49b7..d042d9676 100644 --- a/v2/build/virtual_target.py +++ b/v2/build/virtual_target.py @@ -612,6 +612,9 @@ class FileTarget (AbstractFileTarget): self.path_ = path + def __str__(self): + return self.name_ + "." + self.type_ + def clone_with_different_type(self, new_type): return FileTarget(self.name_, new_type, self.project_, self.action_, self.path_, exact=True) @@ -764,7 +767,7 @@ class Action: toolset.set_target_variables (self.manager_, self.action_name_, actual_targets, properties) engine = self.manager_.engine () - + self.manager_.engine ().set_update_action (self.action_name_, actual_targets, self.actual_sources_, properties) diff --git a/v2/build_system.py b/v2/build_system.py index 57f41cff8..1602d5b2e 100644 --- a/v2/build_system.py +++ b/v2/build_system.py @@ -128,7 +128,6 @@ def actual_clean_targets(targets): if isinstance(t, b2.build.targets.ProjectTarget): project_targets.append(t.project_module()) - # Construct a list of targets explicitly detected on this build system run # as a result of building main targets. targets_to_clean = set() @@ -594,16 +593,8 @@ def main_real(): virtual_targets = [] - # Virtual targets obtained when building main targets references on - # the command line. When running - # - # bjam --clean main_target - # - # we want to clean the files that belong only to that main target, - # so we need to record which targets are produced. - results_of_main_targets = [] + global results_of_main_targets - # Now that we have a set of targets to build and a set of property sets to # build the targets with, we can start the main build process by using each # property set to generate virtual targets from all of our listed targets @@ -849,7 +840,7 @@ def main_real(): bjam.call("UPDATE", "clean") else: # FIXME: - #configure.print-configure-checks-summary ; + #configure.print-configure-checks-summary ; if pre_build_hook: pre_build_hook() diff --git a/v2/tools/gcc.py b/v2/tools/gcc.py index 3b280e3d9..fa1ce387e 100644 --- a/v2/tools/gcc.py +++ b/v2/tools/gcc.py @@ -378,7 +378,7 @@ class GccLinkingGenerator(unix.UnixLinkingGenerator): property while creating or using shared library, since it's not supported by gcc/libc. """ - def run(self, project, name, prop_set, sources): + def run(self, project, name, ps, sources): # TODO: Replace this with the use of a target-os property. no_static_link = False @@ -392,10 +392,9 @@ class GccLinkingGenerator(unix.UnixLinkingGenerator): ## } ## } - properties = prop_set.raw() reason = None - if no_static_link and 'static' in properties: - if 'shared' in properties: + if no_static_link and ps.get('runtime-link') == 'static': + if ps.get('link') == 'shared': reason = "On gcc, DLL can't be build with 'static'." elif type.is_derived(self.target_types[0], 'EXE'): for s in sources: @@ -411,7 +410,7 @@ class GccLinkingGenerator(unix.UnixLinkingGenerator): return else: generated_targets = unix.UnixLinkingGenerator.run(self, project, - name, prop_set, sources) + name, ps, sources) return generated_targets if on_windows():