Skip to content

Commit

Permalink
topological sort ordered includes.
Browse files Browse the repository at this point in the history
  • Loading branch information
swatanabe committed Apr 1, 2014
1 parent 5c1a97b commit 290e284
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 30 deletions.
27 changes: 24 additions & 3 deletions src/build/toolset.jam
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import regex ;
import sequence ;
import set ;
import property-set ;
import order ;
import "class" : new ;


.flag-no = 1 ;
Expand Down Expand Up @@ -237,6 +239,7 @@ rule handle-flag-value ( value * : properties * )
if $(value:G)
{
local matches = [ property.select $(value) : $(properties) ] ;
local order ;
for local p in $(matches)
{
local att = [ feature.attributes $(p:G) ] ;
Expand All @@ -263,18 +266,36 @@ rule handle-flag-value ( value * : properties * )
}
if path in $(att)
{
result += [ sequence.transform path.native : $(values) ] ;
values = [ sequence.transform path.native : $(values) ] ;
}
else
result += $(values) ;
if $(values[2])
{
result += $(values) ;
if ! $(order)
{
order = [ new order ] ;
}
local prev ;
for local v in $(values)
{
if $(prev)
{
$(order).add-pair $(prev) $(v) ;
}
prev = $(v) ;
}
}
}
else
{
result += $(p:G=) ;
}
}
if $(order)
{
result = [ $(order).order [ sequence.unique $(result) : stable ] ] ;
DELETE_MODULE $(order) ;
}
}
else
{
Expand Down
10 changes: 5 additions & 5 deletions src/tools/types/cpp.jam
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@ class c-scanner : scanner
import regex ;
import scanner ;
import sequence ;
import toolset ;
import virtual-target ;

rule __init__ ( includes * )
{
scanner.__init__ ;

for local i in $(includes)
{
self.includes += [ sequence.transform path.native : [ regex.split
$(i:G=) "&&" ] ] ;
}
# toolset.handle-flag-value is a bit of overkill, but it
# does correctly handle the topological sort of && separated
# include paths
self.includes = [ toolset.handle-flag-value <include> : $(includes) ] ;
}

rule pattern ( )
Expand Down
176 changes: 154 additions & 22 deletions test/ordered_include.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,166 @@

import BoostBuild

tester = BoostBuild.Tester(use_test_config=False)
def test_basic():
tester = BoostBuild.Tester(use_test_config=False)
tester.write("jamroot.jam", """
obj test : test.cpp : <include>a&&b ;
""")

tester.write("jamroot.jam", """
obj test : test.cpp : <include>a&&b ;
""")
tester.write("test.cpp", """
#include <test1.hpp>
#include <test2.hpp>
int main() {}
""")

tester.write("a/test1.hpp", """
""")

tester.write("b/test2.hpp", """
""")

tester.run_build_system()

tester.expect_addition("bin/$toolset/debug/test.obj")

# Check that the dependencies are correct
tester.touch("a/test1.hpp")
tester.run_build_system()
tester.expect_touch("bin/$toolset/debug/test.obj")

tester.touch("b/test2.hpp")
tester.run_build_system()
tester.expect_touch("bin/$toolset/debug/test.obj")

tester.write("test.cpp", """
#include <test1.hpp>
#include <test2.hpp>
int main() {}
""")
tester.cleanup()

tester.write("a/test1.hpp", """
""")
def test_order1():
t = BoostBuild.Tester(use_test_config=False)
t.write("jamroot.jam", """
obj test : test.cpp : <include>a&&b ;
""")
t.write("test.cpp", """
#include <test.h>
int main() {}
""")
t.write("a/test.h", """
""")
t.write("b/test.h", """
#error should find a/test.h
""")
t.run_build_system()

tester.write("b/test2.hpp", """
""")
t.touch("a/test.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

tester.run_build_system()
t.touch("b/test.h")
t.run_build_system()
t.expect_nothing_more()

tester.expect_addition("bin/$toolset/debug/test.obj")
t.cleanup()

tester.touch("a/test1.hpp")
tester.run_build_system()
tester.expect_touch("bin/$toolset/debug/test.obj")
def test_order2():
t = BoostBuild.Tester(use_test_config=False)
t.write("jamroot.jam", """
obj test : test.cpp : <include>b&&a ;
""")
t.write("test.cpp", """
#include <test.h>
int main() {}
""")
t.write("a/test.h", """
#error should find b/test.h
""")
t.write("b/test.h", """
""")
t.run_build_system()

tester.touch("b/test2.hpp")
tester.run_build_system()
tester.expect_touch("bin/$toolset/debug/test.obj")
t.touch("a/test.h")
t.run_build_system()
t.expect_nothing_more()

tester.cleanup()
t.touch("b/test.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

t.cleanup()

def test_order_graph():
t = BoostBuild.Tester(use_test_config=False)
t.write("jamroot.jam", """
obj test : test.cpp :
<include>b&&a
<include>c&&b
<include>a
<include>c
<include>b
<include>e&&b&&d
;
""")
t.write("test.cpp", """
#include <test1.h>
#include <test2.h>
#include <test3.h>
#include <test4.h>
int main() {}
""")
t.write("b/test1.h", "")
t.write("a/test1.h", "#error should find b/test1.h\n")

t.write("c/test2.h", "")
t.write("b/test2.h", "#error should find c/test2.h\n")

t.write("e/test3.h", "")
t.write("b/test3.h", "#error should find e/test3.h\n")

t.write("b/test4.h", "")
t.write("d/test4.h", "#error should find b/test4.h\n")

t.run_build_system()
t.expect_addition("bin/$toolset/debug/test.obj")

t.touch("b/test1.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

t.touch("a/test1.h")
t.run_build_system()
t.expect_nothing_more()

t.touch("c/test2.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

t.touch("b/test2.h")
t.run_build_system()
t.expect_nothing_more()

t.touch("e/test3.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

t.touch("b/test3.h")
t.run_build_system()
t.expect_nothing_more()

t.touch("b/test4.h")
t.run_build_system()
t.expect_touch("bin/$toolset/debug/test.obj")
t.expect_nothing_more()

t.touch("d/test4.h")
t.run_build_system()
t.expect_nothing_more()

t.cleanup()

test_basic()
test_order1()
test_order2()
test_order_graph()

0 comments on commit 290e284

Please sign in to comment.