mirror of
https://github.com/opengapps/opengapps.git
synced 2025-11-08 07:54:31 +00:00
6c209510c9
Signed-off-by: Ilya Danilkin <nezorflame@gmail.com>
306 lines
11 KiB
Bash
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"
|
|
}
|