352 |
andreas |
1 |
#!/bin/bash
|
376 |
andreas |
2 |
set -o pipefail
|
352 |
andreas |
3 |
#
|
|
|
4 |
# Set the following paths according to your installation.
|
|
|
5 |
#
|
406 |
andreas |
6 |
QT_VERSION="6.6.1"
|
356 |
andreas |
7 |
QT_VERSION_MAJOR=6
|
|
|
8 |
QT_PATH="/opt/Qt"
|
|
|
9 |
QT_ABI="x86_64"
|
383 |
andreas |
10 |
QT_HOST="gcc_64"
|
352 |
andreas |
11 |
|
356 |
andreas |
12 |
QTBASE="${QT_PATH}/$QT_VERSION"
|
|
|
13 |
QTDIR="${QTBASE}/android_${QT_ABI}"
|
|
|
14 |
|
|
|
15 |
ANDROID_HOME="$HOME/Android/Sdk"
|
|
|
16 |
ANDROID_NDK_PLATFORM="30"
|
|
|
17 |
ANDROID_NDK_ROOT="${ANDROID_HOME}/ndk/25.2.9519653"
|
|
|
18 |
ANDROID_SDK_ROOT="${ANDROID_HOME}"
|
|
|
19 |
ANDROID_PLATFORM="android-$ANDROID_NDK_PLATFORM"
|
375 |
andreas |
20 |
|
|
|
21 |
if [ ! -z $OSTYPE ] && [[ "$OSTYPE" == *darwin* ]]
|
|
|
22 |
then
|
|
|
23 |
QTMACROS="${QT_PATH}/Qt?Creator.app/Contents/Resources/package-manager"
|
|
|
24 |
else
|
|
|
25 |
QTMACROS="${QT_PATH}/Tools/QtCreator/share/qtcreator/package-manager"
|
|
|
26 |
fi
|
|
|
27 |
|
356 |
andreas |
28 |
JAVA_HOME="/usr/lib/jvm/java-17-openjdk-amd64"
|
|
|
29 |
|
381 |
andreas |
30 |
export PATH="${QT_PATH}/Tools/Ninja:${QT_PATH}/Tools/CMake/bin:${QTDIR}/bin:$PATH"
|
356 |
andreas |
31 |
ANDROID_TOOLCHAIN="${ANDROID_NDK_ROOT}/build/cmake/android.toolchain.cmake"
|
|
|
32 |
|
451 |
andreas |
33 |
KEYSTORE="$HOME/projects/tpanel/src/android/android_release.keystore"
|
352 |
andreas |
34 |
KEYALIAS="tpanel"
|
356 |
andreas |
35 |
PASSFILE="$HOME/.keypass"
|
352 |
andreas |
36 |
LOGFILE="`pwd`/build.log"
|
356 |
andreas |
37 |
BUILDDIR="tpanel-6-build"
|
352 |
andreas |
38 |
|
356 |
andreas |
39 |
export EXT_LIB_PATH="$HOME/Android/distribution"
|
|
|
40 |
export EXTRA_PATH="$HOME/Android/extras"
|
|
|
41 |
export SSL_PATH="$HOME/Android/openssl"
|
|
|
42 |
#export ANDROID_ABIS="arm64-v8a armeabi-v7a x86_64 x86"
|
352 |
andreas |
43 |
|
375 |
andreas |
44 |
# This programs must be taken from the Qt framework
|
354 |
andreas |
45 |
QMAKE="$QTDIR/bin/qmake"
|
381 |
andreas |
46 |
ANDROIDDEPLOYQT="$QTBASE/${QT_HOST}/bin/androiddeployqt"
|
375 |
andreas |
47 |
|
|
|
48 |
if [ ! -z $OSTYPE ] && [[ "$OSTYPE" == *darwin* ]]
|
|
|
49 |
then
|
|
|
50 |
CMAKE="${QT_PATH}/Tools/CMake/CMake.app/Contents/bin/cmake"
|
381 |
andreas |
51 |
C_COMPILER_CLANG="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang"
|
|
|
52 |
CXX_COMPILER_CLANG="${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64/bin/clang++"
|
375 |
andreas |
53 |
else
|
|
|
54 |
CMAKE="${QT_PATH}/Tools/CMake/bin/cmake"
|
|
|
55 |
fi
|
|
|
56 |
|
356 |
andreas |
57 |
GREP="/usr/bin/grep"
|
|
|
58 |
SED="/usr/bin/sed"
|
352 |
andreas |
59 |
|
|
|
60 |
#------------------------------------------------------------------------------
|
|
|
61 |
# DO NOT CHANGE ANYTHING BEYOND THIS LINE UNLESS YOU KNOW WHAT YOU'RE DOING!!
|
|
|
62 |
#------------------------------------------------------------------------------
|
356 |
andreas |
63 |
|
|
|
64 |
# Getting the current directory
|
|
|
65 |
CURDIR=`pwd`
|
|
|
66 |
|
352 |
andreas |
67 |
#
|
|
|
68 |
# The following statement determines the number of CPUs. This is used for the
|
356 |
andreas |
69 |
# cmake command to let run the compiler in parallel.
|
352 |
andreas |
70 |
#
|
356 |
andreas |
71 |
CPUS=2
|
|
|
72 |
type nproc > /dev/null 2>&1
|
352 |
andreas |
73 |
|
356 |
andreas |
74 |
if [ $? -eq 0 ]
|
|
|
75 |
then
|
|
|
76 |
CPUS=`nproc`
|
|
|
77 |
fi
|
|
|
78 |
|
352 |
andreas |
79 |
function usage() {
|
353 |
andreas |
80 |
echo "build_android.sh [clean] [debug] [deploy] [sign] [list-avds] [help|--help|-h]"
|
352 |
andreas |
81 |
echo " clean Delete old build, if there is one, and start a new clean build."
|
|
|
82 |
echo " debug Create a binary with debugging enabled."
|
|
|
83 |
echo " deploy Deploy the binary to an Android emulator."
|
353 |
andreas |
84 |
echo " sign Sign the resulting APK file. This requires a file named"
|
|
|
85 |
echo " \"\$HOME/.keypass\" containing the password and has read"
|
|
|
86 |
echo " permissions for the owner only (0400 or 0600). If this file"
|
|
|
87 |
echo " is missing, the script asks for the password."
|
356 |
andreas |
88 |
echo " verbose | --verbose | -v"
|
|
|
89 |
echo " Prints the commands used to create the target file."
|
353 |
andreas |
90 |
echo " list-avds List all available AVDs and exit."
|
352 |
andreas |
91 |
echo
|
353 |
andreas |
92 |
echo " help | --help | -h Displays this help screen and exit."
|
|
|
93 |
echo
|
352 |
andreas |
94 |
echo "Without parameters the source is compiled, if there were changes, and then"
|
353 |
andreas |
95 |
echo "an Android package is created. This package will be an unsigned release APK."
|
352 |
andreas |
96 |
}
|
|
|
97 |
|
|
|
98 |
function log() {
|
|
|
99 |
echo "$@"
|
|
|
100 |
echo "$@" >> ${LOGFILE}
|
|
|
101 |
}
|
|
|
102 |
|
|
|
103 |
> ${LOGFILE}
|
|
|
104 |
|
|
|
105 |
# Test command line for parameters and set options
|
|
|
106 |
OPT_CLEAN=0
|
|
|
107 |
OPT_DEBUG=0
|
|
|
108 |
OPT_DEPLOY=0
|
353 |
andreas |
109 |
OPT_SIGN=0
|
356 |
andreas |
110 |
OPT_VERBOSE=0
|
352 |
andreas |
111 |
|
|
|
112 |
for par in "$@"
|
|
|
113 |
do
|
|
|
114 |
if [ "$par" == "clean" ]
|
|
|
115 |
then
|
|
|
116 |
OPT_CLEAN=1
|
|
|
117 |
elif [ "$par" == "debug" ]
|
|
|
118 |
then
|
|
|
119 |
OPT_DEBUG=1
|
|
|
120 |
elif [ "$par" == "deploy" ]
|
|
|
121 |
then
|
|
|
122 |
OPT_DEPLOY=1
|
353 |
andreas |
123 |
elif [ "$par" == "sign" ]
|
|
|
124 |
then
|
|
|
125 |
OPT_SIGN=1
|
352 |
andreas |
126 |
elif [ "$par" == "list-avds" ] || [ "$par" == "-list-avds" ]
|
|
|
127 |
then
|
|
|
128 |
${ANDROID_SDK_ROOT}/tools/emulator -list-avds
|
353 |
andreas |
129 |
exit 0
|
356 |
andreas |
130 |
elif [ "$par" == "--verbose" ] || [ "$par" == "-v" ] || [ "$par" == "verbose" ]
|
|
|
131 |
then
|
|
|
132 |
OPT_VERBOSE=1
|
352 |
andreas |
133 |
elif [ "$par" == "help" ] || [ "$par" == "--help" ] || [ "$par" == "-h" ]
|
|
|
134 |
then
|
|
|
135 |
usage
|
353 |
andreas |
136 |
exit 0
|
352 |
andreas |
137 |
fi
|
|
|
138 |
done
|
|
|
139 |
|
353 |
andreas |
140 |
if [ $OPT_DEBUG -eq 1 ] && [ $OPT_SIGN -eq 1 ]
|
|
|
141 |
then
|
|
|
142 |
log "You can't sign a debugging version!"
|
|
|
143 |
exit 1
|
|
|
144 |
fi
|
|
|
145 |
|
352 |
andreas |
146 |
if [ $OPT_CLEAN -eq 1 ]
|
|
|
147 |
then
|
|
|
148 |
log "Starting a clean build by deleting a maybe existing old build ..."
|
354 |
andreas |
149 |
rm -rf "$BUILDDIR"
|
352 |
andreas |
150 |
fi
|
|
|
151 |
|
356 |
andreas |
152 |
if [ ! -d "$BUILDDIR" ] || [ ! -f "$BUILDDIR/build.ninja" ]
|
352 |
andreas |
153 |
then
|
354 |
andreas |
154 |
if [ ! -d "$BUILDDIR" ]
|
352 |
andreas |
155 |
then
|
356 |
andreas |
156 |
log "Crating new build directory \"$BUILDDIR\" ..."
|
|
|
157 |
mkdir "${BUILDDIR}" > /dev/null 2>&1
|
451 |
andreas |
158 |
mkdir -p "${BUILDDIR}/src/.qtc/package-manager" > /dev/null 2>&1
|
352 |
andreas |
159 |
|
|
|
160 |
if [ $? -ne 0 ]
|
|
|
161 |
then
|
|
|
162 |
log "Error creating a directory!"
|
|
|
163 |
exit 1
|
|
|
164 |
fi
|
356 |
andreas |
165 |
|
376 |
andreas |
166 |
log "Copying cmake macros from $QTMACROS ..."
|
451 |
andreas |
167 |
cp ${QTMACROS}/* ${BUILDDIR}/src/.qtc/package-manager > /dev/null 2>&1
|
356 |
andreas |
168 |
|
|
|
169 |
if [ $? -ne 0 ]
|
|
|
170 |
then
|
|
|
171 |
log "Error copiing cmake macros!"
|
|
|
172 |
exit 1
|
|
|
173 |
fi
|
352 |
andreas |
174 |
fi
|
|
|
175 |
|
354 |
andreas |
176 |
log "Changing into build directory \"$BUILDDIR\" ..."
|
|
|
177 |
cd "$BUILDDIR"
|
352 |
andreas |
178 |
log "Creating Makefile ..."
|
|
|
179 |
|
|
|
180 |
_dbg=""
|
|
|
181 |
|
|
|
182 |
if [ $OPT_DEBUG -eq 1 ]
|
|
|
183 |
then
|
356 |
andreas |
184 |
_dbg="-DCMAKE_BUILD_TYPE:STRING=Debug"
|
|
|
185 |
else
|
|
|
186 |
_dbg="-DCMAKE_BUILD_TYPE:STRING=Release"
|
352 |
andreas |
187 |
fi
|
|
|
188 |
|
356 |
andreas |
189 |
if [ $OPT_VERBOSE -eq 1 ]
|
|
|
190 |
then
|
451 |
andreas |
191 |
echo "${CMAKE} -S ${CURDIR} -B ${CURDIR}/${BUILDDIR} -DCMAKE_GENERATOR:STRING=Ninja ${_dbg} -DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=${CURDIR}/${BUILDDIR}/src/.qtc/package-manager/auto-setup.cmake -DQT_QMAKE_EXECUTABLE:FILEPATH=${QMAKE} -DCMAKE_PREFIX_PATH:PATH=${QTDIR} -DCMAKE_C_COMPILER:FILEPATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang -DCMAKE_CXX_COMPILER:FILEPATH=${ANDROID_NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/clang++ -DANDROID_PLATFORM:STRING=${ANDROID_PLATFORM} -DANDROID_NDK:PATH=${ANDROID_NDK_ROOT} -DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ANDROID_TOOLCHAIN} -DANDROID_USE_LEGACY_TOOLCHAIN_FILE:BOOL=OFF -DANDROID_ABI:STRING=${QT_ABI} -DANDROID_STL:STRING=c++_shared -DCMAKE_FIND_ROOT_PATH:PATH=${QTDIR} -DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON -DQT_HOST_PATH:PATH=${QTBASE}/gcc_64 -DANDROID_SDK_ROOT:PATH=${ANDROID_HOME} -DQT_ANDROID_BUILD_ALL_ABIS:BOOL=ON -DQT_ANDROID_ABIS:STRING=\"arm64-v8a;armeabi-v7a;x86;x86_64\""
|
356 |
andreas |
192 |
fi
|
352 |
andreas |
193 |
|
356 |
andreas |
194 |
${CMAKE} -S ${CURDIR} -B ${CURDIR}/${BUILDDIR} \
|
|
|
195 |
-DCMAKE_GENERATOR:STRING=Ninja ${_dbg} \
|
451 |
andreas |
196 |
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=${CURDIR}/${BUILDDIR}/src/.qtc/package-manager/auto-setup.cmake \
|
356 |
andreas |
197 |
-DQT_QMAKE_EXECUTABLE:FILEPATH=${QMAKE} \
|
|
|
198 |
-DCMAKE_PREFIX_PATH:PATH=${QTDIR} \
|
381 |
andreas |
199 |
-DCMAKE_C_COMPILER:FILEPATH=${C_COMPILER_CLANG} \
|
|
|
200 |
-DCMAKE_CXX_COMPILER:FILEPATH=${CXX_COMPILER_CLANG} \
|
356 |
andreas |
201 |
-DANDROID_PLATFORM:STRING=${ANDROID_PLATFORM} \
|
|
|
202 |
-DANDROID_NDK:PATH=${ANDROID_NDK_ROOT} \
|
|
|
203 |
-DCMAKE_TOOLCHAIN_FILE:FILEPATH=${ANDROID_TOOLCHAIN} \
|
|
|
204 |
-DANDROID_USE_LEGACY_TOOLCHAIN_FILE:BOOL=OFF \
|
|
|
205 |
-DANDROID_ABI:STRING=${QT_ABI} \
|
|
|
206 |
-DANDROID_STL:STRING=c++_shared \
|
|
|
207 |
-DCMAKE_FIND_ROOT_PATH:PATH=${QTDIR} \
|
|
|
208 |
-DQT_NO_GLOBAL_APK_TARGET_PART_OF_ALL:BOOL=ON \
|
381 |
andreas |
209 |
-DQT_HOST_PATH:PATH=${QTBASE}/${QT_HOST} \
|
356 |
andreas |
210 |
-DANDROID_SDK_ROOT:PATH=${ANDROID_HOME} \
|
|
|
211 |
-DQT_ANDROID_BUILD_ALL_ABIS:BOOL=ON \
|
364 |
andreas |
212 |
-DQT_ANDROID_ABIS:STRING="arm64-v8a;armeabi-v7a;x86;x86_64" \
|
356 |
andreas |
213 |
2>&1 | tee -a ${LOGFILE}
|
|
|
214 |
|
352 |
andreas |
215 |
if [ $? -ne 0 ]
|
|
|
216 |
then
|
|
|
217 |
log "Error creating a Makefile!"
|
|
|
218 |
exit 1
|
|
|
219 |
fi
|
|
|
220 |
else
|
354 |
andreas |
221 |
log "Changing into build directory \"$BUILDDIR\" ..."
|
|
|
222 |
cd "$BUILDDIR"
|
352 |
andreas |
223 |
fi
|
|
|
224 |
|
362 |
andreas |
225 |
log "Compiling the source and using ${CPUS} cpus..."
|
352 |
andreas |
226 |
|
356 |
andreas |
227 |
if [ $OPT_VERBOSE -eq 1 ]
|
|
|
228 |
then
|
|
|
229 |
echo "${CMAKE} --build "${CURDIR}/${BUILDDIR}" --target all -j${CPUS}"
|
|
|
230 |
fi
|
|
|
231 |
|
|
|
232 |
${CMAKE} --build "${CURDIR}/${BUILDDIR}" --target all -j${CPUS} 2>&1 | tee -a ${LOGFILE}
|
|
|
233 |
|
352 |
andreas |
234 |
if [ $? -ne 0 ]
|
|
|
235 |
then
|
|
|
236 |
log "Error compiling the code!"
|
|
|
237 |
exit 1
|
|
|
238 |
fi
|
|
|
239 |
|
|
|
240 |
log "Creating an Android binary (apk) file ..."
|
|
|
241 |
|
|
|
242 |
_install=""
|
|
|
243 |
_pass=""
|
|
|
244 |
|
|
|
245 |
if [ $OPT_DEPLOY -eq 1 ]
|
|
|
246 |
then
|
|
|
247 |
_install="--reinstall"
|
|
|
248 |
fi
|
|
|
249 |
|
353 |
andreas |
250 |
if [ $OPT_DEBUG -eq 0 ] && [ $OPT_SIGN -eq 1 ]
|
352 |
andreas |
251 |
then
|
|
|
252 |
if [ -f "$HOME/.keypass" ]
|
|
|
253 |
then
|
353 |
andreas |
254 |
_perm=`stat -c %a "$HOME/.keypass"`
|
|
|
255 |
|
|
|
256 |
if [ $_perm -ne 400 ] && [ $_perm -ne 600 ]
|
|
|
257 |
then
|
|
|
258 |
echo "The file \"$HOME/.keypass\" must have permission 0400 or 0600. Ignoring file!"
|
|
|
259 |
read -s -p "Password of Android keystore: " _pass
|
|
|
260 |
else
|
|
|
261 |
_pass=`cat $HOME/.keypass`
|
|
|
262 |
fi
|
352 |
andreas |
263 |
else
|
|
|
264 |
read -s -p "Password of Android keystore: " _pass
|
|
|
265 |
fi
|
|
|
266 |
|
451 |
andreas |
267 |
_verbose=""
|
|
|
268 |
|
356 |
andreas |
269 |
if [ $OPT_VERBOSE -eq 1 ]
|
|
|
270 |
then
|
451 |
andreas |
271 |
echo "${ANDROIDDEPLOYQT} --input ${CURDIR}/${BUILDDIR}/src/android-tpanel-deployment-settings.json --output ${CURDIR}/${BUILDDIR}/src/android-build --android-platform ${ANDROID_PLATFORM} --jdk ${JAVA_HOME} --gradle --release --verbose --sign ${KEYSTORE} ${KEYALIAS} --storepass "${_pass}" ${_install}"
|
|
|
272 |
_verbose="--verbose"
|
356 |
andreas |
273 |
fi
|
|
|
274 |
|
451 |
andreas |
275 |
${ANDROIDDEPLOYQT} --input ${CURDIR}/${BUILDDIR}/src/android-tpanel-deployment-settings.json \
|
|
|
276 |
--output ${CURDIR}/${BUILDDIR}/src/android-build \
|
356 |
andreas |
277 |
--android-platform ${ANDROID_PLATFORM} \
|
|
|
278 |
--jdk ${JAVA_HOME} \
|
451 |
andreas |
279 |
--gradle --release ${_verbose} \
|
356 |
andreas |
280 |
--sign ${KEYSTORE} ${KEYALIAS} \
|
|
|
281 |
--storepass "${_pass}" ${_install} 2>&1 | tee -a ${LOGFILE}
|
352 |
andreas |
282 |
else
|
451 |
andreas |
283 |
_verbose=""
|
|
|
284 |
|
356 |
andreas |
285 |
if [ $OPT_VERBOSE -eq 1 ]
|
353 |
andreas |
286 |
then
|
451 |
andreas |
287 |
echo "${ANDROIDDEPLOYQT} --input ${CURDIR}/${BUILDDIR}/src/android-tpanel-deployment-settings.json --output ${CURDIR}/${BUILDDIR}/src/android-build --android-platform ${ANDROID_PLATFORM} --jdk ${JAVA_HOME} --gradle --verbose ${_install}"
|
|
|
288 |
_verbose="--verbose"
|
353 |
andreas |
289 |
fi
|
|
|
290 |
|
451 |
andreas |
291 |
${ANDROIDDEPLOYQT} --input ${CURDIR}/${BUILDDIR}/src/android-tpanel-deployment-settings.json \
|
|
|
292 |
--output ${CURDIR}/${BUILDDIR}/src/android-build \
|
356 |
andreas |
293 |
--android-platform ${ANDROID_PLATFORM} \
|
|
|
294 |
--jdk ${JAVA_HOME} \
|
451 |
andreas |
295 |
--gradle ${_verbose} ${_install} 2>&1 | tee -a ${LOGFILE}
|
352 |
andreas |
296 |
fi
|
|
|
297 |
|
|
|
298 |
if [ $? -ne 0 ]
|
|
|
299 |
then
|
|
|
300 |
log "Error building an Android binary file!"
|
|
|
301 |
exit 1
|
|
|
302 |
fi
|
|
|
303 |
|
|
|
304 |
exit 0
|