]> git.proxmox.com Git - grub2.git/blob - genmk.rb
2003-09-25 Yoshinori K. Okuji <okuji@enbug.org>
[grub2.git] / genmk.rb
1 #! /usr/bin/ruby -w
2 #
3 # Copyright (C) 2002,2003 Yoshinori K. Okuji <okuji@enbug.org>
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}
63 $(CC) -o $@ $^ $(LDFLAGS) $(#{prefix}_LDFLAGS)
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')
112
113 "CLEANFILES += #{@name} #{mod_obj} #{mod_src} #{pre_obj} #{objs_str} #{defsym} #{undsym}
114 MOSTLYCLEANFILES += #{deps_str}
115 DEFSYMFILES += #{defsym}
116 UNDSYMFILES += #{undsym}
117
118 #{@name}: #{pre_obj} #{mod_obj}
119 -rm -f $@
120 $(LD) -r -o $@ $^
121 $(STRIP) --strip-unneeded -K pupa_mod_init -K pupa_mod_fini -R .note -R .comment $@
122
123 #{pre_obj}: #{objs_str}
124 -rm -f $@
125 $(LD) -r -o $@ $^
126
127 #{mod_obj}: #{mod_src}
128 $(CC) $(CPPFLAGS) $(CFLAGS) $(#{prefix}_CFLAGS) -c -o $@ $<
129
130 #{mod_src}: moddep.lst genmodsrc.sh
131 sh $(srcdir)/genmodsrc.sh '#{mod_name}' $< > $@ || (rm -f $@; exit 1)
132
133 #{defsym}: #{pre_obj}
134 $(NM) -g --defined-only -P -p $< | sed 's/^\\([^ ]*\\).*/\\1 #{mod_name}/' > $@
135
136 #{undsym}: #{pre_obj}
137 echo '#{mod_name}' > $@
138 $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
139
140 " + objs.collect_with_index do |obj, i|
141 src = sources[i]
142 fake_obj = File.basename(src).suffix('o')
143 dep = deps[i]
144 flag = if /\.c$/ =~ src then 'CFLAGS' else 'ASFLAGS' end
145 dir = File.dirname(src)
146
147 "#{obj}: #{src}
148 $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -c -o $@ $<
149
150 #{dep}: #{src}
151 set -e; \
152 $(CC) -I#{dir} -I$(srcdir)/#{dir} $(CPPFLAGS) $(#{flag}) $(#{prefix}_#{flag}) -M $< \
153 | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \
154 [ -s $@ ] || rm -f $@
155
156 -include #{dep}
157
158 "
159 end.join('')
160 end
161 end
162
163 class Utility
164 def initialize(dir, name)
165 @dir = dir
166 @name = name
167 end
168 attr_reader :dir, :name
169
170 def rule(sources)
171 prefix = @name.to_var
172 objs = sources.collect do |src|
173 raise "unknown source file `#{src}'" if /\.c$/ !~ src
174 prefix + '-' + src.to_obj
175 end
176 objs_str = objs.join(' ');
177 deps = objs.collect {|obj| obj.suffix('d')}
178 deps_str = deps.join(' ');
179
180 "CLEANFILES += #{@name} #{objs_str}
181 MOSTLYCLEANFILES += #{deps_str}
182
183 #{@name}: #{objs_str}
184 $(BUILD_CC) -o $@ $^ $(BUILD_LDFLAGS) $(#{prefix}_LDFLAGS)
185
186 " + objs.collect_with_index do |obj, i|
187 src = sources[i]
188 fake_obj = File.basename(src).suffix('o')
189 dep = deps[i]
190 dir = File.dirname(src)
191
192 "#{obj}: #{src}
193 $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DPUPA_UTIL=1 $(#{prefix}_CFLAGS) -c -o $@ $<
194
195 #{dep}: #{src}
196 set -e; \
197 $(BUILD_CC) -I#{dir} -I$(srcdir)/#{dir} $(BUILD_CPPFLAGS) $(BUILD_CFLAGS) -DPUPA_UTIL=1 $(#{prefix}_CFLAGS) -M $< \
198 | sed 's,#{Regexp.quote(fake_obj)}[ :]*,#{obj} $@ : ,g' > $@; \
199 [ -s $@ ] || rm -f $@
200
201 -include #{dep}
202
203 "
204 end.join('')
205 end
206 end
207
208 images = []
209 utils = []
210 pmodules = []
211
212 cont = false
213 s = nil
214 while l = gets
215 if cont
216 s += l
217 else
218 s = l
219 end
220
221 print l
222 cont = (/\\$/ =~ l)
223 unless cont
224 s.gsub!(/\\\n/, ' ')
225
226 if /^([a-zA-Z0-9_]+)\s*=\s*(.*?)\s*$/ =~ s
227 var, args = $1, $2
228
229 if var =~ /^([a-zA-Z0-9_]+)_([A-Z]+)$/
230 prefix, type = $1, $2
231
232 case type
233 when 'IMAGES'
234 images += args.split(/\s+/).collect do |img|
235 Image.new(prefix, img)
236 end
237
238 when 'MODULES'
239 pmodules += args.split(/\s+/).collect do |pmod|
240 PModule.new(prefix, pmod)
241 end
242
243 when 'UTILITIES'
244 utils += args.split(/\s+/).collect do |util|
245 Utility.new(prefix, util)
246 end
247
248 when 'SOURCES'
249 if img = images.detect() {|i| i.name.to_var == prefix}
250 print img.rule(args.split(/\s+/))
251 elsif pmod = pmodules.detect() {|m| m.name.to_var == prefix}
252 print pmod.rule(args.split(/\s+/))
253 elsif util = utils.detect() {|u| u.name.to_var == prefix}
254 print util.rule(args.split(/\s+/))
255 end
256 end
257 end
258
259 end
260
261 end
262
263 end
264
265 puts "CLEANFILES += moddep.lst"
266 puts "pkgdata_DATA += moddep.lst"
267 puts "moddep.lst: $(DEFSYMFILES) $(UNDSYMFILES) genmoddep"
268 puts " cat $(DEFSYMFILES) /dev/null | ./genmoddep $(UNDSYMFILES) > $@ \\"
269 puts " || (rm -f $@; exit 1)"