diff options
Diffstat (limited to 'jam-files/boost-build/tools/rc.jam')
-rw-r--r-- | jam-files/boost-build/tools/rc.jam | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/jam-files/boost-build/tools/rc.jam b/jam-files/boost-build/tools/rc.jam new file mode 100644 index 000000000..9964d339b --- /dev/null +++ b/jam-files/boost-build/tools/rc.jam @@ -0,0 +1,156 @@ +# Copyright (C) Andre Hentz 2003. Permission to copy, use, modify, sell and +# distribute this software is granted provided this copyright notice appears in +# all copies. This software is provided "as is" without express or implied +# warranty, and with no claim as to its suitability for any purpose. +# +# Copyright (c) 2006 Rene Rivera. +# +# Use, modification and distribution is subject to the Boost Software +# License Version 1.0. (See accompanying file LICENSE_1_0.txt or +# http://www.boost.org/LICENSE_1_0.txt) + +import type ; +import generators ; +import feature ; +import errors ; +import scanner ; +import toolset : flags ; + +if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] +{ + .debug-configuration = true ; +} + +type.register RC : rc ; + +rule init ( ) +{ +} + +# Configures a new resource compilation command specific to a condition, +# usually a toolset selection condition. The possible options are: +# +# * <rc-type>(rc|windres) - Indicates the type of options the command +# accepts. +# +# Even though the arguments are all optional, only when a command, condition, +# and at minimum the rc-type option are given will the command be configured. +# This is so that callers don't have to check auto-configuration values +# before calling this. And still get the functionality of build failures when +# the resource compiler can't be found. +# +rule configure ( command ? : condition ? : options * ) +{ + local rc-type = [ feature.get-values <rc-type> : $(options) ] ; + + if $(command) && $(condition) && $(rc-type) + { + flags rc.compile.resource .RC $(condition) : $(command) ; + flags rc.compile.resource .RC_TYPE $(condition) : $(rc-type:L) ; + flags rc.compile.resource DEFINES <define> ; + flags rc.compile.resource INCLUDES <include> ; + if $(.debug-configuration) + { + ECHO notice: using rc compiler :: $(condition) :: $(command) ; + } + } +} + +rule compile.resource ( target : sources * : properties * ) +{ + local rc-type = [ on $(target) return $(.RC_TYPE) ] ; + rc-type ?= null ; + compile.resource.$(rc-type) $(target) : $(sources[1]) ; +} + +actions compile.resource.rc +{ + "$(.RC)" -l 0x409 "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -fo "$(<)" "$(>)" +} + +actions compile.resource.windres +{ + "$(.RC)" "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -o "$(<)" -i "$(>)" +} + +actions quietly compile.resource.null +{ + as /dev/null -o "$(<)" +} + +# Since it's a common practice to write +# exe hello : hello.cpp hello.rc +# we change the name of object created from RC file, to +# avoid conflict with hello.cpp. +# The reason we generate OBJ and not RES, is that gcc does not +# seem to like RES files, but works OK with OBJ. +# See http://article.gmane.org/gmane.comp.lib.boost.build/5643/ +# +# Using 'register-c-compiler' adds the build directory to INCLUDES +generators.register-c-compiler rc.compile.resource : RC : OBJ(%_res) ; + +# Register scanner for resources +class res-scanner : scanner +{ + import regex virtual-target path scanner ; + + rule __init__ ( includes * ) + { + scanner.__init__ ; + + self.includes = $(includes) ; + } + + rule pattern ( ) + { + return "(([^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+([^ \"]+|\"[^\"]+\"))|(#include[ ]*(<[^<]+>|\"[^\"]+\")))" ; + } + + rule process ( target : matches * : binding ) + { + local angle = [ regex.transform $(matches) : "#include[ ]*<([^<]+)>" ] ; + local quoted = [ regex.transform $(matches) : "#include[ ]*\"([^\"]+)\"" ] ; + local res = [ regex.transform $(matches) : "[^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+(([^ \"]+)|\"([^\"]+)\")" : 3 4 ] ; + + # Icons and other includes may referenced as + # + # IDR_MAINFRAME ICON "res\\icon.ico" + # + # so we have to replace double backslashes to single ones. + res = [ regex.replace-list $(res) : "\\\\\\\\" : "/" ] ; + + # CONSIDER: the new scoping rule seem to defeat "on target" variables. + local g = [ on $(target) return $(HDRGRIST) ] ; + local b = [ NORMALIZE_PATH $(binding:D) ] ; + + # Attach binding of including file to included targets. + # When target is directly created from virtual target + # this extra information is unnecessary. But in other + # cases, it allows to distinguish between two headers of the + # same name included from different places. + # We don't need this extra information for angle includes, + # since they should not depend on including file (we can't + # get literal "." in include path). + local g2 = $(g)"#"$(b) ; + + angle = $(angle:G=$(g)) ; + quoted = $(quoted:G=$(g2)) ; + res = $(res:G=$(g2)) ; + + local all = $(angle) $(quoted) ; + + INCLUDES $(target) : $(all) ; + DEPENDS $(target) : $(res) ; + NOCARE $(all) $(res) ; + SEARCH on $(angle) = $(self.includes:G=) ; + SEARCH on $(quoted) = $(b) $(self.includes:G=) ; + SEARCH on $(res) = $(b) $(self.includes:G=) ; + + # Just propagate current scanner to includes, in a hope + # that includes do not change scanners. + scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ; + } +} + +scanner.register res-scanner : include ; +type.set-scanner RC : res-scanner ; |