You have 4 summaries left

Software Unscripted

Building a Terminal in Zig and Swift with Mitchell Hashimoto

Wed Jul 19 2023
terminal emulatorsZigSwiftUIclosed-source librariesnotarizationcross compilationGoSIMD

Description

This episode covers various topics related to terminal emulators, including the creation of a high-performance terminal emulator using Zig and SwiftUI, challenges faced when working with closed-source Apple core libraries, notarization and cross compilation in Zig, Go's contributions to programming languages, optimizing terminal memory usage with SIMD, and Zig's limitations in targeting specific architectures for tight SIMD algorithms. The episode also explores the speaker's interest in blogging about topics like BT escape sequence parsing, GPU rendering, rasterization, shaping, and more.

Insights

Open sourcing projects

Open sourcing projects has changed over the years, with higher expectations for polish and functionality in initial releases.

Pressure on creators to share work openly

There is more pressure on creators now to share their work openly. Intentional friction may be used as a way to take pressure off creators.

Bidirectional communication between Zig and Swift

Bidirectional communication between Zig and Swift occurs for various functionalities in Rock. No major issues encountered, but some CABI bugs in Zig were found and fixed.

GPU driver bugs and Apple's focus on ARM architecture

Discovered three GPU driver bugs while using Metal directly on Intel Macs. Possibility of no one maintaining the Intel GPU driver anymore. Looking forward to Apple deprecating Intel and focusing on ARM architecture.

Frustration with closed-source Apple core libraries

The speaker finds it frustrating that the foundation and Swift UI stuff is mostly closed source, making it difficult to understand why certain things aren't working as expected. The speaker wishes that the foundation and Swift UI stuff was open source for better learning opportunities and improved documentation.

Cross compilation challenges

Building software for Linux can be challenging due to different combinations of OS libraries. Switching to muscle build of LLVM requires watching a progress bar as it builds over hours. Zig's cross compilation possibilities are useful for verifying and building across different architectures and OS's.

Zig's single binary approach and Go's contributions

Zig is a single binary with all the necessary headers baked in. Zig is helpful for projects that require unsafe operations and careful memory control. Go has made underrated contributions to programming languages, such as tooling like formatting.

Go's formatting and build times

Go format (fumped) attracted the speaker culturally due to its unique formatting and lack of debate on spaces vs tabs. Early Go stood out for features like built-in testing, static binary building, cross-completion, and fast builds. The speaker noticed a slip in Go's build times over the years, which affected their productivity due to context switching.

Working on code signing and terminal optimization

Working on code signing is a pain point for everyone, but hopefully it won't be thankless in Yaku's case. The speaker finds satisfaction in using the terminal they built every day. Creating a pure Zig event loop taught Andrew a lot about interfaces and gave him respect for Lib UV. His terminal became faster after rewriting parts of it, resulting in double the throughput on Mac compared to Lib UV.

Runtime SIMD detection and Zig's limitations

Zig has no way to target specific architectures for tight SIMD algorithms without dropping down to assembly. There is a big issue in Zig regarding creating functions that target specific architectures. The speaker mentions their interest in blogging about various topics related to the terminal, such as BT escape sequence parsing, GPU rendering, rasterization, shaping, etc.

Chapters

  1. Mitchell Hashimoto's Terminal Emulator
  2. Rock: Zig and SwiftUI for Native Windowing
  3. Bidirectional Communication and GPU Driver Bugs
  4. Closed Source Frustrations and Cross Compilation
  5. Notarization and Cross Compilation in Zig
  6. Zig's Single Binary Approach and Go's Contributions
  7. Go's Formatting and Build Times
  8. Working on Code Signing and Terminal Optimization
  9. Optimizing Terminal Memory Usage and SIMD
  10. Runtime SIMD Detection and Zig's Limitations
Summary
Transcript

Mitchell Hashimoto's Terminal Emulator

00:04 - 06:11

  • Mitchell Hashimoto created a high-performance terminal emulator using Zig and SwiftUI.
  • The project started as a way to understand terminal escape codes and evolved into a fully featured terminal emulator.
  • Mitchell has been using it as his daily driver since May of last year.
  • There are some paper cuts and missing features, but overall it feels good to use.
  • Mitchell is considering open sourcing the project but wants to find the right balance between support and stress.
  • Open sourcing has changed over the years, with higher expectations for polish and functionality in initial releases.

Rock: Zig and SwiftUI for Native Windowing

06:02 - 12:12

  • Rock has intentionally not shipped a 0.1 version to set expectations.
  • They have nightly releases and communicate that it's open source.
  • There is a trick to count commits as a build number, which they plan to steal.
  • Initially, Rock started with a private repo and manually added people before opening it up.
  • They may use Discord for access to the repo in the future.
  • There is more pressure on creators now to share their work openly.
  • Intentional friction may be used as a way to take pressure off creators.
  • Rock is built using Zig and SwiftUI for native windowing experience on Mac.
  • On Linux, Rock is almost pure Zig with some C bindings for interaction with certain things.
  • SwiftUI was chosen over AppKit due to its automatic UI state management and animations capabilities.
  • The build process involves switching from pure Zig Build to Zig Build and Xcode Build for final app production.
  • Bidirectional communication between Zig and Swift occurs for various functionalities in Rock.

Bidirectional Communication and GPU Driver Bugs

11:43 - 17:51

  • Bidirectional communication between Zig and Swift, with function pointers passed between the two
  • No major issues encountered, but some CABI bugs in Zig were found and fixed
  • Discovered three GPU driver bugs while using Metal directly on Intel Macs
  • Possibility of no one maintaining the Intel GPU driver anymore
  • Looking forward to Apple deprecating Intel and focusing on ARM architecture
  • Challenges faced when working with closed-source Apple core libraries
  • Appreciation for insider knowledge but frustration for those without access

