Merge branch 'mainline' into zfs
[grub2/phcoder.git] / genmk.rb
blob36f40201cc2924be495d2b792aa91bbfa782dd07
1 #! /usr/bin/ruby -w
3 # Copyright (C) 2002,2003,2004,2005,2006,2007,2008  Free Software Foundation, Inc.
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.
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.
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
24 class String
25   def to_var
26     self.gsub(/[^a-zA-Z0-9_@]/, '_')
27   end
29   def suffix(str)
30     self.sub(/\.[^\.]*$/, '') + '.' + str
31   end
33   def to_obj
34     self.sub(/\.[^\.]*$/, '').to_var + '.o'
35   end
36 end
38 class Image
39   def initialize(dir, name)
40     @dir = dir
41     @name = name
42   end
43   attr_reader :dir, :name
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(' ')
56     "CLEANFILES += #{@name} #{exe} #{objs_str}
57 MOSTLYCLEANFILES += #{deps_str}
59 ifneq ($(TARGET_APPLE_CC),1)
60 #{@name}: #{exe}
61         $(OBJCOPY) -O $(#{prefix}_FORMAT) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id $< $@
62 else
63 ifneq (#{exe},kernel.exec)
64 #{@name}: #{exe} ./grub-macho2img
65         ./grub-macho2img $< $@
66 else
67 #{@name}: #{exe} ./grub-macho2img
68         ./grub-macho2img --bss $< $@
69 endif
70 endif
72 #{exe}: #{objs_str}
73         $(TARGET_CC) -o $@ $^ $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
75 " + objs.collect_with_index do |obj, i|
76       src = sources[i]
77       fake_obj = File.basename(src).suffix('o')
78       dep = deps[i]
79       flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
80       extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
81       dir = File.dirname(src)
83       "#{obj}: #{src} $(#{src}_DEPENDENCIES)
84         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
85 -include #{dep}
88     end.join('')
89   end
90 end
92 # Use PModule instead Module, to avoid name conflicting.
93 class PModule
94   def initialize(dir, name)
95     @dir = dir
96     @name = name
97   end
98   attr_reader :dir, :name
100   def rule(sources)
101     prefix = @name.to_var
102     objs = sources.collect do |src|
103       raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
104       prefix + '-' + src.to_obj
105     end
106     objs_str = objs.join(' ')
107     deps = objs.collect {|obj| obj.suffix('d')}
108     deps_str = deps.join(' ')
109     pre_obj = 'pre-' + @name.suffix('o')
110     mod_src = 'mod-' + @name.suffix('c')
111     mod_obj = mod_src.suffix('o')
112     defsym = 'def-' + @name.suffix('lst')
113     undsym = 'und-' + @name.suffix('lst')
114     mod_name = File.basename(@name, '.mod')
115     symbolic_name = mod_name.sub(/\.[^\.]*$/, '')
117     "CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{undsym}
118 ifneq ($(#{prefix}_EXPORTS),no)
119 CLEANFILES += #{defsym}
120 DEFSYMFILES += #{defsym}
121 endif
122 MOSTLYCLEANFILES += #{deps_str}
123 UNDSYMFILES += #{undsym}
125 ifneq ($(TARGET_APPLE_CC),1)
126 #{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
127         -rm -f $@
128         $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{pre_obj} #{mod_obj}
129         if test ! -z $(TARGET_OBJ2ELF); then ./$(TARGET_OBJ2ELF) $@ || (rm -f $@; exit 1); fi
130         $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -K _grub_mod_init -K _grub_mod_fini -R .note -R .comment $@
131 else
132 #{@name}: #{pre_obj} #{mod_obj} $(TARGET_OBJ2ELF)
133         -rm -f $@
134         -rm -f $@.bin
135         $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@.bin #{pre_obj} #{mod_obj}
136         $(OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -wd1106 -nu -nd $@.bin $@
137         -rm -f $@.bin
138 endif
140 #{pre_obj}: $(#{prefix}_DEPENDENCIES) #{objs_str}
141         -rm -f $@
142         $(TARGET_CC) $(#{prefix}_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ #{objs_str}
144 #{mod_obj}: #{mod_src}
145         $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $<
147 #{mod_src}: $(builddir)/moddep.lst $(srcdir)/genmodsrc.sh
148         sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1)
150 ifneq ($(#{prefix}_EXPORTS),no)
151 ifneq ($(TARGET_APPLE_CC),1)
152 #{defsym}: #{pre_obj}
153         $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
154 else
155 #{defsym}: #{pre_obj}
156         $(NM) -g -P -p $< | grep -E '^[a-zA-Z0-9_]* [TDS]'  | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
157 endif
158 endif
160 #{undsym}: #{pre_obj}
161         echo '#{mod_name}' > $@
162         $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
164 " + objs.collect_with_index do |obj, i|
165       src = sources[i]
166       fake_obj = File.basename(src).suffix('o')
167       command = 'cmd-' + obj.suffix('lst')
168       fs = 'fs-' + obj.suffix('lst')
169       partmap = 'partmap-' + obj.suffix('lst')
170       handler = 'handler-' + obj.suffix('lst')
171       parttool = 'parttool-' + obj.suffix('lst')
172       dep = deps[i]
173       flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
174       extra_flags = if /\.S$/ =~ src then '-DASM_FILE=1' else '' end
175       dir = File.dirname(src)
177       "#{obj}: #{src} $(#{src}_DEPENDENCIES)
178         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -MD -c -o $@ $<
179 -include #{dep}
181 CLEANFILES += #{command} #{fs} #{partmap} #{handler} #{parttool}
182 COMMANDFILES += #{command}
183 FSFILES += #{fs}
184 PARTTOOLFILES += #{parttool}
185 PARTMAPFILES += #{partmap}
186 HANDLERFILES += #{handler}
188 #{command}: #{src} $(#{src}_DEPENDENCIES) gencmdlist.sh
189         set -e; \
190           $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
191           | sh $(srcdir)/gencmdlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
193 #{fs}: #{src} $(#{src}_DEPENDENCIES) genfslist.sh
194         set -e; \
195           $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
196           | sh $(srcdir)/genfslist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
198 #{parttool}: #{src} $(#{src}_DEPENDENCIES) genparttoollist.sh
199         set -e; \
200           $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
201           | sh $(srcdir)/genparttoollist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
203 #{partmap}: #{src} $(#{src}_DEPENDENCIES) genpartmaplist.sh
204         set -e; \
205           $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
206           | sh $(srcdir)/genpartmaplist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
208 #{handler}: #{src} $(#{src}_DEPENDENCIES) genhandlerlist.sh
209         set -e; \
210           $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) #{extra_flags} $(TARGET_#{flag}) $(#{prefix}_#{flag}) -E $< \
211           | sh $(srcdir)/genhandlerlist.sh #{symbolic_name} > $@ || (rm -f $@; exit 1)
214     end.join('')
215   end
218 class Utility
219   def initialize(dir, name)
220     @dir = dir
221     @name = name
222   end
223   attr_reader :dir, :name
225   def rule(sources)
226     prefix = @name.to_var
227     objs = sources.collect do |src|
228       raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
229       prefix + '-' + src.to_obj
230     end
231     objs_str = objs.join(' ');
232     deps = objs.collect {|obj| obj.suffix('d')}
233     deps_str = deps.join(' ');
235     "CLEANFILES += #{@name}$(EXEEXT) #{objs_str}
236 MOSTLYCLEANFILES += #{deps_str}
238 #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str}
239         $(CC) -o $@ #{objs_str} $(LDFLAGS) $(#{prefix}_LDFLAGS)
241 " + objs.collect_with_index do |obj, i|
242       src = sources[i]
243       fake_obj = File.basename(src).suffix('o')
244       dep = deps[i]
245       dir = File.dirname(src)
247       "#{obj}: #{src} $(#{src}_DEPENDENCIES)
248         $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(CFLAGS) -DGRUB_UTIL=1 $(#{prefix}_CFLAGS) -MD -c -o $@ $<
249 -include #{dep}
252     end.join('')
253   end
256 class Program
257   def initialize(dir, name)
258     @dir = dir
259     @name = name
260   end
261   attr_reader :dir, :name
263   def rule(sources)
264     prefix = @name.to_var
265     objs = sources.collect do |src|
266       raise "unknown source file `#{src}'" if /\.[cS]$/ !~ src
267       prefix + '-' + src.to_obj
268     end
269     objs_str = objs.join(' ');
270     deps = objs.collect {|obj| obj.suffix('d')}
271     deps_str = deps.join(' ');
273     "CLEANFILES += #{@name} #{objs_str}
274 MOSTLYCLEANFILES += #{deps_str}
276 #{@name}: $(#{prefix}_DEPENDENCIES) #{objs_str}
277         $(TARGET_CC) -o $@ #{objs_str} $(TARGET_LDFLAGS) $(#{prefix}_LDFLAGS)
279 " + objs.collect_with_index do |obj, i|
280       src = sources[i]
281       fake_obj = File.basename(src).suffix('o')
282       dep = deps[i]
283       dir = File.dirname(src)
285       "#{obj}: #{src} $(#{src}_DEPENDENCIES)
286         $(TARGET_CC) -I#{dir} -I$(srcdir)/#{dir} $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(#{prefix}_CFLAGS) -MD -c -o $@ $<
287 -include #{dep}
290     end.join('')
291   end
294 class Script
295   def initialize(dir, name)
296     @dir = dir
297     @name = name
298   end
299   attr_reader :dir, :name
301   def rule(sources)
302     if sources.length != 1
303       raise "only a single source file must be specified for a script"
304     end
305     src = sources[0]
306     if /\.in$/ !~ src
307       raise "unknown source file `#{src}'"
308     end
310     "CLEANFILES += #{@name}
312 #{@name}: #{src} $(#{src}_DEPENDENCIES) config.status
313         ./config.status --file=#{name}:#{src}
314         chmod +x $@
317   end
320 images = []
321 utils = []
322 pmodules = []
323 programs = []
324 scripts = []
326 l = gets
327 print l
328 print "# Generated by genmk.rb, please don't edit!\n"
330 cont = false
331 str = nil
332 while l = gets
333   if cont
334     str += l
335   else
336     str = l
337   end
339   print l
340   cont = (/\\$/ =~ l)
341   unless cont
342     str.gsub!(/\\\n/, ' ')
344     if /^([a-zA-Z0-9_]+)\s*\+?=\s*(.*?)\s*$/ =~ str
345       var, args = $1, $2
347       if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/
348         prefix, type = $1, $2
350         case type
351         when 'IMAGES'
352           images += args.split(/\s+/).collect do |img|
353             Image.new(prefix, img)
354           end
356         when 'MODULES'
357           pmodules += args.split(/\s+/).collect do |pmod|
358             PModule.new(prefix, pmod)
359           end
361         when 'UTILITIES'
362           utils += args.split(/\s+/).collect do |util|
363             Utility.new(prefix, util)
364           end
366         when 'PROGRAMS'
367           programs += args.split(/\s+/).collect do |prog|
368             Program.new(prefix, prog)
369           end
371         when 'SCRIPTS'
372           scripts += args.split(/\s+/).collect do |script|
373             Script.new(prefix, script)
374           end
376         when 'SOURCES'
377           if img = images.detect() {|i| i.name.to_var == prefix}
378             print img.rule(args.split(/\s+/))
379           elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix}
380             print pmod.rule(args.split(/\s+/))
381           elsif util = utils.detect() {|u| u.name.to_var == prefix}
382             print util.rule(args.split(/\s+/))
383           elsif program = programs.detect() {|u| u.name.to_var == prefix}
384             print program.rule(args.split(/\s+/))
385           elsif script = scripts.detect() {|s| s.name.to_var == prefix}
386             print script.rule(args.split(/\s+/))
387           end
388         end
389       end
391     end
393   end