BUILD

Almost everyone should just follow the INSTALL page. It installs the tools, builds SATELLITE and installs it, and you never need to read this one. This page is for people who want to know how the build works, or want to change it.

SATELLITE 004 is built with GNU make on AlmaLinux 10 (x86-64). Everything happens inside the folder you downloaded. A plain make builds satl and its libraries into build/, then installs them into ~/.satl.

The top-level Makefile is an index. Each part of the build lives in its own numbered file under make_support/, and each one explains its choices in comments beside the code. If you want to change something, the index tells you which file to open.

COMPILERS

SATELLITE is written in C++20. make picks the compiler for you, in this order:

  1. ~/opt/clang-current/bin/clang++, if you keep your own clang there.
  2. clang++, if there is one on your PATH.
  3. c++, which on AlmaLinux is g++.

To choose a compiler yourself, name it: make CXX=g++ or make CXX=clang++. A CXX set in your environment wins too.

It is known to build with clang 21 and g++ 14, the versions AlmaLinux 10 ships, and with clang 24. Older compilers have not been tried. The carried GTK (below) must be built with clang.

Two things only clang gives you:

  • The speed-up steps. PGO, ThinLTO and BOLT are clang’s. With g++ you get a plain -O2 build.
  • The carried GTK. make window refuses to start without clang.

A satl built on AlmaLinux 10 needs glibc 2.38 or newer and the libstdc++ that comes with gcc 13 or newer. AlmaLinux 10 has both. AlmaLinux 9 does not, so a satl built on 10 will not run there.

WHAT YOU INSTALL FIRST

The same command as on the INSTALL page. ninja-build and nasm come from AlmaLinux’s CRB repository, which --enablerepo=crb turns on for this one command:

install-the-tools.shBASH Download
Every package the build uses
sudo dnf install --enablerepo=crb git make clang lld llvm gcc-c++ python3 ninja-build cmake bison perl pkgconf-pkg-config wayland-devel libglvnd-devel nasm tar xz bzip2

What each group is for:

  • clang and gcc-c++: the compilers. llvm gives llvm-profdata, which PGO needs. lld gives ld.lld, which ThinLTO needs.
  • git, make and python3: the download and the build itself. Parts of the build are small Python programs.
  • ninja-build, cmake, bison, perl, pkgconf-pkg-config and nasm: the tools make window uses to build the carried GTK. It also needs Python 3.11 or newer, and AlmaLinux 10 has 3.12. tar, xz and bzip2 unpack its sources.
  • wayland-devel and libglvnd-devel: the Wayland libraries and the graphics headers GTK is compiled against. Wayland stays the machine’s own at run time (see below).

WHAT A PLAIN MAKE DOES

Roughly in this order:

  1. Decides the build number. If anything satl is made from has changed since the last build (a source file, the compiler, the flags), the build number goes up by one before anything compiles. See THE BUILD NUMBER below.
  2. Builds the numbered libraries. Every word of the language is a small compiled library named by the word’s number, such as 1.5.1.so. There are 62 of them, and they go into build/satellite-numbers/. satl loads them from the folder beside itself when it starts.
  3. Compiles satl into build/satl, with each object file under build/objects/. A change recompiles only the files it touches.
  4. Trains and optimises it (PGO, ThinLTO and BOLT, below).
  5. Links GTK inside it, if make window has built the carried GTK, and checks what the finished satl needs from the system.
  6. Checks the build number. It runs the new satl --version and makes sure the number it shows is the one just decided. If they differ, the build fails rather than lying.
  7. Builds the test helpers that make check uses, and satl-cpu-level.
  8. Installs. It copies satl and its libraries into ~/.satl, runs a small program with the installed copy to prove it works, and writes the Satellite 004 menu entry.

The install writes these into your home folder:

  • ~/.satl/satl: the interpreter.
  • ~/.satl/satellite-numbers/: its libraries.
  • ~/.satl/.satellite-004-install: a record of every file the install put there, with its checksum.
  • ~/.satl/config.ini: your settings. It is written once and never overwritten, so your settings survive every update.
  • ~/.local/share/applications/org.satellite.terminal.desktop: the menu entry. It names satl by its full path, so it works even though a desktop session doesn’t look in ~/.local/bin.

The install does not put satl on your PATH. Step 4 of INSTALL makes the link.

To run a satl you have built without installing it, use its path: build/satl hello.satl.

PGO, THINLTO AND BOLT

