From 6d9d4fcfceb8ed5df301de7cea0bb48638894ad1 Mon Sep 17 00:00:00 2001 From: Vladimir Prus Date: Thu, 29 Jul 2010 10:39:31 +0000 Subject: [PATCH] Port notfile.py. Attempt to clean the mess with decorating action names. [SVN r64431] --- v2/build/engine.py | 17 ++++++++++--- v2/build/project.py | 2 +- v2/build/property.py | 10 ++++++-- v2/build/targets.py | 16 ++++++++++++ v2/build/virtual_target.py | 19 +++++++++----- v2/kernel/bootstrap.jam | 8 ++++++ v2/test/BoostBuild.py | 2 +- v2/test/notfile.py | 2 +- v2/tools/make.py | 13 ++-------- v2/tools/notfile.py | 51 ++++++++++++++++++++++++++++++++++++++ 10 files changed, 115 insertions(+), 25 deletions(-) create mode 100644 v2/tools/notfile.py diff --git a/v2/build/engine.py b/v2/build/engine.py index 1fd70446c..2c98e2fb1 100644 --- a/v2/build/engine.py +++ b/v2/build/engine.py @@ -7,9 +7,12 @@ bjam_interface = __import__('bjam') import operator +import re import b2.build.property_set as property_set +_extract_jamfile_and_rule = re.compile("@(Jamfile<.*>)%(.*)") + class BjamAction: """Class representing bjam action defined from Python.""" @@ -20,6 +23,7 @@ class BjamAction: def __call__(self, targets, sources, property_set): if self.function: self.function(targets, sources, property_set) + # Bjam actions defined from Python have only the command # to execute, and no associated jam procedural code. So # passing 'property_set' to it is not necessary. @@ -33,12 +37,19 @@ class BjamNativeAction: self.action_name = action_name def __call__(self, targets, sources, property_set): + p = [] if property_set: - bjam_interface.call("set-update-action", self.action_name, - targets, sources, property_set.raw()) + p = property_set.raw() + + # FIXME: whazzup? + m = None #_extract_jamfile_and_rule.match(self.action_name) + if m: + bjam_interface.call("set-update-action-in-module", + m.group(1), m.group(2), + targets, sources, p) else: bjam_interface.call("set-update-action", self.action_name, - targets, sources, []) + targets, sources, p) action_modifiers = {"updated": 0x01, "together": 0x02, diff --git a/v2/build/project.py b/v2/build/project.py index 8202f8a08..8cf714d7e 100644 --- a/v2/build/project.py +++ b/v2/build/project.py @@ -637,7 +637,7 @@ actual value %s""" % (jamfile_module, saved_project, self.current_project)) mname = "__build_build_temporary__" file = open(location) - try: + try: # TODO: this means we'll never make use of .pyc module, # which might be a problem, or not. module = imp.load_module(mname, file, os.path.basename(location), diff --git a/v2/build/property.py b/v2/build/property.py index c40fea879..41b45b359 100644 --- a/v2/build/property.py +++ b/v2/build/property.py @@ -231,10 +231,16 @@ def translate_indirect(properties, context_module): # will conflict. m = context_module + "." + m - v = context_module + '%' + m + # FIXME: now sure if we should register name with '@' + # or without. + #v = '@' + context_module + '%' + m + #print "REGISTER", get_manager().engine().register_bjam_action(m) + ## FIXME: whatsup? + #get_manager().engine().register_bjam_action(v) + v = '@' + m - result.append(Property(p.feature(), "@" + v, p.condition())) + result.append(Property(p.feature(), v, p.condition())) else: result.append(p) diff --git a/v2/build/targets.py b/v2/build/targets.py index 4d327a044..f93651aaf 100644 --- a/v2/build/targets.py +++ b/v2/build/targets.py @@ -1281,6 +1281,22 @@ class TypedTarget (BasicTarget): return r + +def create_typed_metatarget(name, type, sources, requirements, default_build, usage_requirements): + + from b2.manager import get_manager + t = get_manager().targets() + + project = get_manager().projects().current() + + return t.main_target_alternative( + TypedTarget(name, project, type, + t.main_target_sources(sources, name), + t.main_target_requirements(requirements, project), + t.main_target_default_build(default_build, project), + t.main_target_usage_requirements(usage_requirements, project))) + + def metatarget_function_for_class(class_): @bjam_signature((["name"], ["sources", "*"], ["requirements", "*"], diff --git a/v2/build/virtual_target.py b/v2/build/virtual_target.py index 6d1634902..25b672cc0 100644 --- a/v2/build/virtual_target.py +++ b/v2/build/virtual_target.py @@ -105,7 +105,10 @@ class VirtualTargetRegistry: and equal action. If such target is found it is retured and 'target' is not registered. Otherwise, 'target' is registered and returned. """ - signature = target.path() + "-" + target.name() + if target.path(): + signature = target.path() + "-" + target.name() + else: + signature = "-" + target.name() result = None if not self.cache_.has_key (signature): @@ -566,7 +569,9 @@ def add_prefix_and_suffix(specified_name, type, property_set): """Appends the suffix appropriate to 'type/property-set' combination to the specified name and returns the result.""" - suffix = b2.build.type.generated_target_suffix(type, property_set) + suffix = "" + if type: + suffix = b2.build.type.generated_target_suffix(type, property_set) # Handle suffixes for which no leading dot is desired. Those are # specified by enclosing them in <...>. Needed by python so it @@ -576,7 +581,9 @@ def add_prefix_and_suffix(specified_name, type, property_set): elif suffix: suffix = "." + suffix - prefix = b2.build.type.generated_target_prefix(type, property_set) + prefix = "" + if type: + prefix = b2.build.type.generated_target_prefix(type, property_set) if specified_name.startswith(prefix): prefix = "" @@ -687,8 +694,8 @@ class FileTarget (AbstractFileTarget): class NotFileTarget(AbstractFileTarget): - def __init__(self, name, project): - AbstractFileTarget.__init__(name, project) + def __init__(self, name, project, action): + AbstractFileTarget.__init__(self, name, None, project, action) def path(self): """Returns nothing, to indicate that target path is not known.""" @@ -696,7 +703,7 @@ class NotFileTarget(AbstractFileTarget): def actualize_location(self, target): bjam.call("NOTFILE", target) - bjam.call("ALWAYS", taget) + bjam.call("ALWAYS", target) bjam.call("NOUPDATE", target) diff --git a/v2/kernel/bootstrap.jam b/v2/kernel/bootstrap.jam index a3a5952d7..28ec57348 100644 --- a/v2/kernel/bootstrap.jam +++ b/v2/kernel/bootstrap.jam @@ -192,6 +192,14 @@ if ! $(dont-build) $(action) $(targets) : $(sources) : $(properties) ; } + rule set-update-action-in-module ( m : action : targets * : sources * : properties * ) + { + module $(m) + { + $(2) $(3) : $(4) : $(5) ; + } + } + rule set-target-variable ( targets + : variable : value * : append ? ) { if $(append) diff --git a/v2/test/BoostBuild.py b/v2/test/BoostBuild.py index 8c5024f15..e9756342e 100644 --- a/v2/test/BoostBuild.py +++ b/v2/test/BoostBuild.py @@ -261,7 +261,7 @@ class Tester(TestCmd.TestCmd): verbosity = ['-d+2'] if boost_build_path is None: - boost_build_path = self.original_workdir + boost_build_path = self.original_workdir + "/.." program_list = [] diff --git a/v2/test/notfile.py b/v2/test/notfile.py index c061326a9..f4db79665 100644 --- a/v2/test/notfile.py +++ b/v2/test/notfile.py @@ -38,7 +38,7 @@ t.fail_test(string.find(t.stdout(), "echo hi") == -1) name = t.adjust_names(["bin/$toolset/debug/hello.exe"])[0] name = apply(os.path.join, string.split(name, "/")); -c = "valgrind " + name +c = "valgrind *" + name t.expect_output_line(c) t.cleanup() diff --git a/v2/tools/make.py b/v2/tools/make.py index 391c1380d..10baa1cb4 100644 --- a/v2/tools/make.py +++ b/v2/tools/make.py @@ -16,22 +16,13 @@ from b2.build import type from b2.manager import get_manager import b2.build.property_set -# FIXME: copy-paste from generate.py -import re -_extract_jamfile_and_rule = re.compile("@(Jamfile<.*>)%(.*)") class MakeTarget(BasicTarget): def construct(self, name, source_targets, property_set): - action_name = property_set.get("")[0] - - (jamfile, rule) = _extract_jamfile_and_rule.match(action_name).groups() - # This is very bad. We need to call rule inside the proper module, - # not at global scope, where it might not be available at all. - action_name = rule - - action = Action(get_manager(), source_targets, action_name, property_set) + action_name = property_set.get("")[0] + action = Action(get_manager(), source_targets, action_name[1:], property_set) target = FileTarget(self.name(), type.type(self.name()), self.project(), action, exact=True) return [ b2.build.property_set.empty(), diff --git a/v2/tools/notfile.py b/v2/tools/notfile.py new file mode 100644 index 000000000..afbf68fb0 --- /dev/null +++ b/v2/tools/notfile.py @@ -0,0 +1,51 @@ +# Status: ported. +# Base revision: 64429. +# +# Copyright (c) 2005-2010 Vladimir Prus. +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + + +import b2.build.type as type +import b2.build.generators as generators +import b2.build.virtual_target as virtual_target +import b2.build.toolset as toolset +import b2.build.targets as targets + +from b2.manager import get_manager +from b2.util import bjam_signature + +type.register("NOTFILE_MAIN") + +class NotfileGenerator(generators.Generator): + + def run(self, project, name, ps, sources): + pass + action_name = ps.get('action')[0] + if action_name[0] == '@': + action = virtual_target.Action(get_manager(), sources, action_name[1:], ps) + else: + action = virtual_target.Action(get_manager(), sources, "notfile.run", ps) + + return [get_manager().virtual_targets().register( + virtual_target.NotFileTarget(name, project, action))] + +generators.register(NotfileGenerator("notfile.main", False, [], ["NOTFILE_MAIN"])) + +toolset.flags("notfile.run", "ACTION", [], [""]) + +get_manager().engine().register_action("notfile.run", "$(ACTION)") + +@bjam_signature((["target_name"], ["action"], ["sources", "*"], ["requirements", "*"], + ["default_build", "*"])) +def notfile(target_name, action, sources, requirements, default_build): + + requirements.append("" + action) + + return targets.create_typed_metatarget(target_name, "NOTFILE_MAIN", sources, requirements, + default_build, []) + + +get_manager().projects().add_rule("notfile", notfile)