Skip to content

Instantly share code, notes, and snippets.

@XVilka
Created December 10, 2020 08:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save XVilka/cfbf51471707888380420fbf2a6a2eec to your computer and use it in GitHub Desktop.
Save XVilka/cfbf51471707888380420fbf2a6a2eec to your computer and use it in GitHub Desktop.
#!/bin/bash
# We use unicode quotes on purpose
# shellcheck disable=SC1112
BASEDIR=${HOME}/rizin/rizin
LOGSDIR=${HOME}/rizin
RZ_PREFIX=${HOME}/bin/prefix/rizin
BUILDSTDOUT=${LOGSDIR}/rizin.build.log
BUILDSTDERR=${LOGSDIR}/rizin.builderrors.log
GIT_CMD="git -C ${BASEDIR}"
# Use always only English language for messages
export LANGUAGE=en_US.UTF-8
export LANG=en_US.UTF-8
# Use the capstone snapshot to build faster
export CS_COMMIT_ARCHIVE=1
O_ASAN="sanitize=address"
O_LSAN="sanitize=leak"
O_UBSAN="sanitize=undefined"
O_PCSAN="sanitize=pointer-compare"
O_PSSAN="sanitize=pointer-subtract"
O_TSAN="sanitize=thread"
F_ASAN="-f${O_ASAN}"
F_LSAN="-f${O_LSAN}"
F_UBSAN="-f${O_UBSAN}"
F_PCSAN="-f${O_PCSAN}"
F_PSSAN="-f${O_PSSAN}"
F_TSAN="-f${O_TSAN}"
L_ASAN="-lasan"
ASAN_FLAGS="${F_ASAN} ${F_PCSAN} ${F_PSSAN}"
UBSAN_FLAGS="${F_UBSAN}"
AUBSAN_FLAGS="${ASAN_FLAGS} ${UBSAN_FLAGS}"
ALL_SAN_FLAGS="${F_ASAN} ${F_LSAN} ${F_UBSAN} ${F_PCSAN} ${F_PSSAN} ${F_TSAN}"
HARDEN_FLAGS="-Wall -Werror=format-security -Wp,-DFORTIFY_SOURCE=2,-D_GLIBCXX_ASSERTIONS -fstack-clash-protection"
# Remove Unicode quotes that can be met on non-English locales
filtertext ()
{
sed -i 's/\x1b\[[0-9;]*m//g' "$1"
sed -i 's/‘/"/g' "$1"
sed -i 's/’/"/g' "$1"
sed -i 's/[ \t]*$//' "$1"
}
# Filter messages that appear in stderr but still not an errors
filterirrelevant ()
{
sed -i '/^ar: creating .*/d' "$1"
}
clean_errorlog ()
{
filtertext "$1"
filterirrelevant "$1"
}
# Record stdout and stderr to the separate files, also show them on the screen
logerror ()
{
($@ | tee "${BUILDSTDOUT}") 3>&1 1>&2 2>&3 | tee "${BUILDSTDERR}"
}
git_has_uncommitted_changes ()
{
(cd "${BASEDIR}" || exit; git diff-index --quiet HEAD --)
}
git_has_uncommitted_files ()
{
(cd "${BASEDIR}" || exit; test -z "$(git status --porcelain)")
}
CS_DIR="/shlr/capstone"
# Update first
git_update=0
# -----------------------------------------------------------------------------
# GIT DIRECTORY CLEANUP
# -----------------------------------------------------------------------------
sources_cleanup ()
{
# Check if we have some uncommitted changes in the repository
local git_clean
git_clean=1
git_has_uncommitted_changes || git_clean=0
git_has_uncommitted_files || git_clean=0
# Update changes from the remote repository
if [ $git_update = 1 ]; then
echo "Updating from the remote repository..."
$GIT_CMD checkout master
$GIT_CMD pull --recursive
$GIT_CMD checkout rizin
$GIT_CMD rebase master
fi
# Cleanup
if [ $git_clean = 1 ]; then
# TODO: Add other subdirectories too
echo "Cleaning up the repository..."
$GIT_CMD clean -xdf
if [ -d "${BASEDIR}/${CS_DIR}" ]; then
${GIT_CMD}${CS_DIR} clean -xdf
fi
if [ -f "${BASEDIR}/rz_version.h" ]; then
rm -f "${BASEDIR}/rz_version.h"
fi
fi
}
# -----------------------------------------------------------------------------
# CONFIGURE + MAKE
# -----------------------------------------------------------------------------
# $1 is the additional configure option
build_configure_gnumake ()
{
sources_cleanup || exit
./configure --prefix="${RZ_PREFIX}" "$1" || exit
# Remove the old installation first
make purge
rm -rf "{RZ_PREFIX}/*"
mkdir -p "${RZ_PREFIX}/lib"
# Then build and install
logerror make || exit
clean_errorlog "${BUILDSTDERR}"
filtertext "${BUILDSTDOUT}"
make symstall || exit
make user-install || exit
cd "${DIR}" || exit
}
# -----------------------------------------------------------------------------
# MESON + NINJA
# -----------------------------------------------------------------------------
# TODO: Create a Meson + Ninja ASAN variant, with ccls rebuilding index
# meson -Db_sanitize=address build-asan
# ninja -C build-asan
build_meson_ninja ()
{
D_ASAN="-Db_${O_ASAN}"
BUILD_DIRECTORY=build
sources_cleanup || exit
meson --prefix=~/.local "${BUILD_DIRECTORY}" || exit
logerror "ninja -C ${BUILD_DIRECTORY}" || exit
# We don't log any error during the installation since usually there
# is not much
ninja -C ${BUILD_DIRECTORY} install || exit
clean_errorlog "${BUILDSTDERR}"
filtertext "${BUILDSTDOUT}"
cd "${DIR}" || exit
}
# -----------------------------------------------------------------------------
# MAIN PROCESSING
# -----------------------------------------------------------------------------
usage ()
{
printf "\t-h --help\n"
printf "\t-s --sanitizer {asan|ubsan|aubsan|san}\n"
printf "\t-t --tcc\n"
printf "\t--harden\n"
}
# Now configure the sources
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd )"
cd "${BASEDIR}" || exit
# Default behavior - just build with meson/ninja locally
if [ "$1" == "" ]; then
build_meson_ninja || exit
fi
while [ "$1" != "" ]; do
PARAM=$(printf "%s\n" "$1" | awk -F= '{print $1}')
VALUE=$(printf "%s\n" "$1" | sed 's/^[^=]*=//g')
if [ "$VALUE" = "$PARAM" ]; then
shift
VALUE="$1"
fi
case $PARAM in
-h | --help)
usage
exit
;;
-s | --sanitizer)
# TODO: Fold/simplify these somehow
export CC=gcc
export CXX=gcc
if [ "$VALUE" = "asan" ]; then
export CFLAGS="${CFLAGS} ${ASAN_FLAGS} ${L_ASAN}"
export LDFLAGS="${L_ASAN}"
fi
if [ "$VALUE" = "ubsan" ]; then
export CFLAGS="${CFLAGS} ${UBSAN_FLAGS}"
fi
if [ "$VALUE" = "aubsan" ]; then
export CFLAGS="${CFLAGS} ${AUBSAN_FLAGS}"
fi
if [ "$VALUE" = "san" ]; then
export CFLAGS="${CFLAGS} ${ALL_SAN_FLAGS} ${L_ASAN}"
export LDFLAGS="${L_ASAN}"
fi
if [ "$VALUE" != "" ]; then
build_configure_gnumake "" || exit
fi
;;
--harden)
export CC=gcc
export CXX=gcc
export CFLAGS="${CFLAGS} ${HARDEN_FLAGS}"
build_configure_gnumake "" || exit
;;
-t | --tcc)
export CC=tcc
build_configure_gnumake "--with-compiler=tcc" || exit
;;
*)
echo "ERROR: unknown parameter \"$PARAM\""
usage
exit 1
;;
esac
shift
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment