1#!/usr/bin/python 2 3# Copyright 2012 Jurko Gospodnetic 4# Distributed under the Boost Software License, Version 1.0. 5# (See accompanying file LICENSE_1_0.txt or copy at 6# http://www.boost.org/LICENSE_1_0.txt) 7 8# Tests rc toolset behaviour. 9 10import BoostBuild 11 12 13def included_resource_newer_than_rc_script(): 14 """ 15 When a .rc script file includes another resource file - the resource file 16 being newer than the .rc script file should not cause the .rc script file 17 to be considered old and force all of its dependents to rebuild. 18 19 """ 20 toolsetName = "__myDummyResourceCompilerToolset__" 21 22 # Used options rationale: 23 # 24 # -d4 & --debug-configuration 25 # Display additional information in case of test failure. In the past 26 # we have had testing system issues causing this test to fail 27 # sporadically for which -d+3 output had been instrumental in getting to 28 # the root cause (a touched file's timestamp was not as new as it should 29 # have been). 30 # 31 # --ignore-site-config --user-config= 32 # Disable reading any external Boost Build configuration. This test is 33 # self sufficient so these options protect it from being adversly 34 # affected by any local (mis)configuration.. 35 t = BoostBuild.Tester(["-d4", "--debug-configuration", 36 "--ignore-site-config", "--user-config=", "toolset=%s" % toolsetName], 37 pass_toolset=False, use_test_config=False, 38 translate_suffixes=False) 39 40 # Prepare a dummy toolset so we do not get errors in case the default one 41 # is not found and that we can test rc.jam functionality without having to 42 # depend on the externally specified toolset actually supporting it exactly 43 # the way it is required for this test, e.g. gcc toolset, under some 44 # circumstances, uses a quiet action for generating its null RC targets. 45 t.write(toolsetName + ".jam", """\ 46import feature ; 47import rc ; 48import type ; 49local toolset-name = "%s" ; 50feature.extend toolset : $(toolset-name) ; 51rule init ( ) { } 52rc.configure dummy-rc-command : <toolset>$(toolset-name) : <rc-type>dummy ; 53module rc 54{ 55 rule compile.resource.dummy ( targets * : sources * : properties * ) 56 { 57 import common ; 58 .TOUCH on $(targets) = [ common.file-touch-command ] ; 59 } 60 actions compile.resource.dummy { $(.TOUCH) "$(<)" } 61} 62# Make OBJ files generated by our toolset use the "obj" suffix on all 63# platforms. We need to do this explicitly for <target-os> windows & cygwin to 64# override the default OBJ type configuration (otherwise we would get 65# 'ambiguous key' errors on those platforms). 66local rule set-generated-obj-suffix ( target-os ? ) 67{ 68 type.set-generated-target-suffix OBJ : <toolset>$(toolset-name) 69 <target-os>$(target-os) : obj ; 70} 71set-generated-obj-suffix ; 72set-generated-obj-suffix windows ; 73set-generated-obj-suffix cygwin ; 74""" % toolsetName) 75 76 t.write( 77 toolsetName + '.py', 78""" 79from b2.build import feature, type as type_ 80from b2.manager import get_manager 81from b2.tools import rc, common 82 83MANAGER = get_manager() 84ENGINE = MANAGER.engine() 85 86toolset_name = "{0}" 87 88feature.extend('toolset', [toolset_name]) 89 90def init(*args): 91 pass 92 93rc.configure(['dummy-rc-command'], ['<toolset>' + toolset_name], ['<rc-type>dummy']) 94 95ENGINE.register_action( 96 'rc.compile.resource.dummy', 97 ''' 98 %s "$(<)" 99 ''' % common.file_creation_command() 100) 101 102def set_generated_obj_suffix(target_os=''): 103 requirements = ['<toolset>' + toolset_name] 104 if target_os: 105 requirements.append('<target-os>' + target_os) 106 type_.set_generated_target_suffix('OBJ', requirements, 'obj') 107 108set_generated_obj_suffix() 109set_generated_obj_suffix('windows') 110set_generated_obj_suffix('cygwin') 111""".format(toolsetName) 112 ) 113 114 # Prepare project source files. 115 t.write("jamroot.jam", """\ 116ECHO "{{{" [ modules.peek : XXX ] [ modules.peek : NOEXEC ] "}}}" ; 117obj xxx : xxx.rc ; 118""") 119 t.write("xxx.rc", '1 MESSAGETABLE "xxx.bin"\n') 120 t.write("xxx.bin", "foo") 121 122 def test1(n, expect, noexec=False): 123 params = ["-sXXX=%d" % n] 124 if noexec: 125 params.append("-n") 126 params.append("-sNOEXEC=NOEXEC") 127 t.run_build_system(params) 128 t.expect_output_lines("*NOEXEC*", noexec) 129 obj_file = "xxx_res.obj" 130 t.expect_output_lines("compile.resource.dummy *%s" % obj_file, expect) 131 if expect and not noexec: 132 expect("bin/%s/debug/%s" % (toolsetName, obj_file)) 133 t.expect_nothing_more() 134 135 def test(n, expect): 136 test1(n, expect, noexec=True) 137 test1(n, expect) 138 139 test(1, t.expect_addition) 140 test(2, None) 141 t.touch("xxx.bin") 142 test(3, t.expect_touch) 143 test(4, None) 144 145 t.cleanup() 146 147 148included_resource_newer_than_rc_script() 149