]>
Commit | Line | Data |
---|---|---|
6a161fa9 | 1 | #! /usr/bin/ruby -w |
2 | # | |
5822ff87 | 3 | # Copyright (C) 2002,2003,2004,2005 Free Software Foundation, Inc. |
6a161fa9 | 4 | # |
5 | # This genmk.rb is free software; the author | |
6 | # gives unlimited permission to copy and/or distribute it, | |
7 | # with or without modifications, as long as this notice is preserved. | |
8 | # | |
9 | # This program is distributed in the hope that it will be useful, | |
10 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without | |
11 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A | |
12 | # PARTICULAR PURPOSE. | |
13 | ||
14 | module Enumerable | |
15 | def collect_with_index | |
16 | ret = [] | |
17 | self.each_with_index do |item, index| | |
18 | ret.push(yield(item, index)) | |
19 | end | |
20 | ret | |
21 | end | |
22 | end | |
23 | ||
24 | class String | |
25 | def to_var | |
26 | self.gsub(/[^a-zA-Z0-9_@]/, '_') | |
27 | end | |
28 | ||
29 | def suffix(str) | |
30 | self.sub(/\.[^\.]*$/, '') + '.' + str | |
31 | end | |
32 | ||
33 | def to_obj | |
34 | self.sub(/\.[^\.]*$/, '').to_var + '.o' | |
35 | end | |
36 | end | |
37 | ||
38 | class Image | |
39 | def initialize(dir, name) | |
40 | @dir = dir | |
41 | @name = name | |
42 | end | |
43 | attr_reader :dir, :name | |
44 | ||
45 | def rule(sources) | |
46 | prefix = @name.to_var | |
47 | exe = @name.suffix('exec') | |
48 | objs = sources.collect do |src| | |
49 | raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src | |
50 | prefix + '-' + src.to_obj | |
51 | end | |
52 | objs_str = objs.join(' ') | |
53 | deps = objs.collect {|obj| obj.suffix('d')} | |
54 | deps_str = deps.join(' ') | |
55 | ||
56 | "CLEANFILES += #{@name} #{exe} #{objs_str} | |
57 | MOSTLYCLEANFILES += #{deps_str} | |
58 | ||
59 | #{@name}: #{exe} | |
60 | $(OBJCOPY) -O binary -R .note -R .comment $< $@ | |
61 | ||
62 | #{exe}: #{objs_str} | |
1f5ab428 | 63 | $(CC) -o $@ $^ $(LDFLAGS) $(#{prefix}_LDFLAGS) |
6a161fa9 | 64 | |
65 | " + objs.collect_with_index do |obj, i| | |
66 | src = sources[i] | |
67 | fake_obj = File.basename(src).suffix('o') | |
68 | dep = deps[i] | |
69 | flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end | |
70 | extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end | |
71 | dir = File.dirname(src) | |
72 | ||
73 | "#{obj}: #{src} | |
74 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) #{extra_flags} $(#{flag}) $(#{prefix}_#{flag}) -c -o $@ $< | |
75 | ||
76 | #{dep}: #{src} | |
77 | set -e; \ | |
78 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) #{extra_flags} $(#{flag}) $(#{prefix}_#{flag}) -M $< \ | |
79 | | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ | |
80 | [ -s $@ ] || rm -f $@ | |
81 | ||
82 | -include #{dep} | |
83 | ||
84 | " | |
85 | end.join('') | |
86 | end | |
87 | end | |
88 | ||
89 | # Use PModule instead Module, to avoid name conflicting. | |
90 | class PModule | |
91 | def initialize(dir, name) | |
92 | @dir = dir | |
93 | @name = name | |
94 | end | |
95 | attr_reader :dir, :name | |
96 | ||
97 | def rule(sources) | |
98 | prefix = @name.to_var | |
99 | objs = sources.collect do |src| | |
100 | raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src | |
101 | prefix + '-' + src.to_obj | |
102 | end | |
103 | objs_str = objs.join(' ') | |
104 | deps = objs.collect {|obj| obj.suffix('d')} | |
105 | deps_str = deps.join(' ') | |
106 | pre_obj = 'pre-' + @name.suffix('o') | |
107 | mod_src = 'mod-' + @name.suffix('c') | |
108 | mod_obj = mod_src.suffix('o') | |
109 | defsym = 'def-' + @name.suffix('lst') | |
110 | undsym = 'und-' + @name.suffix('lst') | |
111 | mod_name = File.basename(@name, '.mod') | |
5822ff87 | 112 | symbolic_name = mod_name.sub(/\.[^\.]*$/, '') |
6a161fa9 | 113 | |
83709125 | 114 | "CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym} |
115 | ifneq ($(#{prefix}_EXPORTS),no) | |
116 | CLEANFILES += #{defsym} | |
6a161fa9 | 117 | DEFSYMFILES += #{defsym} |
83709125 | 118 | endif |
119 | MOSTLYCLEANFILES += #{deps_str} | |
6a161fa9 | 120 | UNDSYMFILES += #{undsym} |
121 | ||
122 | #{@name}: #{pre_obj} #{mod_obj} | |
123 | -rm -f $@ | |
ff04ec24 | 124 | $(CC) $(#{prefix}_LDFLAGS) $(LDFLAGS) -Wl,-r,-d -o $@ $^ |
4b13b216 | 125 | $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@ |
6a161fa9 | 126 | |
127 | #{pre_obj}: #{objs_str} | |
128 | -rm -f $@ | |
ff04ec24 | 129 | $(CC) $(#{prefix}_LDFLAGS) $(LDFLAGS) -Wl,-r,-d -o $@ $^ |
6a161fa9 | 130 | |
131 | #{mod_obj}: #{mod_src} | |
62ddcc8f | 132 | $(CC) $(CPPFLAGS) $(CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $< |
6a161fa9 | 133 | |
134 | #{mod_src}: moddep.lst genmodsrc.sh | |
135 | sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1) | |
136 | ||
83709125 | 137 | ifneq ($(#{prefix}_EXPORTS),no) |
6a161fa9 | 138 | #{defsym}: #{pre_obj} |
139 | $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@ | |
83709125 | 140 | endif |
6a161fa9 | 141 | |
142 | #{undsym}: #{pre_obj} | |
143 | echo '#{mod_name}' > $@ | |
98d15063 | 144 | $(NM) -u -P -p $< | cut -f1 -d' ' >> $@ |
6a161fa9 | 145 | |
146 | " + objs.collect_with_index do |obj, i| | |
147 | src = sources[i] | |
148 | fake_obj = File.basename(src).suffix('o') | |
233b1628 | 149 | command = 'cmd-' + obj.suffix('lst') |
150 | fs = 'fs-' + obj.suffix('lst') | |
6a161fa9 | 151 | dep = deps[i] |
152 | flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end | |
153 | dir = File.dirname(src) | |
154 | ||
155 | "#{obj}: #{src} | |
156 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -c -o $@ $< | |
157 | ||
158 | #{dep}: #{src} | |
159 | set -e; \ | |
160 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -M $< \ | |
161 | | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ | |
162 | [ -s $@ ] || rm -f $@ | |
163 | ||
164 | -include #{dep} | |
165 | ||
39c9d41d | 166 | CLEANFILES += #{command} #{fs} |
7b1f4b57 | 167 | COMMANDFILES += #{command} |
39c9d41d | 168 | FSFILES += #{fs} |
7b1f4b57 | 169 | |
170 | #{command}: #{src} gencmdlist.sh | |
171 | set -e; \ | |
172 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -E $< \ | |
5822ff87 | 173 | | sh $(srcdir)/gencmdlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) |
7b1f4b57 | 174 | |
39c9d41d | 175 | #{fs}: #{src} genfslist.sh |
176 | set -e; \ | |
177 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -E $< \ | |
178 | | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1) | |
179 | ||
180 | ||
6a161fa9 | 181 | " |
182 | end.join('') | |
183 | end | |
184 | end | |
185 | ||
186 | class Utility | |
187 | def initialize(dir, name) | |
188 | @dir = dir | |
189 | @name = name | |
190 | end | |
191 | attr_reader :dir, :name | |
192 | ||
193 | def rule(sources) | |
194 | prefix = @name.to_var | |
195 | objs = sources.collect do |src| | |
e56cdf21 | 196 | raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src |
6a161fa9 | 197 | prefix + '-' + src.to_obj |
198 | end | |
199 | objs_str = objs.join(' '); | |
200 | deps = objs.collect {|obj| obj.suffix('d')} | |
201 | deps_str = deps.join(' '); | |
202 | ||
203 | "CLEANFILES += #{@name} #{objs_str} | |
204 | MOSTLYCLEANFILES += #{deps_str} | |
205 | ||
206 | #{@name}: #{objs_str} | |
1f5ab428 | 207 | $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(#{prefix}_LDFLAGS) |
6a161fa9 | 208 | |
209 | " + objs.collect_with_index do |obj, i| | |
210 | src = sources[i] | |
211 | fake_obj = File.basename(src).suffix('o') | |
212 | dep = deps[i] | |
213 | dir = File.dirname(src) | |
214 | ||
215 | "#{obj}: #{src} | |
4b13b216 | 216 | $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -c -o $@ $< |
6a161fa9 | 217 | |
218 | #{dep}: #{src} | |
219 | set -e; \ | |
4b13b216 | 220 | $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -M $< \ |
6a161fa9 | 221 | | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ |
222 | [ -s $@ ] || rm -f $@ | |
223 | ||
224 | -include #{dep} | |
225 | ||
226 | " | |
227 | end.join('') | |
228 | end | |
229 | end | |
230 | ||
924b6140 | 231 | class Program |
232 | def initialize(dir, name) | |
233 | @dir = dir | |
234 | @name = name | |
235 | end | |
236 | attr_reader :dir, :name | |
237 | ||
238 | def rule(sources) | |
239 | prefix = @name.to_var | |
240 | objs = sources.collect do |src| | |
241 | raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src | |
242 | prefix + '-' + src.to_obj | |
243 | end | |
244 | objs_str = objs.join(' '); | |
245 | deps = objs.collect {|obj| obj.suffix('d')} | |
246 | deps_str = deps.join(' '); | |
247 | ||
248 | "CLEANFILES += #{@name} #{objs_str} | |
249 | MOSTLYCLEANFILES += #{deps_str} | |
250 | ||
251 | #{@name}: #{objs_str} | |
121c1d83 | 252 | $(CC) -o $@ $^ $(LDFLAGS) $(#{prefix}_LDFLAGS) |
924b6140 | 253 | |
254 | " + objs.collect_with_index do |obj, i| | |
255 | src = sources[i] | |
256 | fake_obj = File.basename(src).suffix('o') | |
257 | dep = deps[i] | |
258 | dir = File.dirname(src) | |
259 | ||
260 | "#{obj}: #{src} | |
121c1d83 | 261 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $< |
924b6140 | 262 | |
263 | #{dep}: #{src} | |
264 | set -e; \ | |
121c1d83 | 265 | $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) $(#{prefix}_CFLAGS) -M $< \ |
924b6140 | 266 | | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \ |
267 | [ -s $@ ] || rm -f $@ | |
268 | ||
269 | -include #{dep} | |
270 | ||
271 | " | |
272 | end.join('') | |
273 | end | |
274 | end | |
275 | ||
075a1650 | 276 | class Script |
277 | def initialize(dir, name) | |
278 | @dir = dir | |
279 | @name = name | |
280 | end | |
281 | attr_reader :dir, :name | |
282 | ||
283 | def rule(sources) | |
284 | if sources.length != 1 | |
285 | raise "only a single source file must be specified for a script" | |
286 | end | |
287 | src = sources[0] | |
288 | if /\.in$/ !~ src | |
289 | raise "unknown source file `#{src}'" | |
290 | end | |
291 | ||
292 | "CLEANFILES += #{@name} | |
293 | ||
294 | #{@name}: #{src} config.status | |
295 | ./config.status --file=#{name}:#{src} | |
f4917dfd | 296 | chmod +x $@ |
075a1650 | 297 | |
298 | " | |
299 | end | |
300 | end | |
301 | ||
6a161fa9 | 302 | images = [] |
303 | utils = [] | |
304 | pmodules = [] | |
924b6140 | 305 | programs = [] |
075a1650 | 306 | scripts = [] |
6a161fa9 | 307 | |
308 | cont = false | |
309 | s = nil | |
310 | while l = gets | |
311 | if cont | |
312 | s += l | |
313 | else | |
314 | s = l | |
315 | end | |
316 | ||
317 | print l | |
318 | cont = (/\\$/ =~ l) | |
319 | unless cont | |
320 | s.gsub!(/\\\n/, ' ') | |
321 | ||
233b1628 | 322 | if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ s |
6a161fa9 | 323 | var, args = $1, $2 |
324 | ||
325 | if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/ | |
326 | prefix, type = $1, $2 | |
327 | ||
328 | case type | |
329 | when 'IMAGES' | |
330 | images += args.split(/\s+/).collect do |img| | |
331 | Image.new(prefix, img) | |
332 | end | |
333 | ||
334 | when 'MODULES' | |
335 | pmodules += args.split(/\s+/).collect do |pmod| | |
336 | PModule.new(prefix, pmod) | |
337 | end | |
338 | ||
339 | when 'UTILITIES' | |
340 | utils += args.split(/\s+/).collect do |util| | |
341 | Utility.new(prefix, util) | |
342 | end | |
343 | ||
924b6140 | 344 | when 'PROGRAMS' |
075a1650 | 345 | programs += args.split(/\s+/).collect do |prog| |
346 | Program.new(prefix, prog) | |
347 | end | |
348 | ||
349 | when 'SCRIPTS' | |
350 | scripts += args.split(/\s+/).collect do |script| | |
351 | Script.new(prefix, script) | |
924b6140 | 352 | end |
353 | ||
6a161fa9 | 354 | when 'SOURCES' |
355 | if img = images.detect() {|i| i.name.to_var == prefix} | |
356 | print img.rule(args.split(/\s+/)) | |
357 | elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix} | |
358 | print pmod.rule(args.split(/\s+/)) | |
359 | elsif util = utils.detect() {|u| u.name.to_var == prefix} | |
360 | print util.rule(args.split(/\s+/)) | |
924b6140 | 361 | elsif program = programs.detect() {|u| u.name.to_var == prefix} |
362 | print program.rule(args.split(/\s+/)) | |
075a1650 | 363 | elsif script = scripts.detect() {|s| s.name.to_var == prefix} |
364 | print script.rule(args.split(/\s+/)) | |
6a161fa9 | 365 | end |
366 | end | |
367 | end | |
368 | ||
369 | end | |
370 | ||
371 | end | |
372 | ||
373 | end | |
374 |