Build a single APK for all ABIs

This commit is contained in:
topjohnwu 2021-05-13 00:21:04 -07:00
parent 66cc9bc545
commit 5e1fba3603
12 changed files with 70 additions and 83 deletions

View File

@ -1,4 +1,3 @@
import com.android.build.gradle.internal.api.ApkVariantOutputImpl
import org.apache.tools.ant.filters.FixCrLfFilter
import java.io.PrintStream
@ -42,13 +41,6 @@ android {
}
}
splits {
abi {
isEnable = true
isUniversalApk = true
}
}
buildFeatures {
dataBinding = true
}
@ -81,40 +73,24 @@ val syncLibs by tasks.registering(Sync::class) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
from(rootProject.file("native/out/arm64-v8a")) {
include("magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
}
into("x86") {
from(rootProject.file("native/out/x86")) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
from(rootProject.file("native/out/x86_64")) {
include("magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
}
into("arm64-v8a") {
from(rootProject.file("native/out/arm64-v8a")) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
from(rootProject.file("native/out/armeabi-v7a")) {
include("magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
}
into("x86_64") {
from(rootProject.file("native/out/x86_64")) {
include("busybox", "magiskboot", "magiskinit", "magisk")
rename { if (it == "magisk") "libmagisk64.so" else "lib$it.so" }
}
from(rootProject.file("native/out/x86")) {
include("magisk")
rename { if (it == "magisk") "libmagisk32.so" else "lib$it.so" }
}
}
onlyIf {
if (inputs.sourceFiles.files.size != 16)
@ -139,10 +115,9 @@ val syncAssets by tasks.registering(Sync::class) {
}
filesMatching("**/util_functions.sh") {
filter {
it.replace(
"#MAGISK_VERSION_STUB",
it.replace("#MAGISK_VERSION_STUB",
"MAGISK_VER='${Config.version}'\n" +
"MAGISK_VER_CODE=${Config.versionCode}"
"MAGISK_VER_CODE=${Config.versionCode}"
)
}
filter<FixCrLfFilter>("eol" to FixCrLfFilter.CrLf.newInstance("lf"))
@ -196,13 +171,6 @@ android.applicationVariants.all {
}
}
registerJavaGeneratingTask(genSrcTask.get(), outSrcDir)
outputs.all {
val output = this as ApkVariantOutputImpl
output.filters.forEach {
output.versionNameOverride += "-${it.identifier}"
}
}
}
dependencies {

View File

@ -9,6 +9,7 @@
android:name=".core.App"
android:extractNativeLibs="true"
android:icon="@drawable/ic_launcher"
android:multiArch="true"
tools:ignore="UnusedAttribute,GoogleAppIndexingWarning">
<!-- Splash -->

View File

@ -7,8 +7,12 @@ import com.topjohnwu.magisk.BuildConfig
@Suppress("DEPRECATION")
object Const {
val CPU_ABI: String = Build.SUPPORTED_ABIS[0]
val CPU_ABI_32: String = Build.SUPPORTED_32_BIT_ABIS.firstOrNull() ?: CPU_ABI
val CPU_ABI: String get() = Build.SUPPORTED_ABIS[0]
// Null if 32-bit only or 64-bit only
val CPU_ABI_32 =
if (Build.SUPPORTED_64_BIT_ABIS.isEmpty()) null
else Build.SUPPORTED_32_BIT_ABIS.firstOrNull()
// Paths
lateinit var MAGISKTMP: String

View File

@ -17,7 +17,6 @@ val isRunningAsStub get() = Info.stub != null
object Info {
var stub: DynAPK.Data? = null
var stubArch = "lib/${Const.CPU_ABI}"
val EMPTY_REMOTE = UpdateInfo()
var remote = EMPTY_REMOTE

View File

@ -37,6 +37,7 @@ import java.io.*
import java.nio.ByteBuffer
import java.security.SecureRandom
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
abstract class MagiskInstallImpl protected constructor(
@ -93,8 +94,14 @@ abstract class MagiskInstallImpl protected constructor(
// Extract binaries
if (isRunningAsStub) {
val zf = ZipFile(DynAPK.current(context))
// Also extract magisk32 on non 64-bit only 64-bit devices
val is32lib = Const.CPU_ABI_32?.let {
{ entry: ZipEntry -> entry.name == "lib/$it/libmagisk32.so" }
} ?: { false }
zf.entries().asSequence().filter {
!it.isDirectory && it.name.startsWith(Info.stubArch)
!it.isDirectory && (it.name.startsWith("lib/${Const.CPU_ABI}/") || is32lib(it))
}.forEach {
val n = it.name.substring(it.name.lastIndexOf('/') + 1)
val name = n.substring(3, n.length - 3)
@ -102,9 +109,17 @@ abstract class MagiskInstallImpl protected constructor(
zf.getInputStream(it).writeTo(dest)
}
} else {
val libs = File(context.applicationInfo.nativeLibraryDir).listFiles { _, name ->
val info = context.applicationInfo
var libs = File(info.nativeLibraryDir).listFiles { _, name ->
name.startsWith("lib") && name.endsWith(".so")
} ?: emptyArray()
// Also symlink magisk32 on non 64-bit only 64-bit devices
val lib32 = info.javaClass.getDeclaredField("secondaryNativeLibraryDir").get(info) as String?
if (lib32 != null) {
libs += File(lib32, "libmagisk32.so")
}
for (lib in libs) {
val name = lib.name.substring(3, lib.name.length - 3)
Os.symlink(lib.path, "$installDir/$name")

View File

@ -33,11 +33,7 @@ class BusyBoxInit : BaseShellInit() {
if (!shell.isRoot)
return true
val jar = JarFile(DynAPK.current(context))
var bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so")
if (bb == null) {
Info.stubArch = "lib/${Const.CPU_ABI_32}"
bb = jar.getJarEntry("${Info.stubArch}/libbusybox.so")
}
val bb = jar.getJarEntry("lib/${Const.CPU_ABI}/libbusybox.so")
localBB = context.deviceProtectedContext.cachedFile("busybox")
localBB.delete()
jar.getInputStream(bb).writeTo(localBB)

View File

@ -347,19 +347,11 @@ def build_apk(args, module):
build_type = build_type.lower()
if module == 'app':
for arch in archs + ['universal']:
apk = f'{module}-{arch}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
else:
apk = f'{module}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
apk = f'{module}-{build_type}.apk'
source = op.join(module, 'build', 'outputs', 'apk', build_type, apk)
target = op.join(config['outdir'], apk)
mv(source, target)
header('Output: ' + target)
def build_app(args):

View File

@ -1,4 +1,4 @@
APP_ABI := armeabi-v7a x86 arm64-v8a x86_64
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto \
-D__MVSTR=${MAGISK_VERSION} -D__MCODE=${MAGISK_VER_CODE}
APP_LDFLAGS := -flto

View File

@ -147,15 +147,22 @@ echo "RECOVERYMODE=$RECOVERYMODE" >> config
[ ! -z $SHA1 ] && echo "SHA1=$SHA1" >> config
# Compress to save precious ramdisk space
./magiskboot compress=xz magisk32 magisk32.xz
./magiskboot compress=xz magisk64 magisk64.xz
$IS64BIT && SKIP64="" || SKIP64="#"
SKIP32="#"
SKIP64="#"
if [ -f magisk32 ]; then
./magiskboot compress=xz magisk32 magisk32.xz
unset SKIP32
fi
if [ -f magisk64 ]; then
./magiskboot compress=xz magisk64 magisk64.xz
unset SKIP64
fi
./magiskboot cpio ramdisk.cpio \
"add 0750 init magiskinit" \
"mkdir 0750 overlay.d" \
"mkdir 0750 overlay.d/sbin" \
"add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \
"$SKIP32 add 0644 overlay.d/sbin/magisk32.xz magisk32.xz" \
"$SKIP64 add 0644 overlay.d/sbin/magisk64.xz magisk64.xz" \
"patch" \
"backup ramdisk.cpio.orig" \

View File

@ -50,16 +50,15 @@ api_level_arch_detect
[ $API -lt 21 ] && abort "! Magisk only support Android 5.0 and above"
ui_print "- Device platform: $ARCH"
ui_print "- Device platform: $ABI"
BINDIR=$INSTALLER/lib/$ABILONG
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a
BINDIR=$INSTALLER/lib/$ABI
cd $BINDIR
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
cd /
chmod -R 755 $CHROMEDIR $BINDIR
cp -af $INSTALLER/lib/$ABI32/libmagisk32.so $BINDIR/magisk32 2>/dev/null
cp -af $CHROMEDIR/. $BINDIR/chromeos
chmod -R 755 $BINDIR
# Check if system root is installed and remove
$BOOTMODE || remove_system_su

View File

@ -55,16 +55,14 @@ ui_print "- Target image: $BOOTIMAGE"
# Detect version and architecture
api_level_arch_detect
ui_print "- Device platform: $ARCH"
ui_print "- Device platform: $ABI"
BINDIR=$INSTALLER/lib/$ABILONG
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/$ARCH32
[ -d "$BINDIR" ] || BINDIR=$INSTALLER/lib/armeabi-v7a
BINDIR=$INSTALLER/lib/$ABI
cd $BINDIR
for file in lib*.so; do mv "$file" "${file:3:${#file}-6}"; done
cd /
chmod -R 755 $CHROMEDIR $BINDIR
cp -af $CHROMEDIR/. $BINDIR/chromeos
chmod -R 755 $BINDIR
############
# Uninstall

View File

@ -519,17 +519,25 @@ remove_system_su() {
api_level_arch_detect() {
API=$(grep_get_prop ro.build.version.sdk)
ABI=$(grep_get_prop ro.product.cpu.abi | cut -c-3)
ABI2=$(grep_get_prop ro.product.cpu.abi2 | cut -c-3)
ABILONG=$(grep_get_prop ro.product.cpu.abi)
ARCH=arm
ARCH32=arm
IS64BIT=false
if [ "$ABI" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
if [ "$ABI2" = "x86" ]; then ARCH=x86; ARCH32=x86; fi;
if [ "$ABILONG" = "arm64-v8a" ]; then ARCH=arm64; ARCH32=arm; IS64BIT=true; fi;
if [ "$ABILONG" = "x86_64" ]; then ARCH=x64; ARCH32=x86; IS64BIT=true; fi;
ABI=$(grep_get_prop ro.product.cpu.abi)
if [ "$ABI" = "x86" ]; then
ARCH=x86
ABI32=x86
IS64BIT=false
elif [ "$ABI" = "arm64-v8a" ]; then
ARCH=arm64
ABI32=armeabi-v7a
IS64BIT=true
elif [ "$ABI" = "x86_64" ]; then
ARCH=x64
ABI32=x86
IS64BIT=true
else
ARCH=arm
ABI=armeabi-v7a
ABI32=armeabi-v7a
IS64BIT=false
fi
}
check_data() {