Get started with Lima on macOS
When working on C projects at Epita, your code is evaluated in an x86_64 Linux environment (Debian/Ubuntu).
Using macOS natively can lead to compatibility issues, especially when linking against precompiled static libraries (e.g. .a files) provided for x86_64.
Lima (Linux Virtual Machines) allows you to run a lightweight Linux VM on macOS with automatic file sharing between host and guest.
Architecture differences
| Mac Model | Native Architecture | Target Architecture | Solution |
|---|---|---|---|
| Intel Mac | x86_64 | x86_64 Linux | Standard Lima instance |
| Apple Silicon (M1/M2/M3/M4) | arm64 (aarch64) | x86_64 Linux | Rosetta 2 accelerated x86_64 VM |
Prerequisites
- Homebrew
- An IDE (VSCode, CLion, Emacs, ...) installed on macOS
Installation
Install lima along with lima-additional-guestagents via Homebrew.
lima-additional-guestagents is required on Apple Silicon Macs to run x86_64 guest virtual machines. Without it, Lima will fail with a guest agent binary could not be found error.
brew install lima lima-additional-guestagents
Creating and Starting the VM
Choose the initialization command according to your Mac's CPU architecture:
- Apple Silicon (M1/M2/M3/M4)
- Intel Mac
Run an x86_64 Linux VM accelerated by Rosetta 2 using the native macOS vz virtualization driver:
limactl start --name=ubuntu-x86 --vm-type=vz --rosetta template:ubuntu
Software emulation via QEMU is very slow and often causes boot timeouts (FATA: did not receive an event with the running status). Rosetta 2 provides near-native execution speed for x86_64 binaries.
On Intel Macs, a standard Linux VM works out of the box:
limactl start --name=ubuntu-x86 template:ubuntu
Setup the Linux Environment
Once the VM is created, enter the Linux shell:
lima -n ubuntu-x86
Inside the VM, update packages and install the essential C toolchain:
sudo apt update && sudo apt install -y \
build-essential \
gcc clang clang-format \
make cmake gdb valgrind \
libcriterion-dev libreadline-dev
Daily Workflow
- Open a terminal on your Mac and navigate to your project directory:
cd ~/path/to/your/project
- Open the Linux VM shell in this directory:
lima -n ubuntu-x86
- Edit your code using your favorite editor on macOS.
- Compile and run inside the Linux VM:
make
./my_program
- Exit the VM:
exit
Troubleshooting
1. skipping incompatible lib/libexample.a when searching for -lexample
- Cause: You are attempting to link an
x86_64static library inside anARM64(aarch64) Linux VM. - Fix: Ensure you created the VM with the
--arch=x86_64or--rosettaflag. Check your architecture inside Linux with:
uname -m
# Output must be: x86_64
2. cannot open output file my_program: Read-only file system
- Cause: The macOS shared mount in Lima dropped into read-only mode (often happens after system sleep).
- Fix:
- Quick workaround: Copy your project to the VM's
/tmpdirectory and compile there:
cp -r . /tmp/my_project && cd /tmp/my_project
make
- Permanent fix: Stop and restart the Lima instance from macOS:
limactl stop ubuntu-x86 && limactl start ubuntu-x86
3. guest agent binary could not be found for Linux-x86_64
- Cause: Missing
x86_64guest agent binaries on macOS. - Fix: Run the following commands on your Mac terminal:
brew install lima-additional-guestagents
limactl delete -f ubuntu-x86
limactl start --name=ubuntu-x86 --vm-type=vz --rosetta template:ubuntu
4. implicit declaration of function or format %f expects double
- Cause: Using a function without including its header file (
.h). In C89/C99, missing declarations default to returningint. - Fix: Include the appropriate headers at the top of your
.cfiles:
#include <stdio.h>
#include "my_header.h"
5. Silence unused parameter warnings for TODO stubs
When starting a project with unimplemented function stubs, compiler warnings can become overwhelming.
- Fix A (Makefile flag): Pass
-Wno-unused-parametertemporarily:
make CFLAGS="-Wall -Wextra -Wno-unused-parameter -Iinclude"
- Fix B (In C code): Cast unused variables to
void:
int my_function(int unused_param) {
(void)unused_param;
return 0;
}
Useful Commands
| Action | Command (on macOS) |
|---|---|
| Open Linux Shell | lima -n ubuntu-x86 |
| Start VM | limactl start ubuntu-x86 |
| Stop VM | limactl stop ubuntu-x86 |
| List VMs | limactl list |
| Delete VM | limactl delete ubuntu-x86 |
Add an alias to your ~/.zshrc on macOS for quick access:
echo 'alias linux="lima -n ubuntu-x86"' >> ~/.zshrc && source ~/.zshrc
You can now simply type linux in any project folder to drop into your x86_64 Linux environment.