]>
Commit | Line | Data |
---|---|---|
8c411768 | 1 | #! /usr/bin/python |
e3ec28ab | 2 | # GRUB -- GRand Unified Bootloader |
ab4f1501 | 3 | # Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc. |
e3ec28ab VS |
4 | # |
5 | # GRUB is free software: you can redistribute it and/or modify | |
6 | # it under the terms of the GNU General Public License as published by | |
7 | # the Free Software Foundation, either version 3 of the License, or | |
8 | # (at your option) any later version. | |
9 | # | |
10 | # GRUB is distributed in the hope that it will be useful, | |
11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | # GNU General Public License for more details. | |
14 | # | |
15 | # You should have received a copy of the GNU General Public License | |
16 | # along with GRUB. If not, see <http://www.gnu.org/licenses/>. | |
8c411768 | 17 | |
aa437b58 MG |
18 | from __future__ import print_function |
19 | ||
ab4f1501 CW |
20 | __metaclass__ = type |
21 | ||
22 | from optparse import OptionParser | |
23 | import re | |
24 | ||
8c411768 | 25 | # |
ab4f1501 | 26 | # This is the python script used to generate Makefile.*.am |
8c411768 BC |
27 | # |
28 | ||
29 | GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", | |
062cdbc1 | 30 | "i386_multiboot", "i386_ieee1275", "x86_64_efi", |
9c062ad4 | 31 | "i386_xen", "x86_64_xen", "i386_xen_pvh", |
54da1feb | 32 | "mips_loongson", "sparc64_ieee1275", |
3666d5f6 | 33 | "powerpc_ieee1275", "mips_arc", "ia64_efi", |
24e37a88 | 34 | "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", |
ad5e446a | 35 | "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] |
8c411768 BC |
36 | |
37 | GROUPS = {} | |
eefe8abd VS |
38 | |
39 | GROUPS["common"] = GRUB_PLATFORMS[:] | |
40 | ||
41 | # Groups based on CPU | |
ad5e446a XW |
42 | GROUPS["i386"] = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ] |
43 | GROUPS["x86_64"] = [ "x86_64_efi" ] | |
44 | GROUPS["x86"] = GROUPS["i386"] + GROUPS["x86_64"] | |
45 | GROUPS["mips"] = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ] | |
46 | GROUPS["sparc64"] = [ "sparc64_ieee1275" ] | |
47 | GROUPS["powerpc"] = [ "powerpc_ieee1275" ] | |
48 | GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] | |
49 | GROUPS["arm64"] = [ "arm64_efi" ] | |
50 | GROUPS["loongarch64"] = [ "loongarch64_efi" ] | |
51 | GROUPS["riscv32"] = [ "riscv32_efi" ] | |
52 | GROUPS["riscv64"] = [ "riscv64_efi" ] | |
8427685f | 53 | |
eefe8abd | 54 | # Groups based on firmware |
f1957dc8 | 55 | GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", |
ad5e446a | 56 | "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] |
8427685f | 57 | GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] |
389b31cd | 58 | GROUPS["uboot"] = [ "arm_uboot" ] |
9612ebc0 | 59 | GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] |
24e37a88 | 60 | GROUPS["coreboot"] = [ "i386_coreboot", "arm_coreboot" ] |
8427685f | 61 | |
eefe8abd VS |
62 | # emu is a special case so many core functionality isn't needed on this platform |
63 | GROUPS["noemu"] = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu") | |
64 | ||
65 | # Groups based on hardware features | |
a07a81b3 VS |
66 | GROUPS["cmos"] = GROUPS["x86"][:] + ["mips_loongson", "mips_qemu_mips", |
67 | "sparc64_ieee1275", "powerpc_ieee1275"] | |
9612ebc0 | 68 | GROUPS["cmos"].remove("i386_efi"); GROUPS["cmos"].remove("x86_64_efi"); |
bee1aeb9 | 69 | GROUPS["pci"] = GROUPS["x86"] + ["mips_loongson"] |
d11ced1e | 70 | GROUPS["usb"] = GROUPS["pci"] + ["arm_coreboot"] |
8427685f | 71 | |
eefe8abd | 72 | # If gfxterm is main output console integrate it into kernel |
24e37a88 | 73 | GROUPS["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ] |
eefe8abd VS |
74 | GROUPS["videomodules"] = GRUB_PLATFORMS[:]; |
75 | for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i) | |
8427685f | 76 | |
ee74fa48 | 77 | # Similar for terminfo |
9c062ad4 | 78 | GROUPS["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS["xen"] + GROUPS["ieee1275"] + GROUPS["uboot"]; |
ee74fa48 VS |
79 | GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; |
80 | for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) | |
81 | ||
389b31cd | 82 | # Flattened Device Trees (FDT) |
ad5e446a | 83 | GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ] |
389b31cd | 84 | |
f034fab6 VS |
85 | # Needs software helpers for division |
86 | # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h | |
f1957dc8 | 87 | GROUPS["softdiv"] = GROUPS["arm"] + ["ia64_efi"] + GROUPS["riscv32"] |
f034fab6 VS |
88 | GROUPS["no_softdiv"] = GRUB_PLATFORMS[:] |
89 | for i in GROUPS["softdiv"]: GROUPS["no_softdiv"].remove(i) | |
90 | ||
fd73b3d0 | 91 | # Miscellaneous groups scheduled to disappear in future |
eefe8abd VS |
92 | GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] |
93 | GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") | |
8c411768 BC |
94 | |
95 | # | |
96 | # Create platform => groups reverse map, where groups covering that | |
97 | # platform are ordered by their sizes | |
98 | # | |
99 | RMAP = {} | |
100 | for platform in GRUB_PLATFORMS: | |
101 | # initialize with platform itself as a group | |
102 | RMAP[platform] = [ platform ] | |
103 | ||
104 | for k in GROUPS.keys(): | |
105 | v = GROUPS[k] | |
106 | # skip groups that don't cover this platform | |
107 | if platform not in v: continue | |
108 | ||
109 | bigger = [] | |
110 | smaller = [] | |
111 | # partition currently known groups based on their size | |
112 | for group in RMAP[platform]: | |
113 | if group in GRUB_PLATFORMS: smaller.append(group) | |
114 | elif len(GROUPS[group]) < len(v): smaller.append(group) | |
115 | else: bigger.append(group) | |
116 | # insert in the middle | |
117 | RMAP[platform] = smaller + [ k ] + bigger | |
118 | ||
ab4f1501 CW |
119 | # |
120 | # Input | |
121 | # | |
122 | ||
123 | # We support a subset of the AutoGen definitions file syntax. Specifically, | |
34b2003d CW |
124 | # compound names are disallowed; some preprocessing directives are |
125 | # disallowed (though #if/#endif are allowed; note that, like AutoGen, #if | |
126 | # skips everything to the next #endif regardless of the value of the | |
127 | # conditional); and shell-generated strings, Scheme-generated strings, and | |
128 | # here strings are disallowed. | |
ab4f1501 CW |
129 | |
130 | class AutogenToken: | |
131 | (autogen, definitions, eof, var_name, other_name, string, number, | |
132 | semicolon, equals, comma, lbrace, rbrace, lbracket, rbracket) = range(14) | |
133 | ||
134 | class AutogenState: | |
135 | (init, need_def, need_tpl, need_semi, need_name, have_name, need_value, | |
136 | need_idx, need_rbracket, indx_name, have_value, done) = range(12) | |
137 | ||
138 | class AutogenParseError(Exception): | |
7e90f5ad | 139 | def __init__(self, message, path, line): |
ab4f1501 | 140 | super(AutogenParseError, self).__init__(message) |
7e90f5ad | 141 | self.path = path |
ab4f1501 CW |
142 | self.line = line |
143 | ||
144 | def __str__(self): | |
145 | return ( | |
146 | super(AutogenParseError, self).__str__() + | |
7e90f5ad | 147 | " at file %s line %d" % (self.path, self.line)) |
ab4f1501 CW |
148 | |
149 | class AutogenDefinition(list): | |
150 | def __getitem__(self, key): | |
151 | try: | |
152 | return super(AutogenDefinition, self).__getitem__(key) | |
153 | except TypeError: | |
154 | for name, value in self: | |
155 | if name == key: | |
156 | return value | |
157 | ||
158 | def __contains__(self, key): | |
159 | for name, value in self: | |
160 | if name == key: | |
161 | return True | |
162 | return False | |
163 | ||
164 | def get(self, key, default): | |
165 | for name, value in self: | |
166 | if name == key: | |
167 | return value | |
168 | else: | |
169 | return default | |
170 | ||
171 | def find_all(self, key): | |
172 | for name, value in self: | |
173 | if name == key: | |
174 | yield value | |
175 | ||
176 | class AutogenParser: | |
177 | def __init__(self): | |
178 | self.definitions = AutogenDefinition() | |
179 | self.def_stack = [("", self.definitions)] | |
180 | self.curdef = None | |
181 | self.new_name = None | |
7e90f5ad | 182 | self.cur_path = None |
ab4f1501 CW |
183 | self.cur_line = 0 |
184 | ||
185 | @staticmethod | |
186 | def is_unquotable_char(c): | |
187 | return (ord(c) in range(ord("!"), ord("~") + 1) and | |
188 | c not in "#,;<=>[\\]`{}?*'\"()") | |
189 | ||
190 | @staticmethod | |
191 | def is_value_name_char(c): | |
192 | return c in ":^-_" or c.isalnum() | |
193 | ||
7e90f5ad CW |
194 | def error(self, message): |
195 | raise AutogenParseError(message, self.cur_file, self.cur_line) | |
196 | ||
ab4f1501 CW |
197 | def read_tokens(self, f): |
198 | data = f.read() | |
199 | end = len(data) | |
200 | offset = 0 | |
201 | while offset < end: | |
202 | while offset < end and data[offset].isspace(): | |
203 | if data[offset] == "\n": | |
204 | self.cur_line += 1 | |
205 | offset += 1 | |
206 | if offset >= end: | |
207 | break | |
208 | c = data[offset] | |
34b2003d CW |
209 | if c == "#": |
210 | offset += 1 | |
211 | try: | |
212 | end_directive = data.index("\n", offset) | |
213 | directive = data[offset:end_directive] | |
214 | offset = end_directive | |
215 | except ValueError: | |
216 | directive = data[offset:] | |
217 | offset = end | |
218 | name, value = directive.split(None, 1) | |
219 | if name == "if": | |
220 | try: | |
221 | end_if = data.index("\n#endif", offset) | |
222 | new_offset = end_if + len("\n#endif") | |
223 | self.cur_line += data[offset:new_offset].count("\n") | |
224 | offset = new_offset | |
225 | except ValueError: | |
226 | self.error("#if without matching #endif") | |
227 | else: | |
228 | self.error("Unhandled directive '#%s'" % name) | |
229 | elif c == "{": | |
ab4f1501 CW |
230 | yield AutogenToken.lbrace, c |
231 | offset += 1 | |
232 | elif c == "=": | |
233 | yield AutogenToken.equals, c | |
234 | offset += 1 | |
235 | elif c == "}": | |
236 | yield AutogenToken.rbrace, c | |
237 | offset += 1 | |
238 | elif c == "[": | |
239 | yield AutogenToken.lbracket, c | |
240 | offset += 1 | |
241 | elif c == "]": | |
242 | yield AutogenToken.rbracket, c | |
243 | offset += 1 | |
244 | elif c == ";": | |
245 | yield AutogenToken.semicolon, c | |
246 | offset += 1 | |
247 | elif c == ",": | |
248 | yield AutogenToken.comma, c | |
249 | offset += 1 | |
250 | elif c in ("'", '"'): | |
251 | s = [] | |
252 | while True: | |
253 | offset += 1 | |
254 | if offset >= end: | |
7e90f5ad | 255 | self.error("EOF in quoted string") |
ab4f1501 CW |
256 | if data[offset] == "\n": |
257 | self.cur_line += 1 | |
258 | if data[offset] == "\\": | |
259 | offset += 1 | |
260 | if offset >= end: | |
7e90f5ad | 261 | self.error("EOF in quoted string") |
ab4f1501 CW |
262 | if data[offset] == "\n": |
263 | self.cur_line += 1 | |
264 | # Proper escaping unimplemented; this can be filled | |
265 | # out if needed. | |
266 | s.append("\\") | |
267 | s.append(data[offset]) | |
268 | elif data[offset] == c: | |
269 | offset += 1 | |
270 | break | |
271 | else: | |
272 | s.append(data[offset]) | |
273 | yield AutogenToken.string, "".join(s) | |
34b2003d CW |
274 | elif c == "/": |
275 | offset += 1 | |
276 | if data[offset] == "*": | |
277 | offset += 1 | |
278 | try: | |
279 | end_comment = data.index("*/", offset) | |
280 | new_offset = end_comment + len("*/") | |
281 | self.cur_line += data[offset:new_offset].count("\n") | |
282 | offset = new_offset | |
283 | except ValueError: | |
284 | self.error("/* without matching */") | |
285 | elif data[offset] == "/": | |
286 | try: | |
287 | offset = data.index("\n", offset) | |
288 | except ValueError: | |
289 | pass | |
ab4f1501 CW |
290 | elif (c.isdigit() or |
291 | (c == "-" and offset < end - 1 and | |
292 | data[offset + 1].isdigit())): | |
293 | end_number = offset + 1 | |
294 | while end_number < end and data[end_number].isdigit(): | |
295 | end_number += 1 | |
296 | yield AutogenToken.number, data[offset:end_number] | |
297 | offset = end_number | |
298 | elif self.is_unquotable_char(c): | |
299 | end_name = offset | |
300 | while (end_name < end and | |
301 | self.is_value_name_char(data[end_name])): | |
302 | end_name += 1 | |
303 | if end_name < end and self.is_unquotable_char(data[end_name]): | |
304 | while (end_name < end and | |
305 | self.is_unquotable_char(data[end_name])): | |
306 | end_name += 1 | |
307 | yield AutogenToken.other_name, data[offset:end_name] | |
308 | offset = end_name | |
309 | else: | |
310 | s = data[offset:end_name] | |
311 | if s.lower() == "autogen": | |
312 | yield AutogenToken.autogen, s | |
313 | elif s.lower() == "definitions": | |
314 | yield AutogenToken.definitions, s | |
315 | else: | |
316 | yield AutogenToken.var_name, s | |
317 | offset = end_name | |
318 | else: | |
7e90f5ad | 319 | self.error("Invalid input character '%s'" % c) |
ab4f1501 CW |
320 | yield AutogenToken.eof, None |
321 | ||
322 | def do_need_name_end(self, token): | |
323 | if len(self.def_stack) > 1: | |
7e90f5ad | 324 | self.error("Definition blocks were left open") |
ab4f1501 CW |
325 | |
326 | def do_need_name_var_name(self, token): | |
327 | self.new_name = token | |
328 | ||
329 | def do_end_block(self, token): | |
330 | if len(self.def_stack) <= 1: | |
7e90f5ad | 331 | self.error("Too many close braces") |
ab4f1501 CW |
332 | new_name, parent_def = self.def_stack.pop() |
333 | parent_def.append((new_name, self.curdef)) | |
334 | self.curdef = parent_def | |
335 | ||
336 | def do_empty_val(self, token): | |
337 | self.curdef.append((self.new_name, "")) | |
338 | ||
339 | def do_str_value(self, token): | |
340 | self.curdef.append((self.new_name, token)) | |
341 | ||
342 | def do_start_block(self, token): | |
343 | self.def_stack.append((self.new_name, self.curdef)) | |
344 | self.curdef = AutogenDefinition() | |
345 | ||
346 | def do_indexed_name(self, token): | |
347 | self.new_name = token | |
348 | ||
7e90f5ad | 349 | def read_definitions_file(self, f): |
ab4f1501 CW |
350 | self.curdef = self.definitions |
351 | self.cur_line = 0 | |
352 | state = AutogenState.init | |
353 | ||
354 | # The following transition table was reduced from the Autogen | |
355 | # documentation: | |
356 | # info -f autogen -n 'Full Syntax' | |
357 | transitions = { | |
358 | AutogenState.init: { | |
359 | AutogenToken.autogen: (AutogenState.need_def, None), | |
360 | }, | |
361 | AutogenState.need_def: { | |
362 | AutogenToken.definitions: (AutogenState.need_tpl, None), | |
363 | }, | |
364 | AutogenState.need_tpl: { | |
365 | AutogenToken.var_name: (AutogenState.need_semi, None), | |
366 | AutogenToken.other_name: (AutogenState.need_semi, None), | |
367 | AutogenToken.string: (AutogenState.need_semi, None), | |
368 | }, | |
369 | AutogenState.need_semi: { | |
370 | AutogenToken.semicolon: (AutogenState.need_name, None), | |
371 | }, | |
372 | AutogenState.need_name: { | |
373 | AutogenToken.autogen: (AutogenState.need_def, None), | |
374 | AutogenToken.eof: (AutogenState.done, self.do_need_name_end), | |
375 | AutogenToken.var_name: ( | |
376 | AutogenState.have_name, self.do_need_name_var_name), | |
377 | AutogenToken.rbrace: ( | |
378 | AutogenState.have_value, self.do_end_block), | |
379 | }, | |
380 | AutogenState.have_name: { | |
381 | AutogenToken.semicolon: ( | |
382 | AutogenState.need_name, self.do_empty_val), | |
383 | AutogenToken.equals: (AutogenState.need_value, None), | |
384 | AutogenToken.lbracket: (AutogenState.need_idx, None), | |
385 | }, | |
386 | AutogenState.need_value: { | |
387 | AutogenToken.var_name: ( | |
388 | AutogenState.have_value, self.do_str_value), | |
389 | AutogenToken.other_name: ( | |
390 | AutogenState.have_value, self.do_str_value), | |
391 | AutogenToken.string: ( | |
392 | AutogenState.have_value, self.do_str_value), | |
393 | AutogenToken.number: ( | |
394 | AutogenState.have_value, self.do_str_value), | |
395 | AutogenToken.lbrace: ( | |
396 | AutogenState.need_name, self.do_start_block), | |
397 | }, | |
398 | AutogenState.need_idx: { | |
399 | AutogenToken.var_name: ( | |
400 | AutogenState.need_rbracket, self.do_indexed_name), | |
401 | AutogenToken.number: ( | |
402 | AutogenState.need_rbracket, self.do_indexed_name), | |
403 | }, | |
404 | AutogenState.need_rbracket: { | |
405 | AutogenToken.rbracket: (AutogenState.indx_name, None), | |
406 | }, | |
407 | AutogenState.indx_name: { | |
408 | AutogenToken.semicolon: ( | |
409 | AutogenState.need_name, self.do_empty_val), | |
410 | AutogenToken.equals: (AutogenState.need_value, None), | |
411 | }, | |
412 | AutogenState.have_value: { | |
413 | AutogenToken.semicolon: (AutogenState.need_name, None), | |
414 | AutogenToken.comma: (AutogenState.need_value, None), | |
415 | }, | |
416 | } | |
417 | ||
418 | for code, token in self.read_tokens(f): | |
419 | if code in transitions[state]: | |
420 | state, handler = transitions[state][code] | |
421 | if handler is not None: | |
422 | handler(token) | |
423 | else: | |
7e90f5ad | 424 | self.error( |
ab4f1501 | 425 | "Parse error in state %s: unexpected token '%s'" % ( |
7e90f5ad | 426 | state, token)) |
ab4f1501 CW |
427 | if state == AutogenState.done: |
428 | break | |
429 | ||
7e90f5ad CW |
430 | def read_definitions(self, path): |
431 | self.cur_file = path | |
432 | with open(path) as f: | |
433 | self.read_definitions_file(f) | |
434 | ||
ab4f1501 CW |
435 | defparser = AutogenParser() |
436 | ||
437 | # | |
438 | # Output | |
439 | # | |
440 | ||
441 | outputs = {} | |
442 | ||
443 | def output(s, section=''): | |
444 | if s == "": | |
445 | return | |
446 | outputs.setdefault(section, []) | |
447 | outputs[section].append(s) | |
448 | ||
449 | def write_output(section=''): | |
450 | for s in outputs.get(section, []): | |
aa437b58 | 451 | print(s, end='') |
ab4f1501 | 452 | |
8c411768 BC |
453 | # |
454 | # Global variables | |
455 | # | |
8c411768 BC |
456 | |
457 | def gvar_add(var, value): | |
ab4f1501 | 458 | output(var + " += " + value + "\n") |
8c411768 BC |
459 | |
460 | # | |
461 | # Per PROGRAM/SCRIPT variables | |
462 | # | |
463 | ||
ab4f1501 CW |
464 | seen_vars = set() |
465 | ||
466 | def vars_init(defn, *var_list): | |
467 | name = defn['name'] | |
468 | ||
469 | if name not in seen_target and name not in seen_vars: | |
470 | for var in var_list: | |
471 | output(var + " = \n", section='decl') | |
472 | seen_vars.add(name) | |
e1fd1939 | 473 | |
8c411768 | 474 | def var_set(var, value): |
ab4f1501 | 475 | output(var + " = " + value + "\n") |
8c411768 BC |
476 | |
477 | def var_add(var, value): | |
ab4f1501 | 478 | output(var + " += " + value + "\n") |
8c411768 BC |
479 | |
480 | # | |
ab4f1501 | 481 | # Variable names and rules |
8c411768 BC |
482 | # |
483 | ||
ab4f1501 CW |
484 | canonical_name_re = re.compile(r'[^0-9A-Za-z@_]') |
485 | canonical_name_suffix = "" | |
486 | ||
487 | def set_canonical_name_suffix(suffix): | |
488 | global canonical_name_suffix | |
489 | canonical_name_suffix = suffix | |
490 | ||
491 | def cname(defn): | |
492 | return canonical_name_re.sub('_', defn['name'] + canonical_name_suffix) | |
8c411768 | 493 | |
911bd640 BC |
494 | def rule(target, source, cmd): |
495 | if cmd[0] == "\n": | |
ab4f1501 | 496 | output("\n" + target + ": " + source + cmd.replace("\n", "\n\t") + "\n") |
911bd640 | 497 | else: |
ab4f1501 | 498 | output("\n" + target + ": " + source + "\n\t" + cmd.replace("\n", "\n\t") + "\n") |
8c411768 | 499 | |
d9b78bce | 500 | # |
ab4f1501 | 501 | # Handle keys with platform names as values, for example: |
d9b78bce BC |
502 | # |
503 | # kernel = { | |
504 | # nostrip = emu; | |
f6023b61 | 505 | # ... |
d9b78bce BC |
506 | # } |
507 | # | |
ab4f1501 CW |
508 | def platform_tagged(defn, platform, tag): |
509 | for value in defn.find_all(tag): | |
510 | for group in RMAP[platform]: | |
511 | if value == group: | |
512 | return True | |
513 | return False | |
8c411768 | 514 | |
ab4f1501 CW |
515 | def if_platform_tagged(defn, platform, tag, snippet_if, snippet_else=None): |
516 | if platform_tagged(defn, platform, tag): | |
517 | return snippet_if | |
518 | elif snippet_else is not None: | |
519 | return snippet_else | |
8c411768 | 520 | |
d9b78bce | 521 | # |
ab4f1501 | 522 | # Handle tagged values |
8427685f BC |
523 | # |
524 | # module = { | |
525 | # extra_dist = ... | |
526 | # extra_dist = ... | |
527 | # ... | |
528 | # }; | |
529 | # | |
ab4f1501 CW |
530 | def foreach_value(defn, tag, closure): |
531 | r = [] | |
532 | for value in defn.find_all(tag): | |
533 | r.append(closure(value)) | |
534 | return ''.join(r) | |
8427685f BC |
535 | |
536 | # | |
ab4f1501 | 537 | # Handle best matched values for a platform, for example: |
d9b78bce BC |
538 | # |
539 | # module = { | |
540 | # cflags = '-Wall'; | |
541 | # emu_cflags = '-Wall -DGRUB_EMU=1'; | |
f6023b61 | 542 | # ... |
d9b78bce BC |
543 | # } |
544 | # | |
ab4f1501 CW |
545 | def foreach_platform_specific_value(defn, platform, suffix, nonetag, closure): |
546 | r = [] | |
911bd640 | 547 | for group in RMAP[platform]: |
ab4f1501 CW |
548 | values = list(defn.find_all(group + suffix)) |
549 | if values: | |
550 | for value in values: | |
551 | r.append(closure(value)) | |
552 | break | |
553 | else: | |
554 | for value in defn.find_all(nonetag): | |
555 | r.append(closure(value)) | |
556 | return ''.join(r) | |
8667a314 | 557 | |
8427685f | 558 | # |
ab4f1501 | 559 | # Handle values from sum of all groups for a platform, for example: |
8427685f BC |
560 | # |
561 | # module = { | |
562 | # common = kern/misc.c; | |
563 | # emu = kern/emu/misc.c; | |
564 | # ... | |
565 | # } | |
566 | # | |
ab4f1501 CW |
567 | def foreach_platform_value(defn, platform, suffix, closure): |
568 | r = [] | |
8427685f | 569 | for group in RMAP[platform]: |
ab4f1501 CW |
570 | for value in defn.find_all(group + suffix): |
571 | r.append(closure(value)) | |
ab2aeda7 | 572 | r.sort() |
ab4f1501 | 573 | return ''.join(r) |
8427685f | 574 | |
ab4f1501 CW |
575 | def platform_conditional(platform, closure): |
576 | output("\nif COND_" + platform + "\n") | |
577 | closure(platform) | |
578 | output("endif\n") | |
8c411768 | 579 | |
8427685f | 580 | # |
ab4f1501 | 581 | # Handle guarding with platform-specific "enable" keys, for example: |
8427685f BC |
582 | # |
583 | # module = { | |
584 | # name = pci; | |
585 | # noemu = bus/pci.c; | |
586 | # emu = bus/emu/pci.c; | |
587 | # emu = commands/lspci.c; | |
588 | # | |
589 | # enable = emu; | |
590 | # enable = i386_pc; | |
591 | # enable = x86_efi; | |
592 | # enable = i386_ieee1275; | |
593 | # enable = i386_coreboot; | |
594 | # }; | |
595 | # | |
ab4f1501 CW |
596 | def foreach_enabled_platform(defn, closure): |
597 | if 'enable' in defn: | |
598 | for platform in GRUB_PLATFORMS: | |
599 | if platform_tagged(defn, platform, "enable"): | |
600 | platform_conditional(platform, closure) | |
601 | else: | |
602 | for platform in GRUB_PLATFORMS: | |
603 | platform_conditional(platform, closure) | |
d9b78bce | 604 | |
8427685f | 605 | # |
ab4f1501 | 606 | # Handle guarding with platform-specific automake conditionals, for example: |
8427685f BC |
607 | # |
608 | # module = { | |
609 | # name = usb; | |
610 | # common = bus/usb/usb.c; | |
611 | # noemu = bus/usb/usbtrans.c; | |
612 | # noemu = bus/usb/usbhub.c; | |
613 | # enable = emu; | |
614 | # enable = i386; | |
54da1feb | 615 | # enable = mips_loongson; |
9d25b0da | 616 | # emu_condition = COND_GRUB_EMU_SDL; |
8427685f BC |
617 | # }; |
618 | # | |
ab4f1501 CW |
619 | def under_platform_specific_conditionals(defn, platform, closure): |
620 | output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "if " + cond + "\n")) | |
621 | closure(defn, platform) | |
622 | output(foreach_platform_specific_value(defn, platform, "_condition", "condition", lambda cond: "endif " + cond + "\n")) | |
623 | ||
624 | def platform_specific_values(defn, platform, suffix, nonetag): | |
625 | return foreach_platform_specific_value(defn, platform, suffix, nonetag, | |
8427685f | 626 | lambda value: value + " ") |
911bd640 | 627 | |
ab4f1501 CW |
628 | def platform_values(defn, platform, suffix): |
629 | return foreach_platform_value(defn, platform, suffix, lambda value: value + " ") | |
630 | ||
631 | def extra_dist(defn): | |
632 | return foreach_value(defn, "extra_dist", lambda value: value + " ") | |
633 | ||
634 | def platform_sources(defn, p): return platform_values(defn, p, "") | |
635 | def platform_nodist_sources(defn, p): return platform_values(defn, p, "_nodist") | |
636 | ||
637 | def platform_startup(defn, p): return platform_specific_values(defn, p, "_startup", "startup") | |
638 | def platform_ldadd(defn, p): return platform_specific_values(defn, p, "_ldadd", "ldadd") | |
639 | def platform_dependencies(defn, p): return platform_specific_values(defn, p, "_dependencies", "dependencies") | |
640 | def platform_cflags(defn, p): return platform_specific_values(defn, p, "_cflags", "cflags") | |
641 | def platform_ldflags(defn, p): return platform_specific_values(defn, p, "_ldflags", "ldflags") | |
642 | def platform_cppflags(defn, p): return platform_specific_values(defn, p, "_cppflags", "cppflags") | |
643 | def platform_ccasflags(defn, p): return platform_specific_values(defn, p, "_ccasflags", "ccasflags") | |
644 | def platform_stripflags(defn, p): return platform_specific_values(defn, p, "_stripflags", "stripflags") | |
645 | def platform_objcopyflags(defn, p): return platform_specific_values(defn, p, "_objcopyflags", "objcopyflags") | |
8c411768 | 646 | |
e1fd1939 CW |
647 | # |
648 | # Emit snippet only the first time through for the current name. | |
649 | # | |
ab4f1501 CW |
650 | seen_target = set() |
651 | ||
652 | def first_time(defn, snippet): | |
653 | if defn['name'] not in seen_target: | |
654 | return snippet | |
655 | return '' | |
656 | ||
b1f742c1 VS |
657 | def is_platform_independent(defn): |
658 | if 'enable' in defn: | |
659 | return False | |
660 | for suffix in [ "", "_nodist" ]: | |
661 | template = platform_values(defn, GRUB_PLATFORMS[0], suffix) | |
662 | for platform in GRUB_PLATFORMS[1:]: | |
663 | if template != platform_values(defn, platform, suffix): | |
664 | return False | |
665 | ||
666 | for suffix in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]: | |
667 | template = platform_specific_values(defn, GRUB_PLATFORMS[0], "_" + suffix, suffix) | |
668 | for platform in GRUB_PLATFORMS[1:]: | |
669 | if template != platform_specific_values(defn, platform, "_" + suffix, suffix): | |
670 | return False | |
671 | for tag in [ "nostrip" ]: | |
672 | template = platform_tagged(defn, GRUB_PLATFORMS[0], tag) | |
673 | for platform in GRUB_PLATFORMS[1:]: | |
674 | if template != platform_tagged(defn, platform, tag): | |
675 | return False | |
676 | ||
677 | return True | |
678 | ||
ab4f1501 CW |
679 | def module(defn, platform): |
680 | name = defn['name'] | |
681 | set_canonical_name_suffix(".module") | |
682 | ||
683 | gvar_add("platform_PROGRAMS", name + ".module") | |
684 | gvar_add("MODULE_FILES", name + ".module$(EXEEXT)") | |
685 | ||
686 | var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") | |
687 | var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") | |
688 | var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) | |
689 | var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) | |
690 | var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) | |
691 | var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) | |
692 | var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) | |
693 | var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) | |
694 | ||
695 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
696 | gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
697 | gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
698 | ||
699 | gvar_add("MOD_FILES", name + ".mod") | |
700 | gvar_add("MARKER_FILES", name + ".marker") | |
701 | gvar_add("CLEANFILES", name + ".marker") | |
702 | output(""" | |
703 | """ + name + """.marker: $(""" + cname(defn) + """_SOURCES) $(nodist_""" + cname(defn) + """_SOURCES) | |
704 | $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1) | |
a274bf45 | 705 | grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new |
ab4f1501 CW |
706 | """) |
707 | ||
708 | def kernel(defn, platform): | |
709 | name = defn['name'] | |
710 | set_canonical_name_suffix(".exec") | |
711 | gvar_add("platform_PROGRAMS", name + ".exec") | |
712 | var_set(cname(defn) + "_SOURCES", platform_startup(defn, platform)) | |
713 | var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) | |
714 | var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") | |
715 | var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) | |
716 | var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn, platform)) | |
717 | var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn, platform)) | |
718 | var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn, platform)) | |
719 | var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn, platform)) | |
720 | var_set(cname(defn) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn, platform)) | |
721 | var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)") | |
722 | ||
723 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
724 | gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
725 | gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
726 | ||
727 | gvar_add("platform_DATA", name + ".img") | |
728 | gvar_add("CLEANFILES", name + ".img") | |
729 | rule(name + ".img", name + ".exec$(EXEEXT)", | |
730 | if_platform_tagged(defn, platform, "nostrip", | |
a9f25a08 | 731 | """if test x$(TARGET_APPLE_LINKER) = x1; then \ |
fc97214f | 732 | $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \ |
22899b9c | 733 | elif test ! -z '$(TARGET_OBJ2ELF)'; then \ |
60b967be | 734 | $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \ |
22899b9c | 735 | else cp $< $@; fi""", |
a9f25a08 | 736 | """if test x$(TARGET_APPLE_LINKER) = x1; then \ |
ab4f1501 | 737 | $(TARGET_STRIP) -S -x $(""" + cname(defn) + """) -o $@.bin $<; \ |
c8f7614b | 738 | $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -ed2016 -wd1106 -nu -nd $@.bin $@; \ |
4d6e9c8a | 739 | rm -f $@.bin; \ |
60b967be VS |
740 | elif test ! -z '$(TARGET_OBJ2ELF)'; then \ |
741 | """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@.bin $< && \ | |
742 | $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \ | |
4d6e9c8a | 743 | rm -f $@.bin; \ |
ab4f1501 | 744 | else """ + "$(TARGET_STRIP) $(" + cname(defn) + "_STRIPFLAGS) -o $@ $<; \ |
22899b9c | 745 | fi""")) |
ab4f1501 CW |
746 | |
747 | def image(defn, platform): | |
748 | name = defn['name'] | |
749 | set_canonical_name_suffix(".image") | |
750 | gvar_add("platform_PROGRAMS", name + ".image") | |
751 | var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) | |
752 | var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources") | |
753 | var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) | |
754 | var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform)) | |
755 | var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform)) | |
756 | var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform)) | |
757 | var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform)) | |
758 | var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform)) | |
759 | # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) | |
760 | ||
761 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
762 | gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
763 | gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
764 | ||
765 | gvar_add("platform_DATA", name + ".img") | |
766 | gvar_add("CLEANFILES", name + ".img") | |
767 | rule(name + ".img", name + ".image$(EXEEXT)", """ | |
a9f25a08 | 768 | if test x$(TARGET_APPLE_LINKER) = x1; then \ |
8c411768 BC |
769 | $(MACHO2IMG) $< $@; \ |
770 | else \ | |
b58aa4e2 | 771 | $(TARGET_OBJCOPY) $(""" + cname(defn) + """_OBJCOPYFLAGS) --strip-unneeded -R .note -R .comment -R .note.gnu.build-id -R .MIPS.abiflags -R .reginfo -R .rel.dyn -R .note.gnu.gold-version -R .note.gnu.property -R .ARM.exidx -R .interp $< $@; \ |
8c411768 BC |
772 | fi |
773 | """) | |
ab4f1501 CW |
774 | |
775 | def library(defn, platform): | |
776 | name = defn['name'] | |
777 | set_canonical_name_suffix("") | |
778 | ||
779 | vars_init(defn, | |
780 | cname(defn) + "_SOURCES", | |
781 | "nodist_" + cname(defn) + "_SOURCES", | |
782 | cname(defn) + "_CFLAGS", | |
783 | cname(defn) + "_CPPFLAGS", | |
784 | cname(defn) + "_CCASFLAGS") | |
785 | # cname(defn) + "_DEPENDENCIES") | |
786 | ||
787 | if name not in seen_target: | |
788 | gvar_add("noinst_LIBRARIES", name) | |
789 | var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform)) | |
790 | var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) | |
791 | var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform)) | |
792 | var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform)) | |
793 | var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform)) | |
794 | # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) | |
795 | ||
796 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
797 | if name not in seen_target: | |
798 | gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
799 | gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
800 | ||
801 | def installdir(defn, default="bin"): | |
802 | return defn.get('installdir', default) | |
803 | ||
804 | def manpage(defn, adddeps): | |
805 | name = defn['name'] | |
806 | mansection = defn['mansection'] | |
807 | ||
808 | output("if COND_MAN_PAGES\n") | |
809 | gvar_add("man_MANS", name + "." + mansection) | |
810 | rule(name + "." + mansection, name + " " + adddeps, """ | |
811 | chmod a+x """ + name + """ | |
812 | PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ | |
8c411768 | 813 | """) |
ab4f1501 CW |
814 | gvar_add("CLEANFILES", name + "." + mansection) |
815 | output("endif\n") | |
816 | ||
817 | def program(defn, platform, test=False): | |
818 | name = defn['name'] | |
819 | set_canonical_name_suffix("") | |
820 | ||
821 | if 'testcase' in defn: | |
5e10be48 | 822 | gvar_add("check_PROGRAMS_" + defn['testcase'], name) |
ab4f1501 CW |
823 | else: |
824 | var_add(installdir(defn) + "_PROGRAMS", name) | |
825 | if 'mansection' in defn: | |
826 | manpage(defn, "") | |
827 | ||
828 | var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform)) | |
829 | var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform)) | |
830 | var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) | |
831 | var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform)) | |
832 | var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform)) | |
833 | var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform)) | |
834 | var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform)) | |
835 | # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform)) | |
836 | ||
837 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
838 | gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
839 | gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)") | |
840 | ||
841 | def data(defn, platform): | |
842 | var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform)) | |
843 | gvar_add("dist_noinst_DATA", extra_dist(defn)) | |
844 | ||
368ecfc3 VS |
845 | def transform_data(defn, platform): |
846 | name = defn['name'] | |
847 | ||
848 | var_add(installdir(defn) + "_DATA", name) | |
849 | ||
850 | rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ | |
851 | (for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- | |
852 | chmod a+x """ + name + """ | |
853 | """) | |
854 | ||
855 | gvar_add("CLEANFILES", name) | |
856 | gvar_add("EXTRA_DIST", extra_dist(defn)) | |
857 | gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) | |
858 | ||
ab4f1501 CW |
859 | def script(defn, platform): |
860 | name = defn['name'] | |
861 | ||
862 | if 'testcase' in defn: | |
5e10be48 | 863 | gvar_add("check_SCRIPTS_" + defn['testcase'], name) |
ab4f1501 CW |
864 | else: |
865 | var_add(installdir(defn) + "_SCRIPTS", name) | |
866 | if 'mansection' in defn: | |
867 | manpage(defn, "grub-mkconfig_lib") | |
868 | ||
869 | rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """ | |
870 | (for x in """ + platform_sources(defn, platform) + """; do cat $(srcdir)/"$$x"; done) | $(top_builddir)/config.status --file=$@:- | |
871 | chmod a+x """ + name + """ | |
8c411768 BC |
872 | """) |
873 | ||
ab4f1501 CW |
874 | gvar_add("CLEANFILES", name) |
875 | gvar_add("EXTRA_DIST", extra_dist(defn)) | |
876 | gvar_add("dist_noinst_DATA", platform_sources(defn, platform)) | |
8c411768 | 877 | |
e1fd1939 | 878 | def rules(target, closure): |
ab4f1501 CW |
879 | seen_target.clear() |
880 | seen_vars.clear() | |
881 | ||
882 | for defn in defparser.definitions.find_all(target): | |
b1f742c1 VS |
883 | if is_platform_independent(defn): |
884 | under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure) | |
885 | else: | |
886 | foreach_enabled_platform( | |
887 | defn, | |
888 | lambda p: under_platform_specific_conditionals(defn, p, closure)) | |
ab4f1501 CW |
889 | # Remember that we've seen this target. |
890 | seen_target.add(defn['name']) | |
891 | ||
892 | parser = OptionParser(usage="%prog DEFINITION-FILES") | |
893 | _, args = parser.parse_args() | |
894 | ||
895 | for arg in args: | |
7e90f5ad | 896 | defparser.read_definitions(arg) |
ab4f1501 CW |
897 | |
898 | rules("module", module) | |
899 | rules("kernel", kernel) | |
900 | rules("image", image) | |
901 | rules("library", library) | |
902 | rules("program", program) | |
903 | rules("script", script) | |
904 | rules("data", data) | |
368ecfc3 | 905 | rules("transform_data", transform_data) |
ab4f1501 CW |
906 | |
907 | write_output(section='decl') | |
908 | write_output() |