]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | # Copyright (C) Andre Hentz 2003. Permission to copy, use, modify, sell and |
2 | # distribute this software is granted provided this copyright notice appears in | |
3 | # all copies. This software is provided "as is" without express or implied | |
4 | # warranty, and with no claim as to its suitability for any purpose. | |
5 | # | |
6 | # Copyright (c) 2006 Rene Rivera. | |
7 | # | |
8 | # Use, modification and distribution is subject to the Boost Software | |
9 | # License Version 1.0. (See accompanying file LICENSE_1_0.txt or | |
10 | # http://www.boost.org/LICENSE_1_0.txt) | |
11 | ||
12 | import generators ; | |
13 | import feature ; | |
14 | import scanner ; | |
15 | import toolset : flags ; | |
16 | import type ; | |
17 | ||
18 | if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] | |
19 | { | |
20 | .debug-configuration = true ; | |
21 | } | |
22 | ||
23 | type.register RC : rc ; | |
24 | ||
25 | rule init ( ) | |
26 | { | |
27 | } | |
28 | ||
29 | # Configures a new resource compilation command specific to a condition, | |
30 | # usually a toolset selection condition. The possible options are: | |
31 | # | |
32 | # * <rc-type>(rc|windres) - Indicates the type of options the command | |
33 | # accepts. | |
34 | # | |
35 | # Even though the arguments are all optional, only when a command, condition, | |
36 | # and at minimum the rc-type option are given will the command be configured. | |
37 | # This is so that callers don't have to check auto-configuration values before | |
38 | # calling this. And still get the functionality of build failures when the | |
39 | # resource compiler can not be found. | |
40 | # | |
41 | rule configure ( command ? : condition ? : options * ) | |
42 | { | |
43 | local rc-type = [ feature.get-values <rc-type> : $(options) ] ; | |
44 | ||
45 | if $(command) && $(condition) && $(rc-type) | |
46 | { | |
47 | flags rc.compile.resource .RC $(condition) : $(command) ; | |
48 | flags rc.compile.resource .RC_TYPE $(condition) : $(rc-type:L) ; | |
49 | flags rc.compile.resource DEFINES <define> ; | |
50 | flags rc.compile.resource INCLUDES <include> ; | |
51 | if $(.debug-configuration) | |
52 | { | |
11fdf7f2 | 53 | ECHO "notice:" using rc compiler "::" $(condition) "::" $(command) ; |
7c673cae FG |
54 | } |
55 | } | |
56 | } | |
57 | ||
58 | rule compile.resource ( target : sources * : properties * ) | |
59 | { | |
60 | local rc-type = [ on $(target) return $(.RC_TYPE) ] ; | |
61 | rc-type ?= null ; | |
62 | compile.resource.$(rc-type) $(target) : $(sources[1]) ; | |
63 | } | |
64 | ||
65 | actions compile.resource.rc | |
66 | { | |
67 | "$(.RC)" -l 0x409 "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -fo "$(<)" "$(>)" | |
68 | } | |
69 | ||
70 | actions compile.resource.windres | |
71 | { | |
72 | "$(.RC)" "-U$(UNDEFS)" "-D$(DEFINES)" -I"$(>:D)" -I"$(<:D)" -I"$(INCLUDES)" -o "$(<)" -i "$(>)" | |
73 | } | |
74 | ||
75 | actions quietly compile.resource.null | |
76 | { | |
77 | as /dev/null -o "$(<)" | |
78 | } | |
79 | ||
80 | # Since it is common practice to write | |
81 | # exe hello : hello.cpp hello.rc | |
82 | # we change the name of object created from RC file, to avoid conflict with | |
83 | # hello.cpp. The reason we generate OBJ and not RES, is that gcc does not seem | |
84 | # to like RES files, but works OK with OBJ (see | |
85 | # http://article.gmane.org/gmane.comp.lib.boost.build/5643). | |
86 | # | |
87 | # Using 'register-c-compiler' adds the build directory to INCLUDES | |
88 | generators.register-c-compiler rc.compile.resource : RC : OBJ(%_res) ; | |
89 | ||
90 | # Register scanner for resources | |
91 | class res-scanner : scanner | |
92 | { | |
93 | import path ; | |
94 | import regex ; | |
95 | import scanner ; | |
96 | import virtual-target ; | |
97 | ||
98 | rule __init__ ( includes * ) | |
99 | { | |
100 | scanner.__init__ ; | |
101 | self.includes = $(includes) ; | |
102 | } | |
103 | ||
104 | rule pattern ( ) | |
105 | { | |
106 | return "(([^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+([^ \"]+|\"[^\"]+\"))|(#include[ ]*(<[^<]+>|\"[^\"]+\")))" ; | |
107 | } | |
108 | ||
109 | rule process ( target : matches * : binding ) | |
110 | { | |
111 | local angle = [ regex.transform $(matches) : "#include[ ]*<([^<]+)>" ] ; | |
112 | local quoted = [ regex.transform $(matches) : "#include[ ]*\"([^\"]+)\"" ] ; | |
113 | local res = [ regex.transform $(matches) : "[^ ]+[ ]+(BITMAP|CURSOR|FONT|ICON|MESSAGETABLE|RT_MANIFEST)[ ]+(([^ \"]+)|\"([^\"]+)\")" : 3 4 ] ; | |
114 | ||
115 | # Icons and other includes may be referenced as | |
116 | # | |
117 | # IDR_MAINFRAME ICON "res\\icon.ico" | |
118 | # | |
119 | # so we have to replace double backslashes with single ones. | |
120 | res = [ regex.replace-list $(res) : "\\\\\\\\" : "/" ] ; | |
121 | ||
122 | # CONSIDER: the new scoping rules seem to defeat "on target" variables. | |
123 | local g = [ on $(target) return $(HDRGRIST) ] ; | |
124 | local b = [ NORMALIZE_PATH $(binding:D) ] ; | |
125 | ||
126 | # Attach binding of including file to included targets. When a target is | |
127 | # directly created from a virtual target this extra information is | |
128 | # unnecessary. But in other cases, it allows us to distinguish between | |
129 | # two headers of the same name included from different places. We do not | |
130 | # need this extra information for angle includes, since they should not | |
131 | # depend on the including file (we can not get literal "." in the | |
132 | # include path). | |
133 | local g2 = $(g)"#"$(b) ; | |
134 | ||
135 | angle = $(angle:G=$(g)) ; | |
136 | quoted = $(quoted:G=$(g2)) ; | |
137 | res = $(res:G=$(g2)) ; | |
138 | ||
139 | local all = $(angle) $(quoted) $(res) ; | |
140 | ||
141 | INCLUDES $(target) : $(all) ; | |
142 | NOCARE $(all) ; | |
143 | SEARCH on $(angle) = $(self.includes:G=) ; | |
144 | SEARCH on $(quoted) $(res) = $(b) $(self.includes:G=) ; | |
145 | ||
146 | # Just propagate the current scanner to includes, in hope that includes | |
147 | # do not change scanners. | |
148 | scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ; | |
149 | ||
150 | ISFILE $(all) ; | |
151 | } | |
152 | } | |
153 | ||
154 | scanner.register res-scanner : include ; | |
155 | type.set-scanner RC : res-scanner ; |