aboutsummaryrefslogtreecommitdiffstats
path: root/host/utils/update_fbs.py
diff options
context:
space:
mode:
Diffstat (limited to 'host/utils/update_fbs.py')
-rwxr-xr-xhost/utils/update_fbs.py126
1 files changed, 126 insertions, 0 deletions
diff --git a/host/utils/update_fbs.py b/host/utils/update_fbs.py
new file mode 100755
index 000000000..d97e120a4
--- /dev/null
+++ b/host/utils/update_fbs.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python3
+#
+# Copyright 2020 Ettus Research, a National Instruments Brand
+#
+# SPDX-License-Identifier: GPL-3.0-or-later
+#
+"""
+Utility to update the .fbs files in UHD, or to verify them.
+"""
+
+import os
+import sys
+import glob
+import argparse
+import filecmp
+import pathlib
+import tempfile
+import shutil
+import subprocess
+
+CAL_SUBDIR = ('include', 'uhd', 'cal')
+
+def find_flatc(hint):
+ """
+ Return a valid path to flatc or throw otherwise.
+ """
+ def is_executable(filename):
+ """ Check filename points to an executable """
+ return os.path.isfile(filename) and os.access(filename, os.X_OK)
+ if hint:
+ if is_executable(hint):
+ return hint
+ raise RuntimeError("Not a valid path to a flatc executable: `{}'"
+ .format(hint))
+ for path in os.environ.get("PATH", "").split(os.pathsep):
+ flatc_exe = os.path.join(path, 'flatc')
+ if is_executable(flatc_exe):
+ return flatc_exe
+ raise RuntimeError("Could not find flatc in $PATH.")
+
+def find_uhd_source_path(hint):
+ """
+ Find UHD path
+ """
+ if hint:
+ cal_subdir = os.path.join(hint, *CAL_SUBDIR)
+ if os.path.isdir(cal_subdir):
+ return hint
+ hint = os.path.join(hint, 'host')
+ if os.path.isdir(cal_subdir):
+ return hint
+ raise RuntimeError(
+ "Invalid UHD source path: {} (does not have subdir: {})"
+ .format(hint, os.path.join(*CAL_SUBDIR)))
+ # If there's no hint, we try our own path as a hint:
+ return find_uhd_source_path(str(pathlib.Path().absolute().parent))
+
+def parse_args():
+ """ Parse args and return args object """
+ parser = argparse.ArgumentParser(
+ description="Update or verify FlatBuffer files in UHD",
+ )
+ parser.add_argument(
+ '--flatc-exe',
+ help="Path to flatc executable. Will attempt to find the executable if "
+ "not provided.")
+ parser.add_argument(
+ '--uhd-path',
+ help="Path to UHD repository. Will use the repository this file is in "
+ "if not provided.")
+ parser.add_argument(
+ "-V", "--verify", action='store_true',
+ help="If set, will only check if the files are up-to-date, and return "
+ "non-zero if they are not.")
+ return parser.parse_args()
+
+def verify_fbs(flatc_exe, files):
+ """
+ Make sure that the .fbs files are all up to date w.r.t. their generated
+ files. This is accomplished by re-generating them in an temp dir and diffing
+ the new files with the existing ones.
+ """
+ tmp_dir = tempfile.mkdtemp()
+ # Generate them all again, but put them in a temp dir
+ subprocess.check_call([flatc_exe, '-o', tmp_dir, '--cpp'] + files)
+ uhd_gen_files = sorted(glob.glob("*generated.h"))
+ tmp_gen_files = sorted(glob.glob(os.path.join(tmp_dir, '*generated.h')))
+ if len(uhd_gen_files) != len(tmp_gen_files):
+ print("List of generated files does not match list of .fbs files!")
+ return False
+ try:
+ result = True
+ for uhd_file, tmp_file in zip(uhd_gen_files, tmp_gen_files):
+ print("Checking {}... ".format(uhd_file), end="")
+ if not filecmp.cmp(uhd_file, tmp_file):
+ print("ERROR")
+ result = False
+ else:
+ print("OK")
+ return result
+ except BaseException as ex:
+ print("ERROR: " + str(ex))
+ return False
+ finally:
+ shutil.rmtree(tmp_dir, ignore_errors=True)
+
+def main():
+ """ Go, go, go! """
+ args = parse_args()
+ flatc_exe = find_flatc(args.flatc_exe)
+ print("Found flatc executable: {}".format(flatc_exe))
+ try:
+ cal_path = os.path.join(find_uhd_source_path(args.uhd_path), *CAL_SUBDIR)
+ except RuntimeError as ex:
+ print("ERROR: {}".format(str(ex)))
+ return False
+ print("Checking UHD cal data in: {}".format(cal_path))
+ os.chdir(cal_path)
+ files = glob.glob("*.fbs")
+ if args.verify:
+ return not verify_fbs(flatc_exe, files)
+ subprocess.check_call([flatc_exe, '--cpp'] + files)
+ return True
+
+if __name__ == "__main__":
+ sys.exit(not main())