]> git.proxmox.com Git - mirror_frr.git/blobdiff - python/makefile.py
Merge pull request #12805 from karlquan/kquan_self_orig
[mirror_frr.git] / python / makefile.py
index fe20945ccccbfee16c8ffbe3f09ae42fffba5f31..573871fb68c746678281cd89d3e3d2927e488232 100644 (file)
@@ -13,69 +13,106 @@ import argparse
 from string import Template
 from makevars import MakeReVars
 
-argp = argparse.ArgumentParser(description = 'FRR Makefile extensions')
-argp.add_argument('--dev-build', action = 'store_const', const = True,
-            help = 'run additional developer checks')
+argp = argparse.ArgumentParser(description="FRR Makefile extensions")
+argp.add_argument(
+    "--dev-build",
+    action="store_const",
+    const=True,
+    help="run additional developer checks",
+)
 args = argp.parse_args()
 
-with open('Makefile', 'r') as fd:
+with open("Makefile", "r") as fd:
     before = fd.read()
 
 mv = MakeReVars(before)
 
-clippy_scan = mv['clippy_scan'].strip().split()
+clippy_scan = mv["clippy_scan"].strip().split()
 for clippy_file in clippy_scan:
-    assert clippy_file.endswith('.c')
+    assert clippy_file.endswith(".c")
+
+xref_targets = []
+for varname in [
+    "bin_PROGRAMS",
+    "sbin_PROGRAMS",
+    "lib_LTLIBRARIES",
+    "module_LTLIBRARIES",
+]:
+    xref_targets.extend(mv[varname].strip().split())
 
 # check for files using clippy but not listed in clippy_scan
 if args.dev_build:
     basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    if os.path.exists(os.path.join(basepath, '.git')):
-        clippy_ref = subprocess.check_output([
-            'git', '-C', basepath, 'grep', '-l', '-P', '^#\s*include.*_clippy.c', '--', '**.c']).decode('US-ASCII')
+    if os.path.exists(os.path.join(basepath, ".git")):
+        clippy_ref = subprocess.check_output(
+            [
+                "git",
+                "-C",
+                basepath,
+                "grep",
+                "-l",
+                "-P",
+                "^#\s*include.*_clippy.c",
+                "--",
+                "**.c",
+            ]
+        ).decode("US-ASCII")
 
         clippy_ref = set(clippy_ref.splitlines())
         missing = clippy_ref - set(clippy_scan)
 
         if len(missing) > 0:
-            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))))
+            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)))
+            )
             sys.exit(1)
 
-clippydep = Template('''
+# this additional-dependency rule is stuck onto all compile targets that
+# compile a file which uses clippy-generated input, so it has a dependency to
+# make that first.
+clippydep = Template(
+    """
 ${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c
 ${clippybase}.lo: ${clippybase}_clippy.c
-${clippybase}_clippy.c: $$(CLIPPY_DEPS)''')
+${clippybase}_clippy.c: $$(CLIPPY_DEPS)"""
+)
 
-clippyauxdep = Template('''# clippy{
+# this one is used when one .c file is built multiple times with different
+# CFLAGS
+clippyauxdep = Template(
+    """# clippy{
 # auxiliary clippy target
 ${target}: ${clippybase}_clippy.c
-# }clippy''')
+# }clippy"""
+)
 
 lines = before.splitlines()
-autoderp = '#AUTODERP# '
+autoderp = "#AUTODERP# "
 out_lines = []
 bcdeps = []
-make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)')
+make_rule_re = re.compile("^([^:\s]+):\s*([^:\s]+)\s*($|\n)")
 
 while lines:
     line = lines.pop(0)
     if line.startswith(autoderp):
-        line = line[len(autoderp):]
+        line = line[len(autoderp) :]
 
-    if line == '# clippy{':
+    # allow rerunning on already-clippified Makefile
+    if line == "# clippy{":
         while lines:
             line = lines.pop(0)
-            if line == '# }clippy':
+            if line == "# }clippy":
                 break
         continue
 
-    if line.startswith('#'):
+    if line.startswith("#"):
         out_lines.append(line)
         continue
 
     full_line = line
     full_lines = lines[:]
-    while full_line.endswith('\\'):
+    while full_line.endswith("\\"):
         full_line = full_line[:-1] + full_lines.pop(0)
 
     m = make_rule_re.match(full_line)
@@ -87,43 +124,94 @@ while lines:
 
     target, dep = m.group(1), m.group(2)
 
