Support setting custom ABI list

Also stop building riscv64 by default
This commit is contained in:
topjohnwu 2024-08-01 14:33:08 -07:00
parent 9093be1329
commit 1539cfe888
7 changed files with 71 additions and 41 deletions

View File

@ -134,12 +134,14 @@ abstract class MagiskInstallImpl protected constructor(
val abi32 = Const.CPU_ABI_32 val abi32 = Const.CPU_ABI_32
if (Process.is64Bit() && abi32 != null) { if (Process.is64Bit() && abi32 != null) {
val magisk32 = File(installDir, "magisk32")
val entry = zf.getEntry("lib/$abi32/libmagisk.so") val entry = zf.getEntry("lib/$abi32/libmagisk.so")
if (entry != null) {
val magisk32 = File(installDir, "magisk32")
zf.getInputStream(entry).writeTo(magisk32) zf.getInputStream(entry).writeTo(magisk32)
magisk32.setExecutable(true) magisk32.setExecutable(true)
} }
} }
}
} else { } else {
val info = context.applicationInfo val info = context.applicationInfo
val libs = File(info.nativeLibraryDir).listFiles { _, name -> val libs = File(info.nativeLibraryDir).listFiles { _, name ->

View File

@ -5,6 +5,7 @@ import lzma
import multiprocessing import multiprocessing
import os import os
import platform import platform
import re
import shutil import shutil
import stat import stat
import subprocess import subprocess
@ -51,7 +52,7 @@ if is_windows:
# We can't do ANSI color codes in terminal on Windows without colorama # We can't do ANSI color codes in terminal on Windows without colorama
no_color = True no_color = True
# Environment checks # Environment checks and detection
if not sys.version_info >= (3, 8): if not sys.version_info >= (3, 8):
error("Requires Python 3.8+") error("Requires Python 3.8+")
@ -73,18 +74,19 @@ if shutil.which("ccache") is not None:
cpu_count = multiprocessing.cpu_count() cpu_count = multiprocessing.cpu_count()
os_name = platform.system().lower() os_name = platform.system().lower()
archs = ["armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64"] # Common constants
triples = [ support_abis = {
"armv7a-linux-androideabi", "armeabi-v7a": "thumbv7neon-linux-androideabi",
"i686-linux-android", "x86": "i686-linux-android",
"aarch64-linux-android", "arm64-v8a": "aarch64-linux-android",
"x86_64-linux-android", "x86_64": "x86_64-linux-android",
"riscv64-linux-android", "riscv64": "riscv64-linux-android",
] }
default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} default_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
support_targets = default_targets | {"resetprop"} support_targets = default_targets | {"resetprop"}
rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"} rust_targets = {"magisk", "magiskinit", "magiskboot", "magiskpolicy"}
# Common paths
ndk_root = sdk_path / "ndk" ndk_root = sdk_path / "ndk"
ndk_path = ndk_root / "magisk" ndk_path = ndk_root / "magisk"
ndk_build = ndk_path / "ndk-build" ndk_build = ndk_path / "ndk-build"
@ -97,8 +99,8 @@ native_gen_path = Path("native", "out", "generated").resolve()
# Global vars # Global vars
config = {} config = {}
STDOUT = None args = {}
build_tools = None build_abis = {}
def mv(source: Path, target: Path): def mv(source: Path, target: Path):
@ -137,12 +139,16 @@ def rm_on_error(func, path, _):
def rm_rf(path: Path): def rm_rf(path: Path):
vprint(f"rm -rf {path}") vprint(f"rm -rf {path}")
if sys.version_info >= (3, 12):
shutil.rmtree(path, ignore_errors=False, onexc=rm_on_error)
else:
shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error) shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error)
def execv(cmds: list, env=None): def execv(cmds: list, env=None):
out = None if args.force_out or args.verbose > 0 else subprocess.DEVNULL
# Use shell on Windows to support PATHEXT # Use shell on Windows to support PATHEXT
return subprocess.run(cmds, stdout=STDOUT, env=env, shell=is_windows) return subprocess.run(cmds, stdout=out, env=env, shell=is_windows)
def cmd_out(cmds: list, env=None): def cmd_out(cmds: list, env=None):
@ -172,10 +178,11 @@ def parse_props(file):
prop = line.split("=") prop = line.split("=")
if len(prop) != 2: if len(prop) != 2:
continue continue
key = prop[0].strip(" \t\r\n")
value = prop[1].strip(" \t\r\n") value = prop[1].strip(" \t\r\n")
if len(value) == 0: if not key or not value:
continue continue
props[prop[0].strip(" \t\r\n")] = value props[key] = value
return props return props
@ -204,10 +211,18 @@ def load_config(args):
error('Config error: "versionCode" is required to be an integer') error('Config error: "versionCode" is required to be an integer')
config["outdir"] = Path(config["outdir"]) config["outdir"] = Path(config["outdir"])
config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True) config["outdir"].mkdir(mode=0o755, parents=True, exist_ok=True)
global STDOUT
STDOUT = None if args.verbose > 0 else subprocess.DEVNULL if "abiList" in config:
abiList = re.split("\\s*,\\s*", config["abiList"])
archs = set(abiList) & support_abis.keys()
else:
archs = {"armeabi-v7a", "x86", "arm64-v8a", "x86_64"}
triples = map(support_abis.get, archs)
global build_abis
build_abis = dict(zip(archs, triples))
def clean_elf(): def clean_elf():
@ -238,6 +253,7 @@ def run_ndk_build(args, cmds: list):
os.chdir("native") os.chdir("native")
cmds.append("NDK_PROJECT_PATH=.") cmds.append("NDK_PROJECT_PATH=.")
cmds.append("NDK_APPLICATION_MK=src/Application.mk") cmds.append("NDK_APPLICATION_MK=src/Application.mk")
cmds.append(f"APP_ABI={' '.join(build_abis.keys())}")
cmds.append(f"-j{cpu_count}") cmds.append(f"-j{cpu_count}")
if args.verbose > 1: if args.verbose > 1:
cmds.append("V=1") cmds.append("V=1")
@ -248,8 +264,9 @@ def run_ndk_build(args, cmds: list):
error("Build binary failed!") error("Build binary failed!")
os.chdir("..") os.chdir("..")
for arch in archs: for arch in support_abis.keys():
arch_dir = Path("native", "libs", arch) arch_dir = Path("native", "libs", arch)
if arch_dir.exists():
out_dir = Path("native", "out", arch) out_dir = Path("native", "out", arch)
for source in arch_dir.iterdir(): for source in arch_dir.iterdir():
target = out_dir / source.name target = out_dir / source.name
@ -332,11 +349,8 @@ def build_rust_src(args, targets: set):
cmds.append("--target") cmds.append("--target")
cmds.append("") cmds.append("")
for arch, triple in zip(archs, triples): for arch, triple in build_abis.items():
rust_triple = ( cmds[-1] = triple
"thumbv7neon-linux-androideabi" if triple.startswith("armv7") else triple
)
cmds[-1] = rust_triple
for tgt in targets: for tgt in targets:
cmds[2] = tgt cmds[2] = tgt
@ -347,16 +361,15 @@ def build_rust_src(args, targets: set):
arch_out = native_out / arch arch_out = native_out / arch
arch_out.mkdir(mode=0o755, exist_ok=True) arch_out.mkdir(mode=0o755, exist_ok=True)
for tgt in targets: for tgt in targets:
source = Path("target", rust_triple, rust_out, f"lib{tgt}.a") source = Path("target", triple, rust_out, f"lib{tgt}.a")
target = arch_out / f"lib{tgt}-rs.a" target = arch_out / f"lib{tgt}-rs.a"
mv(source, target) mv(source, target)
os.chdir(Path("..", "..")) os.chdir(Path("..", ".."))
def run_cargo_cmd(args): def cargo_cli(args):
global STDOUT args.force_out = True
STDOUT = None
if len(args.commands) >= 1 and args.commands[0] == "--": if len(args.commands) >= 1 and args.commands[0] == "--":
args.commands = args.commands[1:] args.commands = args.commands[1:]
os.chdir(Path("native", "src")) os.chdir(Path("native", "src"))
@ -677,9 +690,11 @@ binary_parser.add_argument(
) )
binary_parser.set_defaults(func=build_binary) binary_parser.set_defaults(func=build_binary)
cargo_parser = subparsers.add_parser("cargo", help="run cargo with proper environment") cargo_parser = subparsers.add_parser(
"cargo", help="call 'cargo' commands against the project"
)
cargo_parser.add_argument("commands", nargs=argparse.REMAINDER) cargo_parser.add_argument("commands", nargs=argparse.REMAINDER)
cargo_parser.set_defaults(func=run_cargo_cmd) cargo_parser.set_defaults(func=cargo_cli)
rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper") rustup_parser = subparsers.add_parser("rustup", help="setup rustup wrapper")
rustup_parser.add_argument("wrapper_dir", help="path to setup rustup wrapper binaries") rustup_parser.add_argument("wrapper_dir", help="path to setup rustup wrapper binaries")
@ -722,6 +737,7 @@ if len(sys.argv) == 1:
args = parser.parse_args() args = parser.parse_args()
load_config(args) load_config(args)
vars(args)["force_out"] = False
# Call corresponding functions # Call corresponding functions
args.func(args) args.func(args)

