a simple portable CMake-based build system for magiskboot
magiskboot itself depends on the following libraries:
for build-time dependencies:
- pkg-config
- Clang (maybe also others, but GCC doesn't work, see this part)
- Rust (stable channel is OK... spoiler:
RUSTC_BOOTSTRAP
HACK is used) - CMake
- 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
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
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
Linux
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
.
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
sudo pacman -S --needed base-devel xz lz4 bzip2 zlib pkgconf \
clang libc++ cmake ninja rust
macOS
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?)
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
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
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.
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
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
Please refer to Magisk documentation.
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.
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.
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"
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.
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.)
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
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
Please use debug builds and paste your information (like crash or error logs) in a new Issue.
If you need to build with Libstdc++ instead of Libc++, pass -DWITH_LIBCXX=OFF
to CMake during configuring, also apply this patch.
Make sure you are using Clang to build. GCC doesn't work because of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=36566
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.
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.
To quickly discard the current build
directory and dirty vendored submodule (src/
) changes, please run make clean
.
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.
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.
- 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)