1*46035553Spatrick#!/usr/bin/env python 2*46035553Spatrick#===----------------------------------------------------------------------===## 3*46035553Spatrick# 4*46035553Spatrick# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 5*46035553Spatrick# See https://llvm.org/LICENSE.txt for license information. 6*46035553Spatrick# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 7*46035553Spatrick# 8*46035553Spatrick#===----------------------------------------------------------------------===## 9*46035553Spatrick""" 10*46035553Spatricksym_diff - Compare two symbol lists and output the differences. 11*46035553Spatrick""" 12*46035553Spatrick 13*46035553Spatrickfrom argparse import ArgumentParser 14*46035553Spatrickimport sys 15*46035553Spatrickfrom libcxx.sym_check import diff, util 16*46035553Spatrick 17*46035553Spatrick 18*46035553Spatrickdef main(): 19*46035553Spatrick parser = ArgumentParser( 20*46035553Spatrick description='Extract a list of symbols from a shared library.') 21*46035553Spatrick parser.add_argument( 22*46035553Spatrick '--names-only', dest='names_only', 23*46035553Spatrick help='Only print symbol names', 24*46035553Spatrick action='store_true', default=False) 25*46035553Spatrick parser.add_argument( 26*46035553Spatrick '--removed-only', dest='removed_only', 27*46035553Spatrick help='Only print removed symbols', 28*46035553Spatrick action='store_true', default=False) 29*46035553Spatrick parser.add_argument('--only-stdlib-symbols', dest='only_stdlib', 30*46035553Spatrick help="Filter all symbols not related to the stdlib", 31*46035553Spatrick action='store_true', default=False) 32*46035553Spatrick parser.add_argument('--strict', dest='strict', 33*46035553Spatrick help="Exit with a non-zero status if any symbols " 34*46035553Spatrick "differ", 35*46035553Spatrick action='store_true', default=False) 36*46035553Spatrick parser.add_argument( 37*46035553Spatrick '-o', '--output', dest='output', 38*46035553Spatrick help='The output file. stdout is used if not given', 39*46035553Spatrick type=str, action='store', default=None) 40*46035553Spatrick parser.add_argument( 41*46035553Spatrick '--demangle', dest='demangle', action='store_true', default=False) 42*46035553Spatrick parser.add_argument( 43*46035553Spatrick 'old_syms', metavar='old-syms', type=str, 44*46035553Spatrick help='The file containing the old symbol list or a library') 45*46035553Spatrick parser.add_argument( 46*46035553Spatrick 'new_syms', metavar='new-syms', type=str, 47*46035553Spatrick help='The file containing the new symbol list or a library') 48*46035553Spatrick args = parser.parse_args() 49*46035553Spatrick 50*46035553Spatrick old_syms_list = util.extract_or_load(args.old_syms) 51*46035553Spatrick new_syms_list = util.extract_or_load(args.new_syms) 52*46035553Spatrick 53*46035553Spatrick if args.only_stdlib: 54*46035553Spatrick old_syms_list, _ = util.filter_stdlib_symbols(old_syms_list) 55*46035553Spatrick new_syms_list, _ = util.filter_stdlib_symbols(new_syms_list) 56*46035553Spatrick 57*46035553Spatrick added, removed, changed = diff.diff(old_syms_list, new_syms_list) 58*46035553Spatrick if args.removed_only: 59*46035553Spatrick added = {} 60*46035553Spatrick report, is_break, is_different = diff.report_diff( 61*46035553Spatrick added, removed, changed, names_only=args.names_only, 62*46035553Spatrick demangle=args.demangle) 63*46035553Spatrick if args.output is None: 64*46035553Spatrick print(report) 65*46035553Spatrick else: 66*46035553Spatrick with open(args.output, 'w') as f: 67*46035553Spatrick f.write(report + '\n') 68*46035553Spatrick exit_code = 1 if is_break or (args.strict and is_different) else 0 69*46035553Spatrick sys.exit(exit_code) 70*46035553Spatrick 71*46035553Spatrickif __name__ == '__main__': 72*46035553Spatrick main() 73