Closed Source Frustrations and Cross Compilation

17:24 - 23:25

  • The speaker finds it frustrating that the foundation and Swift UI stuff is mostly closed source, making it difficult to understand why certain things aren't working as expected.
  • The speaker wishes that the foundation and Swift UI stuff was open source for better learning opportunities and improved documentation.
  • The speaker acknowledges Apple's perspective on not wanting to open source their code due to potential flood of feature requests and design questions.
  • There is a system in place at Apple for code dumps, but there is no collaboration or acceptance of contributions.
  • Security concerns may be a reason why Apple doesn't open source certain level things.
  • The speaker primarily writes Zig code outside of Xcode and only uses Xcode when modifying Swift for UI code, which is rare.
  • The GLFW build also works for Mac, allowing the speaker to have a pure ZIG CLI workflow without needing Xcode.
  • Code signing is done locally by the CI using the Xcode CLI, and the speaker doesn't sign it themselves.
  • Notarization involves zipping up the binary and sending it to Apple servers for anti-virus scans before receiving an attestation back.

Notarization and Cross Compilation in Zig

23:09 - 29:24

  • Notarization is a process where binary bits are sent to Apple servers for anti-virus scans and attestation
  • Notarization can be time-consuming and may cause delays in releasing software
  • Xcode build has a command that automates the notarization process
  • Building software for Linux can be challenging due to different combinations of OS libraries
  • Switching to muscle build of LLVM requires watching a progress bar as it builds over hours
  • Zig's cross compilation possibilities are useful for verifying and building across different architectures and OS's
  • Using Zig CC instead of Node.js' native addons process improves cross-platform compatibility and speed
  • Zig ships Libsea headers, but additional headers like X11 and Apple SDK would be beneficial
  • The mock project on Zig provides system SDKs with common desktop library headers
  • Cross compiling in Rust is more complex compared to Zig's single binary approach

Zig's Single Binary Approach and Go's Contributions

28:59 - 35:19

  • Zig is a single binary with all the necessary headers baked in
  • The cultural element of languages is important, and Zig's community felt more welcoming than Rust's
  • Zig is helpful for projects that require unsafe operations and careful memory control
  • When doing inter-op across languages, safety in Rust doesn't extend to other languages' boundaries
  • Go has made underrated contributions to programming languages, such as tooling like formatting
  • GoFump, Go's formatter, has zero configuration options and sparked online discourse initially
  • Having no configuration for formatters can prevent arguments about style choices

Go's Formatting and Build Times

34:49 - 41:27

  • Go format (fumped) attracted the speaker culturally due to its unique formatting and lack of debate on spaces vs tabs
  • Early Go stood out for features like built-in testing, static binary building, cross-completion, and fast builds
  • Zig also prioritizes fast builds as a goal
  • The speaker noticed a slip in Go's build times over the years, which affected their productivity due to context switching
  • The speaker aims for sub-second build times in their own project
  • Rewriting dependencies in Zig can improve build speed by reducing reliance on C code
  • Working on infrastructure tooling like code signing is often thankless but important

Working on Code Signing and Terminal Optimization

41:03 - 47:11

  • Working on code signing is a pain point for everyone, but hopefully it won't be thankless in Yaku's case.
  • Some people say the same thing about working on compilers, but those who care appreciate it.
  • There's a certain element of opportunity when something bothers you and you realize you can make it better.
  • The end goal is to solve problems so that nobody has to deal with them anymore and everyone can benefit from a better experience.
  • Andrew also feels motivated by the difficulty of certain tasks and takes matters into his own hands.
  • Learning by actively working on projects is more effective than just reading books or doing toy problems.
  • Building something yourself helps you understand the concepts and edges of a topic better than just learning about it.
  • Creating a pure Zig event loop taught Andrew a lot about interfaces and gave him respect for Lib UV.
  • His terminal became faster after rewriting parts of it, resulting in double the throughput on Mac compared to Lib UV.
  • Casey Muhratory's terminal benchmark was faster, but Andrew couldn't run his code due to compatibility issues.

Optimizing Terminal Memory Usage and SIMD

46:51 - 53:08

  • The terminal screen can be thought of as a flat array if there are no escape sequences
  • Each cell in the terminal has metadata like foreground color, background color, etc.
  • The current cell size is 12 bytes per cell
  • Optimizing memory usage by storing commonly used metadata separately
  • Simd can be used to chunk data and check for unusual elements
  • Using Simd to copy non-escape sequence bytes directly into the terminal structure
  • Intel introduced instructions to handle extra bytes more efficiently than ARM
  • Considering making the array length a multiple of Simd for easier processing
  • Reading about SIMD instructions and their applications in parsing and processing

Runtime SIMD Detection and Zig's Limitations

52:50 - 56:51

  • The speaker discusses a repo they have that uses Zig to do runtime SIMD detection
  • Zig has no way to target specific architectures for tight SIMD algorithms without dropping down to assembly
  • There is a big issue in Zig regarding creating functions that target specific architectures
  • The speaker mentions their interest in blogging about various topics related to the terminal, such as BT escape sequence parsing, GPU rendering, rasterization, shaping, etc.
  • Building a regular expression engine was the speaker's previous project that taught them a lot about computing concepts
  • Working on the terminal project has exposed the speaker to real-world systems-level concepts like GPUs and fonts
  • The speaker finds satisfaction in using the terminal they built every day
  • The conversation concludes with mutual appreciation and mention of following up on links
1