A plain make lays satl out by what a real run of it does. There are three steps, and each one switches itself off when its tool is missing:

  1. PGO (profile-guided optimisation). make builds a second satl with counters in it, in build/pgo-train/. It runs four training programs with it and merges what they counted into a profile. This needs llvm-profdata.
  2. ThinLTO. satl‘s own objects are compiled with that profile and linked by ld.lld, which can optimise across files. This needs ld.lld.
  3. BOLT. The linked satl runs the training again and llvm-bolt rearranges it, so the code that ran sits together. AlmaLinux ships no llvm-bolt, so on AlmaLinux’s own clang this step is skipped. If BOLT fails, make keeps the satl it linked, says why, and carries on.

The tools must sit beside the compiler, in the same folder as clang++. A profile written by one version of LLVM can’t be read by another, so make never picks them up from elsewhere on your PATH.

Only satl‘s own code gets this treatment. The word libraries are built plainly, because the measured runs spent almost no time in them.

On the machine it was measured on, this made satl about 8 to 13 percent faster than a plain -O2 build. -O3, and building for that machine’s own processor, made no difference that could be measured.

The link line says what you got. On AlmaLinux 10 with its own clang, after make window, it reads:

link-line.txtTEXT Download
What the link line says with AlmaLinux's clang, lld and llvm
linking build/satl -- vendored (GTK carried inside satl) -- PGO ThinLTO (no llvm-bolt beside clang++: no BOLT)

THE CARRIED GTK

satl draws its windows and its console with GTK, and it carries its own GTK inside the program. That is why nobody who runs satl has to install GTK.

  • Where it comes from. The download includes the frozen source code of every project in the stack: GTK 4.24, glib, pango, cairo, harfbuzz, freetype, fontconfig, VTE for the console, and the rest. Each one is checked against a SHA-256 sum before it is unpacked.
  • make window builds it into vendor/stage/ and vendor/build/gtk/. It uses no network. It takes a few minutes, and each project writes a log under vendor/build_logs/. It can be resumed: run it again and it skips every project already built. make never runs it for you, because it takes minutes and needs tools a plain build does not.
  • make then links it into satl. It checks the result, and the finished satl may need only these libraries from the system: libc, libm, libstdc++, libgcc_s, the loader, libwayland-client and libwayland-egl. If anything else shows up, the build fails and names it. Wayland stays the machine’s own on purpose, because the graphics driver loads its own copy, and two copies in one program crash.
  • Without it, make still builds a satl that runs every program. The window and console words refuse by name, and make ends with a notice telling you to run make window.
  • The licences. satl carries the licence of every project inside it. satl --license lists them, and the LICENSES page has them too.

satl and its libraries link libstdc++ dynamically on purpose. The libraries are loaded while satl runs, and they must all share one copy with it. A second copy would mean a second std::cout, and a failed write could then report success.

SWITCHES

Each of these is a whole command, run in the satellite folder:

  • make OPTIMISE=no: a plain -O2 build, with no training. It’s quicker while you’re changing satl‘s source, because with training on, every change means training and recompiling again. Switching between the two rebuilds everything and uses a build number each way, so pick one and stay in it.
  • make INSTALL_AFTER_BUILD=no: build, but don’t install into ~/.satl.
  • make -j4: run 4 jobs at once. The default is 24. Use fewer on a machine with little memory, or one that’s busy.
  • make CXX=g++: choose the compiler (see COMPILERS).
  • make OPT=-O3: change the optimisation level. Use OPT and never CXXFLAGS, which would replace the whole set of flags, -std=c++20 included.
  • make check: build (without installing) and run the test suite. It runs satl on every example and test, and checks what each one prints and the code it exits with. To test the installed copy instead, run SATL=~/.satl/satl ./check.sh.
  • make clean: delete build/. The carried GTK and the build number are kept, so the next make is the same build, not a new one.
  • make GTK=system: link the GTK installed on the machine instead of carrying one. satl is then much smaller, but it needs GTK installed to open a window. Building this way needs gtk4-devel, plus vte291-gtk4-devel from CRB for the console. The carried GTK is the build that gets tested.

To install into a different folder, run the installer yourself: sh satellite_enterprise/install.sh --root <folder>. It refuses folders that are on your PATH and /usr/local, and it only writes the menu entry for ~/.satl.

ONE BUILD PER PROCESSOR

The ordinary satl is built without naming a processor (no -march), so it runs wherever your compiler’s ordinary output runs. You can also build copies tuned for particular processors:

  • make CPU=haswell builds build/cpu/haswell/satl and its libraries with -march=haswell. Run an ordinary make first: a processor’s build is the same build number, made from the same source. It installs nothing, never raises the build number, and gets no PGO, because a machine can’t train a build it may not be able to run.
  • make cpus does the ordinary build and then one build for each of 53 processor families, from core2 and k8 up to znver6 and diamondrapids. It took about half an hour at 24 jobs on the machine it was written on. A family your compiler doesn’t know is skipped, with a message.
  • build/satl-cpu-level says which of the builds in build/cpu/ this machine runs best. --explain lists every build, what it needs, and what this machine lacks. It chooses by the instructions a build needs, never by a processor’s name.
