Files
lifting-bits-remill/scripts/bootstrap.sh
T
Peter Goodman da643fa3cb Merge pull request #39 from rgov/mac
Fix build on macOS
2016-09-07 11:57:28 -04:00

346 lines
9.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# Copyright 2015 Peter Goodman (peter@trailofbits.com), all rights reserved.
# Directory in which the script dir resides (i.e. Remill root dir).
DIR=$(dirname $( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd ))
RED=`tput setaf 1`
GREEN=`tput setaf 2`
YELLOW=`tput setaf 3`
BLUE=`tput setaf 4`
RESET=`tput sgr0`
GLOG_RELEASE=v0.3.4
GFLAGS_RELEASE=v2.1.2
PROTOBUF_VERSION=2.5.0
PROTOBUF_RELEASE=protobuf-${PROTOBUF_VERSION}
GTEST_RELEASE=release-1.7.0
XED_RELEASE=2016-02-02
LLVM_RELEASE=3.8.1
LLVM_RELEASE_DIR=releases/${LLVM_RELEASE}
if [[ "$OSTYPE" == "linux"* ]] ; then
FLAVOR=`grep -P '^NAME=' /etc/os-release`
XED_VERSION=xed-install-base-${XED_RELEASE}-lin-x86-64
REMILL_OS_NAME="linux"
LIB_EXT=so
STDLIB="libstdc++"
LIB_LINK_FLAGS=
if [[ "$FLAVOR" == *"Ubuntu"* ]] ; then
UBUNTU_VERSION=`lsb_release -r -s`
LLVM_VERSION=clang+llvm-${LLVM_RELEASE}-x86_64-linux-gnu-ubuntu-${UBUNTU_VERSION}
elif [[ "$FLAVOR" == *"openSUSE"* ]] ; then
LLVM_VERSION=clang+llvm-3.8.1-x86_64-opensuse13.2
else
printf "${RED}Unsupported Linux flavor ${FLAVOR}${RESET}\n"
exit 1
fi;
elif [[ "$OSTYPE" == "darwin"* ]] ; then
XED_VERSION=xed-install-base-${XED_RELEASE}-mac-x86-64
LLVM_RELEASE=3.8.0
LLVM_VERSION=clang+llvm-${LLVM_RELEASE}-x86_64-apple-darwin
REMILL_OS_NAME="mac"
LIB_EXT=dylib
STDLIB="libc++"
LIB_LINK_FLAGS="-lc++ -lc++abi"
if [ -z "$SDKROOT" ]; then
export SDKROOT=$(xcrun --sdk macosx --show-sdk-path)
fi
else
printf "${RED}Unsupported platform: ${OSTYPE}${RESET}\n"
exit 1
fi;
XED_URL=https://software.intel.com/system/files/managed/58/cc/${XED_VERSION}.zip
LLVM_URL=http://llvm.org/${LLVM_RELEASE_DIR}/${LLVM_VERSION}.tar.xz
GLOG_URL=https://github.com/google/glog/archive/${GLOG_RELEASE}.tar.gz
GFLAGS_URL=https://github.com/gflags/gflags/archive/${GFLAGS_RELEASE}.tar.gz
PROTOBUF_URL=https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOBUF_RELEASE}.tar.gz
GTEST_URL=https://github.com/google/googletest/archive/${GTEST_RELEASE}.tar.gz
function fix_library()
{
if [[ "$OSTYPE" == "darwin"* ]] ; then
install_name_tool -id $DIR/third_party/lib/lib$1.dylib $DIR/third_party/lib/lib$1.dylib
fi;
}
function category()
{
printf "\n${GREEN}${1}${RESET}\n"
}
function sub_category()
{
printf "${YELLOW}${1}${RESET}\n"
}
function notice()
{
printf "${BLUE}${1}${RESET}\n"
}
function error()
{
printf "${RED}${1}${RESET}\n"
exit 1
}
function download_and_install_llvm()
{
sub_category "Downloading LLVM and clang ${LLVM_VERSION}."
# Create third_party directory if it doesn't exist
mkdir -p $DIR/third_party
pushd $DIR/third_party
# Download a pre-built clang+llvm to it. OS X doesn't have wget by default. :(
curl -O ${LLVM_URL}
# Extract it to the path expected by compile_semantics.sh
mkdir -p $DIR/third_party/src/llvm/
tar xf ${LLVM_VERSION}.tar.xz -C $DIR/third_party --strip-components=1
rm ${LLVM_VERSION}.tar.xz
popd
}
function download_and_install_gflags()
{
sub_category "Downloading and installing gflags."
pushd $DIR/third_party
curl -L -O ${GFLAGS_URL}
mkdir -p $DIR/third_party/src/gflags
tar xf ${GFLAGS_RELEASE}.tar.gz -C src/gflags/ --strip-components=1
rm ${GFLAGS_RELEASE}.tar.gz
popd
pushd $DIR/third_party/src/gflags
mkdir build
cd build
cmake \
-G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX:STRING=$DIR/third_party \
-DGFLAGS_NAMESPACE:STRING=google \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=ON \
..
make
make install
fix_library gflags
popd
}
function download_and_install_glog()
{
sub_category "Downloading and installing glog."
pushd $DIR/third_party
curl -L -O https://github.com/google/glog/archive/${GLOG_RELEASE}.tar.gz
mkdir -p $DIR/third_party/src/glog
tar xf ${GLOG_RELEASE}.tar.gz -C src/glog/ --strip-components=1
rm ${GLOG_RELEASE}.tar.gz
popd
pushd $DIR/third_party/src/glog
./configure \
--prefix=$DIR/third_party \
--libdir=$DIR/third_party/lib \
--enable-static \
--enable-shared \
--disable-rtti \
--disable-backtrace
make
make install
fix_library glog
popd
}
function download_and_install_protobuf()
{
sub_category "Downloading and installing protobuf."
pushd $DIR/third_party
curl -L -O ${PROTOBUF_URL}
mkdir -p $DIR/third_party/src/protobuf
tar xf ${PROTOBUF_RELEASE}.tar.gz -C src/protobuf/ --strip-components=1
rm ${PROTOBUF_RELEASE}.tar.gz
popd
pushd $DIR/third_party/src/protobuf
CXXFLAGS="${CXXFLAGS} -DGOOGLE_PROTOBUF_NO_RTTI" \
./configure \
--prefix=$DIR/third_party \
--libdir=$DIR/third_party/lib \
--enable-static \
--enable-shared \
--disable-rtti
make
make install
fix_library protobuf
popd
}
function download_and_install_gtest()
{
sub_category "Downloading and installing googletest."
pushd $DIR/third_party
curl -L -O ${GTEST_URL}
mkdir -p $DIR/third_party/src/googletest
tar xf ${GTEST_RELEASE}.tar.gz -C src/googletest/ --strip-components=1
rm ${GTEST_RELEASE}.tar.gz
popd
pushd $DIR/third_party/src/googletest
mkdir build
cd build
cmake \
-G "Unix Makefiles" \
-DCMAKE_INSTALL_PREFIX:STRING=$DIR/third_party \
-DBUILD_SHARED_LIBS=ON \
-DBUILD_STATIC_LIBS=OFF \
..
make
cp $DIR/third_party/src/googletest/build/libgtest.$LIB_EXT $DIR/third_party/lib
cp -r $DIR/third_party/src/googletest/include/gtest $DIR/third_party/include
fix_library gtest
popd
}
function download_and_extract_xed()
{
sub_category "Downloading and installing XED."
if [[ ! -e $DIR/blob/xed/${XED_VERSION}.zip ]] ; then
error "Please download XED from ${XED_URL} and place it into ${DIR}/blob/xed/."
fi;
mkdir -p $DIR/third_party/src/xed
unzip $DIR/blob/xed/${XED_VERSION}.zip -d $DIR/third_party/src/xed
# 'install' XED.
mkdir -p $DIR/third_party/include/intel
cp -r $DIR/third_party/src/xed/kits/${XED_VERSION}/lib/* $DIR/third_party/lib
cp -r $DIR/third_party/src/xed/kits/${XED_VERSION}/include/* $DIR/third_party/include/intel
}
function create_directory_tree()
{
mkdir -p $DIR/third_party
mkdir -p $DIR/third_party/bin
mkdir -p $DIR/third_party/lib
mkdir -p $DIR/third_party/include
mkdir -p $DIR/third_party/src
mkdir -p $DIR/third_party/share
mkdir -p $DIR/generated
mkdir -p $DIR/generated/Arch
mkdir -p $DIR/generated/CFG
touch $DIR/generated/__init__.py
touch $DIR/generated/CFG/__init__.py
}
function change_compiler_to_llvm()
{
export CC="${DIR}/third_party/bin/clang"
export CXX="${DIR}/third_party/bin/clang++"
export CFLAGS="-isystem ${DIR}/third_party/include -g3 -fno-omit-frame-pointer -fPIC"
export CXXFLAGS="-isystem ${DIR}/third_party/include -g3 -fno-omit-frame-pointer -fPIC -fno-rtti -fno-exceptions -stdlib=${STDLIB}"
export LDFLAGS="-g ${LIB_LINK_FLAGS}"
}
function download_dependencies()
{
category "Checking dependencies."
if [[ -e $DIR/third_party/bin/clang ]] ; then
notice "LLVM and clang FOUND!"
else
download_and_install_llvm
fi;
change_compiler_to_llvm
if [[ -e $DIR/third_party/lib/libgflags.$LIB_EXT ]] ; then
notice "gflags FOUND!"
else
download_and_install_gflags
fi;
if [[ -e $DIR/third_party/lib/libglog.$LIB_EXT ]] ; then
notice "${BLUE}glog FOUND!"
else
download_and_install_glog
fi;
if [[ -e $DIR/third_party/bin/protoc ]] ; then
notice "${BLUE}protobuf FOUND!"
else
download_and_install_protobuf
fi;
if [[ -e $DIR/third_party/lib/libgtest.$LIB_EXT ]] ; then
notice "${BLUE}googletest FOUND!"
else
download_and_install_gtest
fi;
if [[ -e $DIR/third_party/lib/libxed.$LIB_EXT || -e $DIR/third_party/lib/libxed.a ]] ; then
notice "${BLUE}XED FOUND!"
else
download_and_extract_xed
fi;
}
function generate_files()
{
# Create the generated files directories.
category "Auto-generating files."
pushd $DIR
# Generate 32- and 64-bit x86 machine state modules for importing by
# `cfg_to_bc`.
sub_category "Generating architecture-specific state files."
$DIR/scripts/compile_semantics.sh || {
error "Error compiling instruction semantics."
}
# Generate the protocol buffer file for the CFG definition. The lifter will
# read in CFG protobuf files and output LLVM bitcode files.
sub_category "Generating protocol buffers."
cd $DIR/generated/CFG
cp $DIR/remill/CFG/CFG.proto $DIR/generated/CFG
$DIR/third_party/bin/protoc --cpp_out=. CFG.proto
$DIR/third_party/bin/protoc --python_out=. CFG.proto
sub_category "Generating test save state code."
$DIR/scripts/print_x86_save_state_asm.sh
popd
}
function build_remill()
{
category "Compiling Remill"
python $DIR/scripts/build.py --debug --num_workers 1 --stop_on_error
}
create_directory_tree
download_dependencies
generate_files
build_remill