Cross-compilation SDK for use with checkra1n.
The SDK for each target is built in build/[target]. When cross-compiling checkra1n, this folder should be passed in the appropriate environment variable.
Example:
LINUX_STATIC_ARM64_SDK=/path/to/this/repo/build/arm64-linux-musl make
- If you'd like to use this to cross-compile something other than checkra1n, then you will have to pass this folder to clang with the
--sysrootoption. - For statically linked Linux, you'll also want to pass
--rtlib=compiler-rtand-resource-dir=/path/to/this/repo/build/[target]/lib/clang. - For statically linked Windows, you'll want to pass
-I$(clang -print-resource-dir)/includein addition to the former two.
The SDK is split into several logical components, which can be built individually for the selected target(s). The basic way to build any component is by running:
./make.sh [target] [component]
Multiple components may be given in one invocation.
Example: ./make.sh x86_64-linux-gnu libc ncurses
See the next section for a detailed list of supported combinations of targets and components.
When in doubt, all can be used as a component name to build all components needed to compile checkra1n.
There are two more supported invocations to clean the build environment:
./make.sh clean - Removes all extracted and built files, but keeps downloaded files and configuration artifacts.
./make.sh distclean - Same as above, but also removes downloaded files and configuration artifacts.
The supported targets fall into the following categories:
-
Debian-based Linux
This uses dynamic linking and pulls packages straight from the Debian 8 package mirror. That should make compiled programs compatible with rather old builds of Debian, Ubuntu, and other Debian derivatives.
The target identifiers for this are:all-linux-gnu(acts as short-hand for all targets below)armel-linux-gnu(ARMv4T, soft-float)armhf-linux-gnu(ARMv7, hard-float)arm64-linux-gnux86-linux-gnu(i486)x86_64-linux-gnu
-
Bare-bones Linux
This uses static linking and builds the required components from source. That should make compiled programs run on virtually any flavour of Linux, but produces bigger binaries and does not support GUI libraries.
The target identifiers for this are:all-linux-musl(acts as short-hand for all targets below)armel-linux-musl(ARMv6, soft-float)arm64-linux-muslx86-linux-musl(i486)x86_64-linux-musl
armhfis not supported because statically linkedarmelbinaries should work just fine there. -
Windows
This uses static linking and builds the required components from source.
The target identifiers for this are:all-windows(acts as short-hand for all targets below)armhf-windows(ARMv7, hard-float)arm64-windowsx86-windows(i686)x86_64-windows
The list of supported components is:
-
all
Builds all supported components for the selected target. -
libc
Builds the C standard library, compiler runtime library and kernel interface headers. -
libc++
Builds the C++ standard library. -
ncurses
Builds ncurses.
Here's an overview of supported combinations of targets and components:
| Target | libc | libc++ | ncurses |
|---|---|---|---|
*-linux-gnu |
✅ | ✅ | 🚫 |
*-linux-musl |
✅ | ✅ | ✅ |
*-windows |
✅ | 🚫 | 🚫 |
There are two "undocumented" targets, arm64-linux-gnu-dev and x86_64-linux-gnu-dev (along with the all-linux-gnu-dev short-hand). These only accept the all component and are only used to build parts of the Linux toolchain necessary to build checkra1n.
The *-linux-gnu targets are based on the following packages (and their dependencies) from the Debian 8 package mirror:
libc6 (>= 2.19)libstdc++6 (>= 4.9.2)
The *-linux-musl targets are based on the following source tarballs:
The kernel source has been stripped to only include userspace headers like so:
find . -depth 1 -not \( -name arch -o -name include -o -name COPYING -o -name CREDITS \) -print0 | xargs -0 rm -rf
find include -depth 1 -not -name uapi -print0 | xargs -0 rm -rf
find arch -depth 2 -not -name include -print0 | xargs -0 rm -rf
find arch -depth 3 -not -name uapi -print0 | xargs -0 rm -rf
printf '#define LINUX_VERSION_CODE 200789\n#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))\n' >include/uapi/linux/version.h
The LLVM source has been stripped to only include the projects that are actually built.
The *-windows targets are based on the following source tarballs:
mingw has a patch applied to compile with clang.
All over the place, check individual components.