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
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
|
#!/bin/bash
#
# build a multi architecture package for Android
#
# this requires Qt5.14 or newer with matching NDK
#
# the packaging/android/android-build-setup.sh sets up an environment that works for this
set -eu
exec 1> >(tee ./android-build.log) 2>&1
# get the absolute path
pushd "$(dirname "$0")/../../"
export SUBSURFACE_SOURCE=$PWD
cd ..
export BUILDROOT=$PWD
popd
# Set build defaults
# is this a release or debug build
BUILD_TYPE=Debug
# and now we need a monotonic build number...
if [ ! -f ./buildnr.dat ] ; then
BUILDNR=0
else
BUILDNR=$(cat ./buildnr.dat)
fi
BUILDNR=$((BUILDNR+1))
echo "${BUILDNR}" > ./buildnr.dat
# Read build variables
source $SUBSURFACE_SOURCE/packaging/android/variables.sh
# this assumes that the Subsurface source directory is in the same
# directory hierarchy as the SDK and NDK
export ANDROID_NDK_ROOT="$SUBSURFACE_SOURCE/../$ANDROID_NDK"
export ANDROID_SDK_ROOT="$SUBSURFACE_SOURCE/.."
export JAVA_OPTS="-Dsun.jnu.encoding=UTF-8 -Dfile.encoding=UTF-8"
QUICK=""
ARCHITECTURES=""
BUILD_ABIS=""
versionOnly=""
while [ "$#" -gt 0 ] ; do
case "$1" in
Release|release)
shift
BUILD_TYPE=Release
;;
Debug|debug)
# this is the default - still need to eat the argument if given
BUILD_TYPE=Debug
shift
;;
-buildnr)
shift
BUILDNR=$1
shift
;;
-version)
# only update the version info without rebuilding
# this is useful when working with Xcode
versionOnly="1"
;;
arm|arm64|x86|x86_64)
ARCHITECTURES=$1
shift
;;
-quick)
QUICK="1"
shift
;;
*)
echo "Unknown argument $1"
exit 1
;;
esac
done
mkdir -p "$BUILDROOT"/subsurface-mobile-build
pushd "$BUILDROOT"/subsurface-mobile-build
# set up the Subsurface versions by hand
GITVERSION=$(cd "$SUBSURFACE_SOURCE" ; git describe --abbrev=12)
CANONICALVERSION=$(echo "$GITVERSION" | sed -e 's/-g.*$// ; s/^v//' | sed -e 's/-/./')
MOBILEVERSION=$(grep MOBILE "$SUBSURFACE_SOURCE"/cmake/Modules/version.cmake | cut -d\" -f 2)
echo "#define GIT_VERSION_STRING \"$GITVERSION\"" > ssrf-version.h
echo "#define CANONICAL_VERSION_STRING \"$CANONICALVERSION\"" >> ssrf-version.h
echo "#define MOBILE_VERSION_STRING \"$MOBILEVERSION\"" >> ssrf-version.h
SUBSURFACE_MOBILE_VERSION="$MOBILEVERSION ($CANONICALVERSION)"
popd
if [ "$versionOnly" = "1" ] ; then
exit 0
fi
# pick the Qt setup and show the configuration info
if [ -n "${QT5_ANDROID+X}" ] ; then
echo "Using Qt5 in $QT5_ANDROID"
elif [ -d "$SUBSURFACE_SOURCE/../${LATEST_QT}" ] ; then
export QT5_ANDROID=$SUBSURFACE_SOURCE/../${LATEST_QT}
else
echo "Cannot find Qt 5.12 or newer under $SUBSURFACE_SOURCE/.."
exit 1
fi
QMAKE=$QT5_ANDROID/android/bin/qmake
echo $QMAKE
$QMAKE -query
export TOOLCHAIN="$ANDROID_NDK_ROOT"/toolchains/llvm/prebuilt/linux-x86_64
PATH=$TOOLCHAIN/bin:$PATH
export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT # redundant, but that's what openssl wants
# make sure we have the font that we need for OnePlus phones due to https://bugreports.qt.io/browse/QTBUG-69494
if [ ! -f "$SUBSURFACE_SOURCE"/android-mobile/Roboto-Regular.ttf ] ; then
cp "$ANDROID_SDK_ROOT"/platforms/"$ANDROID_PLATFORMS"/data/fonts/Roboto-Regular.ttf "$SUBSURFACE_SOURCE"/android-mobile || exit 1
fi
# next, make sure that the libdivecomputer sources are downloaded and
# ready for autoconfig
pushd "$SUBSURFACE_SOURCE"
if [ ! -d libdivecomputer/src ] ; then
git submodule init
git submodule update
fi
if [ ! -f libdivecomputer/configure ] ; then
cd libdivecomputer
autoreconf -i
fi
popd
# build default architectures, or the given one?
if [ "$ARCHITECTURES" = "" ] ; then
ARCHITECTURES="armv7a aarch64"
fi
# it would of course be too easy to use these terms consistently, so let's not
# no where do we support x86 style Android builds - there aren't any relevant devices
for ARCH in $ARCHITECTURES ; do
if [ "$ARCH" = "armv7a" ] ; then
ANDROID_ABI="armeabi-v7a"
else
ANDROID_ABI="arm64-v8a"
fi
BUILD_ABIS="$BUILD_ABIS $ANDROID_ABI"
done
# if this isn't just a quick rebuild, pull kirigami, icons, etc, and finally build the Googlemaps plugin
if [ "$QUICK" = "" ] ; then
pushd "$SUBSURFACE_SOURCE"
bash -x ./scripts/mobilecomponents.sh
popd
# build google maps plugin
# this is the easy one as it uses qmake which ensures things get built for all platforms, etc
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . googlemaps
# but unfortunately, on Android (and apparently only on Android) the naming pattern for geoservice
# plugins has changed
pushd googlemaps
sed -i 's/TARGET = qtgeoservices_googlemaps/TARGET = plugins_geoservices_qtgeoservices_googlemaps/' googlemaps.pro
popd
QT_PLUGINS_PATH=$($QMAKE -query QT_INSTALL_PLUGINS)
GOOGLEMAPS_BIN=libplugins_geoservices_qtgeoservices_googlemaps_arm64-v8a.so
if [ ! -e "$QT_PLUGINS_PATH"/geoservices/$GOOGLEMAPS_BIN ] || [ googlemaps/.git/HEAD -nt "$QT_PLUGINS_PATH"/geoservices/$GOOGLEMAPS_BIN ] ; then
mkdir -p googlemaps-build
pushd googlemaps-build
$QMAKE ANDROID_ABIS="$BUILD_ABIS" ../googlemaps/googlemaps.pro
make -j4
make install
popd
fi
fi
# autoconf based libraries are harder
for ARCH in $ARCHITECTURES ; do
echo "START building libraries for $ARCH"
echo "====================================="
# it would of course be too easy to use these terms consistently, so let's not
if [ "$ARCH" = "armv7a" ] ; then
EABI="eabi"
BINUTIL_ARCH="arm"
OPENSSL_ARCH="arm"
ANDROID_ABI="armeabi-v7a"
else
EABI=""
BINUTIL_ARCH="aarch64"
OPENSSL_ARCH="arm64"
ANDROID_ABI="arm64-v8a"
fi
export TARGET=$ARCH-linux-android
export AR=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ar
export AS=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-as
export CC=$TOOLCHAIN/bin/$TARGET$EABI$ANDROID_PLATFORM_LEVEL-clang
export CXX=$TOOLCHAIN/bin/$TARGET$EABI$ANDROID_PLATFORM_LEVEL-clang++
export LD=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ld
export RANLIB=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-ranlib
export STRIP=$TOOLCHAIN/bin/$BINUTIL_ARCH-linux-android$EABI-strip
# set up an install root and create part of the directory structure so the openssl
# manual install below doesn't fail
export PREFIX="$BUILDROOT"/install-root-"$ANDROID_ABI"
mkdir -p "$PREFIX"/include
mkdir -p "$PREFIX"/lib/pkgconfig
export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig
if [ "$QUICK" = "" ] ; then
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . openssl
if [ ! -e "$PKG_CONFIG_PATH/libssl.pc" ] ; then
# openssl build fails with these set
export SYSROOT=""
export CFLAGS=""
export CPPFLAGS=""
export CXXFLAGS=""
mkdir -p openssl-build-"$ARCH"
cp -r openssl/* openssl-build-"$ARCH"
pushd openssl-build-"$ARCH"
perl -pi -e 's/-mandroid//g' Configure
./Configure shared android-"$OPENSSL_ARCH" no-ssl2 no-ssl3 no-comp no-hw no-engine no-asm \
--prefix="$PREFIX" -DOPENSSL_NO_UI_CONSOLE -DOPENSSL_NO_STDIO \
-D__ANDROID_API__=$ANDROID_PLATFORM_LEVEL
make depend
# follow the suggestions here: https://doc.qt.io/qt-5/android-openssl-support.html
make SHLIB_VERSION_NUMBER= SHLIB_EXT=_1_1.so build_libs
cp -RL include/openssl $PREFIX/include/openssl
cp libcrypto.a $PREFIX/lib
cp libcrypto_1_1.so* $PREFIX/lib
cp libssl.a $PREFIX/lib
cp libssl_1_1.so* $PREFIX/lib
cp *.pc $PKG_CONFIG_PATH
popd
fi
fi
# autoconf seems to get lost without this -- but openssl fails if these are set
SYSROOT="$ANDROID_NDK_ROOT"/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CFLAGS="--sysroot=${SYSROOT} -fPIC"
CPPFLAGS="--sysroot=${SYSROOT} -fPIC"
CXXFLAGS="--sysroot=${SYSROOT} -fPIC"
if [ "$QUICK" = "" ] ; then
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . sqlite
if [ ! -e "$PKG_CONFIG_PATH/sqlite3.pc" ] ; then
mkdir -p sqlite-build-"$ARCH"
pushd sqlite-build-"$ARCH"
../sqlite/configure --host="$TARGET" --prefix="$PREFIX" --enable-static --disable-shared
make
make install
popd
fi
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libxml2
if [ ! -e libxml2/configure ] ; then
pushd libxml2
autoreconf --install
popd
fi
if [ ! -e "$PKG_CONFIG_PATH/libxml-2.0.pc" ] ; then
mkdir -p libxml2-build-"$ARCH"
pushd libxml2-build-"$ARCH"
../libxml2/configure --host="$TARGET" --prefix="$PREFIX" --without-python --without-iconv --enable-static --disable-shared
perl -pi -e 's/runtest\$\(EXEEXT\)//' Makefile
perl -pi -e 's/testrecurse\$\(EXEEXT\)//' Makefile
make
make install
popd
fi
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libxslt
if [ ! -e libxslt/configure ] ; then
pushd libxslt
autoreconf --install
popd
fi
if [ ! -e "$PKG_CONFIG_PATH/libxslt.pc" ] ; then
mkdir -p libxslt-build-"$ARCH"
pushd libxslt-build-"$ARCH"
../libxslt/configure --host="$TARGET" --prefix="$PREFIX" --with-libxml-prefix="$PREFIX" --without-python --without-crypto --enable-static --disable-shared
make
make install
popd
fi
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libzip
if [ ! -e "$PKG_CONFIG_PATH/libzip.pc" ] ; then
# libzip expects a predefined macro that isn't there for our compiler
pushd libzip
git reset --hard
sed -i 's/SIZEOF_SIZE_T/__SIZEOF_SIZE_T__/g' lib/compat.h
# also, don't deal with manuals and bzip2
sed -i 's/ADD_SUBDIRECTORY(man)//' CMakeLists.txt
sed -i 's/^FIND_PACKAGE(ZLIB/#&/' CMakeLists.txt
popd
mkdir -p libzip-build-"$ARCH"
pushd libzip-build-"$ARCH"
cmake \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_LINKER="$CC" \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCMAKE_INSTALL_LIBDIR="lib" \
-DBUILD_SHARED_LIBS=OFF \
-DCMAKE_DISABLE_FIND_PACKAGE_BZip2=TRUE \
-DZLIB_VERSION_STRING=1.2.7 \
-DZLIB_LIBRARY=z \
../libzip/
make
make install
popd
fi
"${SUBSURFACE_SOURCE}"/scripts/get-dep-lib.sh singleAndroid . libgit2
if [ ! -e "$PKG_CONFIG_PATH/libgit2.pc" ] ; then
# We don't want to find the HTTP_Parser package of the build host by mistake
mkdir -p libgit2-build-"$ARCH"
pushd libgit2-build-"$ARCH"
cmake \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_LINKER="$CC" \
-DBUILD_CLAR=OFF -DBUILD_SHARED_LIBS=OFF \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DCURL=OFF \
-DUSE_SSH=OFF \
-DOPENSSL_SSL_LIBRARY="$PREFIX"/lib/libssl_1_1.so \
-DOPENSSL_CRYPTO_LIBRARY="$PREFIX"/lib/libcrypto_1_1.so \
-DOPENSSL_INCLUDE_DIR="$PREFIX"/include \
-D_OPENSSL_VERSION="${OPENSSL_VERSION}" \
-DCMAKE_DISABLE_FIND_PACKAGE_HTTP_Parser=TRUE \
../libgit2/
make
make install
# Patch away pkg-config dependency to zlib, its there, i promise
perl -pi -e 's/^(Requires.private:.*)zlib(.*)$/$1 $2/' "$PKG_CONFIG_PATH"/libgit2.pc
popd
fi
fi # QUICK
# on Android I can't make an integrated build work, so let's build Kirigami separately?
mkdir -p "$BUILDROOT"/kirigami-build-"$ARCH"
pushd "$BUILDROOT"/kirigami-build-"$ARCH"
cmake \
-DANDROID="1" \
-DANDROID_ABI="$ANDROID_ABI" \
-DBUILD_SHARED_LIBS="OFF" \
-DBUILD_EXAMPLES="OFF" \
-DCMAKE_PREFIX_PATH=/android/5.15.1/android/lib/cmake \
-DCMAKE_C_COMPILER="$CC" \
-DCMAKE_LINKER="$CC" \
-DCMAKE_INSTALL_PREFIX="$PREFIX" \
-DECM_DIR="$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/ECM \
"$SUBSURFACE_SOURCE"/mobile-widgets/3rdparty/kirigami
make
make install
popd
CURRENT_SHA=$(cd "$SUBSURFACE_SOURCE"/libdivecomputer ; git describe)
PREVIOUS_SHA=$(cat "libdivecomputer-${ARCH}.SHA" 2>/dev/null || echo)
if [ ! "$CURRENT_SHA" = "$PREVIOUS_SHA" ] || [ ! -e "$PKG_CONFIG_PATH/libdivecomputer.pc" ] ; then
mkdir -p libdivecomputer-build-"$ARCH"
pushd libdivecomputer-build-"$ARCH"
"$SUBSURFACE_SOURCE"/libdivecomputer/configure --host="$TARGET" --prefix="$PREFIX" --enable-static --disable-shared --enable-examples=no
make
make install
popd
echo "$CURRENT_SHA" > "libdivecomputer-${ARCH}.SHA"
fi
echo "DONE building libraries for $ARCH"
echo "====================================="
done # ARCH
# set up the final build
pushd "$BUILDROOT"/subsurface-mobile-build
rm -rf android-build
mkdir android-build
pushd "$SUBSURFACE_SOURCE"/android-mobile
tar c . | (cd "$BUILDROOT"/subsurface-mobile-build/android-build ; tar x)
popd
# call qmake to set up the build
echo "Run qmake to setup the Subsurface-mobile build for all architectures"
$QMAKE BUILD_NR="$BUILDNR" BUILD_VERSION_NAME="$SUBSURFACE_MOBILE_VERSION" ANDROID_ABIS="$BUILD_ABIS" "$SUBSURFACE_SOURCE"/Subsurface-mobile.pro
# if this isn't just a quick rebuild compile the translations
if [ "$QUICK" = "" ] ; then
pushd "$SUBSURFACE_SOURCE"/translations
SRCS=$(ls ./*.ts | grep -v source)
popd
pushd "$SUBSURFACE_SOURCE"/packaging/android
mkdir -p translation-assets
for src in $SRCS; do
"$QT5_ANDROID"/android/bin/lrelease "$SUBSURFACE_SOURCE"/translations/"$src" -qm translation-assets/"${src/.ts/.qm}"
done
popd
fi
# now build the Subsurface aab
make aab
|