Skip to content

ookiineko/magiskboot_build

Repository files navigation

magiskboot_build

Magisk Version Badge GitHub Workflow Status Last Upstream Sync Date

a simple portable CMake-based build system for magiskboot

Requirements

magiskboot itself depends on the following libraries:

  1. LZMA
  2. LZ4
  3. bzip2
  4. zlib

for build-time dependencies:

  1. pkg-config
  2. Clang (maybe also others, but GCC doesn't work, see this part)
  3. Rust (stable channel is OK... spoiler: RUSTC_BOOTSTRAP HACK is used)
  4. CMake
  5. Libc++ (optional, see this part)

please make sure you have installed the above softwares before building

here are examples for some supported popular operating systems/distributions:

Android

Android

Please check the instructions for Cross compiling first.

Download ONDK, set environment variable ANDROID_NDK_HOME to the extracted directory, and use vcpkg to install the dependencies.

Use /path/to/your/ondk/build/cmake/android.toolchain.cmake as the toolchain file for vcpkg.

Then, set the CMake variable ANDROID_PLATFORM to the desired API level, and ANDROID_ABI to the desired archiecture,

for more details about these variables, please refer to the NDK documentation.

Make sure to enable source build for the Rust standard library (STD), then activate the Rust toolchain by append it to your current PATH:

export PATH=/path/to/your/ondk/toolchains/rust/bin:$PATH

Termux

Note

Termux build is not actively tested by CI, but it might work without problem.

If you find the build is broken, please file a bug report.

apt update
apt upgrade  # upgrade all existing packages (optional)
apt install build-essential liblzma liblz4 libbz2 zlib pkg-config \
            clang rust cmake ninja

When configuring, pass -DCMAKE_INSTALL_PREFIX=$PREFIX to CMake.

Linux

Ubuntu 22.04 (jammy)

sudo apt update
sudo apt upgrade  # upgrade all existing packages (optional)

# replace clang-15, libc++-15-dev, libc++abi-15-dev with
# appropriate version according to your Ubuntu release
sudo apt install build-essential lzma-dev liblzma-dev liblz4-dev libbz2-dev \
                 zlib1g-dev pkg-config clang-15 libc++-15-dev libc++abi-15-dev cmake \
                 ninja-build rustc cargo

When configuring, set CC and CXX to correct values, for example: clang-15 and clang++-15.

Alpine Linux (edge)

sudo apk update
sudo apk upgrade  # upgrade all existing packages (recommended)
sudo apk add build-base linux-headers xz-dev lz4-dev bzip2-dev \
             zlib-dev pkgconf clang libc++-dev cmake \
             samurai rust cargo

archlinux

sudo pacman -S --needed base-devel xz lz4 bzip2 zlib pkgconf \
                        clang libc++ cmake ninja rust
macOS

macOS Monterey (or higher verison)

install Homebrew first

brew update
brew upgrade  # upgrade all existing packages (optional)
brew install xz lz4 pkg-config cmake ninja rust

Theoretically you can build for older macOS version as well, but Homebrew only support the last three OS releases of macOS, so you will need to install the depended packages using other ways (maybe using MacPorts or sth?)

LTO configuration

To use LTO (optional), also install the llvm package, and add it to your current PATH:

export PATH="$(brew --prefix)/opt/llvm/bin:$PATH" CC=clang CXX=clang++

and pass -DCMAKE_AR=llvm-ar -DCMAKE_RANLIB=llvm-ranlib to CMake when configuring.

Windows

Windows (MinGW)

Install MSYS2 first, and change the setting of mintty.exe to grant it with administrator privileges (needed for using native symlinks in some conditions).

Warning

LLD from MINGW/UCRT environments currently has a bug that produces bad executables, so if you want to use LTO, please build under CLANG environments.

For more details on differences between these environments, you can refer to the MSYS2 documentation.

don't forget to set this environtment variable to allow symlinks to work properly: export MSYS=winsymlinks:native (required for the build I guess)

pacman -Syu  # upgrade all existing packages (optional, you may need to do this for multiple times)
pacman -S --needed base-devel pactoys
pacboy -S --needed {xz,lz4,bzip2,zlib,pkgconf,clang,cmake,libc++,ninja,rust}:p
Cross builds

If you are cross-compiling from a non-Windows host and using vcpkg to manage the dependencies, please make sure CMake variable MINGW is set to TRUE during configuring.

Cygwin (Experimental)

Warning

Cygwin support is experimental, you may run into problems.

Note

You can get a prebuilt binary at GitHub releases.

To build for Cygwin, you need to compile a Rust toolchain from source, for more info: Cygwin Rust porting

Currently Cygwin Rust has no host tools support, so cross compiling is needed, make sure to read the instructions for Cross compiling.

The cross compiler is available on Fedora Linux, provided by the Fedora Cygwin, alternatively, you can also try arch-cygwin.

When configuring, use cygwin64-cmake (x86_64-pc-cygwin-cmake on arch-cygwin) instead of cmake, but don't use it for cmake --build and other CMake commands.

For Fedora Cygwin, you need to build the LLVM & Clang yourself, a patched LLVM 15 source is there. To use the patched Clang in Fedora Cygwin, set both CMAKE_C_COMPILER_TARGET and CMAKE_CXX_COMPILER_TARGET to x86_64-unknown-windows-cygnus and CMAKE_SYSROOT to /usr/x86_64-pc-cygwin/sys-root when configuring.

On Fedora Cygwin, there is another issue that cygwin64-cmake overrides C and C++ compilers to GCC, this is not supported by Magisk, and somehow ignoring the CC and CXX variables we are settings. To workaround this, set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER manually to the path of the previous Cygwin cross Clang and Clang++.

On arch-cygwin, set CYGWIN_CC and CYGWIN_CXX to x86_64-pc-cygwin-clang and x86_64-pc-cygwin-clang++.

WebAssembly

Emscripten

Note

Currently this port only support running with NodeJS.

A web frontend wrapper must be written to handle the argument passing and file system management in browsers.

This should be implemented soon in the future (#19), but unfortunately I am not a web developer, any help on this will be welcome QwQ

Please read the Cross compiling instructions first.

Install the Emscripten SDK and also a Rust compiler with Emscripten target (probably via rustup).

Warning

emsdk version 3.1.37 is recommended, you might run into weird problems with other versions.

Use vcpkg to install the depended libraries, the triplet is called wasm32-emscripten.

When configuring, use emcmake cmake instead of cmake (but don't use it for cmake --build and other CMake commands) , and use /path/to/your/emsdk/emscripten/cmake/Modules/Platform/Emscripten.cmake as the toolchain file for vcpkg.

For NodeJS, make sure to set CMAKE_EXE_LINKER_FLAGS to -sNODERAWFS to allow using the host filesystem.

finally, you can run the result with NodeJS using: node magiskboot.js

Usage

Please refer to Magisk documentation.

Download

Important

The official magiskboot only supports running on Android and Linux,

If you find something that works on the officially supported platforms, but not on the extra platforms supported by magiskboot_build, then that is a magiskboot_build-specific bug.

Please, do NOT report magiskboot_build bugs to the upstream Magisk!

For prebuilt binaries, go check GitHub Releases for selected CI builds.

Build & Install

First get and extract the latest source tarball (called magiskboot_<COMMIT_ID>_<VERCODE>-src.tar.xz) from Github Releases.

Or clone this repository using Git, note that cloning with --recurse-submodules is not recommended, and you should run scripts/clone_submodules.sh after clone because it skips the submodules that is not necessary for building magiskboot.

CC=clang CXX=clang++ cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release  # configure
cmake --build build -j $(nproc)  # build
./build/magiskboot  # running
# install to system (may need sudo, to specify different install dir, set the `DESTDIR' environment variable)
cmake --install build

To produce a statically linked binary (optional), pass -DPREFER_STATIC_LINKING=ON to CMake while configuring, make sure you have the static version of the depended libraries, otherwise you'll run into configure or link errors.

Rust

You can specify extra arguments passed to Cargo by setting CMake variable CARGO_FLAGS while configuring, you can also provide an initial value of environment RUSTFLAGS by setting the corresponding CMake variable.

Note: these variables are using CMake's list syntax, not string. that is, replace all your spaces with ;, e.g. -DCARGO_FLAGS="-Z;no-index-update" instead of -DCARGO_FLAGS="-Z no-index-update"

Cross compiling

First get a cross-compiler and likely also a Clang from somewhere (usually your distribution's package manager). If you don't have Libc++ installed for your crossed target, you could probably also try to link against Libstdc++ instead, see this part.

Install Rust using rustup and add your cross target like this: rustup target add aarch64-unknown-linux-gnu (replace aarch64-unknown-linux-gnu with the Rust target of your target platform).

If the cross Rust target can't be installed using rustup, you can still compile if you build the Rust standard library (STD) from source, to do this, pass -DRUST_BUILD_STD=ON during configuration (Note this will require Nightly Rust and the STD source code to be installed on your system).

To cross-compile, you may need a CMake toolchain file describing your target specs (for example the sysroot location, and target triplet for using Clang), the location of the cross compiler toolchain and strategy for CMake to seek for the depended libraries.

You can install the depended libraries for your cross target by using vcpkg, for example:

vcpkg install --host-triplet=arm64-linux bzip2 lz4 zlib liblzma

arm64-linux is the triplet of your cross target, pass this value to CMake using the VCPKG_TARGET_TRIPLET variable during configuration.

Set variable Rust_CARGO_TARGET to the Rust target you wanted to cross compile for, e.g. aarch64-unknown-linux-gnu (You can find them in rustc documentation).

To integrate vcpkg with CMake, pass -DCMAKE_TOOLCHAIN_FILE=/path/to/your/vcpkg/scripts/buildsystems/vcpkg.cmake to CMake, to use your toolchain file with vcpkg, set the variable VCPKG_CHAINLOAD_TOOLCHAIN_FILE to the path of your actual toolchain file.

LTO

Set LDFLAGS to " -flto" before calling CMake.

If you want to perform LTO for the Rust part at final link time, pass -DFULL_RUST_LTO=ON to CMake during configuring. (And you will need to install LLD. Note: you may need to make sure your LLVM and LLD are sharing the same LLVM version with Rust.)

Testing

Note

Features not tested by CI doesn't necessarily mean it can't work.

A very basic shell script is provided under the scripts directory, currently the following functions are automatically tested with Github CI:

  • unpack* (currently not all header versions and variants are tested)
  • repack* (same as above)
  • verify
  • sign
  • extract
  • hexpatch
  • cpio* (currently not widely tested on all common ramdisks)

    • cpio exists
    • cpio ls
    • cpio rm
    • cpio mkdir
    • cpio ln
    • cpio mv
    • cpio add
    • cpio extract
    • cpio test
    • cpio patch
    • cpio backup
    • cpio restore
  • dtb

    • dtb print
    • dtb test
    • dtb patch
  • split
  • sha1
  • cleanup
  • compress
  • decompress

Generating source tarball

Note

You may not be able to generate source tarball on Windows/Cygwin due to issues with symlinks.

# configure for only packaging source
CC=true cmake -G Ninja -B build \
    -DCMAKE_C_COMPILER_WORKS=YES -DWITHOUT_BUILD=ON
cmake --build build -t package_source  # make a source package

Make sure to pass the above flags to CMake while configuring, which will allow creating source tarball without installing the build dependencies.

you should be able to find your source package under the build folder

FAQ

Something isn't working

Please use debug builds and paste your information (like crash or error logs) in a new Issue.

Can I build without Libcxx?

If you need to build with Libstdc++ instead of Libc++, pass -DWITH_LIBCXX=OFF to CMake during configuring, also apply this patch.

"Your compiler is not capable of building magiskboot"

Make sure you are using Clang to build. GCC doesn't work because of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566

Is this thing using the latest Magisk source?

Check the version status badges at the top of README.

This project is very similiar to android-tools which just maintains a set of patches on top of a specific upstream Magisk commit and require manual adaption for compiling with newer source.

Although I may update the version once in a while, Pull requests are welcome.

Can you add ... platform support?

This project aims to be portable, it should be possible to port it to new platforms with some efforts, as long as your platform meets the the above requirements.

Feel free to add an Issue about support on your new platform.

Development

Clean builds

To quickly discard the current build directory and dirty vendored submodule (src/) changes, please run make clean.

Vendor projects patching

If you are building directly from the Git source tree, all the patches under the patches/ directory will be automatically applied on the first configure. After that a flag file called .mbb_patched is created under your build directory (i.e. build/).

Removing the flag file and re-configure will discard any dirty changes in vendored projects, and re-apply all the patches to them again.

To avoid applying any patch at configure time, create the flag file manually before calling CMake. Note that in this case this project might not build on anything other than Android.

License

Patches and stub codes created by this project (not borrowed from other places) are licensed under Apache 2.0 or GNU General Public License (GPL) v3 at your option,

All parts of the code borrowed from other projects are licensed under their corresponding license.

However, please note that when combining them are a whole and to distribute the magiskboot binary, all sources have to be licensed under GPL v3.

For more details about these licenses, please see LICENSE and LICENSE.magiskboot.

Special thanks to

  • android-tools developers for many code and inspiration of this repository
  • Magisk developers for the magiskboot utility
  • all other used projects' developers (mentioned in the Requirements section)