A Swift 6.1 wrapper around libevent providing event-driven async I/O and non-blocking TCP sockets. Supports macOS 13+, iOS 13+, tvOS 13+, watchOS 6+, visionOS 1+, and Linux (Ubuntu 22.04+). Uses Swift 6 strict concurrency (swiftLanguageModes: [.v6]). Two products: libevent (raw C bindings) and Event (idiomatic Swift API).
- Build:
swift build - Test:
swift test - External-consumer probe:
cd Examples/LinuxConsumerProbe && swift build - Linux build:
docker build .(also builds the consumer probe)
- Conditional dev deps:
Package.swiftusesContext.gitInformation?.currentTagto excludeswift-plugin-subtreeat tagged releases. Consumers resolving a tagged version get zero transitive dependencies; the package has no runtime dependencies. - Two-product split:
libeventis the raw C bindings product (consumable standalone);Eventis the idiomatic Swift API (EventLoop,Socket,ServerSocket,SocketAddress,SocketError). Never leak raw C pointers throughEvent's public API without anunsafe*-prefixed affordance. - Extraction flow: libevent upstream is extracted via
subtree.yaml(remotelibevent/libevent, branchrelease-2.1.12-stable).Vendor/libevent→Sources/libevent/. Do NOT editSources/libevent/**directly; changes are overwritten on the next extraction. Manually maintained files are listed inVendor/AGENTS.md. - Excluded sources:
Sources/libevent/src/arc4random.cis excluded from build viaPackage.swift(bundled BSD implementation usinggetrandom()on Linux replaces it). - Linux-only C define:
_GNU_SOURCEis defined on Linux only, to enable glibc features likegethostbyname_r. - Backend runtime verification:
EventLoop().backendMethodMUST reportkqueueon Apple platforms andepollon Linux. This is an invariant enforced by a test (EventTests › EventLoop uses optimal backend). - Forbidden backends (per constitution Principle I): Windows IOCP, Solaris
devpoll/evport, OpenSSL-backed bufferevents. Do not port or bundle these. - libevent modulemap is shim-based:
Sources/libevent/include/module.modulemapclaims onlyswift-shim.h, NOT theevent2/*.hfamily. The shim header textually#includes every public libevent header, so Swift'simport libeventsees the full C API while C++ consumers using Swift C++ interop (-fmodulesforced) can#include <event2/...>as a plain textual include without hitting the "module 'libevent' is incompatible with feature 'cplusplus'" error. Do NOT change the modulemap toumbrella "."— that breaks downstream packages like swift-bitcoin. Regression coverage lives inExamples/LinuxConsumerProbe/.
- Never: edit files under
Vendor/**orSources/libevent/**directly; broaden GitHub Actionspermissionswithout justification; add runtime dependencies; re-introduce excluded backends. - Ask first: add new third-party dependencies (dev or runtime); modify
subtree.yamlextraction patterns; add a new platform or I/O backend. - See the 21-DOT-DEV contributing guidelines for branching and commit guidelines. See the 21-DOT-DEV SECURITY.md for vulnerability reporting.
Directory-specific AGENTS.md files provide additional context:
.github/AGENTS.md— CI workflows and Actions security policySources/AGENTS.md— Swift targets, C bindings, extraction pathsTests/AGENTS.md— Swift Testing framework, backend-verification invariantVendor/AGENTS.md— vendored libevent sources and subtree sync rulesExamples/LinuxConsumerProbe/AGENTS.md— external-consumer regression coverage (libevent modulemap, C++ interop)
- Keep scoped
AGENTS.mdfiles limited to deltas; avoid duplicating root guidance. - Update when build/test workflows, toolchain versions, platform support, or extraction patterns change.