mirror of
https://github.com/lifting-bits/remill
synced 2026-06-21 13:56:07 +00:00
da643fa3cb
Fix build on macOS
346 lines
9.2 KiB
Bash
Executable File
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
|