-    if target.endswith('.lo') or target.endswith('.o'):
-        if not dep.endswith('.h'):
-            bcdeps.append('%s.bc: %s' % (target, target))
-            bcdeps.append('\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s' % (dep))
+    filename = os.path.basename(target)
+    if "-" in filename:
+        # dashes in output filename = building same .c with different CFLAGS
+        am_name, _ = filename.split("-", 1)
+        am_name = os.path.join(os.path.dirname(target), am_name)
+        am_name = am_name.replace("/", "_")
+        extraflags = " $(%s_CFLAGS)" % (am_name,)
+    else:
+        # this path isn't really triggered because automake is using a generic
+        # .c => .o rule unless CFLAGS are customized for a target
+        extraflags = ""
+
+    if target.endswith(".lo") or target.endswith(".o"):
+        if not dep.endswith(".h"):
+            # LLVM bitcode targets for analysis tools
+            bcdeps.append("%s.bc: %s" % (target, target))
+            bcdeps.append(
+                "\t$(AM_V_LLVM_BC)$(COMPILE)%s -emit-llvm -c -o $@ %s"
+                % (extraflags, dep)
+            )
     if m.group(2) in clippy_scan:
-        out_lines.append(clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2]))
+        # again - this is only hit for targets with custom CFLAGS, because
+        # automake uses a generic .c -> .o rule for standard CFLAGS
+        out_lines.append(
+            clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2])
+        )
 
     out_lines.append(line)
 
-out_lines.append('# clippy{\n# main clippy targets')
+# now, cover all the .c files that don't have special build rules
+out_lines.append("# clippy{\n# main clippy targets")
 for clippy_file in clippy_scan:
-    out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2]))
-
-out_lines.append('')
+    out_lines.append(clippydep.substitute(clippybase=clippy_file[:-2]))
+
+# combine daemon .xref files into frr.xref
+out_lines.append("")
+xref_targets = [
+    target
+    for target in xref_targets
+    if target
+    not in [
+        "bgpd/rfp-example/rfptest/rfptest",
+        "pimd/mtracebis",
+        "tools/ssd",
+        "vtysh/vtysh",
+    ]
+]
+out_lines.append(
+    "xrefs = %s" % (" ".join(["%s.xref" % target for target in xref_targets]))
+)
+out_lines.append("frr.xref: $(xrefs)")
+out_lines.append("")
+
+# analog but slower way to get the same frr.xref
+# frr.xref: $(bin_PROGRAMS) $(sbin_PROGRAMS) $(lib_LTLIBRARIES) $(module_LTLIBRARIES)
+#      $(AM_V_XRELFO) $(CLIPPY) $(top_srcdir)/python/xrelfo.py -o $@ $^
+
+# LLVM bitcode link targets creating a .bc file for whole daemon or lib
+out_lines.append("")
 out_lines.extend(bcdeps)
-out_lines.append('')
+out_lines.append("")
 bc_targets = []
-for varname in ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES', 'noinst_LIBRARIES']:
+for varname in [
+    "bin_PROGRAMS",
+    "sbin_PROGRAMS",
+    "lib_LTLIBRARIES",
+    "module_LTLIBRARIES",
+    "noinst_LIBRARIES",
+]:
     bc_targets.extend(mv[varname].strip().split())
 for target in bc_targets:
-    amtgt = target.replace('/', '_').replace('.', '_').replace('-', '_')
-    objs = mv[amtgt + '_OBJECTS'].strip().split()
-    objs = [obj + '.bc' for obj in objs]
-    deps = mv.get(amtgt + '_DEPENDENCIES', '').strip().split()
-    deps = [d + '.bc' for d in deps if d.endswith('.a')]
+    amtgt = target.replace("/", "_").replace(".", "_").replace("-", "_")
+    objs = mv[amtgt + "_OBJECTS"].strip().split()
+    objs = [obj + ".bc" for obj in objs]
+    deps = mv.get(amtgt + "_DEPENDENCIES", "").strip().split()
+    deps = [d + ".bc" for d in deps if d.endswith(".a")]
     objs.extend(deps)
-    out_lines.append('%s.bc: %s' % (target, ' '.join(objs)))
-    out_lines.append('\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^')
-    out_lines.append('')
+    out_lines.append("%s.bc: %s" % (target, " ".join(objs)))
+    out_lines.append("\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^")
+    out_lines.append("")
 
-out_lines.append('# }clippy')
-out_lines.append('')
+out_lines.append("# }clippy")
+out_lines.append("")
 
-after = '\n'.join(out_lines)
+after = "\n".join(out_lines)
 if after == before:
     sys.exit(0)
 
-with open('Makefile.pyout', 'w') as fd:
+with open("Makefile.pyout", "w") as fd:
     fd.write(after)
-os.rename('Makefile.pyout', 'Makefile')
+os.rename("Makefile.pyout", "Makefile")