Created
December 10, 2020 08:43
-
-
Save XVilka/cfbf51471707888380420fbf2a6a2eec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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