macOS Apple Silicon

fortsh on Apple Silicon (M1/M2/M3/M4) uses a C string backend to work around Fortran compiler bugs on ARM64.

Background

gfortran Issues

gfortran on ARM64 macOS has multiple severe bugs:

  1. Stack corruption with programs using more than ~600KB stack
  2. Deferred-length string length loss during argument passing
  3. Segfaults on intent(out) string arguments
  4. Heap corruption on string assignment

These bugs make gfortran unusable for fortsh on Apple Silicon.

flang-new Workaround

fortsh uses flang-new (LLVM's Fortran compiler) on Apple Silicon. Older versions of flang-new had a 128-byte substring bug that caused heap corruption, but this is now worked around by the C string library.

C String Library

Since v1.1.0, fortsh includes a C string backend (src/c_interop/) that implements all string operations in C, bypassing flang-new's string handling entirely. This is automatically enabled when building on macOS ARM64.

The C library handles:

  • String allocation and deallocation via malloc/free
  • All substring, copy, append, insert, and delete operations
  • Safe buffer management with 1MB capacity limit per string

With the C string library enabled, the command line limit is 1024 characters. On Linux, the editing buffers are fully allocatable (no hard limit), but the C string backend on ARM uses fixed-capacity buffers capped at 1024.

Disabling the C String Library

If you need to build without it (not recommended):

make NO_C_STRINGS=1

Without it, the old 127-character command line limit applies.

Installation

Via Homebrew

brew install FortranGoingOnForty/tap/fortsh

From Source

# Install LLVM (provides flang-new)
brew install llvm

# Add to PATH
export PATH="/opt/homebrew/opt/llvm/bin:$PATH"

# Build (C string library is auto-enabled)
git clone https://github.com/fortrangoingonforty/fortsh.git
cd fortsh
make
sudo make install

The Makefile automatically detects ARM64, selects flang-new, and enables the C string library.

Configuration Differences

SettingLinuxmacOS ARM64
Editing buffersAllocatable (no hard limit)C string backend (1024 chars)
MAX_HISTORY1000100
String libraryNative FortranC interop
Compilergfortranflang-new

Remaining Differences from Linux

  • History is capped at 100 entries (vs 1000 on Linux) to reduce memory pressure
  • Some internal operations use character-by-character copies instead of bulk assignment to avoid flang-new code generation issues
  • Prompt formatting uses fixed-length buffers as an additional safety measure

Workarounds for Long Commands

If you hit the 1024-character limit (unlikely in practice):

Use Aliases

alias deploy='cd ~/projects/myapp && ./scripts/deploy.sh --env=prod'

Use Variables

export APP="$HOME/long/path/to/application"
cd "$APP"

Use Scripts

cat > script.sh << 'EOF'
# Your complex commands here
EOF
fortsh script.sh