198 lines
7.3 KiB
Bash
Executable file
198 lines
7.3 KiB
Bash
Executable file
#!/bin/bash
|
|
|
|
set -ex
|
|
|
|
PHASES=(${@:-CONFIGURE MAKE INSTALL CHECK DISTCHECK})
|
|
COMPILER="${COMPILER:?}"
|
|
COMPILER_VERSION="${COMPILER_VERSION}"
|
|
CFLAGS=(-O1 -g)
|
|
CXXFLAGS=(-O1 -g)
|
|
LDFLAGS=()
|
|
COVERITY_SCAN_TOOL_BASE="/tmp/coverity-scan-analysis"
|
|
|
|
# The project is still called "karelzak/util-linux" on Coverity
|
|
# so it shouldn't be changed to "util-linux/util-linux"
|
|
COVERITY_SCAN_PROJECT_NAME="karelzak/util-linux"
|
|
|
|
if [[ "$COMPILER" == clang ]]; then
|
|
CC="clang${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
|
CXX="clang++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
|
elif [[ "$COMPILER" == gcc ]]; then
|
|
CC="gcc${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
|
CXX="g++${COMPILER_VERSION:+-$COMPILER_VERSION}"
|
|
fi
|
|
|
|
function coverity_install_script {
|
|
set +x # This is supposed to hide COVERITY_SCAN_TOKEN
|
|
local platform=$(uname)
|
|
local tool_url="https://scan.coverity.com/download/${platform}"
|
|
local tool_archive="/tmp/cov-analysis-${platform}.tgz"
|
|
|
|
echo -e "\033[33;1mDownloading Coverity Scan Analysis Tool...\033[0m"
|
|
wget -nv -O $tool_archive $tool_url --post-data "project=$COVERITY_SCAN_PROJECT_NAME&token=$COVERITY_SCAN_TOKEN" || return
|
|
|
|
echo -e "\033[33;1mExtracting Coverity Scan Analysis Tool...\033[0m"
|
|
mkdir -p $COVERITY_SCAN_TOOL_BASE
|
|
pushd $COVERITY_SCAN_TOOL_BASE
|
|
tar xzf $tool_archive || return
|
|
popd
|
|
set -x
|
|
}
|
|
|
|
function run_coverity {
|
|
set +x # This is supposed to hide COVERITY_SCAN_TOKEN
|
|
local results_dir="cov-int"
|
|
local tool_dir=$(find $COVERITY_SCAN_TOOL_BASE -type d -name 'cov-analysis*')
|
|
local results_archive="analysis-results.tgz"
|
|
local sha=$(git rev-parse --short HEAD)
|
|
local author_email=$(git log -1 --pretty="%aE")
|
|
local response status_code
|
|
|
|
echo -e "\033[33;1mRunning Coverity Scan Analysis Tool...\033[0m"
|
|
COVERITY_UNSUPPORTED=1 $tool_dir/bin/cov-build --dir $results_dir sh -c "make -j && make -j check-programs" || return
|
|
$tool_dir/bin/cov-import-scm --dir $results_dir --scm git --log $results_dir/scm_log.txt || return
|
|
|
|
echo -e "\033[33;1mTarring Coverity Scan Analysis results...\033[0m"
|
|
tar czf $results_archive $results_dir || return
|
|
|
|
echo -e "\033[33;1mUploading Coverity Scan Analysis results...\033[0m"
|
|
response=$(curl \
|
|
--silent --write-out "\n%{http_code}\n" \
|
|
--form project=$COVERITY_SCAN_PROJECT_NAME \
|
|
--form token=$COVERITY_SCAN_TOKEN \
|
|
--form email=$author_email \
|
|
--form file=@$results_archive \
|
|
--form version=$sha \
|
|
--form description="Daily build" \
|
|
https://scan.coverity.com/builds)
|
|
printf "\033[33;1mThe response is\033[0m\n%s\n" "$response"
|
|
status_code=$(echo "$response" | sed -n '$p')
|
|
if [ "$status_code" != "200" ]; then
|
|
echo -e "\033[33;1mCoverity Scan upload failed: $(echo "$response" | sed '$d').\033[0m"
|
|
return 1
|
|
fi
|
|
|
|
echo -e "\n\033[33;1mCoverity Scan Analysis completed successfully.\033[0m"
|
|
set -x
|
|
}
|
|
|
|
for phase in "${PHASES[@]}"; do
|
|
case $phase in
|
|
CONFIGURE)
|
|
opts=(
|
|
--disable-use-tty-group
|
|
--disable-makeinstall-chown
|
|
--enable-all-programs
|
|
--enable-werror
|
|
)
|
|
|
|
if [[ "$COVERAGE" == "yes" ]]; then
|
|
opts+=(--enable-coverage)
|
|
fi
|
|
|
|
if [[ "$SANITIZE" == "yes" ]]; then
|
|
opts+=(--enable-asan --enable-ubsan)
|
|
CFLAGS+=(-fno-omit-frame-pointer)
|
|
CXXFLAGS+=(-fno-omit-frame-pointer)
|
|
fi
|
|
|
|
if [[ "$COMPILER" == clang* && "$SANITIZE" == "yes" ]]; then
|
|
opts+=(--enable-fuzzing-engine)
|
|
CFLAGS+=(-shared-libasan)
|
|
CXXFLAGS+=(-shared-libasan)
|
|
fi
|
|
|
|
if [[ "$HOST_TRIPLET" != "" ]]; then
|
|
opts+=(--host "$HOST_TRIPLET")
|
|
fi
|
|
|
|
git config --global --add safe.directory "$PWD"
|
|
git clean -xdf
|
|
|
|
./autogen.sh
|
|
CC="$CC" CXX="$CXX" CFLAGS="${CFLAGS[@]}" CXXFLAGS="${CXXFLAGS[@]}" LDFLAGS="${LDFLAGS[@]}" ./configure "${opts[@]}"
|
|
;;
|
|
MAKE)
|
|
make -j"$(nproc)"
|
|
make -j"$(nproc)" check-programs
|
|
;;
|
|
INSTALL)
|
|
make install DESTDIR=/tmp/dest
|
|
;;
|
|
MESONCONF)
|
|
meson build
|
|
;;
|
|
MESONBUILD)
|
|
ninja -C build
|
|
;;
|
|
CODECHECK)
|
|
make checklibdoc
|
|
make checkxalloc
|
|
;;
|
|
CHECK)
|
|
if [[ "$SANITIZE" == "yes" ]]; then
|
|
# All the following black magic is to make test/eject/umount work, since
|
|
# eject execl()s the uninstrumented /bin/umount binary, which confuses
|
|
# ASan. The workaround for this is to set $LD_PRELOAD to the ASan's
|
|
# runtime DSO, which works well with gcc without any additional hassle.
|
|
# However, since clang, by default, links ASan statically, we need to
|
|
# explicitly state we want dynamic linking (see -shared-libasan above).
|
|
# That, however, introduces another issue - clang's ASan runtime is in
|
|
# a non-standard path, so all binaries compiled in such way refuse
|
|
# to start. That's what the following blob of code is for - it detects
|
|
# the ASan's runtime path and adds the respective directory to
|
|
# the dynamic linker cache.
|
|
#
|
|
# The actual $LD_PRELOAD sheanigans are done directly in
|
|
# tests/ts/eject/umount.
|
|
asan_rt_name="$(ldd ./kill | awk '/lib.+asan.*.so/ {print $1; exit}')"
|
|
asan_rt_path="$($CC --print-file-name "$asan_rt_name")"
|
|
echo "Detected ASan runtime: $asan_rt_name ($asan_rt_path)"
|
|
if [[ -z "$asan_rt_name" || -z "$asan_rt_path" ]]; then
|
|
echo >&2 "Couldn't detect ASan runtime, can't continue"
|
|
exit 1
|
|
fi
|
|
|
|
if [[ "$COMPILER" == clang* ]]; then
|
|
mkdir -p /etc/ld.so.conf.d/
|
|
echo "${asan_rt_path%/*}" > /etc/ld.so.conf.d/99-clang-libasan.conf
|
|
ldconfig
|
|
fi
|
|
fi
|
|
|
|
if [[ "$COVERAGE" == "yes" ]]; then
|
|
# Make (almost) everything under current directory readable/writable
|
|
# for everyone to allow gcov to write the .gcda files even with
|
|
# dropped privileges
|
|
find . tests/helpers/ -maxdepth 1 -type d ! -name . ! -name tests \
|
|
-exec setfacl -R -m 'd:g::rwX,d:o::rwX' -m 'g::rwX,o::rwX' '{}' \;
|
|
# Make sure we can access $PWD as an unpriv user
|
|
path="$PWD"
|
|
while [[ "$path" != / ]]; do
|
|
chmod o+rx "$path"
|
|
path="$(dirname "$path")"
|
|
done
|
|
fi
|
|
|
|
./tests/run.sh --show-diff
|
|
|
|
if [[ "$COVERAGE" == "yes" ]]; then
|
|
lcov --directory . --capture --initial --output-file coverage.info.initial
|
|
lcov --directory . --capture --output-file coverage.info.run --no-checksum --rc lcov_branch_coverage=1
|
|
lcov -a coverage.info.initial -a coverage.info.run --rc lcov_branch_coverage=1 -o coverage.info.raw
|
|
lcov --extract coverage.info.raw "$(pwd)/*" --rc lcov_branch_coverage=1 --output-file coverage.info
|
|
fi
|
|
;;
|
|
DISTCHECK)
|
|
make distcheck
|
|
;;
|
|
COVERITY)
|
|
coverity_install_script
|
|
run_coverity
|
|
;;
|
|
|
|
*)
|
|
echo >&2 "Unknown phase '$phase'"
|
|
exit 1
|
|
esac
|
|
done
|