Improvements in RC files support.

- Specialized RC->RES generators were added for msvc. This allows
  to invoke setup script before calling rc.exe, which adds necessary
  include paths.
- Includes scanner for RC files added.

Thanks to Alexey Pakhunov for the patch.


[SVN r23036]
This commit is contained in:
Vladimir Prus 2004-06-07 07:24:24 +00:00
parent 882d62b6b9
commit 0a9ffafd85
2 changed files with 119 additions and 9 deletions

View File

@ -13,6 +13,7 @@ import feature : feature ;
import path ;
import sequence : unique ;
import common ;
import scanner ;
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
{
@ -72,10 +73,11 @@ rule init (
# be searched
#
# - if compiler is not found in default locations, PATH will be searched.
: vendor ? : setup ? compiler ? linker ? )
: vendor ? : setup ? compiler ? linker ? resource-compiler ? )
{
compiler ?= cl ;
linker ?= link ;
resource-compiler ?= rc ;
if $(version)
{
@ -136,6 +138,7 @@ rule init (
condition = <toolset>msvc$(condition) ;
flags msvc.compile .CC $(condition) : $(prefix)$(compiler) ;
flags msvc.compile .RC $(condition) : $(prefix)$(resource-compiler) ;
flags msvc.link .LD $(condition) : $(prefix)$(linker) ;
flags msvc.archive .LD $(condition) : $(prefix)$(linker) ;
}
@ -146,6 +149,7 @@ rule init (
# use 'unspecified' as version. Therefore, just set global
# variables in this module.
.CC = $(prefix)$(compiler) ;
.RC = $(prefix)$(resource-compiler) ;
.LD = $(prefix)$(linker) ;
}
.initialized = true ; # remember that we've initialized at least one version of msvc
@ -162,6 +166,7 @@ rule init (
.CC = cl ;
.LD = LINK ;
.RC = rc ;
# Attempts to find the vcvars32.bat script for the relevant version, and returns the path
@ -260,18 +265,89 @@ local rule locate ( setup : version ? : vendor ? )
}
# Register scanner for resources
type.register RC : rc ;
type.register RES : res ;
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 ;
# Declare generators
# is it possible to combine these?
# make the generators non-composing, so that they don't convert each source
# into separate rsp file.
generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : EXE RSP : <toolset>msvc ;
generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB : SHARED_LIB IMPORT_LIB RSP : <toolset>msvc ;
generators.register-linker msvc.link : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB RES : EXE RSP : <toolset>msvc ;
generators.register-linker msvc.link.dll : OBJ SEARCHED_LIB STATIC_LIB IMPORT_LIB RES : SHARED_LIB IMPORT_LIB RSP : <toolset>msvc ;
generators.register-composing msvc.archive : OBJ : STATIC_LIB RSP : <toolset>msvc ;
generators.register-composing msvc.archive : OBJ RES : STATIC_LIB RSP : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c++ : CPP : OBJ : <toolset>msvc ;
generators.register-c-compiler msvc.compile.c : C : OBJ : <toolset>msvc ;
generators.register-standard msvc.compile.rc : RC : RES : <toolset>msvc ;
#
# Declare flags and action for compilation
@ -317,6 +393,10 @@ actions compile.c++
$(.CC) /Zm800 -nologo -TP -U$(UNDEFS) -D$(DEFINES) $(CFLAGS) $(USER_CFLAGS) -I"$(INCLUDES)" -c -Fo"$(<)" "$(>)"
}
actions compile.rc
{
$(.RC) -l 0x409 -U$(UNDEFS) -D$(DEFINES) -I"$(INCLUDES)" -fo "$(<)" "$(>)"
}
# Declare flags and action for linking
flags msvc.link PDB_LINKFLAG <debug-symbols>on/<debug-store>database : /PDB: ; # not used yet

View File

@ -42,22 +42,29 @@ rule match ( pattern : string : indices * )
}
# Matches all elements of 'list' agains the 'pattern'
# and returns a list of first paranthethised groups of
# all successfull matches.
rule transform ( list * : pattern )
# and returns a list of the elements indicated by indices of
# all successfull matches. If 'indices' is omitted returns
# a list of first paranthethised groups of all successfull
# matches.
#
rule transform ( list * : pattern : indices * )
{
indices ?= 1 ;
local result ;
for local e in $(list)
{
local m = [ MATCH $(pattern) : $(e) ] ;
if $(m)
{
result += $(m[1]) ;
result += $(m[$(indices)]) ;
}
}
return $(result) ;
}
NATIVE_RULE regex : transform ;
# Commented out because of 'indices' parameter of 'transform' rule.
#
#NATIVE_RULE regex : transform ;
# Escapes all of the characters in symbols using the escape symbol
# escape-symbol for the given string, and returns the escaped string
@ -106,6 +113,24 @@ rule replace (
return $(result) ;
}
# Replaces occurances of a match string in a given list of strings.
# Returns the list of new strings. The match string can be a regex
# expression.
#
# list - the list of strings to modify.
# match - the search expression.
# replacement - the string to replace with.
#
rule replace-list ( list * : match : replacement )
{
local result ;
for local e in $(list)
{
result += [ replace $(e) $(match) $(replacement) ] ;
}
return $(result) ;
}
rule __test__ ( )
{
import assert ;
@ -129,6 +154,9 @@ rule __test__ ( )
assert.result a.h c.h
: transform <a.h> \"b.h\" <c.h> : <(.*)> ;
assert.result a.h "" b.h c.h
: transform <a.h> \"b.h\" <c.h> : <([^>]*)>|\"([^\"]*)\" : 1 2 ;
assert.result "^<?xml version=\"1.0\"^>"
: escape "<?xml version=\"1.0\">" : "&|()<>^" : "^" ;
@ -139,4 +167,6 @@ rule __test__ ( )
assert.result "&nbsp;string&nbsp;string" : replace " string string" " " "&nbsp;" ;
assert.result "string&nbsp;&nbsp;string" : replace "string string" " " "&nbsp;" ;
assert.result "-" : replace "&" "&" "-" ;
assert.result "-" "a-b" : replace-list "&" "a&b" : "&" : "-" ;
}