Files
opengapps/scripts/inc.packagetarget.sh
2020-07-14 14:36:29 +02:00

306 lines
11 KiB
Bash

#This file is part of The Open GApps script of @mfonville.
#
# The Open GApps scripts are free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# These scripts are distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
alignbuild() {
echo "Zipaligning APKs..."
for f in $(find "$build" -name '*.apk'); do
# skip zipaligning for APKs signed with apksigner, because zipalign strips its signature
# see https://developer.android.com/studio/command-line/zipalign
if timeout 1m apksigner verify --verbose --print-certs "$f" 2>/dev/null | grep -q "(JAR signing): false"; then
continue
fi
mv "$f" "$f.orig"
zopfli=""
if [ -n "$ZIPALIGNRECOMPRESS" ]; then
zopfli="-z"
fi
zipalign -f -p $zopfli 4 "$f.orig" "$f"
rm "$f.orig"
done
}
commonscripts() {
copy "$SCRIPTS/bkup_tail.sh" "$build"
EXTRACTFILES="$EXTRACTFILES bkup_tail.sh"
install -d "$build/META-INF/com/google/android"
echo "# Dummy file; update-binary is a shell script.">"$build/META-INF/com/google/android/updater-script"
makegappsremovetxt "gapps-remove.txt"
makegprop "g.prop"
makeinstallersh "installer.sh"
bundlebusybox
if [ "$VARIANT" = "aroma" ]; then
COMPRESSION="xz" # Aroma does not play nice with the busybox built-in decompressors
bundlexzdec
fi
bundletar
bundleunzip
bundlezip
makeupdatebinary "META-INF/com/google/android/update-binary" "busybox" "installer.sh" "$EXTRACTFILES" "$CHMODXFILES" # execute as last so that $EXTRACTFILES and $CHMODXFILES are complete
bundlelicense #optionally add a LICENSE file to the package
}
aromascripts() {
aromaupdatebinary
makearomaconfig
install -d "$build/META-INF/com/google/android/aroma" #not necessary, but is safe
copy "$SCRIPTS/aroma-resources/fonts" "$build/META-INF/com/google/android/aroma/fonts"
copy "$SCRIPTS/aroma-resources/icons" "$build/META-INF/com/google/android/aroma/icons"
copy "$SCRIPTS/aroma-resources/langs" "$build/META-INF/com/google/android/aroma/langs"
copy "$SCRIPTS/aroma-resources/scripts" "$build/META-INF/com/google/android/aroma/scripts"
copy "$SCRIPTS/aroma-resources/themes" "$build/META-INF/com/google/android/aroma/themes"
copy "$SCRIPTS/aroma-resources/ttf" "$build/META-INF/com/google/android/aroma/ttf"
copy "$SCRIPTS/aroma-resources/open.png" "$build/META-INF/com/google/android/aroma"
}
aromaupdatebinary() {
if [ -f "$build/META-INF/com/google/android/update-binary-installer" ]
then
rm "$build/META-INF/com/google/android/update-binary-installer"
fi
mv "$build/META-INF/com/google/android/update-binary" "$build/META-INF/com/google/android/update-binary-installer"
copy "$SCRIPTS/aroma-resources/update-binary" "$build/META-INF/com/google/android/update-binary"
}
bundlebusybox() {
case "$ARCH" in #Include busybox binary
arm*) busyboxbin="busybox-arm";;
x86*) busyboxbin="busybox-x86";;
esac
copy "$SCRIPTS/busybox-resources/$busyboxbin" "$build/$busyboxbin"
EXTRACTFILES="$EXTRACTFILES $busyboxbin"
CHMODXFILES="$CHMODXFILES $busyboxbin"
}
bundlexzdec() {
case "$ARCH" in #Include xzdec binary
arm*) xzdecbin="xzdec-arm";;
x86*) xzdecbin="xzdec-x86";;
esac
copy "$SCRIPTS/xz-resources/$xzdecbin" "$build/$xzdecbin"
EXTRACTFILES="$EXTRACTFILES $xzdecbin"
CHMODXFILES="$CHMODXFILES $xzdecbin"
}
bundletar() {
case "$ARCH" in #Include tar binary
arm*) tarbin="tar-arm";;
x86*) tarbin="tar-x86";;
esac
copy "$SCRIPTS/tar-resources/$tarbin" "$build/$tarbin"
EXTRACTFILES="$EXTRACTFILES $tarbin"
CHMODXFILES="$CHMODXFILES $tarbin"
}
bundleunzip() {
case "$ARCH" in #Include unzip binary
arm*) unzipbin="unzip-arm";;
x86*) unzipbin="unzip-x86";;
esac
copy "$SCRIPTS/infozip-resources/$unzipbin" "$build/$unzipbin"
EXTRACTFILES="$EXTRACTFILES $unzipbin"
CHMODXFILES="$CHMODXFILES $unzipbin"
}
bundlezip() {
case "$ARCH" in #Include zip binary
arm*) zipbin="zip-arm";;
x86*) zipbin="zip-x86";;
esac
copy "$SCRIPTS/infozip-resources/$zipbin" "$build/$zipbin"
EXTRACTFILES="$EXTRACTFILES $zipbin"
CHMODXFILES="$CHMODXFILES $zipbin"
}
bundlelicense() {
if [ -n "$OPENGAPPSLICENSEFILE" ] && [ -e "$OPENGAPPSLICENSEFILE" ]; then
echo "INFO: using $OPENGAPPSLICENSEFILE as LICENSE file"
copy "$OPENGAPPSLICENSEFILE" "$build/LICENSE"
elif [ -e "LICENSE" ]; then
copy "LICENSE" "$build/LICENSE"
fi
}
compressapp() {
compression="$COMPRESSION"
compressioncompathack "$2"
case "$compression" in
xz) checktools xz
csuf=".xz"
compress() {
XZ_OPT='-9e -C crc32 -T0' tar --remove-files -cJf "$1.tar.xz" "$1"
}
;;
lz) checktools lzip
csuf=".lz"
compress() {
tar --remove-files -cf - "$1" | lzip -m 273 -s 128MiB -o "$1.tar" #.lz is added by lzip; specify the compression parameters manually to get good results
}
;;
none)
csuf=""
compress() {
tar --remove-files -cf "$1.tar" "$1"
}
;;
*) echo "ERROR: Unsupported compression method! Aborting..."; exit 1;;
esac
hash="$(tar -cf - "$2" | md5sum | cut -f1 -d' ')"
if [ -f "$CACHE/$hash.tar$csuf" ]; then #we have this compressed app in cache
echo "Fetching $1$2 from the cache"
rm -rf "$2" #remove the folder
touch -a "$CACHE/$hash.tar$csuf" #mark this cache object as recently accessed
cp "$CACHE/$hash.tar$csuf" "$2.tar$csuf" #copy from the cache
else
if [ -n "$3" ] && [ -n "$4" ]; then
echo "Thread: $3 | FreeRAM: $4 | Compressing Package: $1$2"
else
echo "Compressing Package: $1$2"
fi
compress "$2"
if [ $? != 0 ]; then
echo "ERROR: compressing $1$2 failed, aborting."
exit 1
fi
cp "$2.tar$csuf" "$CACHE/$hash.tar$csuf" #copy into the cache
fi
touch -d "2008-02-28 21:33:46.000000000 +0100" "$2.tar$csuf"
sync
}
createzip() {
echo "INFO: Total size uncompressed applications: $(du -hs "$build" | awk '{ print $1 }')"
find "$build" -exec touch -d "2008-02-28 21:33:46.000000000 +0100" {} \;
cd "$build"
MEMORY_MIN=800000 # Minimum of RAM required (for single thread) on x86_64 machine based on XZ's documentation (which is a comparable algorithm to lzip)
THREADS="$(($(nproc)))"
if ! grep -q "MemAvailable:" /proc/meminfo; then
MEMORY=0
else
MEMORY="$(($(grep "MemAvailable:" /proc/meminfo | awk '{print $2}') / 4))"
fi
if [ $MEMORY = 0 ] || [ $MEMORY -lt $MEMORY_MIN ]; then
echo "WARNING: Can't establish if enough free memory is available: parallel compression mode disabled."
MEMORY=0
THREADS=1
fi
pidlist=""
for d in $(ls -d */ | grep -v "META-INF"); do #notice that d will end with a slash, ls is safe here because there are no directories with spaces
cd "$build/$d"
for f in $(ls); do # ls is safe here because there are no directories with spaces
apk="$(find "$f/" -name "*.apk" -type f | head -n 1)" # we assume the classes*.dex are around the same size in all APK variants
if [ -f "$apk" ] && ! (unzip -ql "$apk" | grep -q "META-INF/MANIFEST.MF" && unzip -p "$apk" "META-INF/MANIFEST.MF" | grep -q "$classes.dex"); then
printf "%s\t%s\t%d\n" "$f" "odex" "$(($(echo "$(unzip -ql "$apk" "classes*.dex" | tail -n 1)" | awk '{print $1"*(("$2"/2)+2)/1024"}')))" >> "$build/app_sizes.txt" # estimation heuristic: size-dexfiles * ((#-dexfiles/2)+2); bytes -> KiB
fi
for g in $(ls "$f"); do
foldersize="$(du -ck "$f/$g/" | tail -n1 | awk '{ print $1 }')"
printf "%s\t%s\t%d\n" "$f" "$g" "$foldersize" >> "$build/app_sizes.txt"
done
# Use parallel mode only if we have memory metric and have more than 1 CPU
if [ $THREADS -gt 1 ] && [ $MEMORY -gt 0 ]; then
# Wait if we reached RAM or THREADS limit
tries=0; while true; do
# Count still running compressapp instances
threads=0; for p in $pidlist; do test -d /proc/$p && threads=$((threads+1)); done
memory=$(grep "MemAvailable:" /proc/meminfo | awk '{print $2}')
# Check if reached our limits (3/4 of RAM or THREADS), wait if we are
if [ $threads -ge $THREADS ] || [ $MEMORY -ge $memory ] || [ $memory -lt $MEMORY_MIN ]; then
sleep 5
# Update tries counter
tries=$((tries+1))
# If we are trying for more then 180*5 seconds, we bail out (in case machine is to low on memory or CPU we won't run forever!)
if [ $tries -gt 180 ]; then
echo "ERROR: Seems like this machine is too slow or was unable to collect enought usable memory for compression, aborting."
exit 1
fi
continue
else
break
fi
done
# Spawn compressapp thread
compressapp "$d" "$f" "$threads" "$memory" &
# Collect resulting PID
pidlist="$pidlist $!"
else
# Call compressapp
compressapp "$d" "$f"
fi
done
done
for p in $pidlist; do wait $p; done
echo "INFO: Total size compressed applications: $(du -hs "$build" | awk '{ print $1 }')"
unsignedzip="$BUILD/$ARCH/$API/$VARIANT.zip"
if [ -n "$OUTFILE" ]; then
signedzip="$( eval "echo \"$OUTFILE\"")"
else
signedzip="$OUTFOLDER/open_gapps-$ARCH-$PLATFORM-$VARIANT-$DATE-UNOFFICIAL.zip"
fi
if [ -f "$unsignedzip" ]; then
rm "$unsignedzip"
fi
cd "$build"
echo "Packaging and signing $signedzip..."
zip -q -r -D -X -$ZIPCOMPRESSIONLEVEL "$unsignedzip" ./* #don't doublequote zipfolders, contains multiple (safe) arguments
cd "$TOP"
signzip
}
signzip() {
install -d "$(dirname "$signedzip")"
if [ -f "$signedzip" ]
then
rm "$signedzip"
fi
if [ -z "$CERTIFICATEFILE" ] || [ ! -e "$CERTIFICATEFILE" ]; then
unset CERTIFICATEFILE
else
echo "INFO: using $CERTIFICATEFILE as certificate file"
fi
if [ -z "$KEYFILE" ] || [ ! -e "$KEYFILE" ]; then
unset KEYFILE
else
echo "INFO: using $KEYFILE as cryptographic key file"
fi
if [ -z "$TMPSIGNDIR" ] || [ ! -d "$TMPSIGNDIR" ]; then
unset TMPSIGNCMD
else
TMPSIGNCMD="-Djava.io.tmpdir=$TMPSIGNDIR"
echo "INFO: using $TMPSIGNDIR as temporary directory to sign files"
fi
if java $TMPSIGNCMD -jar "$SCRIPTS/zipsigner-resources/zipsigner-"*.jar $CERTIFICATEFILE $KEYFILE "$unsignedzip" "$signedzip"; then #if signing did succeed
rm "$unsignedzip"
else
rm "$signedzip"
echo "ERROR: Creating Flashable ZIP-file failed, unsigned file can be found at $unsignedzip"
exit 1
fi
echo "SUCCESS: Built Open GApps variation $VARIANT with API $API level for $ARCH as $signedzip"
}