source: grub-pc/trunk/fuentes/gentpl.py @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

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