Inside Bitcoin
Opening the selected file…
Inside Bitcoin
Opening the selected file…
The code behind the network, with room to understand it.
Release published 2026-10-28 · Snapshot fetched 2026-11-01. Latest stable release at fetch time; development branches and Git history are excluded. Only the selected code window and visible folders load here.
1#!/usr/bin/env bash3export LC_ALL=C.UTF-84set -Eeuo pipefail6# Declare paths to libraries7declare -A LIBS8LIBS[cli]="libbitcoin_cli.a"9LIBS[common]="libbitcoin_common.a"10LIBS[consensus]="libbitcoin_consensus.a"11LIBS[crypto]="libbitcoin_crypto.a"12LIBS[node]="libbitcoin_node.a"13LIBS[util]="libbitcoin_util.a"14LIBS[wallet]="libbitcoin_wallet.a"16# Declare allowed dependencies "X Y" where X is allowed to depend on Y. This17# list is taken from doc/design/libraries.md.18ALLOWED_DEPENDENCIES=(19"cli common"20"cli util"21"common consensus"22"common crypto"23"common util"24"consensus crypto"25"node common"26"node consensus"27"node crypto"28"node kernel"29"node util"30"util crypto"31"wallet common"32"wallet crypto"33"wallet util"34)36# Add minor dependencies omitted from doc/design/libraries.md to keep the37# dependency diagram simple.38ALLOWED_DEPENDENCIES+=(39"wallet consensus"40)42# Declare list of known errors that should be suppressed.43declare -A SUPPRESS44# init/common.cpp file calls InitError and InitWarning from interface_ui which45# is currently part of the node library. interface_ui should just be part of the46# common library instead, and is moved in47# https://github.com/bitcoin/bitcoin/issues/1010248SUPPRESS["common.cpp.o interface_ui.cpp.o _Z11InitWarningRK13bilingual_str"]=149SUPPRESS["common.cpp.o interface_ui.cpp.o _Z9InitErrorRK13bilingual_str"]=151usage() {52echo "Usage: $(basename "${BASH_SOURCE[0]}") [BUILD_DIR]"53}55# Output makefile targets, converting library .a paths to CMake targets56lib_targets() {57for lib in "${!LIBS[@]}"; do58for lib_path in ${LIBS[$lib]}; do59local name="${lib_path##*/}"60name="${name#lib}"61name="${name%.a}"62echo "$name"63done64done65}67# Extract symbol names and object names and write to text files68extract_symbols() {69local temp_dir="$1"70for lib in "${!LIBS[@]}"; do71for lib_path in ${LIBS[$lib]}; do72nm -o "$lib_path" | { grep ' T \| W ' || true; } | awk '{print $3, $1}' >> "${temp_dir}/${lib}_exports.txt"73nm -o "$lib_path" | { grep ' U ' || true; } | awk '{print $3, $1}' >> "${temp_dir}/${lib}_imports.txt"74awk '{print $1}' "${temp_dir}/${lib}_exports.txt" | sort -u > "${temp_dir}/${lib}_exported_symbols.txt"75awk '{print $1}' "${temp_dir}/${lib}_imports.txt" | sort -u > "${temp_dir}/${lib}_imported_symbols.txt"76done77done78}80# Lookup object name(s) corresponding to symbol name in text file81obj_names() {82local symbol="$1"83local txt_file="$2"84sed -n "s/^$symbol [^:]\\+:\\([^:]\\+\\):[^:]*\$/\\1/p" "$txt_file" | sort -u85}87# Iterate through libraries and find disallowed dependencies88check_libraries() {89local temp_dir="$1"90local result=091for src in "${!LIBS[@]}"; do92for dst in "${!LIBS[@]}"; do93if [ "$src" != "$dst" ] && ! is_allowed "$src" "$dst"; then94if ! check_disallowed "$src" "$dst" "$temp_dir"; then95result=196fi97fi98done99done100check_not_suppressed101return $result102}104# Return whether src library is allowed to depend on dst.105is_allowed() {106local src="$1"107local dst="$2"108for allowed in "${ALLOWED_DEPENDENCIES[@]}"; do109if [ "$src $dst" = "$allowed" ]; then110return 0111fi112done113return 1114}116# Return whether src library imports any symbols from dst, assuming src is not117# allowed to depend on dst.118check_disallowed() {119local src="$1"120local dst="$2"121local temp_dir="$3"122local result=0124# Loop over symbol names exported by dst and imported by src125while read symbol; do126local dst_obj127dst_obj=$(obj_names "$symbol" "${temp_dir}/${dst}_exports.txt")128while read src_obj; do129if ! check_suppress "$src_obj" "$dst_obj" "$symbol"; then130echo "Error: $src_obj depends on $dst_obj symbol '$(c++filt "$symbol")', can suppress with:"131echo " SUPPRESS[\"$src_obj $dst_obj $symbol\"]=1"132result=1133fi134done < <(obj_names "$symbol" "${temp_dir}/${src}_imports.txt")135done < <(comm -12 "${temp_dir}/${dst}_exported_symbols.txt" "${temp_dir}/${src}_imported_symbols.txt")136return $result137}139# Declare array to track errors which were suppressed.140declare -A SUPPRESSED142# Return whether error should be suppressed and record suppression in143# SUPPRESSED array.144check_suppress() {145local src_obj="$1"146local dst_obj="$2"147local symbol="$3"148for suppress in "${!SUPPRESS[@]}"; do149read suppress_src suppress_dst suppress_pattern <<<"$suppress"150if [[ "$src_obj" == "$suppress_src" && "$dst_obj" == "$suppress_dst" && "$symbol" =~ $suppress_pattern ]]; then151SUPPRESSED["$suppress"]=1152return 0153fi154done155return 1156}158# Warn about error which were supposed to be suppressed, but were not encountered.159check_not_suppressed() {160for suppress in "${!SUPPRESS[@]}"; do161if [[ ! -v SUPPRESSED[$suppress] ]]; then162echo >&2 "Warning: suppression '$suppress' was ignored, consider deleting."163fi164done165}167# Check arguments.168if [ "$#" = 0 ]; then169BUILD_DIR="$(dirname "${BASH_SOURCE[0]}")/../../build"170elif [ "$#" = 1 ]; then171BUILD_DIR="$1"172else173echo >&2 "Error: wrong number of arguments."174usage >&2175exit 1176fi177if [ ! -f "$BUILD_DIR/Makefile" ]; then178echo >&2 "Error: directory '$BUILD_DIR' does not contain a makefile, please specify path to build directory for library targets."179usage >&2180exit 1181fi183# Build libraries and run checks.184# shellcheck disable=SC2046185cmake --build "$BUILD_DIR" -j"$(nproc)" -t $(lib_targets)186TEMP_DIR="$(mktemp -d)"187cd "$BUILD_DIR/lib"188extract_symbols "$TEMP_DIR"189if check_libraries "$TEMP_DIR"; then190echo "Success! No unexpected dependencies were detected."191RET=0192else193echo >&2 "Error: Unexpected dependencies were detected. Check previous output."194RET=1195fi196rm -r "$TEMP_DIR"197exit $RET
Independent explanations by MyBitcoinExplorer. Not affiliated with or endorsed by Bitcoin Core. Guides are educational and do not replace the source or its tests.
Bitcoin Core source © its contributors, distributed under the MIT license. Original notices and bundled third-party licenses are retained in the source tree.