| # 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 ; |