]> git.proxmox.com Git - mirror_frr.git/blob - python/makefile.py
Merge pull request #7222 from idryzhov/fix-debug
[mirror_frr.git] / python / makefile.py
1 #!/usr/bin/python3
2 #
3 # FRR extended automake/Makefile functionality helper
4 #
5 # This script is executed on/after generating Makefile to add some pieces for
6 # clippy.
7
8 import sys
9 import os
10 import subprocess
11 import re
12 import argparse
13 from string import Template
14 from makevars import MakeReVars
15
16 argp = argparse.ArgumentParser(description="FRR Makefile extensions")
17 argp.add_argument(
18 "--dev-build",
19 action="store_const",
20 const=True,
21 help="run additional developer checks",
22 )
23 args = argp.parse_args()
24
25 with open("Makefile", "r") as fd:
26 before = fd.read()
27
28 mv = MakeReVars(before)
29
30 clippy_scan = mv["clippy_scan"].strip().split()
31 for clippy_file in clippy_scan:
32 assert clippy_file.endswith(".c")
33
34 # check for files using clippy but not listed in clippy_scan
35 if args.dev_build:
36 basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
37 if os.path.exists(os.path.join(basepath, ".git")):
38 clippy_ref = subprocess.check_output(
39 [
40 "git",
41 "-C",
42 basepath,
43 "grep",
44 "-l",
45 "-P",
46 "^#\s*include.*_clippy.c",
47 "--",
48 "**.c",
49 ]
50 ).decode("US-ASCII")
51
52 clippy_ref = set(clippy_ref.splitlines())
53 missing = clippy_ref - set(clippy_scan)
54
55 if len(missing) > 0:
56 sys.stderr.write(
57 'error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n'
58 % ("\n\t".join(sorted(missing)))
59 )
60 sys.exit(1)
61
62 clippydep = Template(
63 """
64 ${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c
65 ${clippybase}.lo: ${clippybase}_clippy.c
66 ${clippybase}_clippy.c: $$(CLIPPY_DEPS)"""
67 )
68
69 clippyauxdep = Template(
70 """# clippy{
71 # auxiliary clippy target
72 ${target}: ${clippybase}_clippy.c
73 # }clippy"""
74 )
75
76 lines = before.splitlines()
77 autoderp = "#AUTODERP# "
78 out_lines = []
79 bcdeps = []
80 make_rule_re = re.compile("^([^:\s]+):\s*([^:\s]+)\s*($|\n)")
81
82 while lines:
83 line = lines.pop(0)
84 if line.startswith(autoderp):
85 line = line[len(autoderp) :]
86
87 if line == "# clippy{":
88 while lines:
89 line = lines.pop(0)
90 if line == "# }clippy":
91 break
92 continue
93
94 if line.startswith("#"):
95 out_lines.append(line)
96 continue
97
98 full_line = line
99 full_lines = lines[:]
100 while full_line.endswith("\\"):
101 full_line = full_line[:-1] + full_lines.pop(0)
102
103 m = make_rule_re.match(full_line)
104 if m is None:
105 out_lines.append(line)
106 continue
107
108 line, lines = full_line, full_lines
109
110 target, dep = m.group(1), m.group(2)
111
112 if target.endswith(".lo") or target.endswith(".o"):
113 if not dep.endswith(".h"):
114 bcdeps.append("%s.bc: %s" % (target, target))
115 bcdeps.append("\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s" % (dep))
116 if m.group(2) in clippy_scan:
117 out_lines.append(
118 clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2])
119 )
120
121 out_lines.append(line)
122
123 out_lines.append("# clippy{\n# main clippy targets")
124 for clippy_file in clippy_scan:
125 out_lines.append(clippydep.substitute(clippybase=clippy_file[:-2]))
126
127 out_lines.append("")
128 out_lines.extend(bcdeps)
129 out_lines.append("")
130 bc_targets = []
131 for varname in [
132 "bin_PROGRAMS",
133 "sbin_PROGRAMS",
134 "lib_LTLIBRARIES",
135 "module_LTLIBRARIES",
136 "noinst_LIBRARIES",
137 ]:
138 bc_targets.extend(mv[varname].strip().split())
139 for target in bc_targets:
140 amtgt = target.replace("/", "_").replace(".", "_").replace("-", "_")
141 objs = mv[amtgt + "_OBJECTS"].strip().split()
142 objs = [obj + ".bc" for obj in objs]
143 deps = mv.get(amtgt + "_DEPENDENCIES", "").strip().split()
144 deps = [d + ".bc" for d in deps if d.endswith(".a")]
145 objs.extend(deps)
146 out_lines.append("%s.bc: %s" % (target, " ".join(objs)))
147 out_lines.append("\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^")
148 out_lines.append("")
149
150 out_lines.append("# }clippy")
151 out_lines.append("")
152
153 after = "\n".join(out_lines)
154 if after == before:
155 sys.exit(0)
156
157 with open("Makefile.pyout", "w") as fd:
158 fd.write(after)
159 os.rename("Makefile.pyout", "Makefile")