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