set -e
set -u
set -f
_program_path_find()
{
if [ "${_program_fattening_program_path+set}" = 'set' ]; then
printf '%s\n' "$_program_fattening_program_path"
elif [ "${0%/*}" = "$0" ]; then
if [ -r "$0" ]; then
pwd -P
else
printf '\n'
fi
else
_program_path_find_parentPath()
{
parentPath="${scriptPath%/*}"
if [ -z "$parentPath" ]; then
parentPath='/'
fi
cd "$parentPath" 1>/dev/null
}
if [ "${CDPATH+set}" = 'set' ]; then
unset CDPATH
fi
if command -v realpath 1>/dev/null 2>/dev/null; then
(
scriptPath="$(realpath "$0")"
_program_path_find_parentPath
pwd -P
)
elif command -v readlink 1>/dev/null 2>/dev/null; then
(
scriptPath="$0"
while [ -L "$scriptPath" ]
do
_program_path_find_parentPath
scriptPath="$(readlink "$scriptPath")"
done
_program_path_find_parentPath
pwd -P
)
else
(
scriptPath="$0"
_program_path_find_parentPath
pwd -P
)
fi
fi
}
compile_pmdk_fail()
{
local message="$1"
printf 'compile-pmdk:FAIL:%s\n' "$message" 1>&2
exit 1
}
compile_pmdk_ensureRequiredBinariesArePresent()
{
local reason="$1"
shift 1
local binary
local missing=false
for binary in "$@"
do
if ! command -v "$binary" 1>/dev/null 2>/dev/null; then
printf 'compile-pmdk:%s\n' "The binary '$binary' needs to be in the path" 1>&2
missing=true
fi
done
if $missing; then
compile_pmdk_fail "Please make sure that the missing binaries are installed because '$reason'"
fi
}
_compile_pmdk_prepareForMacOSX_brewInstall()
{
compile_pmdk_ensureRequiredBinariesArePresent brew
local packageName="$1"
if ! brew ls --versions "$packageName" 1>/dev/null 2>/dev/null; then
brew install "$packageName" 1>&2
fi
}
compile_pmdk_prepareForMacOSX()
{
_compile_pmdk_prepareForMacOSX_brewInstall gnu-sed
_compile_pmdk_prepareForMacOSX_brewInstall make
_compile_pmdk_prepareForMacOSX_brewInstall libelf
_compile_pmdk_prepareForMacOSX_brewInstall coreutils
_compile_pmdk_prepareForMacOSX_brewInstall FiloSottile/musl-cross/musl-cross
_compile_pmdk_prepareForMacOSX_brewInstall pkg-config
_compile_pmdk_prepareForMacOSX_brewInstall grep
_compile_pmdk_prepareForMacOSX_brewInstall autoconf@2.69
_compile_pmdk_prepareForMacOSX_brewInstall libtool
}
compile_pmdk_parseCommandLine()
{
case "$#" in
0)
:
;;
1)
case "$1" in
-h|--help)
printf './compile-pmdk\n'
printf './compile-pmdk -h|--help\n'
printf 'Pass the environment variable NUM_JOBS to control the number of make jobs\n'
exit 0
;;
*)
compile_pmdk_fail "Does not take any arguments"
;;
esac
;;
*)
compile_pmdk_fail "Does not take any arguments"
;;
esac
}
compile_pmdk_setCargoManifestDir()
{
if [ -n "${CARGO_MANIFEST_DIR+set}" ]; then
printf 'compile-pmdk:%s\n' "Building with CARGO_MANIFEST_DIR '$CARGO_MANIFEST_DIR'" 1>&2
else
local programPath="$(_program_path_find)"
cd "$programPath"/.. 1>/dev/null 2>/dev/null
local homeFolder="$(pwd)"
cd - 1>/dev/null 2>/dev/null
printf 'compile-pmdk:%s\n' "Whilst this script is designed to be run under cargo, it can run independently. We're setting CARGO_MANIFEST_DIR to '$homeFolder'" 1>&2
export CARGO_MANIFEST_DIR="$homeFolder"
fi
}
compile_pmdk_findFolderPaths()
{
if [ -z "${OUT_DIR+undefined}" ]; then
pmdkRootFolderPath="$CARGO_MANIFEST_DIR"/bindgen-wrapper.conf.d/temporary/root
else
pmdkRootFolderPath="$OUT_DIR"/root
fi
configurationFolderPath="$CARGO_MANIFEST_DIR"/compile-pmdk.conf.d
}
compile_pmdk_createTemporaryFolder()
{
temporaryFolderPath="$configurationFolderPath"/temporary/root
rm -rf "$temporaryFolderPath"
mkdir -m 0700 -p "$temporaryFolderPath"
}
compile_pmdk_createTemporaryBinariesPath()
{
rm -rf "$additionalPath"
mkdir -m 0700 -p "$additionalPath"
export PATH="$additionalPath":"$PATH"
}
compile_pmdk_platformSpecificPreparation()
{
compile_pmdk_ensureRequiredBinariesArePresent uname
platform="$(uname)"
if [ -z "${NUM_JOBS+undefined}" ]; then
numberOfMakeJobs=0
else
numberOfMakeJobs="$NUM_JOBS"
fi
case "$platform" in
Darwin)
compile_pmdk_prepareForMacOSX
compile_pmdk_ensureRequiredBinariesArePresent brew
export PATH="$(brew --prefix coreutils)"/libexec/gnubin:"$(brew --prefix gnu-sed)"/libexec/gnubin:"$PATH"
ln -s /usr/local/bin/ggrep "$additionalPath"/grep
ln -s /usr/local/bin/glibtool "$additionalPath"/libtool
ln -s /usr/local/bin/glibtoolize "$additionalPath"/libtoolize
muslIncludeFolderPath="$(brew --prefix musl-cross)"/libexec/x86_64-linux-musl/include
if [ $numberOfMakeJobs -eq 0 ]; then
compile_pmdk_ensureRequiredBinariesArePresent sysctl
numberOfMakeJobs="$(sysctl -n hw.ncpu)"
fi
;;
Linux)
compile_pmdk_ensureRequiredBinariesArePresent make sed x86_64-linux-musl-gcc x86_64-linux-musl-ar rm mkdir rsync cat
muslIncludeFolderPath='/usr/include'
if [ $numberOfMakeJobs -eq 0 ]; then
compile_pmdk_ensureRequiredBinariesArePresent grep
numberOfMakeJobs="$(grep -c '^processor' /proc/cpuinfo)"
fi
;;
*)
compile_pmdk_fail "Only Darwin (Mac OS X) and Linux (specifically, Alpine Linux) are supported at this time"
;;
esac
}
compile_pmdk_makeCopyToAlter()
{
rsync --archive --quiet --exclude=.git "$CARGO_MANIFEST_DIR"/lib/pmdk/ "$temporaryFolderPath"/
}
compile_pmdk_unsetSomeCargoEnvironmentVariables()
{
unset DEBUG
unset RELEASE
unset HOST
unset TARGET
}
compile_pmdk_setCompilerEnvironmentVariables()
{
export CXX="${compilerPrefix}"c++
export OBJCOPY="${compilerPrefix}"objcopy
export CC="${compilerPrefix}"cc
export LD="${compilerPrefix}"ld
export AR="${compilerPrefix}"ar
export OBJCOPY="${compilerPrefix}"objcopy
export NM="${compilerPrefix}"nm
unset LIBS
unset OBJS
unset CFLAGS
unset CXXFLAGS
unset LDFLAGS
unset CPPFLAGS
unset CPP
}
compile_pmdk_fixHardcodedFileNameBugs()
{
sed -i -e 's/nm/'"$compilerPrefix"nm'/g' "$temporaryFolderPath"/utils/check-os.sh
sed -i -e 's/objcopy/'"$compilerPrefix"objcopy'/g' \
"$temporaryFolderPath"/src/benchmarks/Makefile \
"$temporaryFolderPath"/src/common.inc
}
compile_pmdk_buildMuslFtsSupport()
{
useMuslFts='true'
muslFtsFolderPath="$temporaryFolderPath"/musl-fts
rsync --archive --quiet --exclude=.git "$CARGO_MANIFEST_DIR"/lib/musl-fts/ "$muslFtsFolderPath"/
cd "$muslFtsFolderPath" 1>/dev/null 2>/dev/null
mkdir -m 0700 -p 'm4'
./bootstrap.sh
./configure --host "$configureHost"
make -j "$numberOfMakeJobs"
cd - 1>/dev/null 2>/dev/null
}
compile_pmdk_fixMuslBugs()
{
sed -i -e 's/#include <stddef.h>/#include <stddef.h>\n#include <limits.h>/g' "$temporaryFolderPath"/src/common/file.h
}
compile_pmdk_fixMuslLacksSecureGetEnv()
{
mv "$temporaryFolderPath"/src/common/os_linux.c "$temporaryFolderPath"/src/common/os_linux.c.orig
cat >"$temporaryFolderPath"/src/common/os_linux.c <<-EOF
#include <stdlib.h>
#include <unistd.h>
static char * secure_getenv(const char *name)
{
if (issetugid() != 0)
{
return NULL;
}
return getenv(name);
}
EOF
cat "$temporaryFolderPath"/src/common/os_linux.c.orig >>"$temporaryFolderPath"/src/common/os_linux.c
}
compile_pmdk_fixNaiveCrossCompilingBugs()
{
sed -i -e 's/\$(shell uname -s | tr "\[:upper:\]" "\[:lower:\]")/linux/g' "$temporaryFolderPath"/src/common/pmemcommon.inc
}
compile_pmdk_fixJemallocForCrossCompiling()
{
cp "$temporaryFolderPath"/src/jemalloc/jemalloc.cfg "$temporaryFolderPath"/src/jemalloc/jemalloc.cfg.orig
{
cat <<-EOF
--host=${configureHost}
EOF
cat "$temporaryFolderPath"/src/jemalloc/jemalloc.cfg.orig
} >"$temporaryFolderPath"/src/jemalloc/jemalloc.cfg
}
compile_pmdk_fixWarningsToNotBeErrors()
{
sed -i \
-e '/-Werror/d' \
"$temporaryFolderPath"/src/Makefile.inc \
"$temporaryFolderPath"/src/tools/Makefile.inc
}
compile_pmdk_fixDoNotCompileBenchmarks()
{
sed -i -e 's/ examples benchmarks//g' "$temporaryFolderPath"/src/Makefile
}
compile_pmdk_fixDynamicLibraries()
{
sed -i -e 's;DYNAMIC_LIBS += \$(LIBSDIR_DEBUG)/libpmemcommon.a;DYNAMIC_LIBS += -lpmemcommon;g' "$temporaryFolderPath"/src/tools/Makefile.inc
}
compile_pmdk_make()
{
cd "$temporaryFolderPath" 1>/dev/null 2>/dev/null
set -- -j "$numberOfMakeJobs"
if $useMuslFts; then
set -- "$@" EXTRA_CFLAGS="-DPMEMOBJ_DIRECT_NON_INLINE -I${muslFtsFolderPath}" EXTRA_LDFLAGS="-L${muslFtsFolderPath}/.libs -lfts"
else
set -- "$@" EXTRA_CFLAGS="-DPMEMOBJ_DIRECT_NON_INLINE"
fi
make "$@"
make -j "$numberOfMakeJobs" install prefix=/usr DESTDIR="$temporaryFolderPath" 1>&2
cd - 1>/dev/null 2>/dev/null
}
compile_pmdk_installRemoteMemoryHeadersEvenThoughLibrpmemIsNotBuiltBecauseLibfabricIsMissing()
{
cp "$temporaryFolderPath"/src/include/librpmem.h "$temporaryFolderPath"/usr/include
}
compile_pmdk_finish()
{
rm -rf "$pmdkRootFolderPath"
mkdir -m 0700 -p "$pmdkRootFolderPath"
rsync -a -v "$temporaryFolderPath"/usr "$pmdkRootFolderPath"/
}
compile_pmdk_main()
{
local configureHost='x86_64-linux-musl'
local compilerPrefix="${configureHost}"-
compile_pmdk_parseCommandLine "$@"
compile_pmdk_setCargoManifestDir
local pmdkRootFolderPath
local configurationFolderPath
compile_pmdk_findFolderPaths
local temporaryFolderPath
compile_pmdk_createTemporaryFolder
local additionalPath="$temporaryFolderPath"/PATH
compile_pmdk_createTemporaryBinariesPath
local platform
local muslIncludeFolderPath
local numberOfMakeJobs
compile_pmdk_platformSpecificPreparation
compile_pmdk_makeCopyToAlter
compile_pmdk_unsetSomeCargoEnvironmentVariables
compile_pmdk_setCompilerEnvironmentVariables
compile_pmdk_fixHardcodedFileNameBugs
local useMuslFts
local muslFtsFolderPath
compile_pmdk_buildMuslFtsSupport
compile_pmdk_fixMuslBugs
compile_pmdk_fixMuslLacksSecureGetEnv
compile_pmdk_fixNaiveCrossCompilingBugs
compile_pmdk_fixJemallocForCrossCompiling
compile_pmdk_fixWarningsToNotBeErrors
compile_pmdk_fixDoNotCompileBenchmarks
compile_pmdk_fixDynamicLibraries
compile_pmdk_make
compile_pmdk_installRemoteMemoryHeadersEvenThoughLibrpmemIsNotBuiltBecauseLibfabricIsMissing
compile_pmdk_finish
printf '\n\n\nFINISHED COMPILATION OF PMDK; look in bindgen-wrapper.conf.d/temporary/root\n\n\n' 1>&2
}
compile_pmdk_main "$@"