Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r48590 - in trunk/tools/build/v2: build test
From: jurko.gospodnetic_at_[hidden]
Date: 2008-09-04 20:26:43


Author: jurko
Date: 2008-09-04 20:26:43 EDT (Thu, 04 Sep 2008)
New Revision: 48590
URL: http://svn.boost.org/trac/boost/changeset/48590

Log:
Added a test for and fixed a Boost Build generator selection bug caused by caching viable source target types for different target types and generators and not maintaining those caches when their content gets invalidated by defining a new generator. Currently quick-fixed by clearing most of the cached values when registering a new generator. Later on this could be made more detailed by clearing only the actually invalidated cache values or updating them or even only marking them to be lazily updated when needed next.

Problem detected & and a reproducible example constructed by Juraj Ivančić. Debugged by Vladimir Prus. Patched and packaged by Jurko Gospodnetić.
Added:
   trunk/tools/build/v2/test/generator_selection.py (contents, props changed)
Text files modified:
   trunk/tools/build/v2/build/generators.jam | 57 ++++++++++++++++++++++++++++++++++++++++
   trunk/tools/build/v2/test/test_all.py | 3 +
   2 files changed, 59 insertions(+), 1 deletions(-)

Modified: trunk/tools/build/v2/build/generators.jam
==============================================================================
--- trunk/tools/build/v2/build/generators.jam (original)
+++ trunk/tools/build/v2/build/generators.jam 2008-09-04 20:26:43 EDT (Thu, 04 Sep 2008)
@@ -58,6 +58,43 @@
 }
 
 
+# Clears cached viable source target type information except for target types
+# and generators with all source types listed as viable. Should be called when
+# something invalidates those cached values by possibly causing some new source
+# types to become viable.
+#
+local rule invalidate-extendable-viable-source-target-type-cache ( )
+{
+ local generators-with-cached-source-types = $(.vstg-cached-generators) ;
+ .vstg-cached-generators = ;
+ for local gen in $(generators-with-cached-source-types)
+ {
+ if $(.vstg.$(gen)) = *
+ {
+ .vstg-cached-generators += $(gen) ;
+ }
+ else
+ {
+ .vstg.$(gen) = ;
+ }
+ }
+
+ local types-with-cached-source-types = $(.vst-cached-types) ;
+ .vst-cached-types = ;
+ for local type in $(types-with-cached-source-types)
+ {
+ if $(.vst.$(type)) = *
+ {
+ .vst-cached-types += $(gen) ;
+ }
+ else
+ {
+ .vst.$(type) = ;
+ }
+ }
+}
+
+
 # Outputs a debug message if generators debugging is on. Each element of
 # 'message' is checked to see if it is a class instance. If so, instead of the
 # value, the result of 'str' call is output.
@@ -643,6 +680,24 @@
         base = $(base:B) ;
     }
     .generators-for-toolset.$(base) += $(g) ;
+
+
+ # After adding a new generator that can construct new target types, we need
+ # to clear the related cached viable source target type information for
+ # constructing a specific target type or using a specific generator. Cached
+ # viable source target type lists affected by this are those containing any
+ # of the target types constructed by the new generator or any of their base
+ # target types.
+ #
+ # A more advanced alternative to clearing that cached viable source target
+ # type information would be to expand it with additional source types or
+ # even better - mark it as needing to be expanded on next use.
+ #
+ # For now we just clear all the cached viable source target type information
+ # that does not simply state 'all types' and may implement a more detailed
+ # algorithm later on if it becomes needed.
+
+ invalidate-extendable-viable-source-target-type-cache ;
 }
 
 
@@ -783,6 +838,7 @@
     local key = .vst.$(target-type) ;
     if ! $($(key))
     {
+ .vst-cached-types += $(target-type) ;
         local v = [ viable-source-types-real $(target-type) ] ;
         if ! $(v)
         {
@@ -844,6 +900,7 @@
     local key = .vstg.$(generator) ;
     if ! $($(key))
     {
+ .vstg-cached-generators += $(generator) ;
         local v = [ viable-source-types-for-generator-real $(generator) ] ;
         if ! $(v)
         {

Added: trunk/tools/build/v2/test/generator_selection.py
==============================================================================
--- (empty file)
+++ trunk/tools/build/v2/test/generator_selection.py 2008-09-04 20:26:43 EDT (Thu, 04 Sep 2008)
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+
+# Copyright 2008 Jurko Gospodnetic
+# Distributed under the Boost Software License, Version 1.0.
+# (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+
+# Tests that generators get selected correctly.
+
+import BoostBuild
+
+
+################################################################################
+#
+# test_generator_added_after_already_building_a_target_of_its_target_type()
+# -------------------------------------------------------------------------
+#
+################################################################################
+
+def test_generator_added_after_already_building_a_target_of_its_target_type():
+ """Regression test for a Boost Build bug causing it to not use a generator
+ if it got added after already building a targer of its target type.
+ """
+
+ t = BoostBuild.Tester()
+
+ t.write("dummy.cpp", "void f() {}\n")
+
+ t.write("jamroot.jam", """
+# Building this dummy target must not cause a later defined CPP target type
+# generator not to be recognized as viable.
+obj dummy : dummy.cpp ;
+alias the-other-obj : Other//other-obj ;
+""")
+
+ t.write("Other/source.extension", "A dummy source file.")
+
+ t.write("Other/mygen.jam", """
+import generators ;
+import type ;
+type.register MY_TYPE : extension ;
+generators.register-standard mygen.generate-a-cpp-file : MY_TYPE : CPP ;
+rule generate-a-cpp-file { ECHO Generating a CPP file... ; }
+actions generate-a-cpp-file { echo void g() {} > "$(<)" }
+""")
+
+ t.write("Other/jamfile.jam", """
+import mygen ;
+obj other-obj : source.extension ;
+""")
+
+ t.run_build_system()
+ t.expect_output_line("Generating a CPP file...")
+
+ t.cleanup()
+
+
+################################################################################
+#
+# main()
+# ------
+#
+################################################################################
+
+test_generator_added_after_already_building_a_target_of_its_target_type()

Modified: trunk/tools/build/v2/test/test_all.py
==============================================================================
--- trunk/tools/build/v2/test/test_all.py (original)
+++ trunk/tools/build/v2/test/test_all.py 2008-09-04 20:26:43 EDT (Thu, 04 Sep 2008)
@@ -171,7 +171,8 @@
           "sort_rule",
           "ordered_include",
           "test_result_dumping",
- "inherited_dependency"
+ "inherited_dependency",
+ "generator_selection"
           ]
 
 if os.name == 'posix':


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk