1#!/usr/bin/env bash 2# 3# Copyright 2023 The Bazel Authors. All rights reserved. 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16set -euo pipefail 17 18# Find all duplicate symbols in the given static library: 19# 1. Use nm to list all global symbols in the library in POSIX format: 20# libstatic.a[my_object.o]: my_function T 1234 abcd 21# 2. Use sed to transform the output to a format that can be sorted by symbol 22# name and is readable by humans: 23# my_object.o: T my_function 24# By using the `t` and `d` commands, lines for symbols of type U (undefined) 25# as well as V and W (weak) and their local lowercase variants are removed. 26# 3. Use sort to sort the lines by symbol name. 27# 4. Use uniq to only keep the lines corresponding to duplicate symbols. 28# 5. Use c++filt to demangle the symbol names. 29# c++filt is applied to the duplicated symbols instead of using the -C flag 30# of nm because it is not in POSIX and demangled names may not be unique 31# (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=35201). 32DUPLICATE_SYMBOLS=$( 33 "%{nm}" -A -g -P %{nm_extra_args} "$1" | 34 sed -E -e 's/.*\[([^][]+)\]: (.+) ([A-TX-Z]) [a-f0-9]+ [a-f0-9]+/\1: \3 \2/g' -e t -e d | 35 LC_ALL=C sort -k 3 | 36 LC_ALL=C uniq -D -f 2 | 37 "%{c++filt}") 38if [[ -n "$DUPLICATE_SYMBOLS" ]]; then 39 >&2 echo "Duplicate symbols found in $1:" 40 >&2 echo "$DUPLICATE_SYMBOLS" 41 exit 1 42else 43 touch "$2" 44fi 45