From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/boost/tools/build/test/dependency_test.py | 239 ++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 src/boost/tools/build/test/dependency_test.py (limited to 'src/boost/tools/build/test/dependency_test.py') diff --git a/src/boost/tools/build/test/dependency_test.py b/src/boost/tools/build/test/dependency_test.py new file mode 100644 index 000000000..852955775 --- /dev/null +++ b/src/boost/tools/build/test/dependency_test.py @@ -0,0 +1,239 @@ +#!/usr/bin/python + +# Copyright 2003 Dave Abrahams +# Copyright 2002, 2003, 2005, 2006 Vladimir Prus +# Distributed under the Boost Software License, Version 1.0. +# (See accompanying file LICENSE_1_0.txt or copy at +# http://www.boost.org/LICENSE_1_0.txt) + +import BoostBuild + + +def test_basic(): + t = BoostBuild.Tester(["-d3", "-d+12"], use_test_config=False) + + t.write("a.cpp", """ +#include +# include "a.h" +#include +int main() {} +""") + t.write("a.h", "\n") + t.write("a_c.c", """\ +#include +# include "a.h" +#include +""") + t.write("b.cpp", """\ +#include "a.h" +int main() {} +""") + t.write("b.h", "\n") + t.write("c.cpp", """\ +#include "x.h" +int main() {} +""") + t.write("e.cpp", """\ +#include "x.h" +int main() {} +""") + t.write("x.foo", "") + t.write("y.foo", "") + + t.write("src1/a.h", '#include "b.h"\n') + t.write("src1/b.h", '#include "c.h"\n') + t.write("src1/c.h", "\n") + t.write("src1/z.h", """\ +extern int dummy_variable_suppressing_empty_file_warning_on_hp_cxx_compiler; +""") + + t.write("src2/b.h", "\n") + + t.write("jamroot.jam", """\ +import foo ; +import types/cpp ; +import types/exe ; + +project test : requirements src1 ; + +exe a : x.foo a.cpp a_c.c ; +exe b : b.cpp ; + +# Because of FOO, c.cpp will be compiled to a different directory than +# everything for main target "a". Therefore, without , C +# preprocessor processing that module will not find "x.h", which is part of +# "a"'s dependency graph. +# +# -------------------------- +# More detailed explanation: +# -------------------------- +# c.cpp includes x.h which does not exist on the current include path so Boost +# Jam will try to match it to existing Jam targets to cover cases as this one +# where the file is generated by the same build. +# +# However, as x.h is not part of "c" metatarget's dependency graph, Boost +# Build will not actualize its target by default, i.e. create its Jam target. +# +# To get the Jam target created in time, we use the +# feature. This tells Boost Build that it needs to actualize the dependency +# graph for metatarget "a", even though that metatarget has not been directly +# mentioned and is not a dependency for any of the metatargets mentioned in the +# current build request. +# +# Note that Boost Build does not automatically add a dependency between the +# Jam targets in question so, if Boost Jam does not add a dependency on a target +# from that other dependency graph (x.h in our case), i.e. if c.cpp does not +# actually include x.h, us actualizing it will have no effect in the end as +# Boost Jam will not have a reason to actually build those targets in spite of +# knowing about them. +exe c : c.cpp : FOO a ; +""") + + t.write("foo.jam", """\ +import generators ; +import modules ; +import os ; +import print ; +import type ; +import types/cpp ; + +type.register FOO : foo ; + +generators.register-standard foo.foo : FOO : CPP H ; + +nl = " +" ; + +rule foo ( targets * : sources * : properties * ) +{ + # On NT, you need an exported symbol in order to have an import library + # generated. We will not really use the symbol defined here, just force the + # import library creation. + if ( [ os.name ] = NT || [ modules.peek : OS ] in CYGWIN ) && + LIB in $(properties) + { + .decl = "void __declspec(dllexport) foo() {}" ; + } + print.output $(<[1]) ; + print.text $(.decl:E="//")$(nl) ; + print.output $(<[2]) ; + print.text "#include "$(nl) ; +} +""") + + t.write("foo.py", +r"""import bjam +import b2.build.type as type +import b2.build.generators as generators + +from b2.manager import get_manager + +type.register("FOO", ["foo"]) +generators.register_standard("foo.foo", ["FOO"], ["CPP", "H"]) + +def prepare_foo(targets, sources, properties): + if properties.get('os') in ['windows', 'cygwin']: + bjam.call('set-target-variable', targets, "DECL", + "void __declspec(dllexport) foo() {}") + +get_manager().engine().register_action("foo.foo", + "echo -e $(DECL:E=//)\\n > $(<[1])\n" + "echo -e "#include \\n" > $(<[2])\n", function=prepare_foo) +""") + + # Check that main target 'c' was able to find 'x.h' from 'a's dependency + # graph. + t.run_build_system() + t.expect_addition("bin/$toolset/debug*/c.exe") + + # Check handling of first level includes. + + # Both 'a' and 'b' include "a.h" and should be updated. + t.touch("a.h") + t.run_build_system() + + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + t.expect_touch("bin/$toolset/debug*/b.exe") + t.expect_touch("bin/$toolset/debug*/b.obj") + t.expect_nothing_more() + + # Only source files using include should be compiled. + t.touch("src1/a.h") + t.run_build_system() + + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + t.expect_nothing_more() + + # "src/a.h" includes "b.h" (in the same dir). + t.touch("src1/b.h") + t.run_build_system() + t.expect_touch("bin/$toolset/debug*/a.exe") + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + t.expect_nothing_more() + + # Included by "src/b.h". We had a bug: file included using double quotes + # (e.g. "b.h") was not scanned at all in this case. + t.touch("src1/c.h") + t.run_build_system() + t.expect_touch("bin/$toolset/debug*/a.exe") + + t.touch("b.h") + t.run_build_system() + t.expect_nothing_more() + + # Test dependency on a generated header. + # + # TODO: we have also to check that generated header is found correctly if + # it is different for different subvariants. Lacking any toolset support, + # this check will be implemented later. + t.touch("x.foo") + t.run_build_system() + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + + # Check that generated headers are scanned for dependencies as well. + t.touch("src1/z.h") + t.run_build_system() + t.expect_touch("bin/$toolset/debug*/a.obj") + t.expect_touch("bin/$toolset/debug*/a_c.obj") + + t.cleanup() + + +def test_scanned_includes_with_absolute_paths(): + """ + Regression test: on Windows, with absolute paths were not + considered when scanning dependencies. + + """ + t = BoostBuild.Tester(["-d3", "-d+12"]) + + t.write("jamroot.jam", """\ +path-constant TOP : . ; +exe app : main.cpp : $(TOP)/include ; +"""); + + t.write("main.cpp", """\ +#include +int main() {} +""") + + t.write("include/dir/header.h", "\n") + + t.run_build_system() + t.expect_addition("bin/$toolset/debug*/main.obj") + + t.touch("include/dir/header.h") + t.run_build_system() + t.expect_touch("bin/$toolset/debug*/main.obj") + + t.cleanup() + + +test_basic() +test_scanned_includes_with_absolute_paths() -- cgit v1.2.3