summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/portaudio/pa_compare_def_files.py
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/portaudio/pa_compare_def_files.py')
-rw-r--r--3rdparty/portaudio/pa_compare_def_files.py98
1 files changed, 98 insertions, 0 deletions
diff --git a/3rdparty/portaudio/pa_compare_def_files.py b/3rdparty/portaudio/pa_compare_def_files.py
new file mode 100644
index 00000000000..d8becabc613
--- /dev/null
+++ b/3rdparty/portaudio/pa_compare_def_files.py
@@ -0,0 +1,98 @@
+# PortAudio Repository .def file checker
+#
+# Run this script from the root of the repository using the command:
+# python pa_compare_def_files.py
+#
+# The PortAudio repository contains two (semi-redundant) .def
+# files that specify exported symbols for Windows dynamic link libraries.
+#
+# This script checks that the two .def files export the same symbols
+# using the same ordinals.
+#
+# The .def files are:
+#
+# 1. msvc/portaudio.def
+# 2. cmake/portaudio.def.in
+#
+# The CMake .def.in file is an input that generates a .def file
+# with host-api-specific symbols commented out when a particular host API
+# is not built.
+
+import sys
+
+msvc_portaudio_def_path = "msvc/portaudio.def"
+cmake_portaudio_def_in_path = "cmake/portaudio.def.in"
+
+def parse_def_file(file):
+ result = {}
+ for line in file:
+ line = line.strip()
+ if line:
+ if "EXPORTS" in line or line[0] == ";":
+ continue
+ columns = line.split()
+ #print(columns)
+ symbol, ordinal = columns
+ #print(symbol, ordinal)
+ if ordinal in result:
+ print(f"error: ordinal {ordinal} referenced multiple times")
+ result[ordinal] = symbol
+ return result
+
+with open(msvc_portaudio_def_path, mode="rt", encoding="utf-8") as msvc_portaudio_def:
+ msvc_portaudio_def_syms = parse_def_file(msvc_portaudio_def)
+
+with open(cmake_portaudio_def_in_path, mode="rt", encoding="utf-8") as cmake_portaudio_def_in:
+ cmake_portaudio_def_in_syms = parse_def_file(cmake_portaudio_def_in)
+
+def clear_cmake_exclude_condition_prefix(sym):
+ if "@" in sym:
+ return sym.split("@")[-1]
+ else:
+ return sym
+
+# dictionary keys are the ordinals
+ordinals = list(set(msvc_portaudio_def_syms.keys()).union(cmake_portaudio_def_in_syms.keys()))
+ordinals.sort(key=lambda s: int(s.replace("@", "")))
+
+msvcMissingCount = 0
+cmakeMissingCount = 0
+differenceCount = 0
+
+print("ordinal, msvc, cmake, remark")
+for ordinal in ordinals:
+ msvc_sym = msvc_portaudio_def_syms[ordinal] if ordinal in msvc_portaudio_def_syms else ""
+ cmake_sym = cmake_portaudio_def_in_syms[ordinal] if ordinal in cmake_portaudio_def_in_syms else ""
+
+ cmake_sym_no_cond = clear_cmake_exclude_condition_prefix(cmake_sym)
+
+ remark = ""
+ if not msvc_sym:
+ remark = "missing in msvc/portaudio.def"
+ msvcMissingCount += msvcMissingCount
+ elif not cmake_sym:
+ remark = "missing in cmake/portaudio.def.in"
+ cmakeMissingCount += cmakeMissingCount
+ elif msvc_sym != cmake_sym_no_cond:
+ remark = "differs"
+ differenceCount += 1
+ else:
+ remark = "ok"
+
+ print(f"{ordinal}, {msvc_sym}, {cmake_sym}, {remark}")
+
+print("SUMMARY")
+print("=======")
+issuesFound = msvcMissingCount > 0 or cmakeMissingCount > 0 or differenceCount > 0
+if msvcMissingCount > 0:
+ print(f"error: {msvc_portaudio_def_path} ({msvcMissingCount} missing symbols)")
+if cmakeMissingCount > 0:
+ print(f"error: {cmake_portaudio_def_in_path} ({cmakeMissingCount} missing symbols)")
+if differenceCount > 0:
+ print(f"error: there are {differenceCount} ordinals with non-matching symbols")
+
+if issuesFound:
+ sys.exit(1)
+else:
+ print("No issues found. All good.")
+ sys.exit(0)