mirror of
https://github.com/opengapps/opengapps.git
synced 2025-11-08 07:54:31 +00:00
393 lines
14 KiB
Bash
Executable File
393 lines
14 KiB
Bash
Executable File
#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.
|
|
#
|
|
|
|
preparebuildarea() {
|
|
build="$BUILD/$ARCH/$API/$VARIANT"
|
|
echo "Cleaning build area: $build"
|
|
rm -rf "$build"
|
|
install -d "$build"
|
|
install -d "$CACHE"
|
|
logfile=""
|
|
if [ -n "$VERSIONLOG" ]; then
|
|
logfile="$(eval "echo \"$VERSIONLOG\"")"
|
|
install -d "$(dirname "$logfile")"
|
|
printf "%-6s%3s| %-61s| %-50s| %s\n-----------------------------------------------------------------------------------------------------------------------------------\n" "Arch." "API" "Application / File / Folder" "Version Name" "DPIs" > "$logfile"
|
|
fi
|
|
}
|
|
|
|
copy() {
|
|
if [ -d "$1" ]; then
|
|
for f in $1/*; do
|
|
copy "$f" "$2/$(basename "$f")"
|
|
done
|
|
fi
|
|
if [ -f "$1" ]; then
|
|
install -D -p "$1" "$2"
|
|
fi
|
|
}
|
|
|
|
buildfile() {
|
|
if [ -z "$4" ]; then usearch="$ARCH"
|
|
else usearch="$4"; fi #allows for an override
|
|
|
|
case "$usearch" in
|
|
all) targetarch="common";; # technically with our currrent APKs-set, every that is 'all' is de-facto also 'common'
|
|
*) targetarch="$usearch";;
|
|
esac
|
|
|
|
if [ -e "$SOURCES/$usearch/$1" ]; then #check if directory or file exists
|
|
if [ -d "$SOURCES/$usearch/$1" ]; then #if we are handling a directory
|
|
targetdir="$build/$2-$targetarch/$3/$1"
|
|
else
|
|
targetdir="$build/$2-$targetarch/$3/$(dirname "$1")"
|
|
fi
|
|
install -d "$targetdir"
|
|
printf "%6s %s\n" "$usearch" "$1"
|
|
if [ -n "$logfile" ]; then
|
|
printf "%6s | %-s\n" "$usearch" "$1">> "$logfile"
|
|
fi
|
|
copy "$SOURCES/$usearch/$1" "$targetdir" #if we have a file specific to this architecture
|
|
# rename etc/sysconfig/google_go.xml to etc/sysconfig/google.xml
|
|
if [ "$1" = "etc/sysconfig/google_go.xml" ]; then
|
|
mv "$targetdir/google_go.xml" "$targetdir/google.xml"
|
|
fi
|
|
else
|
|
get_fallback_arch "$usearch"
|
|
if [ "$usearch" != "$fallback_arch" ]; then
|
|
buildfile "$1" "$2" "$3" "$fallback_arch"
|
|
else
|
|
echo "ERROR: No fallback available. Failed to build file $1"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
buildframework() {
|
|
frameworkname="$1"
|
|
ziplocation="$2"
|
|
targetlocation="$3"
|
|
if [ -z "$4" ]; then usearch="$ARCH"
|
|
else usearch="$4"; fi #allows for an override
|
|
|
|
case "$usearch" in
|
|
all) targetarch="common";; # technically with our currrent APKs-set, every that is 'all' is de-facto also 'common'
|
|
*) targetarch="$usearch";;
|
|
esac
|
|
|
|
if getframeworkforapi "$frameworkname" "$usearch" "$API"; then
|
|
printf "%6s-%s %s\n" "$usearch" "$api" "$frameworkname"
|
|
if [ -n "$logfile" ]; then
|
|
printf "%6s-%s| %-s\n" "$usearch" "$api" "$frameworkname" >> "$logfile"
|
|
fi
|
|
install -D -p "$sourceframework" "$build/$ziplocation-$targetarch/$targetlocation/$targetframework"
|
|
else
|
|
get_fallback_arch "$usearch"
|
|
if [ "$usearch" != "$fallback_arch" ]; then
|
|
buildframework "$frameworkname" "$ziplocation" "$targetlocation" "$fallback_arch"
|
|
else
|
|
echo "ERROR: No fallback available. Failed to build framework $frameworkname"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
buildsystemlib() {
|
|
libname="$1"
|
|
ziplocation="$2"
|
|
targetlocation="$3"
|
|
if [ -z "$4" ]; then usearch="$ARCH"
|
|
else usearch="$4"; fi #allows for an override
|
|
|
|
fallback=""
|
|
case "$libname" in
|
|
*+fallback) libname="$(echo "$libname" | sed 's/+fallback//')"
|
|
fallback="true";;
|
|
esac
|
|
|
|
case "$usearch" in
|
|
all) targetarch="common";; # technically with our currrent APKs-set, every that is 'all' is de-facto also 'common'
|
|
*) targetarch="$usearch";;
|
|
esac
|
|
|
|
if getsystemlibforapi "$libname" "$usearch" "$API"; then
|
|
printf "%6s-%s %s\n" "$usearch" "$api" "$libname"
|
|
if [ -n "$logfile" ]; then
|
|
printf "%6s-%s| %-s\n" "$usearch" "$api" "$libname" >> "$logfile"
|
|
fi
|
|
install -D -p "$sourcelib" "$build/$ziplocation-lib-$targetarch/$targetlocation/$targetlib"
|
|
else
|
|
fallback="true"
|
|
fi
|
|
if [ -n "$fallback" ]; then
|
|
get_fallback_arch "$usearch"
|
|
if [ "$usearch" != "$fallback_arch" ]; then
|
|
buildsystemlib "$libname" "$ziplocation" "$targetlocation" "$fallback_arch"
|
|
else
|
|
echo "ERROR: No fallback available. Failed to build lib $libname"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
getpathsystemlib(){
|
|
libname="$1"
|
|
if [ -z "$2" ]; then usearch="$ARCH"
|
|
else usearch="$2"; fi #allows for an override
|
|
|
|
fallback=""
|
|
case "$libname" in
|
|
*+fallback) libname="$(echo "$libname" | sed 's/+fallback//')"
|
|
fallback="true";;
|
|
esac
|
|
|
|
if getsystemlibforapi "$libname" "$usearch" "$API"; then
|
|
systemlibpath="$targetlib $systemlibpath"
|
|
else
|
|
fallback="true"
|
|
fi
|
|
|
|
if [ -n "$fallback" ]; then
|
|
get_fallback_arch "$usearch"
|
|
if [ "$usearch" != "$fallback_arch" ]; then
|
|
getpathsystemlib "$libname" "$fallback_arch"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
buildapp() {
|
|
package="$1"
|
|
usemaxapi="$2"
|
|
ziplocation="$3"
|
|
targetlocation="$4"
|
|
if [ -z "$5" ]; then usearch="$ARCH"
|
|
else usearch="$5"; fi #allows for an override
|
|
packagedirsuffix="$6"
|
|
|
|
minapihack #Some packages need a minimal api level to maintain compatibility with the OS
|
|
|
|
if getapksforapi "$package" "$usearch" "$usemaxapi" "$useminapi" "$packagedirsuffix"; then
|
|
baseversionname=""
|
|
for dpivariant in $(echo "$sourceapks" | tr ' ' ''); do #we replace the spaces with a special char to survive the for-loop
|
|
dpivariant="$(echo "$dpivariant" | tr '' ' ')" #and we place the spaces back again
|
|
getapkproperties "$dpivariant" #get versionname
|
|
versionname="$(printf "%s" "$versionname" | cut -d ' ' -f 1)" #always cut off everything in the versionname after the space since that indicates a part that is ALWAYS at minimum dpi-specific
|
|
versionnamehack #Some packages have a different versionname, when the actual version is equal
|
|
systemlibhack #Some packages want their libs installed as system libs
|
|
if [ "$API" -le "19" ] || [ "$systemlib" = "true" ]; then
|
|
liblocation="$ziplocation-$usearch/common"
|
|
else
|
|
liblocation="$ziplocation-$usearch/common/$targetlocation"
|
|
fi
|
|
|
|
if [ -z "$baseversionname" ]; then
|
|
baseversionname=$versionname
|
|
buildlib "$dpivariant" "$liblocation" "$usearch" #Use the libs from this baseversion
|
|
printf "%6s-%-2s %-61s %50s" "$usearch" "$api" "$1" "$baseversionname" # use $1 instead of $package to show the foldername packagename instead of the getapkproperties-name to get the setupwizard name right
|
|
if [ -n "$logfile" ]; then
|
|
printf "%6s-%-2s| %-61s| %-50s|" "$usearch" "$api" "$1" "$baseversionname" >> "$logfile"
|
|
fi
|
|
fi
|
|
if [ "$versionname" = "$baseversionname" ]; then
|
|
density=$(basename "$(dirname "$dpivariant")")
|
|
buildapk "$dpivariant" "$ziplocation-$usearch/$density/$targetlocation"
|
|
printf " %s" "$density"
|
|
if [ -n "$logfile" ]; then
|
|
printf " %s" "$density" >> "$logfile"
|
|
fi
|
|
echo "$ziplocation-$usearch/$density/" >> "$build/app_densities.txt"
|
|
fi
|
|
done
|
|
printf "\n"
|
|
if [ -n "$logfile" ]; then
|
|
printf "\n" >> "$logfile"
|
|
fi
|
|
else
|
|
get_fallback_arch "$usearch"
|
|
if [ "$usearch" != "$fallback_arch" ]; then
|
|
buildapp "$package" "$usemaxapi" "$ziplocation" "$targetlocation" "$fallback_arch" "$packagedirsuffix"
|
|
else
|
|
echo "ERROR: No fallback available. Failed to build package $package"
|
|
exit 1
|
|
fi
|
|
fi
|
|
}
|
|
|
|
getapksforapi() {
|
|
#this functions finds the highest available acceptable apk for a given api and architecture
|
|
#$1 package, $2 arch, $3 api, $4 minapi, $5 packagedirsuffix
|
|
if [ -z "$4" ]; then minapi="0"
|
|
else minapi="$4"; fi #specify minimal api
|
|
|
|
if ! stat --printf='' "$SOURCES/$2/"*"app$5/$1" 2>/dev/null; then
|
|
return 1 #appname is not there, error!?
|
|
fi
|
|
|
|
sourceapks=""
|
|
OLDIFS="$IFS"
|
|
IFS="
|
|
" #We set IFS to newline here so that spaces can survive the for loop
|
|
#sed copies filename to the beginning, to compare version, and later we remove it with cut
|
|
maxsdkerrorapi=""
|
|
for foundapk in $(find $SOURCES/$2/*app$5/$1 -iname '*.apk' 2>/dev/null| sed 's!.*/\(.*\)!\1/&!' | sort -r -n -t/ -k1,1 | cut -d/ -f2-); do
|
|
foundpath="$(dirname "$(dirname "$foundapk")")"
|
|
api="$(basename "$foundpath")"
|
|
if [ "$maxsdkerrorapi" = "$api" ]; then
|
|
continue #if we already know that this api hit the maxsdk error, do not try it again
|
|
fi
|
|
if [ "$api" -le "$3" ] && [ "$api" -ge "$minapi" ]; then
|
|
#We need to keep them sorted
|
|
sourceapks="$(find "$foundpath" -iname '*.apk' | sed 's!.*/\(.*\)!\1/&!' | sort -r -n -t/ -k1,1 | cut -d/ -f2-)"
|
|
for maxsdkapk in $sourceapks; do
|
|
maxsdk="$(aapt dump badging "$maxsdkapk" 2>/dev/null | grep -a "maxSdkVersion:" | sed 's/maxSdkVersion://' | sed "s/'//g")"
|
|
if [ -n "$maxsdk" ] && [ "$maxsdk" -lt "$3" ]; then
|
|
echo "WARNING: Newest APK found is incompatible with API level $3 for package $1 on $2, maxSdk: $maxsdk, falling back to higher SDK"
|
|
maxsdkerrorapi="$api"
|
|
continue 2
|
|
fi
|
|
break
|
|
done
|
|
break
|
|
fi
|
|
done
|
|
IFS="$OLDIFS"
|
|
if [ -z "$sourceapks" ]; then
|
|
echo "WARNING: No APK found compatible with API level $3 for package $1 on $2, lowest found: $api"
|
|
return 1 #error
|
|
fi
|
|
#$sourceapks and $api have the useful returnvalues
|
|
return 0 #return that it was a success
|
|
}
|
|
|
|
getframeworkforapi() {
|
|
#this functions finds the highest available acceptable framework for a given api and architecture
|
|
#$1 frameworkname, $2 arch, $3 api
|
|
sourceframework=""
|
|
OLDIFS="$IFS"
|
|
IFS="
|
|
" #We set IFS to newline here so that spaces can survive the for loop
|
|
for foundframework in $(find $SOURCES/$2/framework/ -iname "$1" 2>/dev/null| sort -r); do
|
|
api="$(basename "$(dirname "$foundframework")")"
|
|
if [ "$api" -le "$3" ]; then
|
|
sourceframework="$foundframework"
|
|
break
|
|
fi
|
|
done
|
|
IFS="$OLDIFS"
|
|
if [ -z "$sourceframework" ]; then
|
|
#echo "WARNING: No framework found compatible with API level $3 for framework $1 on $2, lowest found: $api"
|
|
return 1 #error
|
|
fi
|
|
apiframeworkpath="$(echo "$sourceframework" | awk -F'/' '{print $(NF-1)}')" # is api number
|
|
targetframework="$(echo "$sourceframework" | sed "s:^$SOURCES/$2/::" | sed "s:/$apiframeworkpath/:/:g")" # framework/frameworkname.jar
|
|
#$sourceframework, $targetframework and $api have the useful returnvalues
|
|
return 0 #return that it was a success
|
|
}
|
|
|
|
getsystemlibforapi() {
|
|
#this functions finds the highest available acceptable lib for a given api and architecture
|
|
#$1 libname, $2 arch, $3 api
|
|
sourcelib=""
|
|
OLDIFS="$IFS"
|
|
IFS="
|
|
" #We set IFS to newline here so that spaces can survive the for loop
|
|
for foundlib in $(find $SOURCES/$2/lib*/ $SOURCES/$2/vendor/lib*/ -iname "$1" 2>/dev/null| sort -r); do
|
|
api="$(basename "$(dirname "$foundlib")")"
|
|
if [ "$api" -le "$3" ]; then
|
|
sourcelib="$foundlib"
|
|
break
|
|
fi
|
|
done
|
|
IFS="$OLDIFS"
|
|
if [ -z "$sourcelib" ]; then
|
|
#echo "WARNING: No lib found compatible with API level $3 for lib $1 on $2, lowest found: $api"
|
|
return 1 #error
|
|
fi
|
|
apilibpath="$(echo "$sourcelib" | awk -F'/' '{print $(NF-1)}')" # is api number
|
|
targetlib="$(echo "$sourcelib" | sed "s:^$SOURCES/$2/::" | sed "s:/$apilibpath/:/:g")" # lib/libname.so
|
|
#$sourcelib, $targetlib and $api have the useful returnvalues
|
|
return 0 #return that it was a success
|
|
}
|
|
|
|
buildapk() {
|
|
sourceapk="$1"
|
|
targetdir="$build/$2"
|
|
targetapk="$targetdir/$(basename "$targetdir").apk"
|
|
if [ "$API" -le "19" ]; then #We will do this as long as we support KitKat
|
|
targetapk="$targetdir.apk"
|
|
targetdir="$(dirname "$targetapk")"
|
|
fi
|
|
if [ -f "$targetapk" ]; then
|
|
rm "$targetapk"
|
|
fi
|
|
|
|
install -D "$sourceapk" "$targetapk"
|
|
|
|
if (unzip -v "$targetapk" | grep "lib/" | grep -qv "Stored"); then #check if there are compressed libs present
|
|
if [ "$API" -lt "23" ]; then #only if pre-Marshmallow
|
|
unzip -Z -1 "$targetapk" | grep "lib/" | grep -v "/crazy." | xargs zip -q -d "$targetapk" #delete all libs, except crazy-linked
|
|
else #Marshmallow and above needs libs to be stored without compression within the APK
|
|
unzip -qqq -o "$targetapk" -d "$targetdir" "lib/*"
|
|
zip -q -d "$targetapk" "lib/*" #delete all libs
|
|
(
|
|
cd "$targetdir"
|
|
zip -q -r -D -Z store -b "$targetdir" "$targetapk" "lib/" #no parameter for output and mode, we are in 'add and update existing' mode which is default. Lib files have to be stored without compression.
|
|
)
|
|
rm -rf "$targetdir/lib/"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
buildlib() {
|
|
sourceapk="$1"
|
|
targetdir="$build/$2"
|
|
apkarch="$3"
|
|
libsearchpath="lib/*" #default that should never happen: all libs
|
|
if [ "$apkarch" = "arm" ]; then
|
|
libsearchpath="lib/armeabi*/*" #mind the wildcard
|
|
libfallbacksearchpath=""
|
|
elif [ "$apkarch" = "arm64" ]; then
|
|
libsearchpath="lib/arm64*/*" #mind the wildcard
|
|
libfallbacksearchpath="lib/armeabi*/*" #mind the wildcard
|
|
elif [ "$apkarch" = "x86" ]; then
|
|
libsearchpath="lib/x86/*"
|
|
libfallbacksearchpath=""
|
|
elif [ "$apkarch" = "x86_64" ]; then
|
|
libsearchpath="lib/x86_64/*"
|
|
libfallbacksearchpath="lib/x86/*"
|
|
elif [ "$apkarch" = "mips" ]; then
|
|
libsearchpath="lib/mips/*"
|
|
libfallbacksearchpath=""
|
|
elif [ "$apkarch" = "mips64" ]; then
|
|
libsearchpath="lib/mips64/*"
|
|
libfallbacksearchpath="lib/mips/*"
|
|
fi
|
|
get_fallback_arch "$apkarch"
|
|
if [ "$(basename "$targetdir")" = "common" ]; then #if we are installing systemwide libs
|
|
libpath="$LIBFOLDER"
|
|
fallbacklibpath="lib"
|
|
else #Lollipop-style libs bundled in the APK's folder
|
|
libpath="lib/$apkarch"
|
|
fallbacklibpath="lib/$fallback_arch" #notice that this sometimes gives 'illegal' paths like 'lib/all', but the path is not used in those situations
|
|
fi
|
|
if [ "$API" -lt "23" ]; then #libextraction is only necessary on pre-Marshmallow
|
|
if [ -n "$(unzip -Z -1 "$sourceapk" "$libsearchpath" 2>/dev/null)" ]; then
|
|
install -d "$targetdir/$libpath"
|
|
unzip -qqq -j -o "$sourceapk" "$libsearchpath" -x "lib/*/crazy.*" -d "$targetdir/$libpath" 2>/dev/null
|
|
fi
|
|
if [ "$apkarch" != "$fallback_arch" ] && [ -n "$(unzip -Z -1 "$sourceapk" "$libfallbacksearchpath" 2>/dev/null)" ]; then
|
|
install -d "$targetdir/$fallbacklibpath"
|
|
unzip -qqq -j -o "$sourceapk" "$libfallbacksearchpath" -x "lib/*/crazy.*" -d "$targetdir/$fallbacklibpath" 2>/dev/null
|
|
fi
|
|
fi
|
|
}
|