forked from ValveSoftware/steam-runtime
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-runtime.sh
executable file
·364 lines (312 loc) · 10.7 KB
/
build-runtime.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
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#!/bin/bash
#
# Script to build and install packages into the Steam runtime
# The top level directory
TOP=$(cd "${0%/*}" && echo "${PWD}")
cd "${TOP}"
# Process command line options
while [ "$1" != "" ]; do
case "$1" in
--runtime=*)
RUNTIME_PATH=$(expr "$1" : '[^=]*=\(.*\)')
shift
;;
--debug=*)
DEBUG=$(expr "$1" : '[^=]*=\(.*\)')
shift
;;
--devmode=*)
DEVELOPER_MODE=$(expr "$1" : '[^=]*=\(.*\)')
shift
;;
-*)
echo "Usage: $0 [--runtime=<path>] [--debug=<value>] [--devmode=<value>] [package] [package...]" >&2
exit 1
;;
*)
break
esac
done
# Set this to "true" to install debug symbols and developer headers
if [ -z "${DEVELOPER_MODE}" ]; then
DEVELOPER_MODE=false
fi
if [ -z "${DEBUG}" ]; then
DEBUG=false
fi
if [ -z "${ARCHITECTURE}" ]; then
ARCHITECTURE=$(dpkg --print-architecture)
fi
if [ -z "${RUNTIME_PATH}" ]; then
RUNTIME_PATH="${TOP}/runtime/"
fi
valid_package()
{
local PACKAGE=$1
for SOURCE_PACKAGE in $(cat packages.txt | grep -v '^#' | awk '{print $1}'); do
if [ "${SOURCE_PACKAGE}" = "${PACKAGE}" ]; then
return 0
fi
done
echo "Couldn't find source package ${PACKAGE} in packages.txt" >&2
return 1
}
build_package()
{
local ARCHITECTURE=$1
local PACKAGE=$2
local DIR="${TOP}/packages/source/${PACKAGE}"
mkdir -p "${DIR}"; cd "${DIR}"
# Get the source
if [ ! -f downloaded ]; then
echo "DOWNLOADING: ${PACKAGE}"
apt-get source --download-only ${PACKAGE} || exit 10
touch downloaded
fi
# Make sure the package description exists
local DSC=$(echo *.dsc)
if [ ! -f "${DSC}" ]; then
echo "WARNING: Missing dsc file for ${PACKAGE}" >&2
return
fi
# Calculate the checksum for the source
local CHECKSUM=.checksum
md5sum "${DSC}" >"${CHECKSUM}"
for patch in "${TOP}/patches/${PACKAGE}"/*; do
if [ -f "${patch}" ]; then
patchpath="$(dirname "${patch}")"
patchname="$(basename "${patch}")"
(cd "${patchpath}"; md5sum "${patchname}") >>"${CHECKSUM}"
fi
done
# Build
local BUILD="${BINARY_PACKAGE_DIR}/${PACKAGE}"
local BUILDTAG="${BUILD}/built"
mkdir -p ${BUILD}
if [ ! -f "${BUILDTAG}" ] || ! cmp "${BUILDTAG}" "${CHECKSUM}" >/dev/null 2>&1; then
echo "BUILDING: ${PACKAGE} for ${ARCHITECTURE}"
# Make sure we have build dependencies
sudo apt-get build-dep -y --only-source "${PACKAGE}"
# Extract the source and apply patches
SOURCE_DIR="/tmp/source/${PACKAGE}"
PACKAGE_DIR="$(basename "${DSC}" .dsc | sed 's,_\([^-]*\).*,-\1,')"
if [ -d "${SOURCE_DIR}" ]; then
# Always start fresh...
#echo -n "${SOURCE_DIR} already exists, remove it? [Y/n]: "
#read answer
#if [ "$answer" = "n" ]; then
# echo "Please create a patch of any local changes and restart." >&2
# exit 20
#fi
rm -rf "${SOURCE_DIR}"
fi
mkdir -p "${SOURCE_DIR}"
dpkg-source -x "${DSC}" "${SOURCE_DIR}/${PACKAGE_DIR}" || exit 20
for patch in "${TOP}/patches/${PACKAGE}"/*; do
if [ -f "${patch}" ]; then
patchname="$(basename "${patch}")"
echo "APPLYING: ${patchname}"
(cd "${SOURCE_DIR}/${PACKAGE_DIR}" && patch -p1 <"${patch}") || exit 20
fi
done
# Build the package
if [ "${DEBUG}" = "true" ]; then
export DEB_BUILD_OPTIONS="debug noopt nostrip"
export DPKG_GENSYMBOLS_CHECK_LEVEL=1
fi
(cd "${SOURCE_DIR}/${PACKAGE_DIR}" && dpkg-buildpackage -b -uc) || exit 30
# Back up any old binary packages
OLD="${BUILD}/old-versions"
mkdir -p "${OLD}"
for file in "${BUILD}"/*.*; do
if [ -f "${file}" ]; then
mv -fv "${file}" "${OLD}/"
fi
done
# Move the binary packages into place
pushd "${SOURCE_DIR}"
for file in *.changes *.deb *.ddeb *.udeb; do
if [ -f "${file}" ]; then
mv -v "${file}" "${BUILD}/${file}" || exit 40
fi
done
popd
# Clean up the source
rm -rf "${SOURCE_DIR}"
# Copy the checksum to mark the build complete
cp "${CHECKSUM}" "${BUILDTAG}" || exit 40
else
echo "${PACKAGE} for ${ARCHITECTURE} is up to date"
fi
# Don't do this in case there are multiple builds in parallel
#rm -f "${CHECKSUM}"
# Done!
cd "${TOP}"
}
install_source()
{
local PACKAGE=$1
local INSTALL_PATH=$2
local DIR="${TOP}/packages/source/${PACKAGE}"
mkdir -p "${DIR}"; cd "${DIR}"
# Make sure the package description exists
local DSC=$(echo *.dsc)
if [ ! -f "${DSC}" ]; then
echo "WARNING: Missing dsc file for ${PACKAGE}" >&2
return
fi
# Extract the source and apply patches
local SOURCE_DIR="${INSTALL_PATH}/source/${PACKAGE}"
local PACKAGE_DIR="$(basename "${DSC}" .dsc | sed 's,_\([^-]*\).*,-\1,')"
rm -rf "${SOURCE_DIR}"
mkdir -p "${SOURCE_DIR}"
dpkg-source -x "${DSC}" "${SOURCE_DIR}/${PACKAGE_DIR}" || exit 20
for patch in "${TOP}/patches/${PACKAGE}"/*; do
if [ -f "${patch}" ]; then
patchname="$(basename "${patch}")"
echo "APPLYING: ${patchname}"
(cd "${SOURCE_DIR}/${PACKAGE_DIR}" && patch -p1 <"${patch}") || exit 20
fi
done
rm -f "${SOURCE_DIR}"/*.orig.*
# Done!
cd "${TOP}"
}
install_compile_path()
{
local ARCHIVE=$1
local INSTALL_PATH=$2
local SOURCE_ROOT=$3
local INSTALLTAG_DIR="${INSTALL_PATH}/installed"
local INSTALLTAG="$(basename "${ARCHIVE}" | sed -e 's,\.deb$,,' -e 's,\.ddeb$,,')"
# Create the compile paths for symbol resolution
for file in $(cat "${INSTALLTAG_DIR}/${INSTALLTAG}"); do
readelf --debug-dump=info "${INSTALL_PATH=}/$file" 2>/dev/null | grep DW_AT_comp_dir | sed -e 's,.*: ,,' -e 's,/tmp/,,' | sort | uniq | while read path; do
if [ ! -e "${SOURCE_ROOT}/${path}" ]; then
#echo "Adding source path: '/tmp/${path}'"
mkdir -p "${SOURCE_ROOT}/${path}"
fi
done
done
}
install_deb()
{
local ARCHIVE=$1
local INSTALL_PATH=$2
local INSTALLTAG_DIR="${INSTALL_PATH}/installed"
local INSTALLTAG="$(basename "${ARCHIVE}" | sed -e 's,\.deb$,,' -e 's,\.ddeb$,,')"
if [ -f "${INSTALLTAG_DIR}/${INSTALLTAG}.md5" ]; then
local EXISTING="$(cat "${INSTALLTAG_DIR}/${INSTALLTAG}.md5")"
else
local EXISTING=""
fi
local CHECKSUM="$(cd "$(dirname "${ARCHIVE}")"; md5sum "$(basename "${ARCHIVE}")")"
if [ -f "${INSTALLTAG_DIR}/${INSTALLTAG}" -a \
-f "${INSTALLTAG_DIR}/${INSTALLTAG}.md5" -a \
"${EXISTING}" = "${CHECKSUM}" ]; then
echo "INSTALLED: $(basename ${ARCHIVE})"
else
echo "INSTALLING: $(basename ${ARCHIVE})"
mkdir -p "${INSTALLTAG_DIR}"
INSTALL_TMP="${INSTALL_PATH}/tmp"
rm -rf "${INSTALL_TMP}"
mkdir -p "${INSTALL_TMP}"
cd "${INSTALL_TMP}"
ar x "${ARCHIVE}" || exit 40
: >"${INSTALLTAG_DIR}/${INSTALLTAG}"
(tar xvf data.tar.* -C .. | while read file; do
if [ -f "../${file}" ]; then
echo "${file}" >>"${INSTALLTAG_DIR}/${INSTALLTAG}"
fi
done) || exit 40
echo "${CHECKSUM}" >"${INSTALLTAG_DIR}/${INSTALLTAG}.md5" || exit 40
cd "${TOP}"
rm -rf "${INSTALL_TMP}"
fi
}
process_package()
{
local INSTALL_PATH="${RUNTIME_PATH}/${ARCHITECTURE}"
local SOURCE_PACKAGE=$1
echo ""
echo "Processing ${SOURCE_PACKAGE}..."
shift
build_package ${ARCHITECTURE} ${SOURCE_PACKAGE}
if [ "${DEBUG}" = "true" ]; then
install_source ${SOURCE_PACKAGE} "${RUNTIME_PATH}"
fi
for PACKAGE in $*; do
# Skip development packages for end-user runtime
if (echo "${PACKAGE}" | egrep -- '-dbg$|-dev$|-multidev$' >/dev/null) && [ "${DEVELOPER_MODE}" != "true" ]; then
continue
fi
ARCHIVE=$(echo "${BINARY_PACKAGE_DIR}"/${SOURCE_PACKAGE}/${PACKAGE}_*_all.deb)
if [ -f "${ARCHIVE}" ]; then
install_deb "${ARCHIVE}" "${INSTALL_PATH}"
else
ARCHIVE=$(echo "${BINARY_PACKAGE_DIR}"/${SOURCE_PACKAGE}/${PACKAGE}_*_${ARCHITECTURE}.deb)
if [ -f "${ARCHIVE}" ]; then
install_deb "${ARCHIVE}" "${INSTALL_PATH}"
else
echo "WARNING: Missing ${ARCHIVE}" >&2
continue
fi
fi
if [ "${DEVELOPER_MODE}" = "true" -a "${DEBUG}" != "true" ]; then
SYMBOL_ARCHIVE=$(echo "${BINARY_PACKAGE_DIR}"/${SOURCE_PACKAGE}/${PACKAGE}-dbgsym_*_${ARCHITECTURE}.ddeb)
if [ -f "${SYMBOL_ARCHIVE}" ]; then
install_deb "${SYMBOL_ARCHIVE}" "${INSTALL_PATH}"
fi
fi
if [ "${DEBUG}" = "true" ]; then
install_compile_path "${ARCHIVE}" "${INSTALL_PATH}" "${RUNTIME_PATH}"
fi
done
}
# Make sure we're in the build environment
if [ ! -f "/README.txt" ]; then
echo "You are not running in the build environment!"
echo -n "Are you sure you want to continue? [y/N]: "
read answer
if [ "$answer" != "y" -a "$answer" != "Y" ]; then
exit 2
fi
fi
# Figure out where the runtime path is
RESOLVED_PATH="$(realpath -s "${RUNTIME_PATH}")"
if [ ! -d "${RESOLVED_PATH}" ]; then
echo "Couldn't resolve path for: ${RUNTIME_PATH}" >&2
exit 2
fi
RUNTIME_PATH="${RESOLVED_PATH}"
# Figure out where binary packages go
if [ "${DEBUG}" = "true" ]; then
BINARY_PACKAGE_DIR="${TOP}/packages/debug/${ARCHITECTURE}"
else
BINARY_PACKAGE_DIR="${TOP}/packages/binary/${ARCHITECTURE}"
fi
# Build and install the packages
if [ "$1" != "" ]; then
for SOURCE_PACKAGE in "$@"; do
if valid_package "${SOURCE_PACKAGE}"; then
process_package $(awk '{ if ($1 == "'${SOURCE_PACKAGE}'") print $0 }' <packages.txt)
fi
done
else
echo "======================================================="
echo "Building runtime for ${ARCHITECTURE}"
date
for SOURCE_PACKAGE in $(cat packages.txt | grep -v '^#' | awk '{print $1}'); do
process_package $(awk '{ if ($1 == "'${SOURCE_PACKAGE}'") print $0 }' <packages.txt)
done
echo ""
date
echo "======================================================="
echo ""
fi
# Fix up the runtime
if [ "${DEVELOPER_MODE}" = "true" -a "${DEBUG}" != "true" ]; then
"${RUNTIME_PATH}/scripts/fix-debuglinks.sh" "${ARCHITECTURE}"
fi
"${RUNTIME_PATH}/scripts/fix-symlinks.sh" "${ARCHITECTURE}"
# vi: ts=4 sw=4 expandtab