View File

@ -8,6 +8,8 @@ import java.util.Properties
private val props = Properties() private val props = Properties()
private var commitHash = "" private var commitHash = ""
private val supportAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")
private val defaultAbis = setOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64")
object Config { object Config {
operator fun get(key: String): String? { operator fun get(key: String): String? {
@ -20,6 +22,10 @@ object Config {
val version: String get() = get("version") ?: commitHash val version: String get() = get("version") ?: commitHash
val versionCode: Int get() = get("magisk.versionCode")!!.toInt() val versionCode: Int get() = get("magisk.versionCode")!!.toInt()
val stubVersion: String get() = get("magisk.stubVersion")!! val stubVersion: String get() = get("magisk.stubVersion")!!
val abiList: Set<String> get() {
val abiList = get("abiList") ?: return defaultAbis
return abiList.split(Regex("\\s*,\\s*")).toSet() intersect supportAbis
}
} }
class MagiskPlugin : Plugin<Project> { class MagiskPlugin : Plugin<Project> {

View File

@ -121,9 +121,11 @@ const val BUSYBOX_ZIP_CHECKSUM =
fun Project.setupCoreLib() { fun Project.setupCoreLib() {
setupCommon() setupCommon()
val abiList = Config.abiList
val syncLibs by tasks.registering(Sync::class) { val syncLibs by tasks.registering(Sync::class) {
into("src/main/jniLibs") into("src/main/jniLibs")
for (abi in arrayOf("armeabi-v7a", "x86", "arm64-v8a", "x86_64", "riscv64")) { for (abi in abiList) {
into(abi) { into(abi) {
from(rootProject.file("native/out/$abi")) { from(rootProject.file("native/out/$abi")) {
include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so") include("magiskboot", "magiskinit", "magiskpolicy", "magisk", "libinit-ld.so")
@ -132,7 +134,7 @@ fun Project.setupCoreLib() {
} }
} }
onlyIf { onlyIf {
if (inputs.sourceFiles.files.size != 25) if (inputs.sourceFiles.files.size != abiList.size * 5)
throw StopExecutionException("Please build binaries first! (./build.py binary)") throw StopExecutionException("Please build binaries first! (./build.py binary)")
true true
} }
@ -158,6 +160,7 @@ fun Project.setupCoreLib() {
} }
} }
from(zipTree(bb)) from(zipTree(bb))
include(abiList.map { "$it/libbusybox.so" })
into("src/main/jniLibs") into("src/main/jniLibs")
} }

View File

@ -9,6 +9,10 @@ version=string
# Output path. Default: out # Output path. Default: out
outdir=string outdir=string
# List of ABIs to build, separated with ','
# Default: armeabi-v7a,x86,arm64-v8a,x86_64
abiList=[string]
##################################################### #####################################################
# Signing configs for signing zips and APKs # Signing configs for signing zips and APKs
# These 4 variables has to be either all set or not # These 4 variables has to be either all set or not

View File

@ -1,5 +1,4 @@
APP_BUILD_SCRIPT := src/Android.mk APP_BUILD_SCRIPT := src/Android.mk
APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 riscv64
APP_CFLAGS := -Wall -Oz -fomit-frame-pointer APP_CFLAGS := -Wall -Oz -fomit-frame-pointer
APP_CPPFLAGS := -std=c++23 APP_CPPFLAGS := -std=c++23
APP_STL := none APP_STL := none

View File

@ -63,6 +63,6 @@ panic = "abort"
[profile.release] [profile.release]
opt-level = "z" opt-level = "z"
lto = true lto = "fat"
codegen-units = 1 codegen-units = 1
panic = "abort" panic = "abort"