Self-hosted service
sagemath/sage avatar
sagemath/sage

sage: autoconf and Meson in the same tree, and a build that refuses its own subprojects

Main repository of SageMath

2,577 stars949 forksPythonNOASSERTION

At a glance

What is it?
The SageMath source repository, mid-migration between two build systems, with a makefile that breaks on purpose under non-GNU make and a manifest that skips every bundled subproject. The practical constraints are the ones that cost people a weekend: ten gigabytes, no spaces in the path, and a stale Homebrew left on an Apple Silicon Mac.
Who is it for?
This fits someone who needs to build a specific Sage version from source, on Linux or macOS, for a reason a package manager cannot serve, and who can give the build a day and a machine with real disk and memory. It does not fit someone expecting a native Windows build or a one command install.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Two build systems are live in the same tree

The readme describes the familiar route: like many other software packages, Sage is built with configure followed by make. The tree still carries everything that route implies, an autoconf setup with configure.ac, a configure_wrapper, a bootstrap script, an m4 directory and a top-level Makefile.

Alongside all of that is a second, newer system. The manifest declares a Meson backend and requires Meson and meson-python to run it, and the tree has meson.build, meson.options, meson.format and a subprojects directory:

code
[build-system]
build-backend = 'mesonpy'
# Minimum requirements for the build system to execute.
requires = [
  'cypari2 >=2.2.1; sys_platform != "win32"',
  'meson >=1.11.2',
  'meson-python',

So a contributor arriving today can follow the readme and never touch Meson, or install the project as a Python package and never run configure, and both routes exist in the same checkout. The top-level Makefile is the seam between them: rather than listing targets, it defers anything it does not recognise to a second makefile under the build directory, which is where the real target definitions live.

The table of contents in the readme lists build system as its own section, next to directory layout, relocation and redistribution, so the migration is acknowledged as a topic rather than hidden. What the readme does not do is say which system is the intended one for a given release.

The Meson build skips its subprojects and must not be isolated

The manifest argues itself out of two Meson defaults, and the comments explain why in operational terms:

code
[tool.meson-python.args]
# Prevent meson from trying to install the autoconf subprojects
# otherwise we hit https://github.com/mesonbuild/meson-python/issues/598
# The subprojects have to set the rpath to the build directory, which should work as long as
# we don't use build isolation.
# Also don't install subprojects providing static libraries as per https://mesonbuild.com/meson-python/how-to-guides/shared-libraries.html#static-library-from-subproject
# This actually covers all current subprojects; so just don't install any of them. 
install = ['--skip-subprojects']
# Ensure that ``library`` targets are built as static, and nothing gets installed
setup = ['--default-library=static']

Two constraints come out of that. Every bundled subproject is skipped on install, because they provide static libraries and set their rpath to the build directory. And build isolation has to stay off, because that rpath only works while the build directory is the one in play. A build driven by an isolated environment, which is the default for a Python package build, is precisely the case this configuration cannot survive.

There is also a pinned exclusion with a bug reference attached, which is the clearest signal in the file about how this dependency is maintained:

code
  # Exclude 1.12.0 because of https://github.com/sagemath/cysignals/issues/212
  'cysignals >=1.12.1',

A single bad upstream release is fenced off by a lower bound one patch higher. The rest of the build requirements are the compiled parts of the system: cypari2, cython, gmpy2, numpy, memory_allocator and jinja2. None of those install cleanly from source without a C toolchain, and on macOS the readme names gfortran by hand.

PARI is excluded on Windows, which removes the native build there

One dependency carries a platform marker, and it appears in both the build requirements and the runtime dependencies:

code
  'cypari2 >=2.2.1; sys_platform != "win32"',

PARI/GP is a computer algebra system, and its bindings are not available on Windows at all. That is not a soft warning, because the readme already limits Windows support to a layer of indirection: Sage attempts to support the major Linux distributions, recent macOS, and Windows using the Windows Subsystem for Linux or virtualization. Native Windows is out on platform support, and out again on this dependency, so a Windows user is following the WSL instructions or a container.

The WSL guidance comes with numbers. Allocate enough memory that five gigabytes is known to work while two might not be enough for building from source, install a Linux distribution inside WSL, and then treat it as Linux, because all the Linux instructions apply unchanged.

The runtime side of the manifest is smaller than the build side: conway polynomials and six are named as ordinary dependencies, alongside the PARI bindings, which tells you how much of the mathematical core is a separate program rather than part of this package.

A random flag exists to break the build on purpose

The top-level Makefile contains a deliberate trap, and it explains itself in a comment. Unknown targets fall through a double-colon pattern rule, and before recursing it relocates if a helper is present:

code
# Defer unknown targets to build/make/Makefile
%::
	@if [ -x relocate-once.py ]; then ./relocate-once.py; fi
	$(MAKE) build/make/Makefile --stop
	+build/bin/sage-logger \
		"cd build/make && ./install '$@'" logs/install.log

The stop flag is described as a random flag used to induce graceful breakage with non-GNU versions of make, with an issue reference. In other words the build refuses to proceed on a make that does not understand the option, and it does so by design rather than by accident, which is a defensible choice and a confusing one to meet for the first time.

Two more couplings sit below it. A list named CONFIG_FILES has to stay in step with what configure.ac declares, because those are the generated files the build depends on. And a second list, SPKG_COLLECT_FILES, is defined as the package version files and dependency files under the build directory, with a comment stating that they influence the runtime of the generated configure script. That is the surprising one: editing a package version file changes what configure does when it runs, so the build has inputs that are not sources in any conventional sense.

Relocation is supported and the source directory is still immovable

The readme's own table of contents lists relocation, redistribution and changes to included software as sections, and relocation is not a theoretical topic here: the makefile runs a relocation helper before nearly every target, on the first invocation if the helper is executable. Moving an installed tree is a supported operation with machinery behind it.

That sits next to a flat prohibition in the build instructions. Decide on a source and build directory, and after starting the build you cannot move it without breaking things. The two statements are about different trees, and the distinction matters. Relocation moves an installation whose paths were recorded at build time; the build directory is the one place where moving invalidates the recorded paths, because generated makefiles, the log directory and the helper script all reference absolute locations. The instructions also require at least ten gigabytes of free disk, a full path containing no spaces, and warn against slow filesystems such as network file systems.

One more trap is specific to macOS and is a good example of a portability bug class the project asks for help with. macOS lets you change into a directory without matching its capitalization, and ignoring exact capitalization when entering the build directory causes build errors in dependencies that do require exact capitalization in path names.

Three Python versions, fifteen environment files, several ways in

The manifest declares a narrow support surface: Python 3 only, on CPython, for 3.12, 3.13 and 3.14, with the project marked as mature and aimed at education and research. Three consecutive versions is a deliberate policy for a system whose compiled extensions must be rebuilt for each interpreter.

The packaging surface is much wider than that count suggests. The root carries fifteen conda environment files, three Python versions across five targets each, covering Linux, Linux on aarch64, macOS, macOS on x86_64 and Windows. Alongside them sit a conda configuration file, a Homebrew build environment directory, a devcontainer definition, a Gitpod configuration, and a docker directory. That is five independent distribution routes for one program, and the Installation Guide is described as a decision tree for choosing between them.

The readme puts the zero-install options first, before any of it. Three hosted environments are linked at the top for anyone impatient, and the framing is explicit that these need no local installation. A tarball of sources is the alternative to cloning, and support questions go to a mailing list or a question and answer site rather than the issue tracker.

The default make target builds Sage together with the whole HTML documentation, while a separate build target builds only Sage. Anyone who wants the software and not the manual can save a substantial part of the build.

A stale Homebrew in /usr/local breaks an Apple Silicon build

The macOS preparation section leads with a migration hazard rather than an install step. On an Apple Silicon Mac, which it names as the M1 through M4 arm64 generations, a machine set up by transferring files from an older Mac can carry an x86_64 copy of Homebrew in the directory the older architecture used. Homebrew for the M1 installs into a different directory, and the two coexist badly enough that the build picks up the wrong one.

That matters because of what Homebrew is being recommended for. The readme strongly recommends it as the way to get the gfortran compiler and a set of libraries, and the only alternative offered is installing the Xcode Command Line Tools by running a single command and confirming in a dialog. If those tools are already present, the readme suggests a second command to check whether they need updating, since an out of date toolchain is a different failure from a missing one. Conda users are pointed at a section of the installation manual instead, which keeps that route out of this file entirely.

So the macOS path has three branches, and the failure the first branch prevents is invisible until a compiler is not found in the expected place.

The licence lives in prose and is missing from metadata

The metadata carries no licence value at all, and the root holds a copying file rather than a licence file. What the readme says is that Sage is released under the GNU General Public Licence at version 2 or later, and that it includes packages carrying compatible software licences, with a link to that file. Those are different statements: the project as a whole is copyleft, and some of what it ships is not, and the file that would sort out which is which is the one the metadata does not point at.

Project bookkeeping around it is unusually complete. There is an authors file, a code of conduct and a separate committee file for it, a citation file generated from a template, which is how a release gets a machine readable citation without anyone editing it by hand, a dependency update configuration, and a codecov configuration.

The release pattern is short cycle. Version 10.10 was published on 28 September 2026, a beta of the next major line appeared the following day, and a second beta landed on 3 October, with the default branch set to develop. The last commit is dated 29 September 2026, so the tree is at or slightly ahead of the most recent tag, and the mission the readme opens with is a viable open source alternative to the four commercial systems it names.

Editorial conclusion

This fits someone who needs to build a specific Sage version from source, on Linux or macOS, for a reason a package manager cannot serve, and who can give the build a day and a machine with real disk and memory. It does not fit someone expecting a native Windows build or a one command install. Before starting, decide which of the two build systems you are actually using, because the readme still says configure and make while the manifest declares a Meson backend, and install the toolchain the build names rather than discovering it needs gfortran halfway through. If you are on Apple Silicon, check what is sitting in /usr/local first, and if you have an existing checkout, read the relocation notes before you move anything.

Frequently asked questions

Is SageMath just Python?

Python is the interface, and the manifest declares Python 3 only on CPython for 3.12 to 3.14, but the build compiles real extensions and links external systems: cypari2 for PARI/GP, cysignals, cython, gmpy2, numpy and memory_allocator. On macOS the readme tells you to install the gfortran compiler first.

sage vs sagemath

SageMath is the project and the distribution name, published at sagemath.org, and the repository is sagemath/sage. Sage is the system itself and the command you run. The readme uses both, describing the licence as SageMath's while calling the software Sage.

What is the use of SageMath?

The stated aim is creating a viable open source alternative to Magma, Maple, Mathematica and MATLAB. The readme sends you to an installation guide organised as a decision tree, covering building from source, package managers, container images, cloud use, and three hosted environments that need no local installation.

Is SageMath better than Mathematica?

Nothing in the tree makes such a comparison, and no benchmark appears anywhere in it. Its tagline is a statement of intent about being an open source alternative to those systems, and the readme's supported platform and build sections say nothing about speed or feature coverage.

What does building Sage from source require?

At least ten gigabytes of free disk, a full path with no spaces, and a filesystem that is not NFS. On WSL, five gigabytes of memory is known to work while two may not be enough. The default make target also builds the full HTML documentation, while the build target skips it.

Official sources

  1. Issues
  2. Project website
  3. README
  4. Releases
  5. sagemath/sage on GitHub
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/sagemath-sage.svg)](https://hysenlabs.com/projects/sagemath-sage)