satl-cpu-level.txtTEXT Download
Part of what build/satl-cpu-level –explain printed on one machine
  amdfam10           needs   7  lacks 2: __PRFCHW__ __SSE4A__
  bonnell            needs   5  runs here
  broadwell          needs  25  lacks 3: __ADX__ __PRFCHW__ __RDSEED__
  ...

this machine runs haswell best

None of these is installed. To use one, run it by its path, for example build/cpu/haswell/satl hello.satl.

THE BUILD NUMBER

satl --version shows three numbers:

version.txtTEXT Download
The first two title lines, from one build
THE SATELLITE PROGRAMMING LANGUAGE
VERSION 004 REVISION 08 BUILD 0043
  • VERSION is the language: 004.
  • REVISION is the step within that version.
  • BUILD counts the builds of this revision. make raises it by one whenever something satl is made from has changed: a source file, the compiler or its flags. A make with nothing to do keeps the number, and so do make clean, a retry after a failed build, and two makes at once. When the revision goes up, the count starts again at 1.

The third title line names the compiler and the system it was built on, such as CLANG++ 21 ALMALINUX 10.2.

The number lives in the source, in satellite/config/satellite_config.hpp, and the last number used is kept in .satellite_build in the top folder. That’s why a download’s first build is one higher than the number in the source. It’s also why updating takes two extra lines, as the UPDATING part of the INSTALL page shows.

FIXING COMMON FAILURES

THIS satl HAS NO WINDOW

no-window.txtTEXT Download
The notice at the end of make
  THIS satl HAS NO WINDOW. It runs every program; the window and console words refuse by name.

The carried GTK isn’t built yet. Run make window, then make.

make window says there is no clang

no-clang.txtTEXT Download
What make window prints
make window: the carried GTK is built with clang, and this machine has none (AlmaLinux: sudo dnf install clang)

Run sudo dnf install clang.

missing build tools, nasm, or wayland-client.pc

missing-tools.txtTEXT Download
What the GTK build prints when a tool is missing
vendor/build_stack.py: missing build tools: ninja, cmake
vendor/build_stack.py: libjpeg-turbo needs nasm (REQUIRE_SIMD=1) -- AlmaLinux: sudo dnf install --enablerepo=crb nasm
vendor/build_stack.py: /usr/lib64/pkgconfig/wayland-client.pc is missing -- GTK cannot be built without it

Install what it names: ninja-build (from CRB), cmake, bison, perl, make or pkgconf-pkg-config for the first, nasm from CRB for the second, and wayland-devel for the third. Then run make window again. It carries on from where it stopped.

The link line says no PGO or no ThinLTO

no llvm-profdata beside clang++: no PGO means the llvm package is missing, and no ld.lld beside clang++: no ThinLTO means lld is. Install them and run make. no llvm-bolt beside clang++: no BOLT is normal on AlmaLinux, which doesn’t ship BOLT. It isn’t an error.

Out of memory, or posix_spawn failed

make runs 24 jobs at once. On a small or busy machine, run make -j4.

note: not installing as root

make was run with sudo, and it won’t install into root’s home folder. Run make as yourself. If sudo make left files you can’t overwrite, give the folder back to yourself with sudo chown -R "$USER": ~/satellite and run make again.

git pull refuses: your local changes would be overwritten

The file it names is satellite/config/satellite_config.hpp, where make writes the build number. Put it back, pull, clear the record of the last number, and build:

restore-then-pull.shBASH Download
Undo the build number's change, then update
git restore satellite/config/satellite_config.hpp
git pull
rm -f .satellite_build
make

arguments.build is …, but build … was already used

build-number-refused.txtTEXT Download
What make prints when the source's number is below the last one used
build_number.py: satellite_config.hpp: arguments.build is 44, but build 46 was already used (an editor saved an older copy?); write a number above 46, or delete .satellite_build to start over

The number in the source is lower than the last number your machine used. That happens after git restore or git pull. Delete the record of the last number and build again. The count carries on from the number in the source.

reset-build-number.shBASH Download
Start the build count again from the number in the source
rm -f .satellite_build
make

satl: command not found

The build and the install worked, but satl isn’t on your PATH. Make the link in step 4 of INSTALL, then open a new terminal.

Notes that are not failures

  • note: BOLT failed (...) means satl is kept with PGO and ThinLTO, and the logs are in build/bolt/.
  • note: ... cannot link -fsanitize=undefined here means one test helper is built without the checker it would like. Nothing is missing from satl.