#!/usr/bin/python # Copyright 2003 Dave Abrahams # Copyright 2006 Rene Rivera # Copyright 2003 Vladimir Prus # 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) import BoostBuild import os import re spaces_re = re.compile("\ \ +") trailing_spaces_re = re.compile("\ +\n") t = BoostBuild.Tester("-d+1", pass_toolset=0) t.set_tree('module-actions') # Note that the following string contains some trailing spaces that should not # be removed. expected_output = """...found 4 targets... ...updating 3 targets... A.act t1 A.act t1: X1-t1 B.act t1 B.act t1: X1-t1 X2-B act t1 act t1: X1-t1 X2-global X3-global A.act t2 A.act t2: X1-A X2-t2
#!/usr/bin/python # Copyright 2001 Dave Abrahams # Copyright 2011 Steven Watanabe # 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) import BoostBuild import os t = BoostBuild.Tester(["-d1"], pass_toolset=0) t.write("subdir1/file-to-bind", "# This file intentionally left blank") t.write( "file.jam", """\ rule do-nothing ( target : source ) { DEPENDS $(target) : $(source) ; } actions quietly do-nothing { } # Make a non-file target which depends on a file that exists NOTFILE fake-target ; SEARCH on file-to-bind = subdir1 ; do-nothing fake-target : file-to-bind ; # Set jam up to call our bind-rule BINDRULE = bind-rule ;
# 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) # Test the 'symlink' rule. import os import BoostBuild if os.name != 'posix': print "The symlink tests can be run on posix only." import sys sys.exit(1) t = BoostBuild.Tester(use_test_config=False) t.write("jamroot.jam", "import gcc ;") t.write("jamfile.jam", """ exe hello : hello.cpp ; symlink hello_release : hello/<variant>release ; symlink hello_debug : hello/<variant>debug ; symlink links/hello_release : hello/<variant>release ; """) t.write("hello.cpp", """ int main() {} """) t.run_build_system()
def test_invalid(params, expected_error_line): t = BoostBuild.Tester(pass_toolset=0) t.write("file.jam", "SPLIT_BY_CHARACTERS %s ;" % params) t.run_build_system(["-ffile.jam"], status=1) t.expect_output_lines("[*] %s" % expected_error_line) t.cleanup()
#!/usr/bin/python # Copyright 2003 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) # Test that unused sources are at least reported. import BoostBuild t = BoostBuild.Tester(["-d+2"], use_test_config=False) t.write("a.cpp", "int main() {}\n") t.write("b.cpp", "\n") t.write("b.x", "") t.write( "jamroot.jam", """\ import "class" : new ; import modules ; import project ; import targets ; import type ; import virtual-target ; type.register X : x ; class test-target-class : basic-target { rule construct ( name : source-targets * : property-set ) {
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()
# Added to guard against a bug causing targets to be used before they # themselves have finished building. This used to happen for targets built by a # multi-file action that got triggered by another target, except when the target # triggering the action was the first one in the list of targets produced by # that action. # # Example: # When target A and target B were declared as created by a single action with # A being the first one listed, and target B triggered running that action then # while the action was still running, target A was already reporting as being # built causing other targets depending on target A to be built prematurely. import BoostBuild t = BoostBuild.Tester(pass_toolset=0, pass_d0=False) t.write("sleep.bat","""@setlocal @echo off @REM timeout /T %1 /NOBREAK >nul ping 127.0.0.1 -n 2 -w 1000 >nul ping 127.0.0.1 -n %1 -w 1000 >nul @endlocal @exit /B 0 """) t.write("file.jam", """ if $(NT) { SLEEP = @call sleep.bat ;
def test_user_configuration(): """Test Boost Build user configuration handling. Both relative and absolute path handling is tested. """ t = BoostBuild.Tester("--debug-configuration", pass_toolset=False, use_test_config=False) implicitConfigLoadMessage = "notice: Loading user-config configuration file: *" explicitConfigLoadMessage = "notice: Loading explicitly specified user configuration file:" testMessage = "_!_!_!_!_!_!_!_!_ %s _!_!_!_!_!_!_!_!_" toolsetName = "__myDummyToolset__" subdirName = "ASubDirectory" configFileNames = ["ups_lala_1.jam", "ups_lala_2.jam", os.path.join(subdirName, "ups_lala_3.jam")] for configFileName in configFileNames: message = "ECHO \"%s\" ;" % testMessage % configFileName # We need to double any backslashes in the message or Jam will interpret # them as escape characters. t.write(configFileName, message.replace("\\", "\\\\")) # Prepare a dummy toolset so we do not get errors in case the default one is # not found. t.write(toolsetName + ".jam", """ import feature ; feature.extend toolset : %s ; rule init ( ) { } """ % toolsetName ) t.write("jamroot.jam", "using %s ;" % toolsetName) t.run_build_system() t.expect_output_line(explicitConfigLoadMessage, False) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2], False) t.run_build_system("--user-config=") t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage, False) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2], False) t.run_build_system('--user-config=""') t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage, False) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2], False) t.run_build_system('--user-config="%s"' % configFileNames[0]) t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage) t.expect_output_line(testMessage % configFileNames[0] ) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2], False) t.run_build_system('--user-config="%s"' % configFileNames[2]) t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2] ) t.run_build_system('--user-config="%s"' % os.path.abspath(configFileNames[1])) t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1] ) t.expect_output_line(testMessage % configFileNames[2], False) t.run_build_system('--user-config="%s"' % os.path.abspath(configFileNames[2])) t.expect_output_line(implicitConfigLoadMessage, False) t.expect_output_line(explicitConfigLoadMessage) t.expect_output_line(testMessage % configFileNames[0], False) t.expect_output_line(testMessage % configFileNames[1], False) t.expect_output_line(testMessage % configFileNames[2] ) t.cleanup()
#if defined(_WIN32) __declspec(dllexport) #endif foo() {} """) t.write("main.cpp", """\ #ifdef WANT_MAIN int main() {} #endif """) t.run_build_system() ############################################################################### # # main() # ------ # ############################################################################### # We do not pass the '-d0' option to Boost Build here to get more detailed # information in case of failure. t = BoostBuild.Tester(pass_d0=False, use_test_config=False) test_alias_rule(t) test_alias_source_usage_requirements(t) t.cleanup()
#!/usr/bin/python # (c) Copyright Juergen Hunold 2008 # Use, modification, and distribution are subject to the # Boost Software License, Version 1.0. (See accompanying file # LICENSE.txt or copy at https://www.bfgroup.xyz/b2/LICENSE.txt) import BoostBuild import os # Run test in real directory in order to find Boost.Test via Boost Top-Level # Jamroot. qt4_dir = os.getcwd() + "/qt4" t = BoostBuild.Tester(workdir=qt4_dir) t.run_build_system() t.cleanup()
#!/usr/bin/python # Copyright (C) Vladimir Prus 2006. # 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) # Test the 'make' example. import BoostBuild import sys t = BoostBuild.Tester(['example.python.interpreter=%s' % sys.executable]) t.set_tree("../example/make") t.run_build_system() t.expect_addition(["bin/$toolset/debug/main.cpp"]) t.cleanup()
def test_multiple_conditions(): """Basic tests for properties conditioned on multiple other properties.""" t = BoostBuild.Tester( ["--user-config=", "--ignore-site-config", "toolset=testToolset"], pass_toolset=False, use_test_config=False) t.write( "testToolset.jam", """\ import feature ; feature.extend toolset : testToolset ; rule init ( ) { } """) t.write( "testToolset.py", """\ from b2.build import feature feature.extend('toolset', ["testToolset"]) def init ( ): pass """) t.write( "jamroot.jam", """\ import feature ; import notfile ; import toolset ; feature.feature description : : free incidental ; feature.feature aaa : 1 0 : incidental ; feature.feature bbb : 1 0 : incidental ; feature.feature ccc : 1 0 : incidental ; rule buildRule ( name : targets ? : properties * ) { for local description in [ feature.get-values description : $(properties) ] { ECHO "description:" /$(description)/ ; } } notfile testTarget1 : @buildRule : : <description>d <aaa>0:<description>a0 <aaa>1:<description>a1 <aaa>0,<bbb>0:<description>a0-b0 <aaa>0,<bbb>1:<description>a0-b1 <aaa>1,<bbb>0:<description>a1-b0 <aaa>1,<bbb>1:<description>a1-b1 <aaa>0,<bbb>0,<ccc>0:<description>a0-b0-c0 <aaa>0,<bbb>0,<ccc>1:<description>a0-b0-c1 <aaa>0,<bbb>1,<ccc>1:<description>a0-b1-c1 <aaa>1,<bbb>0,<ccc>1:<description>a1-b0-c1 <aaa>1,<bbb>1,<ccc>0:<description>a1-b1-c0 <aaa>1,<bbb>1,<ccc>1:<description>a1-b1-c1 ; """) t.run_build_system(["aaa=1", "bbb=1", "ccc=1"]) t.expect_output_lines("description: /d/") t.expect_output_lines("description: /a0/", False) t.expect_output_lines("description: /a1/") t.expect_output_lines("description: /a0-b0/", False) t.expect_output_lines("description: /a0-b1/", False) t.expect_output_lines("description: /a1-b0/", False) t.expect_output_lines("description: /a1-b1/") t.expect_output_lines("description: /a0-b0-c0/", False) t.expect_output_lines("description: /a0-b0-c1/", False) t.expect_output_lines("description: /a0-b1-c1/", False) t.expect_output_lines("description: /a1-b0-c1/", False) t.expect_output_lines("description: /a1-b1-c0/", False) t.expect_output_lines("description: /a1-b1-c1/") t.run_build_system(["aaa=0", "bbb=0", "ccc=1"]) t.expect_output_lines("description: /d/") t.expect_output_lines("description: /a0/") t.expect_output_lines("description: /a1/", False) t.expect_output_lines("description: /a0-b0/") t.expect_output_lines("description: /a0-b1/", False) t.expect_output_lines("description: /a1-b0/", False) t.expect_output_lines("description: /a1-b1/", False) t.expect_output_lines("description: /a0-b0-c0/", False) t.expect_output_lines("description: /a0-b0-c1/") t.expect_output_lines("description: /a0-b1-c1/", False) t.expect_output_lines("description: /a1-b0-c1/", False) t.expect_output_lines("description: /a1-b1-c0/", False) t.expect_output_lines("description: /a1-b1-c1/", False) t.run_build_system(["aaa=0", "bbb=0", "ccc=0"]) t.expect_output_lines("description: /d/") t.expect_output_lines("description: /a0/") t.expect_output_lines("description: /a1/", False) t.expect_output_lines("description: /a0-b0/") t.expect_output_lines("description: /a0-b1/", False) t.expect_output_lines("description: /a1-b0/", False) t.expect_output_lines("description: /a1-b1/", False) t.expect_output_lines("description: /a0-b0-c0/") t.expect_output_lines("description: /a0-b0-c1/", False) t.expect_output_lines("description: /a0-b1-c1/", False) t.expect_output_lines("description: /a1-b0-c1/", False) t.expect_output_lines("description: /a1-b1-c0/", False) t.expect_output_lines("description: /a1-b1-c1/", False) t.cleanup()
def test_multiple_conditions_with_toolset_version(): """ Regression tests for properties conditioned on the toolset version subfeature and some additional properties. """ toolset = "testToolset" t = BoostBuild.Tester(["--user-config=", "--ignore-site-config"], pass_toolset=False, use_test_config=False) t.write( toolset + ".jam", """\ import feature ; feature.extend toolset : %(toolset)s ; feature.subfeature toolset %(toolset)s : version : 0 1 ; rule init ( version ? ) { } """ % {"toolset": toolset}) t.write( "testToolset.py", """\ from b2.build import feature feature.extend('toolset', ["%(toolset)s"]) feature.subfeature('toolset', "%(toolset)s", "version", ['0','1']) def init (version=''): pass """ % {"toolset": toolset}) t.write( "jamroot.jam", """\ import feature ; import notfile ; import toolset ; toolset.using testToolset ; feature.feature description : : free incidental ; feature.feature aaa : 0 1 : incidental ; feature.feature bbb : 0 1 : incidental ; feature.feature ccc : 0 1 : incidental ; rule buildRule ( name : targets ? : properties * ) { local ttt = [ feature.get-values toolset : $(properties) ] ; local vvv = [ feature.get-values "toolset-testToolset:version" : $(properties) ] ; local aaa = [ feature.get-values aaa : $(properties) ] ; local bbb = [ feature.get-values bbb : $(properties) ] ; local ccc = [ feature.get-values ccc : $(properties) ] ; ECHO "toolset:" /$(ttt)/ "version:" /$(vvv)/ "aaa/bbb/ccc:" /$(aaa)/$(bbb)/$(ccc)/ ; for local description in [ feature.get-values description : $(properties) ] { ECHO "description:" /$(description)/ ; } } notfile testTarget1 : @buildRule : : <toolset>testToolset,<aaa>0:<description>t-a0 <toolset>testToolset,<aaa>1:<description>t-a1 <toolset>testToolset-0,<aaa>0:<description>t0-a0 <toolset>testToolset-0,<aaa>1:<description>t0-a1 <toolset>testToolset-1,<aaa>0:<description>t1-a0 <toolset>testToolset-1,<aaa>1:<description>t1-a1 <toolset>testToolset,<aaa>0,<bbb>0:<description>t-a0-b0 <toolset>testToolset,<aaa>0,<bbb>1:<description>t-a0-b1 <toolset>testToolset,<aaa>1,<bbb>0:<description>t-a1-b0 <toolset>testToolset,<aaa>1,<bbb>1:<description>t-a1-b1 <aaa>0,<toolset>testToolset,<bbb>0:<description>a0-t-b0 <aaa>0,<toolset>testToolset,<bbb>1:<description>a0-t-b1 <aaa>1,<toolset>testToolset,<bbb>0:<description>a1-t-b0 <aaa>1,<toolset>testToolset,<bbb>1:<description>a1-t-b1 <aaa>0,<bbb>0,<toolset>testToolset:<description>a0-b0-t <aaa>0,<bbb>1,<toolset>testToolset:<description>a0-b1-t <aaa>1,<bbb>0,<toolset>testToolset:<description>a1-b0-t <aaa>1,<bbb>1,<toolset>testToolset:<description>a1-b1-t <toolset>testToolset-0,<aaa>0,<bbb>0:<description>t0-a0-b0 <toolset>testToolset-0,<aaa>0,<bbb>1:<description>t0-a0-b1 <toolset>testToolset-0,<aaa>1,<bbb>0:<description>t0-a1-b0 <toolset>testToolset-0,<aaa>1,<bbb>1:<description>t0-a1-b1 <toolset>testToolset-1,<aaa>0,<bbb>0:<description>t1-a0-b0 <toolset>testToolset-1,<aaa>0,<bbb>1:<description>t1-a0-b1 <toolset>testToolset-1,<aaa>1,<bbb>0:<description>t1-a1-b0 <toolset>testToolset-1,<aaa>1,<bbb>1:<description>t1-a1-b1 <aaa>0,<toolset>testToolset-1,<bbb>0:<description>a0-t1-b0 <aaa>0,<toolset>testToolset-1,<bbb>1:<description>a0-t1-b1 <aaa>1,<toolset>testToolset-0,<bbb>0:<description>a1-t0-b0 <aaa>1,<toolset>testToolset-0,<bbb>1:<description>a1-t0-b1 <bbb>0,<aaa>1,<toolset>testToolset-0:<description>b0-a1-t0 <bbb>0,<aaa>0,<toolset>testToolset-1:<description>b0-a0-t1 <bbb>0,<aaa>1,<toolset>testToolset-1:<description>b0-a1-t1 <bbb>1,<aaa>0,<toolset>testToolset-1:<description>b1-a0-t1 <bbb>1,<aaa>1,<toolset>testToolset-0:<description>b1-a1-t0 <bbb>1,<aaa>1,<toolset>testToolset-1:<description>b1-a1-t1 ; """) t.run_build_system(["aaa=1", "bbb=1", "ccc=1", "toolset=%s-0" % toolset]) t.expect_output_lines("description: /t-a0/", False) t.expect_output_lines("description: /t-a1/") t.expect_output_lines("description: /t0-a0/", False) t.expect_output_lines("description: /t0-a1/") t.expect_output_lines("description: /t1-a0/", False) t.expect_output_lines("description: /t1-a1/", False) t.expect_output_lines("description: /t-a0-b0/", False) t.expect_output_lines("description: /t-a0-b1/", False) t.expect_output_lines("description: /t-a1-b0/", False) t.expect_output_lines("description: /t-a1-b1/") t.expect_output_lines("description: /a0-t-b0/", False) t.expect_output_lines("description: /a0-t-b1/", False) t.expect_output_lines("description: /a1-t-b0/", False) t.expect_output_lines("description: /a1-t-b1/") t.expect_output_lines("description: /a0-b0-t/", False) t.expect_output_lines("description: /a0-b1-t/", False) t.expect_output_lines("description: /a1-b0-t/", False) t.expect_output_lines("description: /a1-b1-t/") t.expect_output_lines("description: /t0-a0-b0/", False) t.expect_output_lines("description: /t0-a0-b1/", False) t.expect_output_lines("description: /t0-a1-b0/", False) t.expect_output_lines("description: /t0-a1-b1/") t.expect_output_lines("description: /t1-a0-b0/", False) t.expect_output_lines("description: /t1-a0-b1/", False) t.expect_output_lines("description: /t1-a1-b0/", False) t.expect_output_lines("description: /t1-a1-b1/", False) t.expect_output_lines("description: /a0-t1-b0/", False) t.expect_output_lines("description: /a0-t1-b1/", False) t.expect_output_lines("description: /a1-t0-b0/", False) t.expect_output_lines("description: /a1-t0-b1/") t.expect_output_lines("description: /b0-a1-t0/", False) t.expect_output_lines("description: /b0-a0-t1/", False) t.expect_output_lines("description: /b0-a1-t1/", False) t.expect_output_lines("description: /b1-a0-t1/", False) t.expect_output_lines("description: /b1-a1-t0/") t.expect_output_lines("description: /b1-a1-t1/", False) t.run_build_system(["aaa=1", "bbb=1", "ccc=1", "toolset=%s-1" % toolset]) t.expect_output_lines("description: /t-a0/", False) t.expect_output_lines("description: /t-a1/") t.expect_output_lines("description: /t0-a0/", False) t.expect_output_lines("description: /t0-a1/", False) t.expect_output_lines("description: /t1-a0/", False) t.expect_output_lines("description: /t1-a1/") t.expect_output_lines("description: /t-a0-b0/", False) t.expect_output_lines("description: /t-a0-b1/", False) t.expect_output_lines("description: /t-a1-b0/", False) t.expect_output_lines("description: /t-a1-b1/") t.expect_output_lines("description: /a0-t-b0/", False) t.expect_output_lines("description: /a0-t-b1/", False) t.expect_output_lines("description: /a1-t-b0/", False) t.expect_output_lines("description: /a1-t-b1/") t.expect_output_lines("description: /a0-b0-t/", False) t.expect_output_lines("description: /a0-b1-t/", False) t.expect_output_lines("description: /a1-b0-t/", False) t.expect_output_lines("description: /a1-b1-t/") t.expect_output_lines("description: /t0-a0-b0/", False) t.expect_output_lines("description: /t0-a0-b1/", False) t.expect_output_lines("description: /t0-a1-b0/", False) t.expect_output_lines("description: /t0-a1-b1/", False) t.expect_output_lines("description: /t1-a0-b0/", False) t.expect_output_lines("description: /t1-a0-b1/", False) t.expect_output_lines("description: /t1-a1-b0/", False) t.expect_output_lines("description: /t1-a1-b1/") t.expect_output_lines("description: /a0-t1-b0/", False) t.expect_output_lines("description: /a0-t1-b1/", False) t.expect_output_lines("description: /a1-t0-b0/", False) t.expect_output_lines("description: /a1-t0-b1/", False) t.expect_output_lines("description: /b0-a1-t0/", False) t.expect_output_lines("description: /b0-a0-t1/", False) t.expect_output_lines("description: /b0-a1-t1/", False) t.expect_output_lines("description: /b1-a0-t1/", False) t.expect_output_lines("description: /b1-a1-t0/", False) t.expect_output_lines("description: /b1-a1-t1/") t.cleanup()
def test_conditions_on_default_toolset(): """Test that toolset and toolset subfeature conditioned properties get applied correctly when the toolset is selected by default. Implicitly tests that we can use the set-default-toolset rule to set the default toolset to be used by Boost Build. """ t = BoostBuild.Tester("--user-config= --ignore-site-config", pass_toolset=False, use_test_config=False) toolset_name = "myCustomTestToolset" toolset_version = "v" toolset_version_unused = "v_unused" message_loaded = "Toolset '%s' loaded." % toolset_name message_initialized = "Toolset '%s' initialized." % toolset_name ; # Custom toolset. t.write(toolset_name + ".jam", """ import feature ; ECHO "%(message_loaded)s" ; feature.extend toolset : %(toolset_name)s ; feature.subfeature toolset %(toolset_name)s : version : %(toolset_version)s %(toolset_version_unused)s ; rule init ( version ) { ECHO "%(message_initialized)s" ; } """ % {'message_loaded' : message_loaded , 'message_initialized' : message_initialized, 'toolset_name' : toolset_name , 'toolset_version' : toolset_version , 'toolset_version_unused': toolset_version_unused}) # Main Boost Build project script. t.write("jamroot.jam", """ import build-system ; import errors ; import feature ; import notfile ; build-system.set-default-toolset %(toolset_name)s : %(toolset_version)s ; feature.feature description : : free incidental ; # We use a rule instead of an action to avoid problems with action output not # getting piped to stdout by the testing system. rule buildRule ( names : targets ? : properties * ) { local descriptions = [ feature.get-values description : $(properties) ] ; ECHO "descriptions:" /$(descriptions)/ ; local toolset = [ feature.get-values toolset : $(properties) ] ; ECHO "toolset:" /$(toolset)/ ; local toolset-version = [ feature.get-values "toolset-$(toolset):version" : $(properties) ] ; ECHO "toolset-version:" /$(toolset-version)/ ; } notfile testTarget : @buildRule : : <description>stand-alone <toolset>%(toolset_name)s:<description>toolset <toolset>%(toolset_name)s-%(toolset_version)s:<description>toolset-version <toolset>%(toolset_name)s-%(toolset_version_unused)s:<description>toolset-version-unused ; """ % {'toolset_name' : toolset_name , 'toolset_version' : toolset_version, 'toolset_version_unused': toolset_version_unused}) t.run_build_system() t.expect_output_lines(configuring_default_toolset_message % toolset_name) t.expect_output_lines(message_loaded) t.expect_output_lines(message_initialized) t.expect_output_lines("descriptions: /stand-alone/ /toolset/ " "/toolset-version/") t.expect_output_lines("toolset: /%s/" % toolset_name) t.expect_output_lines("toolset-version: /%s/" % toolset_version) t.cleanup()
#!/usr/bin/python # Copyright 2002, 2003 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) # This tests correct handling of "-d1" and "-d2" options. import BoostBuild t = BoostBuild.Tester(["-ffile.jam"], pass_toolset=0) t.write("file.jam", """\ actions a { } actions quietly b { } ALWAYS all ; a all ; b all ; """) t.run_build_system(["-d0"], stdout="") t.run_build_system(["-d1"]) t.expect_output_lines("a all") t.expect_output_lines("b all", False) t.run_build_system(["-d2"]) t.expect_output_lines("a all") t.expect_output_lines("b all")
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 target of its target type. """ t = BoostBuild.Tester() t.write("dummy.cpp", "void f() {}\n") t.write("jamroot.jam", """\ import common ; import generators ; import type ; type.register MY_OBJ : my_obj ; generators.register-standard common.copy : CPP : MY_OBJ ; # Building this dummy target must not cause a later defined CPP target type # generator not to be recognized as viable. my-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 common ; import generators ; import type ; type.register MY_TYPE : extension ; generators.register-standard $(__name__).generate-a-cpp-file : MY_TYPE : CPP ; rule generate-a-cpp-file { ECHO Generating a CPP file... ; } CREATE-FILE = [ common.file-creation-command ] ; actions generate-a-cpp-file { $(CREATE-FILE) "$(<)" } """) t.write("Other/mygen.py", """\ import b2.build.generators as generators import b2.build.type as type from b2.manager import get_manager import os type.register('MY_TYPE', ['extension']) generators.register_standard('mygen.generate-a-cpp-file', ['MY_TYPE'], ['CPP']) if os.name == 'nt': action = 'echo void g() {} > "$(<)"' else: action = 'echo "void g() {}" > "$(<)"' def f(*args): print "Generating a CPP file..." get_manager().engine().register_action("mygen.generate-a-cpp-file", action, function=f) """) t.write("Other/jamfile.jam", """\ import mygen ; my-obj other-obj : source.extension ; """) t.run_build_system() t.expect_output_lines("Generating a CPP file...") t.expect_addition("bin/$toolset/debug/dummy.my_obj") t.expect_addition("Other/bin/$toolset/debug/other-obj.cpp") t.expect_addition("Other/bin/$toolset/debug/other-obj.my_obj") t.expect_nothing_more() t.cleanup()
#if defined(_WIN32) __declspec(dllexport) #endif foo() {} """) t.write("main.cpp", """\ #ifdef WANT_MAIN int main() {} #endif """) t.run_build_system() ############################################################################### # # main() # ------ # ############################################################################### # We do not pass the '-d0' option to Boost Build here to get more detailed # information in case of failure. t = BoostBuild.Tester(pass_d0=False) test_alias_rule(t) test_alias_source_usage_requirements(t) t.cleanup()
def test_repeated_ids_for_same_project(): t = BoostBuild.Tester() t.write("jamroot.jam", "project foo ; project foo ;") t.run_build_system() t.write("jamroot.jam", "project foo ; use-project foo : . ;") t.run_build_system() t.write("jamroot.jam", "project foo ; use-project foo : ./. ;") t.run_build_system() t.write( "jamroot.jam", """\ project foo ; use-project foo : . ; use-project foo : ./aaa/.. ; use-project foo : ./. ; """) t.run_build_system() # On Windows we have a case-insensitive file system and we can use # backslashes as path separators. # FIXME: Make a similar test pass on Cygwin. if sys.platform in ['win32']: t.write("a/fOo bAr/b/jamfile.jam", "") t.write( "jamroot.jam", r""" use-project bar : "a/foo bar/b" ; use-project bar : "a/foO Bar/b" ; use-project bar : "a/foo BAR/b/" ; use-project bar : "a\\.\\FOO bar\\b\\" ; """) t.run_build_system() t.rm("a") t.write("bar/jamfile.jam", "") t.write( "jamroot.jam", """\ use-project bar : bar ; use-project bar : bar/ ; use-project bar : bar// ; use-project bar : bar/// ; use-project bar : bar//// ; use-project bar : bar/. ; use-project bar : bar/./ ; use-project bar : bar/////./ ; use-project bar : bar/../bar/xxx/.. ; use-project bar : bar/..///bar/xxx///////.. ; use-project bar : bar/./../bar/xxx/.. ; use-project bar : bar/.////../bar/xxx/.. ; use-project bar : bar/././../bar/xxx/.. ; use-project bar : bar/././//////////../bar/xxx/.. ; use-project bar : bar/.///.////../bar/xxx/.. ; use-project bar : bar/./././xxx/.. ; use-project bar : bar/xxx////.. ; use-project bar : bar/xxx/.. ; use-project bar : bar///////xxx/.. ; """) t.run_build_system() t.rm("bar") # On Windows we have a case-insensitive file system and we can use # backslashes as path separators. # FIXME: Make a similar test pass on Cygwin. if sys.platform in ['win32']: t.write("baR/jamfile.jam", "") t.write( "jamroot.jam", r""" use-project bar : bar ; use-project bar : BAR ; use-project bar : bAr ; use-project bar : bAr/ ; use-project bar : bAr\\ ; use-project bar : bAr\\\\ ; use-project bar : bAr\\\\///// ; use-project bar : bAr/. ; use-project bar : bAr/./././ ; use-project bar : bAr\\.\\.\\.\\ ; use-project bar : bAr\\./\\/.\\.\\ ; use-project bar : bAr/.\\././ ; use-project bar : Bar ; use-project bar : BaR ; use-project bar : BaR/./../bAr/xxx/.. ; use-project bar : BaR/./..\\bAr\\xxx/.. ; use-project bar : BaR/xxx/.. ; use-project bar : BaR///\\\\\\//xxx/.. ; use-project bar : Bar\\xxx/.. ; use-project bar : BAR/xXx/.. ; use-project bar : BAR/xXx\\\\/\\/\\//\\.. ; """) t.run_build_system() t.rm("baR") t.cleanup()
def make_tester(): return BoostBuild.Tester(["-dmi"], pass_toolset=False, pass_d0=False, use_test_config=False, ignore_toolset_requirements=False, match=TestCmd.match_re)
def test_unresolved_project_references(): t = BoostBuild.Tester() __write_appender(t, "appender.jam") t.write("a/source._a", "") t.write("a/jamfile.jam", "import alias ; alias target : source._a ;") t.write( "jamroot.jam", """\ import type ; type.register AAA : _a ; type.register BBB : _b ; import appender ; appender.register aaa-to-bbb : AAA : BBB ; use-project foo : a ; bbb b1 : a//target ; bbb b2 : /foo//target ; bbb b-invalid : invalid//target ; bbb b-root-invalid : /invalid//target ; bbb b-missing-root : foo//target ; bbb b-invalid-target : /foo//invalid ; """) t.run_build_system(["b1", "b2"]) t.expect_addition("bin/b%d._b" % x for x in range(1, 3)) t.expect_nothing_more() t.run_build_system(["b-invalid"], status=1) t.expect_output_lines("""\ error: Unable to find file or target named error: 'invalid//target' error: referred to from project at error: '.' error: could not resolve project reference 'invalid'""") t.run_build_system(["b-root-invalid"], status=1) t.expect_output_lines("""\ error: Unable to find file or target named error: '/invalid//target' error: referred to from project at error: '.' error: could not resolve project reference '/invalid'""") t.run_build_system(["b-missing-root"], status=1) t.expect_output_lines("""\ error: Unable to find file or target named error: 'foo//target' error: referred to from project at error: '.' error: could not resolve project reference 'foo' - possibly missing a """ "leading slash ('/') character.") t.run_build_system(["b-invalid-target"], status=1) t.expect_output_lines("""\ error: Unable to find file or target named error: '/foo//invalid' error: referred to from project at error: '.'""") t.expect_output_lines("*could not resolve project reference*", False) t.cleanup()
#!/usr/bin/python # Copyright 2002, 2003, 2004 Vladimir Prus # 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) # Test that we can use already built sources import BoostBuild t = BoostBuild.Tester(["debug", "release"], use_test_config=False) t.set_tree('prebuilt') t.expand_toolset("ext/jamroot.jam") t.expand_toolset("jamroot.jam") # First, build the external project. t.run_build_system(subdir="ext") # Then pretend that we do not have the sources for the external project, and # can only use compiled binaries. t.copy("ext/jamfile2.jam", "ext/jamfile.jam") t.expand_toolset("ext/jamfile.jam") # Now check that we can build the main project, and that correct prebuilt file # is picked, depending of variant. This also checks that correct includes for # prebuilt libraries are used. t.run_build_system() t.expect_addition("bin/$toolset/debug*/hello.exe") t.expect_addition("bin/$toolset/release*/hello.exe")
#!/usr/bin/python # Copyright 2003 Dave Abrahams # Copyright 2002, 2003, 2004 Vladimir Prus # 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) import BoostBuild t = BoostBuild.Tester(translate_suffixes=0) t.set_tree("project-test4") t.run_build_system() t.expect_addition("bin/$toolset/debug*/a.obj") t.expect_content("bin/$toolset/debug*/a.obj", """$toolset/debug*/include-everything a.cpp """) t.expect_addition("bin/$toolset/debug*/a.exe") t.expect_content( "bin/$toolset/debug*/a.exe", "$toolset/debug*/include-everything\n" + "bin/$toolset/debug*/a.obj lib/bin/$toolset/debug/optimization-speed*/b.obj\n" ) t.expect_addition("lib/bin/$toolset/debug/optimization-speed*/b.obj") t.expect_content( "lib/bin/$toolset/debug/optimization-speed*/b.obj", """$toolset/debug/include-everything/optimization-speed*
def included_resource_newer_than_rc_script(): """ When a .rc script file includes another resource file - the resource file being newer than the .rc script file should not cause the .rc script file to be considered old and force all of its dependents to rebuild. """ toolsetName = "__myDummyResourceCompilerToolset__" # Used options rationale: # # -d4 & --debug-configuration # Display additional information in case of test failure. In the past # we have had testing system issues causing this test to fail # sporadically for which -d+3 output had been instrumental in getting to # the root cause (a touched file's timestamp was not as new as it should # have been). # # --ignore-site-config --user-config= # Disable reading any external Boost Build configuration. This test is # self sufficient so these options protect it from being adversly # affected by any local (mis)configuration.. t = BoostBuild.Tester([ "-d4", "--debug-configuration", "--ignore-site-config", "--user-config=", "toolset=%s" % toolsetName ], pass_d0=False, pass_toolset=False, use_test_config=False, translate_suffixes=False) # Prepare a dummy toolset so we do not get errors in case the default one # is not found and that we can test rc.jam functionality without having to # depend on the externally specified toolset actually supporting it exactly # the way it is required for this test, e.g. gcc toolset, under some # circumstances, uses a quiet action for generating its null RC targets. t.write( toolsetName + ".jam", """\ import feature ; import rc ; import type ; local toolset-name = "%s" ; feature.extend toolset : $(toolset-name) ; rule init ( ) { } rc.configure dummy-rc-command : <toolset>$(toolset-name) : <rc-type>dummy ; module rc { rule compile.resource.dummy ( targets * : sources * : properties * ) { import common ; .TOUCH on $(targets) = [ common.file-touch-command ] ; } actions compile.resource.dummy { $(.TOUCH) "$(<)" } } # Make OBJ files generated by our toolset use the "obj" suffix on all # platforms. We need to do this explicitly for <target-os> windows & cygwin to # override the default OBJ type configuration (otherwise we would get # 'ambiguous key' errors on those platforms). local rule set-generated-obj-suffix ( target-os ? ) { type.set-generated-target-suffix OBJ : <toolset>$(toolset-name) <target-os>$(target-os) : obj ; } set-generated-obj-suffix ; set-generated-obj-suffix windows ; set-generated-obj-suffix cygwin ; """ % toolsetName) # Prepare project source files. t.write( "jamroot.jam", """\ ECHO {{{ [ modules.peek : XXX ] [ modules.peek : NOEXEC ] }}} ; obj xxx : xxx.rc ; """) t.write("xxx.rc", '1 MESSAGETABLE "xxx.bin"\n') t.write("xxx.bin", "foo") def test1(n, expect, noexec=False): params = ["-sXXX=%d" % n] if noexec: params.append("-n") params.append("-sNOEXEC=NOEXEC") t.run_build_system(params) t.expect_output_lines("*NOEXEC*", noexec) obj_file = "xxx_res.obj" t.expect_output_lines("compile.resource.dummy *%s" % obj_file, expect) if expect and not noexec: expect("bin/%s/debug/%s" % (toolsetName, obj_file)) t.expect_nothing_more() def test(n, expect): test1(n, expect, noexec=True) test1(n, expect) test(1, t.expect_addition) test(2, None) t.touch("xxx.bin") test(3, t.expect_touch) test(4, None) t.cleanup()
def test_basic(): t = BoostBuild.Tester(pass_d0=False) __write_appender(t, "appender.jam") t.write("a.cpp", "") t.write("b.cxx", "") t.write("c.tui", "") t.write("d.wd", "") t.write("e.cpp", "") t.write("x.l", "") t.write("y.x_pro", "") t.write("z.cpp", "") t.write("lib/c.cpp", "int bar() { return 0; }\n") t.write("lib/jamfile.jam", "my-lib auxilliary : c.cpp ;") t.write( "jamroot.jam", r"""import appender ; import "class" : new ; import generators ; import type ; ################################################################################ # # We use our own custom EXE, LIB & OBJ target generators as using the regular # ones would force us to have to deal with different compiler/linker specific # 'features' that really have nothing to do with this test. For example, IBM XL # C/C++ for AIX, V12.1 (Version: 12.01.0000.0000) compiler exits with a non-zero # exit code and thus fails our build when run with a source file using an # unknown suffix like '.marked_cpp'. # ################################################################################ type.register MY_EXE : my_exe ; type.register MY_LIB : my_lib ; type.register MY_OBJ : my_obj ; appender.register compile-c : C : MY_OBJ ; appender.register compile-cpp : CPP : MY_OBJ ; appender.register link-lib composing : MY_OBJ : MY_LIB ; appender.register link-exe composing : MY_OBJ MY_LIB : MY_EXE ; ################################################################################ # # LEX --> C # ################################################################################ type.register LEX : l ; appender.register lex-to-c : LEX : C ; ################################################################################ # # /--> tUI_H --\ # tUI --< >--> CPP # \------------/ # ################################################################################ type.register tUI : tui ; type.register tUI_H : tui_h ; appender.register ui-to-cpp : tUI tUI_H : CPP ; appender.register ui-to-h : tUI : tUI_H ; ################################################################################ # # /--> X1 --\ # X_PRO --< >--> CPP # \--> X2 --/ # ################################################################################ type.register X1 : x1 ; type.register X2 : x2 ; type.register X_PRO : x_pro ; appender.register x1-x2-to-cpp : X1 X2 : CPP ; appender.register x-pro-to-x1-x2 : X_PRO : X1 X2 ; ################################################################################ # # When the main target type is NM_EXE, build OBJ from CPP-MARKED and not from # anything else, e.g. directly from CPP. # ################################################################################ type.register CPP_MARKED : marked_cpp : CPP ; type.register POSITIONS : positions ; type.register NM.TARGET.CPP : target_cpp : CPP ; type.register NM_EXE : : MY_EXE ; appender.register marked-to-target-cpp : CPP_MARKED : NM.TARGET.CPP ; appender.register cpp-to-marked-positions : CPP : CPP_MARKED POSITIONS ; class nm::target::cpp-obj-generator : generator { rule __init__ ( id ) { generator.__init__ $(id) : NM.TARGET.CPP : MY_OBJ ; generator.set-rule-name appender.appender ; } rule requirements ( ) { return <main-target-type>NM_EXE ; } rule run ( project name ? : properties * : source : multiple ? ) { if [ $(source).type ] = CPP { local converted = [ generators.construct $(project) : NM.TARGET.CPP : $(properties) : $(source) ] ; if $(converted) { return [ generators.construct $(project) : MY_OBJ : $(properties) : $(converted[2]) ] ; } } } } generators.register [ new nm::target::cpp-obj-generator target-obj ] ; generators.override target-obj : all ; ################################################################################ # # A more complex test case scenario with the following generators: # 1. WHL --> CPP, WHL_LR0, H, H(%_symbols) # 2. DLP --> CPP # 3. WD --> WHL(%_parser) DLP(%_lexer) # 4. A custom generator of higher priority than generators 1. & 2. that helps # disambiguate between them when generating CPP files from WHL and DLP # sources. # ################################################################################ type.register WHL : whl ; type.register DLP : dlp ; type.register WHL_LR0 : lr0 ; type.register WD : wd ; local whale-generator-id = [ appender.register whale : WHL : CPP WHL_LR0 H H(%_symbols) ] ; local dolphin-generator-id = [ appender.register dolphin : DLP : CPP ] ; appender.register wd : WD : WHL(%_parser) DLP(%_lexer) ; class wd-to-cpp : generator { rule __init__ ( id : sources * : targets * ) { generator.__init__ $(id) : $(sources) : $(targets) ; } rule run ( project name ? : property-set : source ) { local new-sources = $(source) ; if ! [ $(source).type ] in WHL DLP { local r1 = [ generators.construct $(project) $(name) : WHL : $(property-set) : $(source) ] ; local r2 = [ generators.construct $(project) $(name) : DLP : $(property-set) : $(source) ] ; new-sources = [ sequence.unique $(r1[2-]) $(r2[2-]) ] ; } local result ; for local i in $(new-sources) { local t = [ generators.construct $(project) $(name) : CPP : $(property-set) : $(i) ] ; result += $(t[2-]) ; } return $(result) ; } } generators.override $(__name__).wd-to-cpp : $(whale-generator-id) ; generators.override $(__name__).wd-to-cpp : $(dolphin-generator-id) ; generators.register [ new wd-to-cpp $(__name__).wd-to-cpp : : CPP ] ; ################################################################################ # # Declare build targets. # ################################################################################ # This should not cause two CPP --> MY_OBJ constructions for a.cpp or b.cpp. my-exe a : a.cpp b.cxx obj_1 obj_2 c.tui d.wd x.l y.x_pro lib//auxilliary ; my-exe f : a.cpp b.cxx obj_1 obj_2 lib//auxilliary ; # This should cause two CPP --> MY_OBJ constructions for z.cpp. my-obj obj_1 : z.cpp ; my-obj obj_2 : z.cpp ; nm-exe e : e.cpp ; """) t.run_build_system() t.expect_addition("bin/$toolset/debug*/" * BoostBuild.List( "a.my_exe " "a.my_obj b.my_obj c.tui_h c.cpp c.my_obj d_parser.whl d_lexer.dlp " "d_parser.cpp d_lexer.cpp d_lexer.my_obj d_parser.lr0 d_parser.h " "d_parser.my_obj d_parser_symbols.h x.c x.my_obj y.x1 y.x2 y.cpp " "y.my_obj e.marked_cpp e.positions e.target_cpp e.my_obj e.my_exe " "f.my_exe obj_1.my_obj obj_2.my_obj")) t.expect_addition("lib/bin/$toolset/debug*/" * BoostBuild.List("c.my_obj " "auxilliary.my_lib")) t.expect_nothing_more() folder = "bin/$toolset/debug*" t.expect_content_lines("%s/obj_1.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/obj_2.my_obj" % folder, " Sources: 'z.cpp'") t.expect_content_lines("%s/a.my_obj" % folder, " Sources: 'a.cpp'") lines = t.stdout().splitlines() source_lines = [x for x in lines if re.match("^ Sources: '", x)] if not __match_count_is(source_lines, "'z.cpp'", 2): BoostBuild.annotation("failure", "z.cpp must be compiled exactly " "twice.") t.fail_test(1) if not __match_count_is(source_lines, "'a.cpp'", 1): BoostBuild.annotation("failure", "a.cpp must be compiled exactly " "once.") t.fail_test(1) t.cleanup()
#!/usr/bin/python # Copyright 2004 Vladimir Prus # 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) # This checks that B2 does not reorder <include> properties # lexicographically. import BoostBuild t = BoostBuild.Tester() t.write("a.cpp", """ #include <a.h> int main() { foo(); } """) t.write("jamroot.jam", """ exe a : a.cpp : <include>d2 <include>d1 ; """) t.write("d1/a.h", """ """) t.write("d2/a.h", """ inline void foo() {} """) t.run_build_system() t.expect_addition("bin/$toolset/debug*/a.exe")
def test_generated_target_names(): """ Test generator generated target names. Unless given explicitly, target names should be determined based on their specified source names. All sources for generating a target need to have matching names in order for Boost Build to be able to implicitly determine the target's name. We use the following target generation structure with differently named BBX targets: /---> BB1 ---\ AAA --<----> BB2 ---->--> CCC --(composing)--> DDD \---> BB3 ---/ The extra generator at the end is needed because generating a top-level CCC target directly would requires us to explicitly specify a name for it. The extra generator needs to be composing in order not to explicitly request a specific name for its CCC source target based on its own target name. We also check for a regression where only the first two sources were checked to see if their names match. Note that we need to try out all file renaming combinations as we do not know what ordering Boost Build is going to use when passing in those files as generator sources. """ jamfile_template = """\ import type ; type.register AAA : _a ; type.register BB1 : _b1 ; type.register BB2 : _b2 ; type.register BB3 : _b3 ; type.register CCC : _c ; type.register DDD : _d ; import appender ; appender.register aaa-to-bbX : AAA : BB1%s BB2%s BB3%s ; appender.register bbX-to-ccc : BB1 BB2 BB3 : CCC ; appender.register ccc-to-ddd composing : CCC : DDD ; ddd _xxx : _xxx._a ; """ t = BoostBuild.Tester(pass_d0=False) __write_appender(t, "appender.jam") t.write("_xxx._a", "") def test_one(t, rename1, rename2, rename3, status): def f(rename): if rename: return "(%_x)" return "" jamfile = jamfile_template % (f(rename1), f(rename2), f(rename3)) t.write("jamroot.jam", jamfile, wait=False) # Remove any preexisting targets left over from a previous test run # so we do not have to be careful about tracking which files have been # newly added and which preexisting ones have only been modified. t.rm("bin") t.run_build_system(status=status) if status: t.expect_output_lines( "*.bbX-to-ccc: source targets have " "different names: cannot determine target name") else: def suffix(rename): if rename: return "_x" return "" name = "bin/$toolset/debug*/_xxx" e = t.expect_addition e("%s%s._b1" % (name, suffix(rename1))) e("%s%s._b2" % (name, suffix(rename2))) e("%s%s._b3" % (name, suffix(rename3))) e("%s%s._c" % (name, suffix(rename1 and rename2 and rename3))) e("%s._d" % name) t.expect_nothing_more() test_one(t, False, False, False, status=0) test_one(t, True, False, False, status=1) test_one(t, False, True, False, status=1) test_one(t, False, False, True, status=1) test_one(t, True, True, False, status=1) test_one(t, True, False, True, status=1) test_one(t, False, True, True, status=1) test_one(t, True, True, True, status=0) t.cleanup()
#!/usr/bin/python # Copyright 2003 Dave Abrahams # 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) # This tests the facilities for deleting modules. import BoostBuild t = BoostBuild.Tester(pass_toolset=0) t.write( "file.jam", """ module foo { rule bar { } var = x y ; } DELETE_MODULE foo ; if [ RULENAMES foo ] { EXIT DELETE_MODULE failed to kill foo's rules: [ RULENAMES foo ] ; } module foo { if $(var) { EXIT DELETE_MODULE failed to kill foo's variables ; }
def test_check_target_builds(): t = BoostBuild.Tester(use_test_config=0) t.write("Jamroot", """ import configure ; obj pass : pass.cpp ; obj fail : fail.cpp ; explicit pass fail ; obj foo : foo.cpp : [ configure.check-target-builds pass : <define>PASS : <define>FAIL ] ; obj bar : foo.cpp : [ configure.check-target-builds fail : <define>FAIL : <define>PASS ] ; """) t.write("pass.cpp", "void f() {}\n") t.write("fail.cpp", "#error fail.cpp\n") t.write("foo.cpp", """ #ifndef PASS #error PASS not defined #endif #ifdef FAIL #error FAIL is defined #endif """) t.run_build_system() t.expect_output_lines([ " - pass builds : yes", " - fail builds : no"]) t.expect_addition("bin/$toolset/debug*/pass.obj") t.expect_addition("bin/$toolset/debug*/foo.obj") t.expect_addition("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() # An up-to-date build should use the cache t.run_build_system() t.expect_output_lines([ " - pass builds : yes (cached)", " - fail builds : no (cached)"]) t.expect_nothing_more() # -a should re-run everything, including configuration checks t.run_build_system(["-a"]) t.expect_output_lines([ " - pass builds : yes", " - fail builds : no"]) t.expect_touch("bin/$toolset/debug*/pass.obj") t.expect_touch("bin/$toolset/debug*/foo.obj") t.expect_touch("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() # --reconfigure should re-run configuration checks only t.run_build_system(["--reconfigure"]) t.expect_output_lines([ " - pass builds : yes", " - fail builds : no"]) t.expect_touch("bin/$toolset/debug*/pass.obj") t.expect_nothing_more() # -a -n should not rebuild configuration checks t.run_build_system(["-a", "-n"]) t.expect_output_lines([ " - pass builds : yes (cached)", " - fail builds : no (cached)"]) t.expect_nothing_more() # --clean-all should clear all configuration checks t.run_build_system(["--clean-all"]) t.expect_output_lines([ " - pass builds : yes (cached)", " - fail builds : no (cached)"]) t.expect_removal("bin/$toolset/debug*/pass.obj") t.expect_removal("bin/$toolset/debug*/foo.obj") t.expect_removal("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() # If configuration checks are absent, then --clean-all # should create them and then delete them again. This # currently fails because clean cannot remove targets # that were created in the same build. #t.run_build_system(["--clean-all"]) #t.expect_output_lines([ # " - pass builds : yes", # " - fail builds : no"]) #t.expect_nothing_more() # Just verify that we're actually in the initial # state here. t.run_build_system() t.expect_output_lines([ " - pass builds : yes", " - fail builds : no"]) t.expect_addition("bin/$toolset/debug*/pass.obj") t.expect_addition("bin/$toolset/debug*/foo.obj") t.expect_addition("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() t.cleanup()
#!/usr/bin/python # Copyright (C) 2013 Steven Watanabe # Distributed under the Boost Software License, Version 1.0. # (See accompanying file LICENSE.txt or copy at # https://www.bfgroup.xyz/b2/LICENSE.txt) import BoostBuild import MockToolset t = BoostBuild.Tester(arguments=['toolset=mock', '--ignore-site-config', '--user-config='], pass_toolset=0) MockToolset.create(t) # Build from source t.write("libpng/png.h", 'libpng') t.write("libpng/png.c", 'png') t.write("Jamroot.jam", """ path-constant here : . ; using libpng : : <source>$(here)/libpng ; alias libpng : /libpng//libpng ; """) MockToolset.set_expected(t, ''' source_file('png.c', 'png') action('-c -x c -I./libpng -o $png.o $png.c') action('--archive $png.o -o $png.a') ''') t.run_build_system(["link=static"])
def test_check_target_builds(): t = BoostBuild.Tester(use_test_config=0) t.write( "Jamroot", """ import configure ; obj pass : pass.cpp ; obj fail : fail.cpp ; explicit pass fail ; obj foo : foo.cpp : [ configure.check-target-builds pass : <define>PASS : <define>FAIL ] ; obj bar : foo.cpp : [ configure.check-target-builds fail : <define>FAIL : <define>PASS ] ; """) t.write("pass.cpp", "void f() {}\n") t.write("fail.cpp", "#error fail.cpp\n") t.write( "foo.cpp", """ #ifndef PASS #error PASS not defined #endif #ifdef FAIL #error FAIL is defined #endif """) t.run_build_system() t.expect_output_lines([ " - pass builds : yes", " - fail builds : no" ]) t.expect_addition("bin/$toolset/debug*/pass.obj") t.expect_addition("bin/$toolset/debug*/foo.obj") t.expect_addition("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() # An up-to-date build should use the cache t.run_build_system() t.expect_output_lines([ " - pass builds : yes (cached)", " - fail builds : no (cached)" ]) t.expect_nothing_more() # -a should re-run everything, including configuration checks t.run_build_system(["-a"]) t.expect_output_lines([ " - pass builds : yes", " - fail builds : no" ]) t.expect_touch("bin/$toolset/debug*/pass.obj") t.expect_touch("bin/$toolset/debug*/foo.obj") t.expect_touch("bin/$toolset/debug*/bar.obj") t.expect_nothing_more() # --reconfigure should re-run configuration checks only t.run_build_system(["--reconfigure"]) t.expect_output_lines([ " - pass builds : yes", " - fail builds : no" ]) t.expect_touch("bin/$toolset/debug*/pass.obj") t.expect_nothing_more() t.cleanup()