]> git.proxmox.com Git - mirror_frr.git/blob - python/makefile.py
Merge pull request #6730 from wesleycoakley/pbrd-dscp-ecn
[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('--dev-build', action = 'store_const', const = True,
18 help = 'run additional developer checks')
19 args = argp.parse_args()
20
21 with open('Makefile', 'r') as fd:
22 before = fd.read()
23
24 mv = MakeReVars(before)
25
26 clippy_scan = mv['clippy_scan'].strip().split()
27 for clippy_file in clippy_scan:
28 assert clippy_file.endswith('.c')
29
30 # check for files using clippy but not listed in clippy_scan
31 if args.dev_build:
32 basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
33 if os.path.exists(os.path.join(basepath, '.git')):
34 clippy_ref = subprocess.check_output([
35 'git', '-C', basepath, 'grep', '-l', '-P', '^#\s*include.*_clippy.c', '--', '**.c']).decode('US-ASCII')
36
37 clippy_ref = set(clippy_ref.splitlines())
38 missing = clippy_ref - set(clippy_scan)
39
40 if len(missing) > 0:
41 sys.stderr.write('error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n' % ('\n\t'.join(sorted(missing))))
42 sys.exit(1)
43
44 clippydep = Template('''
45 ${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c
46 ${clippybase}.lo: ${clippybase}_clippy.c
47 ${clippybase}_clippy.c: $$(CLIPPY_DEPS)''')
48
49 clippyauxdep = Template('''# clippy{
50 # auxiliary clippy target
51 ${target}: ${clippybase}_clippy.c
52 # }clippy''')
53
54 lines = before.splitlines()
55 autoderp = '#AUTODERP# '
56 out_lines = []
57 bcdeps = []
58 make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)')
59
60 while lines:
61 line = lines.pop(0)
62 if line.startswith(autoderp):
63 line = line[len(autoderp):]
64
65 if line == '# clippy{':
66 while lines:
67 line = lines.pop(0)
68 if line == '# }clippy':
69 break
70 continue
71
72 if line.startswith('#'):
73 out_lines.append(line)
74 continue
75
76 full_line = line
77 full_lines = lines[:]
78 while full_line.endswith('\\'):
79 full_line = full_line[:-1] + full_lines.pop(0)
80
81 m = make_rule_re.match(full_line)
82 if m is None:
83 out_lines.append(line)
84 continue
85
86 line, lines = full_line, full_lines
87
88 target, dep = m.group(1), m.group(2)
89
90 if target.endswith('.lo') or target.endswith('.o'):
91 if not dep.endswith('.h'):
92 bcdeps.append('%s.bc: %s' % (target, target))
93 bcdeps.append('\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s' % (dep))
94 if m.group(2) in clippy_scan:
95 out_lines.append(clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2]))
96
97 out_lines.append(line)
98
99 out_lines.append('# clippy{\n# main clippy targets')
100 for clippy_file in clippy_scan:
101 out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2]))
102
103 out_lines.append('')
104 out_lines.extend(bcdeps)
105 out_lines.append('')
106 bc_targets = []
107 for varname in ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES', 'noinst_LIBRARIES']:
108 bc_targets.extend(mv[varname].strip().split())
109 for target in bc_targets:
110 amtgt = target.replace('/', '_').replace('.', '_').replace('-', '_')
111 objs = mv[amtgt + '_OBJECTS'].strip().split()
112 objs = [obj + '.bc' for obj in objs]
113 deps = mv.get(amtgt + '_DEPENDENCIES', '').strip().split()
114 deps = [d + '.bc' for d in deps if d.endswith('.a')]
115 objs.extend(deps)
116 out_lines.append('%s.bc: %s' % (target, ' '.join(objs)))
117 out_lines.append('\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^')
118 out_lines.append('')
119
120 out_lines.append('# }clippy')
121 out_lines.append('')
122
123 after = '\n'.join(out_lines)
124 if after == before:
125 sys.exit(0)
126
127 with open('Makefile.pyout', 'w') as fd:
128 fd.write(after)
129 os.rename('Makefile.pyout', 'Makefile')