105 lines · python
1#!/usr/bin/env python2# ===----------------------------------------------------------------------===##3#4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5# See https://llvm.org/LICENSE.txt for license information.6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7#8# ===----------------------------------------------------------------------===##9"""10sym_diff - Compare two symbol lists and output the differences.11"""12 13from argparse import ArgumentParser14import sys15from libcxx.sym_check import diff, util16 17 18def main():19 parser = ArgumentParser(20 description="Extract a list of symbols from a shared library."21 )22 parser.add_argument(23 "--names-only",24 dest="names_only",25 help="Only print symbol names",26 action="store_true",27 default=False,28 )29 parser.add_argument(30 "--removed-only",31 dest="removed_only",32 help="Only print removed symbols",33 action="store_true",34 default=False,35 )36 parser.add_argument(37 "--only-stdlib-symbols",38 dest="only_stdlib",39 help="Filter all symbols not related to the stdlib",40 action="store_true",41 default=False,42 )43 parser.add_argument(44 "--strict",45 dest="strict",46 help="Exit with a non-zero status if any symbols " "differ",47 action="store_true",48 default=False,49 )50 parser.add_argument(51 "-o",52 "--output",53 dest="output",54 help="The output file. stdout is used if not given",55 type=str,56 action="store",57 default=None,58 )59 parser.add_argument(60 "--demangle", dest="demangle", action="store_true", default=False61 )62 parser.add_argument(63 "old_syms",64 metavar="old-syms",65 type=str,66 help="The file containing the old symbol list or a library",67 )68 parser.add_argument(69 "new_syms",70 metavar="new-syms",71 type=str,72 help="The file containing the new symbol list or a library",73 )74 args = parser.parse_args()75 76 old_syms_list = util.extract_or_load(args.old_syms)77 new_syms_list = util.extract_or_load(args.new_syms)78 79 if args.only_stdlib:80 old_syms_list, _ = util.filter_stdlib_symbols(old_syms_list)81 new_syms_list, _ = util.filter_stdlib_symbols(new_syms_list)82 83 for symbol in new_syms_list:84 if symbol["is_defined"] and 'B' in symbol["name"]:85 print(f"Symbol {symbol['name']} contains an ABI tag!")86 sys.exit(1)87 88 added, removed, changed = diff.diff(old_syms_list, new_syms_list)89 if args.removed_only:90 added = {}91 report, is_break, is_different = diff.report_diff(92 added, removed, changed, names_only=args.names_only, demangle=args.demangle93 )94 if args.output is None:95 print(report)96 else:97 with open(args.output, "w") as f:98 f.write(report + "\n")99 exit_code = 1 if is_break or (args.strict and is_different) else 0100 sys.exit(exit_code)101 102 103if __name__ == "__main__":104 main()105