]> git.proxmox.com Git - mirror_frr.git/blame - python/makefile.py
build: fix Makefile rule redefinition
[mirror_frr.git] / python / makefile.py
CommitLineData
94cfb069
DL
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
8import sys
9import os
10import subprocess
11import re
12import argparse
13from string import Template
59994395 14from makevars import MakeReVars
94cfb069
DL
15
16argp = argparse.ArgumentParser(description = 'FRR Makefile extensions')
17argp.add_argument('--dev-build', action = 'store_const', const = True,
18 help = 'run additional developer checks')
19args = argp.parse_args()
20
21with open('Makefile', 'r') as fd:
22 before = fd.read()
23
59994395 24mv = MakeReVars(before)
94cfb069 25
59994395 26clippy_scan = mv['clippy_scan'].strip().split()
94cfb069
DL
27for clippy_file in clippy_scan:
28 assert clippy_file.endswith('.c')
29
30# check for files using clippy but not listed in clippy_scan
31if 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
44clippydep = Template('''
45${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c
46${clippybase}.lo: ${clippybase}_clippy.c
47${clippybase}_clippy.c: $$(CLIPPY_DEPS)''')
48
49clippyauxdep = Template('''# clippy{
50# auxiliary clippy target
51${target}: ${clippybase}_clippy.c
52# }clippy''')
53
54lines = before.splitlines()
55autoderp = '#AUTODERP# '
56out_lines = []
8fb40377 57bcdeps = []
94cfb069
DL
58make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)')
59
60while 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
06852b5b
DL
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)
94cfb069
DL
82 if m is None:
83 out_lines.append(line)
84 continue
85
06852b5b
DL
86 line, lines = full_line, full_lines
87
8fb40377
DL
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))
94cfb069
DL
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
99out_lines.append('# clippy{\n# main clippy targets')
100for clippy_file in clippy_scan:
101 out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2]))
8fb40377
DL
102
103out_lines.append('')
104out_lines.extend(bcdeps)
105out_lines.append('')
106bc_targets = []
107for varname in ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES', 'noinst_LIBRARIES']:
108 bc_targets.extend(mv[varname].strip().split())
109for 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
94cfb069
DL
120out_lines.append('# }clippy')
121out_lines.append('')
122
123after = '\n'.join(out_lines)
124if after == before:
125 sys.exit(0)
126
127with open('Makefile.pyout', 'w') as fd:
128 fd.write(after)
129os.rename('Makefile.pyout', 'Makefile')