diff --git a/build.py b/build.py index 36a0ce864..c702eb342 100755 --- a/build.py +++ b/build.py @@ -140,17 +140,13 @@ def rm_rf(path: Path): shutil.rmtree(path, ignore_errors=False, onerror=rm_on_error) -def execv(cmd, env=None): - return subprocess.run(cmd, stdout=STDOUT, env=env) +def execv(cmds: list, env=None): + return subprocess.run(cmds, stdout=STDOUT, env=env) -def system(cmd): - return subprocess.run(cmd, shell=True, stdout=STDOUT) - - -def cmd_out(cmd, env=None): +def cmd_out(cmds: list, env=None): return ( - subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) + subprocess.run(cmds, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, env=env) .stdout.strip() .decode("utf-8") ) @@ -225,21 +221,22 @@ def clean_elf(): elf_cleaner, ] ) - args = [elf_cleaner, "--api-level", "23"] - args.extend( - Path("native", "out", arch, bin) - for arch in archs - for bin in ["magisk", "magiskpolicy"] - ) - execv(args) + cmds = [elf_cleaner, "--api-level", "23"] + cmds.extend(glob.glob("native/out/*/magisk")) + cmds.extend(glob.glob("native/out/*/magiskpolicy")) + execv(cmds) -def run_ndk_build(args, flags): +def run_ndk_build(args, cmds: list): os.chdir("native") - flags = "NDK_PROJECT_PATH=. NDK_APPLICATION_MK=src/Application.mk " + flags + cmds.append("NDK_PROJECT_PATH=.") + cmds.append("NDK_APPLICATION_MK=src/Application.mk") + cmds.append(f"-j{cpu_count}") if args.verbose > 1: - flags = "V=1 " + flags - proc = system(f"{ndk_build} {flags} -j{cpu_count}") + cmds.append("V=1") + if not args.release: + cmds.append("MAGISK_DEBUG=1") + proc = execv([ndk_build, *cmds]) if proc.returncode != 0: error("Build binary failed!") os.chdir("..") @@ -255,37 +252,37 @@ def run_ndk_build(args, flags): def build_cpp_src(args, targets: set): dump_flag_header() - flags = "" + cmds = [] clean = False if "magisk" in targets: - flags += " B_MAGISK=1" + cmds.append("B_MAGISK=1") clean = True if "magiskpolicy" in targets: - flags += " B_POLICY=1" + cmds.append("B_POLICY=1") clean = True if "magiskinit" in targets: - flags += " B_PRELOAD=1" + cmds.append("B_PRELOAD=1") if "resetprop" in targets: - flags += " B_PROP=1" + cmds.append("B_PROP=1") - if flags: - run_ndk_build(args, flags) + if cmds: + run_ndk_build(args, cmds) - flags = "" + cmds.clear() if "magiskinit" in targets: - flags += " B_INIT=1" + cmds.append("B_INIT=1") if "magiskboot" in targets: - flags += " B_BOOT=1" + cmds.append("B_BOOT=1") - if flags: - flags += " B_CRT0=1" - run_ndk_build(args, flags) + if cmds: + cmds.append("B_CRT0=1") + run_ndk_build(args, cmds) if clean: clean_elf() @@ -295,7 +292,9 @@ def run_cargo(cmds): env = os.environ.copy() env["PATH"] = f'{rust_bin}{os.pathsep}{env["PATH"]}' env["CARGO_BUILD_RUSTC"] = str(rust_bin / f"rustc{EXE_EXT}") - env["RUSTFLAGS"] = f"-Clinker-plugin-lto -Zthreads={min(8, cpu_count)}" + env["RUSTFLAGS"] = ( + f"-Z dwarf-version=4 -Clinker-plugin-lto -Z threads={min(8, cpu_count)}" + ) return execv([cargo, *cmds], env) @@ -503,7 +502,6 @@ def cleanup(args): header("* Cleaning C++") rm_rf(Path("native", "libs")) rm_rf(Path("native", "obj")) - rm_rf(Path("native", "out")) if "rust" in targets: header("* Cleaning Rust") @@ -513,6 +511,9 @@ def cleanup(args): for rs_gen in glob.glob("native/**/*-rs.*pp", recursive=True): rm(rs_gen) + if "native" in targets: + rm_rf(Path("native", "out")) + if "java" in targets: header("* Cleaning java") execv([gradlew, ":app:clean"], env=find_jdk()) diff --git a/native/src/Application.mk b/native/src/Application.mk index 94aa3b88f..3e58fd1ae 100644 --- a/native/src/Application.mk +++ b/native/src/Application.mk @@ -1,7 +1,6 @@ APP_BUILD_SCRIPT := src/Android.mk APP_ABI := armeabi-v7a arm64-v8a x86 x86_64 riscv64 -APP_CFLAGS := -Wall -Oz -fomit-frame-pointer -flto -APP_LDFLAGS := -flto -Wl,--icf=all +APP_CFLAGS := -Wall -Oz -fomit-frame-pointer APP_CPPFLAGS := -std=c++23 APP_STL := none APP_PLATFORM := android-23 @@ -9,11 +8,25 @@ APP_THIN_ARCHIVE := true APP_STRIP_MODE := none APP_SUPPORT_FLEXIBLE_PAGE_SIZES := true +ifdef MAGISK_DEBUG + +NDK_APP_OUT := ./obj/debug +APP_CFLAGS += -flto=thin -gdwarf-4 +APP_LDFLAGS += -flto=thin + +else + +NDK_APP_OUT := ./obj/release +APP_CFLAGS += -flto +APP_LDFLAGS += -flto -Wl,--icf=all + +endif + ifdef B_CRT0 # Disable all security and debugging features APP_CFLAGS += -fno-unwind-tables -fno-asynchronous-unwind-tables -fno-stack-protector -U_FORTIFY_SOURCE # Override output folder to make sure all dependencies are rebuilt with new CFLAGS -NDK_APP_OUT := ./obj/nolibc +NDK_APP_OUT := $(NDK_APP_OUT)-nolibc endif diff --git a/native/src/Cargo.toml b/native/src/Cargo.toml index b96c38376..de4b5cc14 100644 --- a/native/src/Cargo.toml +++ b/native/src/Cargo.toml @@ -58,7 +58,7 @@ rev = "809df65b20d61e88afb7f514b5cfdd3d1958a40f" [profile.dev] opt-level = "z" -lto = true +lto = "thin" panic = "abort" [profile.release] diff --git a/native/src/boot/main.cpp b/native/src/boot/main.cpp index 252058b20..2cd68efe3 100644 --- a/native/src/boot/main.cpp +++ b/native/src/boot/main.cpp @@ -7,8 +7,16 @@ using namespace std; #ifdef USE_CRT0 -__asm__(".global vfprintf \n vfprintf = musl_vfprintf"); -__asm__(".global vsscanf \n vsscanf = tfp_vsscanf"); +__BEGIN_DECLS +int tfp_vsscanf(const char *s, const char *fmt, va_list args); +int vsscanf(const char *s, const char *fmt, va_list args) { + return tfp_vsscanf(s, fmt, args); +} +int musl_vfprintf(FILE *stream, const char *format, va_list arg); +int vfprintf(FILE *stream, const char *format, va_list arg) { + return musl_vfprintf(stream, format, arg); +} +__END_DECLS #endif static void print_formats() { diff --git a/native/src/init/init.cpp b/native/src/init/init.cpp index 6ee0e7145..ae221002e 100644 --- a/native/src/init/init.cpp +++ b/native/src/init/init.cpp @@ -12,7 +12,12 @@ using namespace std; #ifdef USE_CRT0 -__asm__(".global vfprintf \n vfprintf = tfp_vfprintf"); +__BEGIN_DECLS +int tfp_vfprintf(FILE *stream, const char *format, va_list arg); +int vfprintf(FILE *stream, const char *format, va_list arg) { + return tfp_vfprintf(stream, format, arg); +} +__END_DECLS #endif bool unxz(out_stream &strm, rust::Slice bytes) {