Maintain Homebrew for Apple Silicon and Rosetta

macos terminal rosetta homebrew apple-silicon

I needed to have Homebrew available for x86_64 in Rosetta mode without conflicting with native Apple Silicon mode.

To do that:

  • Instantiate a new Terminal running in Rosetta: open -a Terminal --new --arch x86_64
  • In the new Terminal, install Homebrew as per the official manual:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  • Edit .zprofile to:
    • Output current architecture
    • Add x86 to Terminal title when running in Rosetta mode
    • Use corresponding brew version to match current architecture
title() {
    printf '\e]0;%s\a' "$1"
}

# Detect architecture and set up Homebrew accordingly
ARCH=$(arch)
echo "Current architecture: $ARCH"
if [[ $ARCH == "arm64" ]]; then
    # Apple Silicon
    eval "$(/opt/homebrew/bin/brew shellenv)"
else
    title "x86"
    # Intel
    eval "$(/usr/local/bin/brew shellenv)"
fi

Run Applications in Rosetta on macOS

macos terminal rosetta

I needed to run Terminal in x86_64 mode (Rosetta) in parallel with Terminal in arm64 (Apple Silicon native mode), but in the latest versions of macOS, the old way of creating a copy of the Terminal application and selecting Open using Rosetta in Get Info is not available, since Terminal can’t be copied anymore due to security restrictions.

To overcome this, you can use the following command to open any application in Rosetta mode from either Terminal or Automator:

open -a Terminal --new --arch x86_64

This will open a new instance of the Terminal application. To verify Intel emulation mode, running the arch command should output i386 as opposed to arm64 when running natively.

To switch to x86_64 in an already running Terminal session, execute the following command. Note that ~/.zprofile and other shell setup scripts will not be sourced, and the new shell running under x86_64 will inherit the initial shell environment.

arch -arch x86_64 $SHELL

GPIO as Keyboard on Linux

gpio linux keyboard

The Linux kernel provides the gpio-keys driver (CONFIG_KEYBOARD_GPIO) that can map GPIO pins to keyboard keys and expose them to userspace as input devices.

Minimal device tree overlay fragment example:

&{/} {
    gpio_keys {
        compatible = "gpio-keys";
        #address-cells = <1>;
        #size-cells = <0>;

        enter_button {
            label = "enter";
            linux,code = <KEY_ENTER>;
            gpios = <&gpio1 2 GPIO_ACTIVE_HIGH>;
        };
    };
};

Check your board documentation and device tree for GPIO controller names, indexes, and mapping to physical pins. You might also need to adjust pinctrl for multiplexing and pin configuration.

Install the device tree overlay and reboot. If the gpio_keys driver is present and has valid configuration specified via device tree, you should see the following line in the dmesg output:

[   15.218705] input: gpio_keys as /devices/platform/gpio_keys/input/input1

Next, check with evtest if asserting the physical pin produces the desired input events:

sudo evtest /dev/input/event1 
Input driver version is 1.0.1
Input device ID: bus 0x19 vendor 0x1 product 0x1 version 0x100
Input device name: "gpio_keys"
Supported events:
  Event type 0 (EV_SYN)
  Event type 1 (EV_KEY)
    Event code 28 (KEY_ENTER)
Properties:
Testing ... (interrupt to exit)
Event: time 1753802383.310602, type 1 (EV_KEY), code 28 (KEY_ENTER), value 1
Event: time 1753802383.310602, -------------- SYN_REPORT ------------
Event: time 1753802383.870663, type 1 (EV_KEY), code 28 (KEY_ENTER), value 0
Event: time 1753802383.870663, -------------- SYN_REPORT ------------

Additionally, gpio_keys-defined buttons can be configured to serve as wakeup sources, which can wake up the system from sleep, if supported by the board. More information is available in the kernel documentation.

Cleanup GitLab Runner Docker Cache

gitlab docker gitlab-runner cicd

If you have a self-hosted GitLab Runner with Docker executor, you need to periodically clean up Docker containers and volumes left by job executions. Otherwise, the runner machine will eventually run out of space.

GitLab Runner installation comes with a script designed to accomplish cleanup: /usr/share/gitlab-runner/clear-docker-cache

To see how much space can be reclaimed, run:

sudo /usr/share/gitlab-runner/clear-docker-cache space

To run cleanup every Sunday at 2:00 AM, add the following using the sudo crontab -e command:

0 2 * * 0 /usr/share/gitlab-runner/clear-docker-cache

Change to Previous Working Directory

console cwd

When working in the Linux or macOS console, I sometimes find myself in a directory I didn’t intend to be in (for example, after accidentially running cd without arguments, which takes you to your home directory). Manually typing the previous path or searching through command history is tedious.

Luckily, cd has an option to go back to the previous working directory – simply use:

cd -