2 # GRUB -- GRand Unified Bootloader
3 # Copyright (C) 2010,2011,2012,2013 Free Software Foundation, Inc.
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.
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.
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/>.
18 from __future__
import print_function
22 from optparse
import OptionParser
26 # This is the python script used to generate Makefile.*.am
29 GRUB_PLATFORMS
= [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
30 "i386_multiboot", "i386_ieee1275", "x86_64_efi",
31 "i386_xen", "x86_64_xen", "i386_xen_pvh",
32 "mips_loongson", "sparc64_ieee1275",
33 "powerpc_ieee1275", "mips_arc", "ia64_efi",
34 "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi",
35 "arm_coreboot", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
39 GROUPS
["common"] = GRUB_PLATFORMS
[:]
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" ]
54 # Groups based on firmware
55 GROUPS
["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi",
56 "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
57 GROUPS
["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
58 GROUPS
["uboot"] = [ "arm_uboot" ]
59 GROUPS
["xen"] = [ "i386_xen", "x86_64_xen" ]
60 GROUPS
["coreboot"] = [ "i386_coreboot", "arm_coreboot" ]
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")
65 # Groups based on hardware features
66 GROUPS
["cmos"] = GROUPS
["x86"][:] + ["mips_loongson", "mips_qemu_mips",
67 "sparc64_ieee1275", "powerpc_ieee1275"]
68 GROUPS
["cmos"].remove("i386_efi"); GROUPS
["cmos"].remove("x86_64_efi");
69 GROUPS
["pci"] = GROUPS
["x86"] + ["mips_loongson"]
70 GROUPS
["usb"] = GROUPS
["pci"] + ["arm_coreboot"]
72 # If gfxterm is main output console integrate it into kernel
73 GROUPS
["videoinkernel"] = ["mips_loongson", "i386_coreboot", "arm_coreboot" ]
74 GROUPS
["videomodules"] = GRUB_PLATFORMS
[:];
75 for i
in GROUPS
["videoinkernel"]: GROUPS
["videomodules"].remove(i
)
77 # Similar for terminfo
78 GROUPS
["terminfoinkernel"] = [ "emu", "mips_loongson", "mips_arc", "mips_qemu_mips", "i386_xen_pvh" ] + GROUPS
["xen"] + GROUPS
["ieee1275"] + GROUPS
["uboot"];
79 GROUPS
["terminfomodule"] = GRUB_PLATFORMS
[:];
80 for i
in GROUPS
["terminfoinkernel"]: GROUPS
["terminfomodule"].remove(i
)
82 # Flattened Device Trees (FDT)
83 GROUPS
["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "loongarch64_efi", "riscv32_efi", "riscv64_efi" ]
85 # Needs software helpers for division
86 # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h
87 GROUPS
["softdiv"] = GROUPS
["arm"] + ["ia64_efi"] + GROUPS
["riscv32"]
88 GROUPS
["no_softdiv"] = GRUB_PLATFORMS
[:]
89 for i
in GROUPS
["softdiv"]: GROUPS
["no_softdiv"].remove(i
)
91 # Miscellaneous groups scheduled to disappear in future
92 GROUPS
["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
93 GROUPS
["nopc"] = GRUB_PLATFORMS
[:]; GROUPS
["nopc"].remove("i386_pc")
96 # Create platform => groups reverse map, where groups covering that
97 # platform are ordered by their sizes
100 for platform
in GRUB_PLATFORMS
:
101 # initialize with platform itself as a group
102 RMAP
[platform
] = [ platform
]
104 for k
in GROUPS
.keys():
106 # skip groups that don't cover this platform
107 if platform
not in v
: continue
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
123 # We support a subset of the AutoGen definitions file syntax. Specifically,
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.
131 (autogen
, definitions
, eof
, var_name
, other_name
, string
, number
,
132 semicolon
, equals
, comma
, lbrace
, rbrace
, lbracket
, rbracket
) = range(14)
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)
138 class AutogenParseError(Exception):
139 def __init__(self
, message
, path
, line
):
140 super(AutogenParseError
, self
).__init
__(message
)
146 super(AutogenParseError
, self
).__str
__() +
147 " at file %s line %d" % (self
.path
, self
.line
))
149 class AutogenDefinition(list):
150 def __getitem__(self
, key
):
152 return super(AutogenDefinition
, self
).__getitem
__(key
)
154 for name
, value
in self
:
158 def __contains__(self
, key
):
159 for name
, value
in self
:
164 def get(self
, key
, default
):
165 for name
, value
in self
:
171 def find_all(self
, key
):
172 for name
, value
in self
:
178 self
.definitions
= AutogenDefinition()
179 self
.def_stack
= [("", self
.definitions
)]
186 def is_unquotable_char(c
):
187 return (ord(c
) in range(ord("!"), ord("~") + 1) and
188 c
not in "#,;<=>[\\]`{}?*'\"()")
191 def is_value_name_char(c
):
192 return c
in ":^-_" or c
.isalnum()
194 def error(self
, message
):
195 raise AutogenParseError(message
, self
.cur_file
, self
.cur_line
)
197 def read_tokens(self
, f
):
202 while offset
< end
and data
[offset
].isspace():
203 if data
[offset
] == "\n":
212 end_directive
= data
.index("\n", offset
)
213 directive
= data
[offset
:end_directive
]
214 offset
= end_directive
216 directive
= data
[offset
:]
218 name
, value
= directive
.split(None, 1)
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")
226 self
.error("#if without matching #endif")
228 self
.error("Unhandled directive '#%s'" % name
)
230 yield AutogenToken
.lbrace
, c
233 yield AutogenToken
.equals
, c
236 yield AutogenToken
.rbrace
, c
239 yield AutogenToken
.lbracket
, c
242 yield AutogenToken
.rbracket
, c
245 yield AutogenToken
.semicolon
, c
248 yield AutogenToken
.comma
, c
250 elif c
in ("'", '"'):
255 self
.error("EOF in quoted string")
256 if data
[offset
] == "\n":
258 if data
[offset
] == "\\":
261 self
.error("EOF in quoted string")
262 if data
[offset
] == "\n":
264 # Proper escaping unimplemented; this can be filled
267 s
.append(data
[offset
])
268 elif data
[offset
] == c
:
272 s
.append(data
[offset
])
273 yield AutogenToken
.string
, "".join(s
)
276 if data
[offset
] == "*":
279 end_comment
= data
.index("*/", offset
)
280 new_offset
= end_comment
+ len("*/")
281 self
.cur_line
+= data
[offset
:new_offset
].count("\n")
284 self
.error("/* without matching */")
285 elif data
[offset
] == "/":
287 offset
= data
.index("\n", offset
)
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():
296 yield AutogenToken
.number
, data
[offset
:end_number
]
298 elif self
.is_unquotable_char(c
):
300 while (end_name
< end
and
301 self
.is_value_name_char(data
[end_name
])):
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
])):
307 yield AutogenToken
.other_name
, data
[offset
:end_name
]
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
316 yield AutogenToken
.var_name
, s
319 self
.error("Invalid input character '%s'" % c
)
320 yield AutogenToken
.eof
, None
322 def do_need_name_end(self
, token
):
323 if len(self
.def_stack
) > 1:
324 self
.error("Definition blocks were left open")
326 def do_need_name_var_name(self
, token
):
327 self
.new_name
= token
329 def do_end_block(self
, token
):
330 if len(self
.def_stack
) <= 1:
331 self
.error("Too many close braces")
332 new_name
, parent_def
= self
.def_stack
.pop()
333 parent_def
.append((new_name
, self
.curdef
))
334 self
.curdef
= parent_def
336 def do_empty_val(self
, token
):
337 self
.curdef
.append((self
.new_name
, ""))
339 def do_str_value(self
, token
):
340 self
.curdef
.append((self
.new_name
, token
))
342 def do_start_block(self
, token
):
343 self
.def_stack
.append((self
.new_name
, self
.curdef
))
344 self
.curdef
= AutogenDefinition()
346 def do_indexed_name(self
, token
):
347 self
.new_name
= token
349 def read_definitions_file(self
, f
):
350 self
.curdef
= self
.definitions
352 state
= AutogenState
.init
354 # The following transition table was reduced from the Autogen
356 # info -f autogen -n 'Full Syntax'
359 AutogenToken
.autogen
: (AutogenState
.need_def
, None),
361 AutogenState
.need_def
: {
362 AutogenToken
.definitions
: (AutogenState
.need_tpl
, None),
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),
369 AutogenState
.need_semi
: {
370 AutogenToken
.semicolon
: (AutogenState
.need_name
, None),
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
),
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),
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
),
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
),
404 AutogenState
.need_rbracket
: {
405 AutogenToken
.rbracket
: (AutogenState
.indx_name
, None),
407 AutogenState
.indx_name
: {
408 AutogenToken
.semicolon
: (
409 AutogenState
.need_name
, self
.do_empty_val
),
410 AutogenToken
.equals
: (AutogenState
.need_value
, None),
412 AutogenState
.have_value
: {
413 AutogenToken
.semicolon
: (AutogenState
.need_name
, None),
414 AutogenToken
.comma
: (AutogenState
.need_value
, None),
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:
425 "Parse error in state %s: unexpected token '%s'" % (
427 if state
== AutogenState
.done
:
430 def read_definitions(self
, path
):
432 with
open(path
) as f
:
433 self
.read_definitions_file(f
)
435 defparser
= AutogenParser()
443 def output(s
, section
=''):
446 outputs
.setdefault(section
, [])
447 outputs
[section
].append(s
)
449 def write_output(section
=''):
450 for s
in outputs
.get(section
, []):
457 def gvar_add(var
, value
):
458 output(var
+ " += " + value
+ "\n")
461 # Per PROGRAM/SCRIPT variables
466 def vars_init(defn
, *var_list
):
469 if name
not in seen_target
and name
not in seen_vars
:
471 output(var
+ " = \n", section
='decl')
474 def var_set(var
, value
):
475 output(var
+ " = " + value
+ "\n")
477 def var_add(var
, value
):
478 output(var
+ " += " + value
+ "\n")
481 # Variable names and rules
484 canonical_name_re
= re
.compile(r
'[^0-9A-Za-z@_]')
485 canonical_name_suffix
= ""
487 def set_canonical_name_suffix(suffix
):
488 global canonical_name_suffix
489 canonical_name_suffix
= suffix
492 return canonical_name_re
.sub('_', defn
['name'] + canonical_name_suffix
)
494 def rule(target
, source
, cmd
):
496 output("\n" + target
+ ": " + source
+ cmd
.replace("\n", "\n\t") + "\n")
498 output("\n" + target
+ ": " + source
+ "\n\t" + cmd
.replace("\n", "\n\t") + "\n")
501 # Handle keys with platform names as values, for example:
508 def platform_tagged(defn
, platform
, tag
):
509 for value
in defn
.find_all(tag
):
510 for group
in RMAP
[platform
]:
515 def if_platform_tagged(defn
, platform
, tag
, snippet_if
, snippet_else
=None):
516 if platform_tagged(defn
, platform
, tag
):
518 elif snippet_else
is not None:
522 # Handle tagged values
530 def foreach_value(defn
, tag
, closure
):
532 for value
in defn
.find_all(tag
):
533 r
.append(closure(value
))
537 # Handle best matched values for a platform, for example:
541 # emu_cflags = '-Wall -DGRUB_EMU=1';
545 def foreach_platform_specific_value(defn
, platform
, suffix
, nonetag
, closure
):
547 for group
in RMAP
[platform
]:
548 values
= list(defn
.find_all(group
+ suffix
))
551 r
.append(closure(value
))
554 for value
in defn
.find_all(nonetag
):
555 r
.append(closure(value
))
559 # Handle values from sum of all groups for a platform, for example:
562 # common = kern/misc.c;
563 # emu = kern/emu/misc.c;
567 def foreach_platform_value(defn
, platform
, suffix
, closure
):
569 for group
in RMAP
[platform
]:
570 for value
in defn
.find_all(group
+ suffix
):
571 r
.append(closure(value
))
575 def platform_conditional(platform
, closure
):
576 output("\nif COND_" + platform
+ "\n")
581 # Handle guarding with platform-specific "enable" keys, for example:
586 # emu = bus/emu/pci.c;
587 # emu = commands/lspci.c;
592 # enable = i386_ieee1275;
593 # enable = i386_coreboot;
596 def foreach_enabled_platform(defn
, closure
):
598 for platform
in GRUB_PLATFORMS
:
599 if platform_tagged(defn
, platform
, "enable"):
600 platform_conditional(platform
, closure
)
602 for platform
in GRUB_PLATFORMS
:
603 platform_conditional(platform
, closure
)
606 # Handle guarding with platform-specific automake conditionals, for example:
610 # common = bus/usb/usb.c;
611 # noemu = bus/usb/usbtrans.c;
612 # noemu = bus/usb/usbhub.c;
615 # enable = mips_loongson;
616 # emu_condition = COND_GRUB_EMU_SDL;
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"))
624 def platform_specific_values(defn
, platform
, suffix
, nonetag
):
625 return foreach_platform_specific_value(defn
, platform
, suffix
, nonetag
,
626 lambda value
: value
+ " ")
628 def platform_values(defn
, platform
, suffix
):
629 return foreach_platform_value(defn
, platform
, suffix
, lambda value
: value
+ " ")
631 def extra_dist(defn
):
632 return foreach_value(defn
, "extra_dist", lambda value
: value
+ " ")
635 return foreach_value(defn
, "depends", lambda value
: value
+ " ")
637 def platform_sources(defn
, p
): return platform_values(defn
, p
, "")
638 def platform_nodist_sources(defn
, p
): return platform_values(defn
, p
, "_nodist")
640 def platform_startup(defn
, p
): return platform_specific_values(defn
, p
, "_startup", "startup")
641 def platform_ldadd(defn
, p
): return platform_specific_values(defn
, p
, "_ldadd", "ldadd")
642 def platform_dependencies(defn
, p
): return platform_specific_values(defn
, p
, "_dependencies", "dependencies")
643 def platform_cflags(defn
, p
): return platform_specific_values(defn
, p
, "_cflags", "cflags")
644 def platform_ldflags(defn
, p
): return platform_specific_values(defn
, p
, "_ldflags", "ldflags")
645 def platform_cppflags(defn
, p
): return platform_specific_values(defn
, p
, "_cppflags", "cppflags")
646 def platform_ccasflags(defn
, p
): return platform_specific_values(defn
, p
, "_ccasflags", "ccasflags")
647 def platform_stripflags(defn
, p
): return platform_specific_values(defn
, p
, "_stripflags", "stripflags")
648 def platform_objcopyflags(defn
, p
): return platform_specific_values(defn
, p
, "_objcopyflags", "objcopyflags")
651 # Emit snippet only the first time through for the current name.
655 def first_time(defn
, snippet
):
656 if defn
['name'] not in seen_target
:
660 def is_platform_independent(defn
):
663 for suffix
in [ "", "_nodist" ]:
664 template
= platform_values(defn
, GRUB_PLATFORMS
[0], suffix
)
665 for platform
in GRUB_PLATFORMS
[1:]:
666 if template
!= platform_values(defn
, platform
, suffix
):
669 for suffix
in [ "startup", "ldadd", "dependencies", "cflags", "ldflags", "cppflags", "ccasflags", "stripflags", "objcopyflags", "condition" ]:
670 template
= platform_specific_values(defn
, GRUB_PLATFORMS
[0], "_" + suffix
, suffix
)
671 for platform
in GRUB_PLATFORMS
[1:]:
672 if template
!= platform_specific_values(defn
, platform
, "_" + suffix
, suffix
):
674 for tag
in [ "nostrip" ]:
675 template
= platform_tagged(defn
, GRUB_PLATFORMS
[0], tag
)
676 for platform
in GRUB_PLATFORMS
[1:]:
677 if template
!= platform_tagged(defn
, platform
, tag
):
682 def module(defn
, platform
):
684 set_canonical_name_suffix(".module")
686 gvar_add("platform_PROGRAMS", name
+ ".module")
687 gvar_add("MODULE_FILES", name
+ ".module$(EXEEXT)")
689 var_set(cname(defn
) + "_SOURCES", platform_sources(defn
, platform
) + " ## platform sources")
690 var_set("nodist_" + cname(defn
) + "_SOURCES", platform_nodist_sources(defn
, platform
) + " ## platform nodist sources")
691 var_set(cname(defn
) + "_LDADD", platform_ldadd(defn
, platform
))
692 var_set(cname(defn
) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn
, platform
))
693 var_set(cname(defn
) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn
, platform
))
694 var_set(cname(defn
) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn
, platform
))
695 var_set(cname(defn
) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn
, platform
))
696 var_set(cname(defn
) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn
, platform
))
698 gvar_add("dist_noinst_DATA", extra_dist(defn
))
699 gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn
) + "_SOURCES)")
700 gvar_add("CLEANFILES", "$(nodist_" + cname(defn
) + "_SOURCES)")
702 gvar_add("MOD_FILES", name
+ ".mod")
703 gvar_add("MARKER_FILES", name
+ ".marker")
704 gvar_add("CLEANFILES", name
+ ".marker")
706 for dep
in defn
.find_all("depends"):
707 gvar_add("EXTRA_DEPS", "depends " + name
+ " " + dep
+ ":")
710 """ + name
+ """.marker: $(""" + cname(defn
) + """_SOURCES) $(nodist_""" + cname(defn
) + """_SOURCES)
711 $(TARGET_CPP) -DGRUB_LST_GENERATOR $(CPPFLAGS_MARKER) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(""" + cname(defn
) + """_CPPFLAGS) $(CPPFLAGS) $^ > $@.new || (rm -f $@; exit 1)
712 grep 'MARKER' $@.new | grep -v '^#' > $@; rm -f $@.new
715 def kernel(defn
, platform
):
717 set_canonical_name_suffix(".exec")
718 gvar_add("platform_PROGRAMS", name
+ ".exec")
719 var_set(cname(defn
) + "_SOURCES", platform_startup(defn
, platform
))
720 var_add(cname(defn
) + "_SOURCES", platform_sources(defn
, platform
))
721 var_set("nodist_" + cname(defn
) + "_SOURCES", platform_nodist_sources(defn
, platform
) + " ## platform nodist sources")
722 var_set(cname(defn
) + "_LDADD", platform_ldadd(defn
, platform
))
723 var_set(cname(defn
) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_KERNEL) " + platform_cflags(defn
, platform
))
724 var_set(cname(defn
) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_KERNEL) " + platform_ldflags(defn
, platform
))
725 var_set(cname(defn
) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_KERNEL) " + platform_cppflags(defn
, platform
))
726 var_set(cname(defn
) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_KERNEL) " + platform_ccasflags(defn
, platform
))
727 var_set(cname(defn
) + "_STRIPFLAGS", "$(AM_STRIPFLAGS) $(STRIPFLAGS_KERNEL) " + platform_stripflags(defn
, platform
))
728 var_set(cname(defn
) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF)")
730 gvar_add("dist_noinst_DATA", extra_dist(defn
))
731 gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn
) + "_SOURCES)")
732 gvar_add("CLEANFILES", "$(nodist_" + cname(defn
) + "_SOURCES)")
734 gvar_add("platform_DATA", name
+ ".img")
735 gvar_add("CLEANFILES", name
+ ".img")
736 rule(name
+ ".img", name
+ ".exec$(EXEEXT)",
737 if_platform_tagged(defn
, platform
, "nostrip",
738 """if test x$(TARGET_APPLE_LINKER) = x1; then \
739 $(TARGET_OBJCONV) -f$(TARGET_MODULE_FORMAT) -nr:_grub_mod_init:grub_mod_init -nr:_grub_mod_fini:grub_mod_fini -ed2022 -wd1106 -nu -nd $< $@; \
740 elif test ! -z '$(TARGET_OBJ2ELF)'; then \
741 $(TARGET_OBJ2ELF) $< $@ || (rm -f $@; exit 1); \
742 else cp $< $@; fi""",
743 """if test x$(TARGET_APPLE_LINKER) = x1; then \
744 $(TARGET_STRIP) -S -x $(""" + cname(defn
) + """) -o $@.bin $<; \
745 $(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 $@; \
747 elif test ! -z '$(TARGET_OBJ2ELF)'; then \
748 """ + "$(TARGET_STRIP) $(" + cname(defn
) + "_STRIPFLAGS) -o $@.bin $< && \
749 $(TARGET_OBJ2ELF) $@.bin $@ || (rm -f $@; rm -f $@.bin; exit 1); \
751 else """ + "$
(TARGET_STRIP
) $
(" + cname(defn) + "_STRIPFLAGS
) -o $
@ $
<; \
754 def image(defn, platform):
756 set_canonical_name_suffix(".image")
757 gvar_add("platform_PROGRAMS", name + ".image")
758 var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
759 var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + "## platform nodist sources")
760 var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
761 var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_IMAGE) " + platform_cflags(defn, platform))
762 var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_IMAGE) " + platform_ldflags(defn, platform))
763 var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_IMAGE) " + platform_cppflags(defn, platform))
764 var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_IMAGE) " + platform_ccasflags(defn, platform))
765 var_set(cname(defn) + "_OBJCOPYFLAGS", "$(OBJCOPYFLAGS_IMAGE) " + platform_objcopyflags(defn, platform))
766 # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
768 gvar_add("dist_noinst_DATA", extra_dist(defn))
769 gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
770 gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
772 gvar_add("platform_DATA", name + ".img")
773 gvar_add("CLEANFILES", name + ".img")
774 rule(name + ".img", name + ".image$(EXEEXT)", """
775 if test x$
(TARGET_APPLE_LINKER
) = x1
; then \
776 $
(MACHO2IMG
) $
< $
@; \
778 $
(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 $
< $
@; \
782 def library(defn, platform):
784 set_canonical_name_suffix("")
787 cname(defn) + "_SOURCES",
788 "nodist_" + cname(defn) + "_SOURCES",
789 cname(defn) + "_CFLAGS",
790 cname(defn) + "_CPPFLAGS",
791 cname(defn) + "_CCASFLAGS")
792 # cname(defn) + "_DEPENDENCIES")
794 if name not in seen_target:
795 gvar_add("noinst_LIBRARIES", name)
796 var_add(cname(defn) + "_SOURCES", platform_sources(defn, platform))
797 var_add("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
798 var_add(cname(defn) + "_CFLAGS", first_time(defn, "$(AM_CFLAGS) $(CFLAGS_LIBRARY) ") + platform_cflags(defn, platform))
799 var_add(cname(defn) + "_CPPFLAGS", first_time(defn, "$(AM_CPPFLAGS) $(CPPFLAGS_LIBRARY) ") + platform_cppflags(defn, platform))
800 var_add(cname(defn) + "_CCASFLAGS", first_time(defn, "$(AM_CCASFLAGS) $(CCASFLAGS_LIBRARY) ") + platform_ccasflags(defn, platform))
801 # var_add(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
803 gvar_add("dist_noinst_DATA", extra_dist(defn))
804 if name not in seen_target:
805 gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
806 gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
808 def installdir(defn, default="bin"):
809 return defn.get('installdir', default)
811 def manpage(defn, adddeps):
813 mansection = defn['mansection']
815 output("if COND_MAN_PAGES\n")
816 gvar_add("man_MANS", name + "." + mansection)
817 rule(name + "." + mansection, name + " " + adddeps, """
818 chmod a
+x
""" + name + """
819 PATH
=$
(builddir
):$$PATH pkgdatadir
=$
(builddir
) $
(HELP2MAN
) --section
=""" + mansection + """ -i $
(top_srcdir
)/docs
/man
/""" + name + """.h2m
-o $
@ """ + name + """
821 gvar_add("CLEANFILES", name + "." + mansection)
824 def program(defn, platform, test=False):
826 set_canonical_name_suffix("")
828 if 'testcase' in defn:
829 gvar_add("check_PROGRAMS_" + defn['testcase'], name)
831 var_add(installdir(defn) + "_PROGRAMS", name)
832 if 'mansection' in defn:
835 var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform))
836 var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform))
837 var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform))
838 var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_PROGRAM) " + platform_cflags(defn, platform))
839 var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_PROGRAM) " + platform_ldflags(defn, platform))
840 var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_PROGRAM) " + platform_cppflags(defn, platform))
841 var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_PROGRAM) " + platform_ccasflags(defn, platform))
842 # var_set(cname(defn) + "_DEPENDENCIES", platform_dependencies(defn, platform) + " " + platform_ldadd(defn, platform))
844 gvar_add("dist_noinst_DATA", extra_dist(defn))
845 gvar_add("BUILT_SOURCES", "$(nodist_" + cname(defn) + "_SOURCES)")
846 gvar_add("CLEANFILES", "$(nodist_" + cname(defn) + "_SOURCES)")
848 def data(defn, platform):
849 var_add("dist_" + installdir(defn) + "_DATA", platform_sources(defn, platform))
850 gvar_add("dist_noinst_DATA", extra_dist(defn))
852 def transform_data(defn, platform):
855 var_add(installdir(defn) + "_DATA", name)
857 rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
858 (for x
in """ + platform_sources(defn, platform) + """; do cat $
(srcdir
)/"$$x"; done
) | $
(top_builddir
)/config
.status
--file=$
@:-
859 chmod a
+x
""" + name + """
862 gvar_add("CLEANFILES", name)
863 gvar_add("EXTRA_DIST", extra_dist(defn))
864 gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
866 def script(defn, platform):
869 if 'testcase' in defn:
870 gvar_add("check_SCRIPTS_" + defn['testcase'], name)
872 var_add(installdir(defn) + "_SCRIPTS", name)
873 if 'mansection' in defn:
874 manpage(defn, "grub-mkconfig_lib")
876 rule(name, "$(top_builddir)/config.status " + platform_sources(defn, platform) + platform_dependencies(defn, platform), """
877 (for x
in """ + platform_sources(defn, platform) + """; do cat $
(srcdir
)/"$$x"; done
) | $
(top_builddir
)/config
.status
--file=$
@:-
878 chmod a
+x
""" + name + """
881 gvar_add("CLEANFILES", name)
882 gvar_add("EXTRA_DIST", extra_dist(defn))
883 gvar_add("dist_noinst_DATA", platform_sources(defn, platform))
885 def rules(target, closure):
889 for defn in defparser.definitions.find_all(target):
890 if is_platform_independent(defn):
891 under_platform_specific_conditionals(defn, GRUB_PLATFORMS[0], closure)
893 foreach_enabled_platform(
895 lambda p: under_platform_specific_conditionals(defn, p, closure))
896 # Remember that we've seen this target.
897 seen_target.add(defn['name'])
899 parser = OptionParser(usage="%prog DEFINITION-FILES")
900 _, args = parser.parse_args()
903 defparser.read_definitions(arg)
905 rules("module", module)
906 rules("kernel", kernel)
907 rules("image", image)
908 rules("library", library)
909 rules("program", program)
910 rules("script", script)
912 rules("transform_data", transform_data)
914 write_output(section='decl')