-
Notifications
You must be signed in to change notification settings - Fork 1
/
build_binary.sh
230 lines (191 loc) · 6.67 KB
/
build_binary.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/bin/bash
# Bail out on errors, be strict
# cd
# git clone --recursive https://github.com/neondatabase/neon.git
# cd neon
# mkdir WORKDIR
# bash -x build_binary.sh ${PWD}/WORKDIR/
PGVERSION="14"
VERSION="1.0.0"
set -ue
# Examine parameters
TARGET="$(uname -m)"
TARGET_CFLAGS=''
#
# Some programs that may be overriden
TAR=${TAR:-tar}
# Check if we have a functional getopt(1)
if ! getopt --test
then
go_out="$(getopt --options="i" --longoptions=i686 \
--name="$(basename "$0")" -- "$@")"
test $? -eq 0 || exit 1
eval set -- $go_out
fi
for arg
do
case "$arg" in
-- ) shift; break;;
-i | --i686 )
shift
TARGET="i686"
TARGET_CFLAGS="-m32 -march=i686"
;;
esac
done
if [ -f /etc/debian_version ]; then
GLIBC_VER_TMP="$(dpkg-query -W -f='${Version}' libc6 | awk -F'-' '{print $1}')"
else
GLIBC_VER_TMP="$(rpm glibc -qa --qf %{VERSION})"
fi
export GLIBC_VER=".glibc${GLIBC_VER_TMP}"
# Working directory
if test "$#" -eq 0
then
WORKDIR="$(readlink -f $(dirname $0)/../../../)"
# Check that the current directory is not empty
if test "x$(echo *)" != "x*"
then
echo >&2 \
"Current directory is not empty. Use $0 . to force build in ."
exit 1
fi
WORKDIR_ABS="$(cd "$WORKDIR"; pwd)"
elif test "$#" -eq 1
then
WORKDIR="$1"
# Check that the provided directory exists and is a directory
if ! test -d "$WORKDIR"
then
echo >&2 "$WORKDIR is not a directory"
exit 1
fi
WORKDIR_ABS="$(cd "$WORKDIR"; pwd)"
else
echo >&2 "Usage: $0 [target dir]"
exit 1
fi
SOURCEDIR="$(cd $(dirname "$0"); pwd)"
echo $SOURCEDIR
# Compilation flags
export CC=${CC:-gcc}
export CXX=${CXX:-g++}
export CFLAGS=${CFLAGS:-}
export CXXFLAGS=${CXXFLAGS:-}
export MAKE_JFLAG=-j4
# Create a temporary working directory
BASEINSTALLDIR="$(cd "$WORKDIR" && TMPDIR="$WORKDIR_ABS" mktemp -d neondatabase-neon.XXXXXX)"
INSTALLDIR="$WORKDIR_ABS/$BASEINSTALLDIR/neondatabase-neon-PG$PGVERSION-$VERSION-$(uname -s)-$(uname -m)$GLIBC_VER" # Make it absolute
mkdir "$INSTALLDIR"
# Build
(
cd "$WORKDIR"
# Build proper
(
cd $SOURCEDIR
# Install the f1iles
sed -i 's/BUILD_TYPE ?= debug/BUILD_TYPE ?= release/' Makefile
make -j 4
mkdir -p $INSTALLDIR/target/release
for file in $(find target/release -maxdepth 1 -type f -executable); do
cp $file $INSTALLDIR/target/release/
done
mkdir -p $INSTALLDIR/pg_install/v$PGVERSION/bin
for file in $(find pg_install/v14/bin -maxdepth 1 -type f -executable); do
cp $file $INSTALLDIR/pg_install/v$PGVERSION/bin
done
mkdir -p $INSTALLDIR/pg_install/build
cp -r pg_install/v$PGVERSION $INSTALLDIR/pg_install
cp -r pg_install/build/*v$PGVERSION $INSTALLDIR/pg_install/build
)
exit_value=$?
if test "x$exit_value" = "x0"
then
cd "$INSTALLDIR"
LIBLIST="linux-vdso.so libgcc_s.so librt.so libpthread.so libm.so libdl.so libcrypto.so libssl.so libpq.so"
DIRLIST="target/release pg_install/v$PGVERSION/bin"
LIBPATH=""
function gather_libs {
local elf_path=$1
for lib in $LIBLIST; do
for elf in $(find $elf_path -maxdepth 1 -exec file {} \; | grep 'ELF ' | cut -d':' -f1); do
IFS=$'\n'
for libfromelf in $(ldd $elf | grep $lib | awk '{print $3}'); do
if [ ! -f lib/private/$(basename $(readlink -f $libfromelf)) ] && [ ! -L lib/$(basename $(readlink -f $libfromelf)) ]; then
echo "Copying lib $(basename $(readlink -f $libfromelf))"
cp $(readlink -f $libfromelf) lib/private
echo "Symlinking lib $(basename $(readlink -f $libfromelf))"
cd lib
ln -s private/$(basename $(readlink -f $libfromelf)) $(basename $(readlink -f $libfromelf))
cd -
LIBPATH+=" $(echo $libfromelf | grep -v $(pwd))"
fi
done
unset IFS
done
done
}
function set_runpath {
# Set proper runpath for bins but check before doing anything
local elf_path=$1
local r_path=$2
for elf in $(find $elf_path -maxdepth 1 -exec file {} \; | grep 'ELF ' | cut -d':' -f1); do
echo "Checking LD_RUNPATH for $elf"
if [ -z $(patchelf --print-rpath $elf) ]; then
echo "Changing RUNPATH for $elf"
patchelf --set-rpath $r_path $elf
fi
done
}
function replace_libs {
local elf_path=$1
for libpath_sorted in $LIBPATH; do
for elf in $(find $elf_path -maxdepth 1 -exec file {} \; | grep 'ELF ' | cut -d':' -f1); do
LDD=$(ldd $elf | grep $libpath_sorted|head -n1|awk '{print $1}')
if [[ ! -z $LDD ]]; then
echo "Replacing lib $(basename $(readlink -f $libpath_sorted)) for $elf"
patchelf --replace-needed $LDD $(basename $(readlink -f $libpath_sorted)) $elf
fi
done
done
}
function check_libs {
local elf_path=$1
for elf in $(find $elf_path -maxdepth 1 -exec file {} \; | grep 'ELF ' | cut -d':' -f1); do
if ! ldd $elf; then
exit 1
fi
done
}
if [ ! -d lib/private ]; then
mkdir -p lib/private
fi
# Gather libs
for DIR in $DIRLIST; do
gather_libs $DIR
done
# Set proper runpath
set_runpath target/release '$ORIGIN/../../lib/private/'
set_runpath pg_install/v$PGVERSION/bin '$ORIGIN/../../../lib/private/'
set_runpath lib/private '$ORIGIN'
# Replace libs
for DIR in $DIRLIST; do
replace_libs $DIR
done
# Make final check in order to determine any error after linkage
for DIR in $DIRLIST; do
check_libs $DIR
done
cd "$WORKDIR"
$TAR czf "neondatabase-neon-PG$PGVERSION-$VERSION-$(uname -s)-$(uname -m)$GLIBC_VER.tar.gz" \
--owner=0 --group=0 -C "$INSTALLDIR/../" \
"neondatabase-neon-PG$PGVERSION-$VERSION-$(uname -s)-$(uname -m)$GLIBC_VER"
fi
# Clean up build dir
rm -rf "neondatabase-neon-PG$PGVERSION-$VERSION-$(uname -s)-$(uname -m)$GLIBC_VER"
exit $exit_value
)
exit_value=$?
# Clean up
rm -rf "$WORKDIR_ABS/$BASEINSTALLDIR"
exit $exit_value