Skip to content

Commit 77094d1

Browse files
authored
Add ABI compatibility tasks to EVG config (CXX-641, CXX-2746) (#1083)
1 parent 330fd84 commit 77094d1

File tree

7 files changed

+606
-0
lines changed

7 files changed

+606
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
6+
declare working_dir
7+
working_dir="$(pwd)"
8+
9+
export PATH
10+
PATH="${working_dir:?}/install/bin:${PATH:-}"
11+
12+
# Install prefix to use for ABI compatibility scripts.
13+
[[ -d "${working_dir}/install" ]]
14+
15+
declare parallel_level
16+
parallel_level="$(("$(nproc)" + 1))"
17+
18+
# Obtain abi-compliance-checker.
19+
echo "Fetching abi-compliance-checker..."
20+
[[ -d checker ]] || {
21+
git clone -b "2.3" --depth 1 https://github.com/lvc/abi-compliance-checker.git checker
22+
pushd checker
23+
make -j "${parallel_level:?}" --no-print-directory install prefix="${working_dir:?}/install"
24+
popd # checker
25+
} >/dev/null
26+
echo "Fetching abi-compliance-checker... done."
27+
28+
# Obtain ctags.
29+
echo "Fetching ctags..."
30+
[[ -d ctags ]] || {
31+
git clone -b "v6.0.0" --depth 1 https://github.com/universal-ctags/ctags.git ctags
32+
pushd ctags
33+
./autogen.sh
34+
./configure --prefix="${working_dir}/install"
35+
make -j "${parallel_level:?}"
36+
make install
37+
popd # ctags
38+
} >/dev/null
39+
echo "Fetching ctags... done."
40+
41+
command -V abi-compliance-checker
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
6+
declare working_dir
7+
working_dir="$(pwd)"
8+
9+
declare base current
10+
base="$(cat base-commit.txt)"
11+
current="$(cat current-commit.txt)"
12+
13+
export PATH
14+
PATH="${working_dir:?}/install/bin:${PATH:-}"
15+
16+
# Remove 'r' prefix in version string.
17+
declare old_ver new_ver
18+
old_ver="${base:1}-base"
19+
new_ver="${current:1}-current"
20+
21+
command -V abi-compliance-checker >/dev/null
22+
23+
mkdir cxx-abi cxx-noabi
24+
25+
cat >cxx-abi/old.xml <<DOC
26+
<version>
27+
${old_ver:?}
28+
</version>
29+
30+
<headers>
31+
../install/old/include/bsoncxx/
32+
../install/old/include/mongocxx/
33+
</headers>
34+
35+
<skip_headers>
36+
/v_noabi/
37+
</skip_headers>
38+
39+
<libs>
40+
../install/old/lib
41+
</libs>
42+
43+
<add_include_paths>
44+
../install/old/include/
45+
</add_include_paths>
46+
47+
<skip_including>
48+
bsoncxx/enums/
49+
/config/
50+
</skip_including>
51+
DOC
52+
53+
cat >cxx-abi/new.xml <<DOC
54+
<version>
55+
${new_ver:?}
56+
</version>
57+
58+
<headers>
59+
../install/new/include/mongocxx/
60+
../install/new/include/bsoncxx/
61+
</headers>
62+
63+
<skip_headers>
64+
/v_noabi/
65+
</skip_headers>
66+
67+
<libs>
68+
../install/new/lib
69+
</libs>
70+
71+
<add_include_paths>
72+
../install/new/include/
73+
</add_include_paths>
74+
75+
<skip_including>
76+
bsoncxx/enums/
77+
/config/
78+
</skip_including>
79+
DOC
80+
81+
cat >cxx-noabi/old.xml <<DOC
82+
<version>
83+
${old_ver:?}
84+
</version>
85+
86+
<headers>
87+
../install/old/include/bsoncxx/v_noabi
88+
../install/old/include/mongocxx/v_noabi
89+
</headers>
90+
91+
<libs>
92+
../install/old/lib
93+
</libs>
94+
95+
<add_include_paths>
96+
../install/old/include/
97+
</add_include_paths>
98+
99+
<skip_including>
100+
bsoncxx/enums/
101+
/config/
102+
</skip_including>
103+
DOC
104+
105+
cat >cxx-noabi/new.xml <<DOC
106+
<version>
107+
${new_ver:?}
108+
</version>
109+
110+
<headers>
111+
../install/new/include/bsoncxx/v_noabi
112+
../install/new/include/mongocxx/v_noabi
113+
</headers>
114+
115+
<libs>
116+
../install/new/lib
117+
</libs>
118+
119+
<add_include_paths>
120+
../install/new/include/
121+
</add_include_paths>
122+
123+
<skip_including>
124+
bsoncxx/enums/
125+
/config/
126+
</skip_including>
127+
DOC
128+
129+
# Allow task to upload the HTML report despite failed status.
130+
echo "Generating stable ABI report..."
131+
pushd cxx-abi
132+
if ! abi-compliance-checker -lib mongo-cxx-driver -old old.xml -new new.xml; then
133+
: # CXX-2812: enable code below once stable ABI symbols exist in the base commit libraries.
134+
# declare status
135+
# status='{"status":"failed", "type":"test", "should_continue":true, "desc":"abi-compliance-checker emitted one or more errors"}'
136+
# curl -sS -d "${status:?}" -H "Content-Type: application/json" -X POST localhost:2285/task_status || true
137+
fi
138+
popd # cxx-abi
139+
echo "Generating stable ABI report... done."
140+
141+
# Also create a report for the unstable ABI. Errors are expected and OK.
142+
echo "Generating unstable ABI report..."
143+
pushd cxx-noabi
144+
abi-compliance-checker -lib mongo-cxx-driver -old old.xml -new new.xml || true
145+
popd # cxx-noabi
146+
echo "Generating unstable ABI report... done."
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
6+
command -V nm >/dev/null
7+
8+
declare -a libs
9+
libs=(
10+
install/new/lib/libbsoncxx.so
11+
install/new/lib/libmongocxx.so
12+
)
13+
14+
for lib in "${libs[@]}"; do
15+
[[ -f "${lib:?}" ]] || {
16+
echo "error: missing ${lib:?}"
17+
exit 1
18+
} 1>&2
19+
done
20+
21+
# Patterns for library symbols to check.
22+
match_pattern=(
23+
-e '(bsoncxx|mongocxx)::'
24+
)
25+
26+
# Patterns for bad symbols.
27+
bad_pattern=(
28+
-e '(bsoncxx|mongocxx)::(.+::)?detail::'
29+
-e '(bsoncxx|mongocxx)::(.+::)?test::'
30+
)
31+
32+
# Ensure implementation details do not leak into the ABI.
33+
mapfile -t bad_symbols < <(
34+
nm --demangle --dynamic --defined-only --extern-only --just-symbols "${libs[@]}" |
35+
grep -E "${match_pattern[@]}" |
36+
grep -E "${bad_pattern[@]}"
37+
)
38+
39+
# Print list of bad symbols.
40+
(("${#bad_symbols[*]}" == 0)) || {
41+
echo "error: found ${#bad_symbols[@]} prohibited symbols in exported ABI:"
42+
printf " - %s\n" "${bad_symbols[@]}"
43+
exit 1
44+
} 1>&2

.evergreen/abi-stability-setup.sh

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
6+
: "${cxx_standard:?}" # Set by abi-stability-checks-* build variant definition.
7+
8+
command -V git >/dev/null
9+
10+
# Files prepared by EVG config.
11+
[[ -d "mongoc" ]] || {
12+
echo "missing mongoc" 1>&2
13+
exit 1
14+
}
15+
[[ -d "mongo-cxx-driver" ]] || {
16+
echo "missing mongo-cxx-driver" 1>&2
17+
exit 1
18+
}
19+
20+
declare working_dir
21+
working_dir="$(pwd)"
22+
23+
declare cmake_binary
24+
# shellcheck source=/dev/null
25+
. ./mongoc/.evergreen/scripts/find-cmake-latest.sh
26+
cmake_binary="$(find_cmake_latest)"
27+
command -V "${cmake_binary:?}"
28+
29+
# To use a different base commit, replace `--abbrev 0` with the intended commit.
30+
# Note: EVG treat all changes relative to the EVG base commit as staged changes!
31+
declare base current
32+
base="$(git -C mongo-cxx-driver describe --tags --abbrev=0)"
33+
current="$(git -C mongo-cxx-driver describe --tags)"
34+
35+
echo "Old Version (Base): ${base:?}"
36+
echo "New Version (Current): ${current:?}"
37+
38+
printf "%s" "${base:?}" >base-commit.txt
39+
printf "%s" "${current:?}" >current-commit.txt
40+
41+
# Remove 'r' prefix in version string.
42+
declare old_ver new_ver
43+
old_ver="${base:1}"
44+
new_ver="${current:1}"
45+
46+
declare parallel_level
47+
parallel_level="$(("$(nproc)" + 1))"
48+
49+
# Use Ninja if available.
50+
if command -V ninja; then
51+
export CMAKE_GENERATOR
52+
CMAKE_GENERATOR="Ninja"
53+
else
54+
export CMAKE_BUILD_PARALLEL_LEVEL
55+
CMAKE_BUILD_PARALLEL_LEVEL="${parallel_level:?}"
56+
fi
57+
58+
# Use ccache if available.
59+
if command -V ccache; then
60+
export CMAKE_C_COMPILER_LAUNCHER CMAKE_CXX_COMPILER_LAUNCHER
61+
CMAKE_C_COMPILER_LAUNCHER="ccache"
62+
CMAKE_CXX_COMPILER_LAUNCHER="ccache"
63+
fi
64+
65+
# Install prefix to use for ABI compatibility scripts.
66+
mkdir -p "${working_dir}/install"
67+
68+
# As encouraged by ABI compatibility checkers.
69+
export CFLAGS CXXFLAGS
70+
CFLAGS="-g -Og"
71+
CXXFLAGS="-g -Og"
72+
73+
# Build and install the base commit first.
74+
git -C mongo-cxx-driver stash push -u
75+
git -C mongo-cxx-driver reset --hard "${base:?}"
76+
77+
# Install old (base) to install/old.
78+
echo "Building old libraries..."
79+
{
80+
"${cmake_binary:?}" \
81+
-S mongo-cxx-driver \
82+
-B build/old \
83+
-DCMAKE_INSTALL_PREFIX="install/old" \
84+
-DCMAKE_PREFIX_PATH="${working_dir:?}/mongoc" \
85+
-DBUILD_VERSION="${old_ver:?}-base" \
86+
-DCMAKE_CXX_STANDARD="${cxx_standard:?}"
87+
"${cmake_binary:?}" --build build/old
88+
"${cmake_binary:?}" --install build/old
89+
} &>old.log || {
90+
cat old.log 1>&2
91+
exit 1
92+
}
93+
echo "Building old libraries... done."
94+
95+
# Restore all pending changes.
96+
git -C mongo-cxx-driver reset --hard "HEAD@{1}"
97+
git -C mongo-cxx-driver stash pop -q || true # Only patch builds have stashed changes.
98+
99+
# Install new (current) to install/new.
100+
echo "Building new libraries..."
101+
{
102+
"${cmake_binary:?}" \
103+
-S mongo-cxx-driver \
104+
-B build/new \
105+
-DCMAKE_INSTALL_PREFIX="install/new" \
106+
-DCMAKE_PREFIX_PATH="${working_dir:?}/mongoc" \
107+
-DBUILD_VERSION="${new_ver:?}-current" \
108+
-DCMAKE_CXX_STANDARD="${cxx_standard:?}"
109+
"${cmake_binary:?}" --build build/new
110+
"${cmake_binary:?}" --install build/new
111+
} &>new.log || {
112+
cat new.log 1>&2
113+
exit 1
114+
}
115+
echo "Building new libraries... done."

.evergreen/abidiff-setup.sh

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/usr/bin/env bash
2+
3+
set -o errexit
4+
set -o pipefail
5+
6+
declare working_dir
7+
working_dir="$(pwd)"
8+
9+
export PATH
10+
PATH="${working_dir:?}/install/bin:${PATH:-}"
11+
12+
# Install prefix to use for ABI compatibility scripts.
13+
[[ -d "${working_dir}/install" ]]
14+
15+
if command -V abidiff 2>/dev/null; then
16+
exit # Already available.
17+
fi
18+
19+
# Expected to be run on Ubuntu.
20+
echo "Installing abigail-tools..."
21+
sudo apt-get install -q -y abigail-tools >/dev/null
22+
echo "Installing abigail-tools... done."
23+
24+
command -V abidiff

0 commit comments

Comments
 (0)