musl-cross-make: building a relocatable musl cross-compiler
Simple makefile-based build for musl cross compiler
At a glance
- What is it?
- musl-cross-make is a Makefile-based build system for producing GCC cross-compilers that target musl. It handles source acquisition, patching, staged libc construction and installation, but it remains a compiler build project rather than a packaged toolchain service.
- Who is it for?
- Adopt musl-cross-make when you specifically need to build or bootstrap a musl-targeting GCC toolchain and are prepared to manage compiler source builds. Do not choose it for a quick binary distribution, an unsupported target variant or a production toolchain without first checking `config.mak`, `presets/*`, the selected component versions, host prerequisites and licensing for the generated artifacts.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 17 days ago.
- What is it written in?
- Mainly Makefile, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on November 7, 2026, and from our analysis. They are not legal advice.
Star history
- richfelker/musl-cross-make1,596 ★ · +4
| Repository | 2026-10-17 | 2026-11-07 |
|---|---|---|
| richfelker/musl-cross-make | 1.6k | 1.6k |
4 Stars in the last 21 days, measured from the daily GitHub snapshot. Compare with other projects
Editorial analysis
The musl cross-compiler problem addressed by musl-cross-make
musl-cross-make addresses the difficult part of assembling a cross-compiler whose target C library is musl. A native compiler and target libc are not enough by themselves: GCC, binutils, libc headers, static libraries, shared libraries and target support libraries have to be configured in a compatible order. The project turns that work into a Makefile-driven build for users who need to produce musl-linked applications, bootstrap another system or test musl and toolchain changes.
The intended result is a GCC cross-compiler for a selected target tuple, such as `x86_64-linux-musl` or `aarch64-linux-musl`. The README lists several architecture families, including ARM, MIPS, PowerPC, RISC-V, s390x, SuperH and x86. That list is explicitly non-exhaustive and describes tuples that are believed to work, so it should be treated as guidance rather than a compatibility guarantee.
This is not a hosted compiler service or a collection of prebuilt binaries. It is a source-build system. Its strongest documented properties are practical ones: the compiler does not depend on hard-coded absolute paths, installation is separate from compilation, and one set of patched source trees can support multiple target builds. Those properties fit developers who understand build systems and need control over target support patches. They do not fit users seeking a downloadable toolchain with a packaged installation path.
Two-layer architecture from source archives to target libraries
The repository separates orchestration from compilation. The top-level Makefile downloads and verifies source archives, extracts them, applies patches and creates a build directory. Litecross is symlinked into that build directory and performs the cross-compiler work. According to the README, Litecross can also operate independently with a pre-extracted and properly patched source tree collection.
The build uses a single-stage GCC process for musl and for target shared libraries that depend on the libc. It does not install intermediate files as part of the initial build. This matters for staging because Litecross can construct a temporary sysroot without writing a partially usable toolchain into the final installation directory.
Litecross first assembles `src_toolchain`, a directory of symlinks combining GCC and binutils sources with GMP, MPC and MPFR. One configured invocation establishes the GNU toolchain components without requiring them to be installed first. It then builds GCC and enough of its prerequisites to obtain `xgcc`. That executable configures musl. Musl headers are installed into a staged build sysroot, after which GCC can build `libgcc.a` against those headers.
The dependency sequence then becomes libc itself. Once `libc.a` and `libc.so` exist, GCC's other target libraries have the libc facilities they require, allowing the full toolchain `make all` stage to proceed. This staged ordering is the core technical contribution of the project. It also explains why this is more than a set of patches for a conventional two-stage compiler build.
Source versions, target selection and fetch verification
The top-level Makefile selects component versions through variables rather than requiring a separate dependency manager. As shown in the repository Makefile, the default selections include binutils 2.44, GCC 9.4.0, musl 1.2.6, GMP 6.3.0, MPC 1.3.1, MPFR 4.2.2 and Linux headers 4.19.88-2. It also defines `CONFIG_SUB_REV`, source locations, `wget -c -O` as `DL_CMD` and `sha1sum -c` as `SHA1_CMD`.
Downloads are checked against files under `hashes/`. The README describes this as HTTPS source acquisition with hash checking. GCC prerequisites are included in that process. An external `SOURCES` path is treated as immutable, so an organization can provide source archives separately without allowing the Makefile to modify that directory.
Configuration is intentionally lightweight. `config.mak` is read by the Makefile through an include directive, and `TARGET` is the only mandatory variable. `OUTPUT` controls the installation root and defaults to `output` for a local build. When `NATIVE` affects the computed host portion, the output name also gains a host-specific suffix. The repository includes `config.mak.dist` and files under `presets/` for concrete configuration examples, which are the right starting points for evaluating a particular architecture.
The repository has no GitHub releases. That means there is no release artifact described by the project metadata, and operators should account for the cost of building the configured source versions themselves.
Installing config.mak and performing the first toolchain build
Start with `config.mak.dist` or a matching file under `presets/`, then set the mandatory target tuple in the top-level `config.mak`. The following example uses a target tuple explicitly listed by the README. Confirm the selected presets and component variables against the checked-out repository before treating the file as a production configuration.
TARGET = x86_64-linux-muslRun `make` from the repository root. According to the README, this downloads and verifies missing archives, extracts and patches the sources, prepares the build directory and compiles the cross-compiler. Nothing is installed by this step. The command can therefore be stopped after compilation while leaving final placement until the installation stage.
After compilation succeeds, install the toolchain under `$(OUTPUT)`. With the default `OUTPUT`, the documented destination is `output` in the repository directory.
make installThe README states that the resulting cross compilers have no hard-coded absolute paths and may be copied or moved after installation. The first practical verification should therefore include checking that the expected cross-tool names are present beneath `output` and invoking the compiler appropriate to the configured `TARGET` with a small program. The exact executable name is derived from the target tuple, so it should not be assumed to be the same for every configuration.
For another architecture, create or select another `config.mak` with a different `TARGET`. The documented design permits multiple cross-compilers to be built from the same patched source trees, but each target still needs a coherent configuration and separate build directory under `build/`.
Patch scope, supported component combinations and build constraints
musl-cross-make carries canonical musl support patches for GCC and binutils, plus changes described as static-linked PIE support, `--enable-default-pie`, SuperH bug fixes, J2 Core CPU target support and SH/FDPIC ABI support. Many of these changes are said to be integrated into GCC trunk or binutils master, but that does not make every historical component version equivalent to a current upstream release.
The README also records version boundaries. SH/FDPIC and J2-specific functionality is available only with GCC 5.2.0 or later and binutils 2.25.1 or later in the context described by the project. This matters because the default Makefile pins GCC 9.4.0 and binutils 2.44, while users may be tempted to substitute other versions. The README does not provide a general compatibility matrix for those substitutions.
Project scope is deliberately narrow. Patches are intended not to break non-musl configurations, but musl-cross-make itself targets musl. Exotic target variants outside upstream musl support are probably outside scope unless a change is non-invasive. Fixes that allow the build system to run on non-Linux systems are considered acceptable when implemented cleanly.
The source build also depends on a capable build host. The documentation discusses support fixes for non-Linux systems but does not publish a tested host matrix in the available text. Disk consumption, build duration, parallelism controls and host package prerequisites are not documented here. Those are material adoption constraints for compiler builds, even though they do not affect the correctness of the staged dependency model.
Relocation, maintenance and licensing boundaries
Relocation is a documented property, not an assumption. The build avoids hard-coded absolute paths, and the README says the installed compiler can be moved anywhere. `OUTPUT` is selected only at installation time, which keeps compilation and deployment separate. An external `SOURCES` archive directory is also treated as immutable, giving organizations a defined boundary between source acquisition and build output.
The repository is not archived and was recently updated, but that does not guarantee support for every target or component combination. The absence of GitHub releases leaves the Makefile and repository documentation as the authoritative configuration surface described here.
The MIT/Expat license covers the build tools and documentation. It does not cover files under `patches/` or resulting binary artifacts. Each patch follows the license of its upstream project, while generated binaries retain the licensing of the upstream components from which they derive. Contributors must not add further terms unless they explicitly state otherwise. This is a licensing boundary to track, not legal advice: a distribution containing the installed compiler must account for GCC, binutils, musl, GMP, MPC, MPFR, Linux headers and any separately distributed patches under their respective terms.
Why Litecross is the relevant alternative to the top-level workflow
The repository itself identifies a meaningful alternative path: use Litecross without the musl-cross-make top-level build system. Litecross performs the compiler construction from already prepared source trees, while the top-level Makefile adds source download, verification, extraction, patching and build-directory setup.
The difference is ownership of source preparation. A team that already maintains patched GCC, binutils, musl and prerequisite source trees can feed those trees to Litecross directly. This may fit a reproducible internal toolchain pipeline that applies changes through another build or source-management process. It also avoids making the musl-cross-make top-level acquisition layer part of that pipeline.
Litecross is not a convenient alternative for a first-time user who does not yet have properly patched trees. Its documented requirements include a `TARGET` configuration, the expected source layout, musl support patches and enough compiler prerequisites. The top-level musl-cross-make workflow is more approachable because it owns those preparation steps. The practical comparison is therefore between an integrated musl-specific build system and a lower-level compiler build driver for organizations that already control their source inputs.
Editorial conclusion
Adopt musl-cross-make when you specifically need to build or bootstrap a musl-targeting GCC toolchain and are prepared to manage compiler source builds. Do not choose it for a quick binary distribution, an unsupported target variant or a production toolchain without first checking `config.mak`, `presets/*`, the selected component versions, host prerequisites and licensing for the generated artifacts. On the documented configuration, the decisive check is whether `make` reaches `make install` and produces the expected toolchain under `output`.
Frequently asked questions
What does musl-cross-make build?
It builds a GCC cross-compiler that targets musl. The build also assembles binutils, musl, GCC prerequisites and target libraries required by the selected `TARGET`.
How do I install and build a musl cross-compiler with musl-cross-make?
Create `config.mak` with the mandatory `TARGET` variable, then run `make` followed by `make install`. The default `OUTPUT` is `output`, and installation is separate from compilation.
Can the musl-cross-make compiler be moved after installation?
Yes. The README states that the resulting cross compilers have no hard-coded absolute paths and can be copied or moved after installation.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/richfelker-musl-cross-make)Star history chart for your README
[](https://hysenlabs.com/projects/richfelker-musl-cross-make)Was this useful?