GNAT.Serial_Communications broke on Ubuntu 26.04 / glibc 2.42+, here is why (and how to fix it)
Hey everyone,
If you’ve recently upgraded your Linux environment (running Ubuntu 26.04 or any distro with glibc 2.42+) and noticed your Ada serial port code suddenly stopped working, you aren’t losing your mind.
If you are using an Alire-provided GNAT toolchain (like GCC 15), there is a subtle breaking change under the hood of glibc that directly clashes with how GNAT bakes in OS constants.
The Problem: Glibc Changed the Rules
In glibc 2.42, Linux introduced support for arbitrary baud rates. As part of this change, speed_t was redefined to simply match the kernel interface as an unsigned integer representing the actual baud rate.
The Catch: GNAT relies on a file called
System.OS_Constants(s-oscons.ads), which is generated during the compilation of GNAT itself by probing the host OS headers.
Because Alire toolchains are typically compiled on older Linux releases for maximum compatibility, they are baked with the old octal/constant values. When you run that pre-compiled compiler on a brand-new OS, things break. Fortunately, only GNAT.Serial_Communications is affected.
The Proof is in the Headers
Look at the difference in termios-baud.h between Ubuntu 22.04 and Ubuntu 26.04:
ubuntu22.04$ grep 57600 /usr/include/x86_64-linux-gnu/bits/termios-baud.h
#define B57600 0010001
ubuntu26.04$ grep 57600 /usr/include/x86_64-linux-gnu/bits/termios-baud.h
#define B57600 57600U
If you regenerate s-oscons.ads on the new OS, look at the massive discrepancy:
- B57600 : constant := 4097; -- 57600 bps
+ B57600 : constant := 57600; -- 57600 bps
The Impact
When your code calls GNAT.Serial_Communications.Open ("/dev/ttyACM0", B57600);, your Alire-built compiler passes 4097 to the OS. But the new glibc interprets 4097 literally as 4097 baud instead of the magic constant for 57600!
(For more context, check out this Sourceware Bugzilla ticket.)
3 Ways to Fix It
If you are hit by this on Ubuntu 26.04 with Alire’s GNAT, here are three ways to get your serial ports working again, ranging from easiest to most advanced:
1. Use the System Package Manager (Easiest)
Instead of relying on Alire’s pre-built binary toolchain, switch to the GNAT compiler provided natively by Ubuntu. Because it was compiled directly on and for your current OS version, its s-oscons.ads file will perfectly match your system’s glibc.
- How: Install
gnatviaapt, and configure Alire to use the system compiler as an external toolchain.
2. Rebuild gnat_native via Alire Scripts
If you prefer to keep your toolchains fully managed inside Alire, you can custom-build your own native GNAT compiler right on your machine. This ensures the newly compiled toolchain probes your updated host headers.
- How: Use the build scripts provided by the community over at the Alire GNAT-FSF-builds GitHub repository.
3. Surgical Strike: Regenerate Just One File & Rebuild Ada RTL (Advanced)
If you don’t want to rebuild the entire compiler and just want to fix the Ada Run-Time Library (RTL), you can regenerate s-oscons.ads manually and swap it out.
How to do it:
- Unpack the GCC 15 source code somewhere onto your system.
- Navigate into the
gcc/ada/directory. - Run the following commands to generate the updated constants file:
# Preprocess the template with your current OS headers
gcc -DTARGET=\"x86_64-linux-gnu\" -C -E s-oscons-tmplt.c > s-oscons-tmplt.i
# Build the generator utility
gnatmake xoscons.adb
# Run it to output the new s-oscons.ads file
./xoscons s-oscons
- Take the newly created
s-oscons.adsfile from the current directory and replace the original file in your Alire toolchain path. - Use the scripts from the my GitHub repository to cleanly recompile the Ada RTL with the fixed file.
Has anyone else bumped into this yet? Let me know which solution worked best for your workflow!
- How: You can automate this specific runtime fix using the scripts available in the libada GitHub repository to rebuild your runtime cleanly.
Has anyone else bumped into this yet? Let me know which solution worked best for your workflow!