Platforms

This document defines platform identifiers and implementation differences. The portable behavior remains the one described in the other documents.

Identifiers

linux-x64
linux-arm64
macos-x64
macos-arm64
windows-x64

Identifiers are exact lowercase values in the form <os>-<arch>. Unsupported operating systems and architectures are rejected before catalog or path use.

Host and target

host    platform where the package executable runs
target  platform the package targets

The host is detected from the running executable. The target defaults to the host and can be overridden by commands that accept --target.

A cross-target package is still built for the current host. For example:

host=linux-x64 target=windows-x64

means a Linux executable that produces or manages Windows-targeted output. It does not mean a Windows executable installed on Linux.

Availability is determined by the exact catalog tuple. Not every tool supports every host/target combination.

Persistent roots

Linux/macOS  $HOME/.cup
Windows      %USERPROFILE%\.cup

These are the primary names. When the primary path is an unrelated directory, CUP preserves it and uses .coffee-cup in the same home. A strict root.txt marker keeps selection stable. Unix-like shells on Windows delegate cup asset installation to PowerShell and use the selected native Windows root.

Executable names

POSIX    cup
Windows  cup.exe

Component entry files retain their package-specific names. Managed default wrappers are:

native       <entry>
cross-target <target>-<entry>

On Windows the managed wrapper uses .cmd representation where required by the entry-point implementation.

POSIX implementation

system_posix.c uses native POSIX primitives for:

  • HOME resolution;
  • lstat-style path inspection without following links;
  • permissions and executable bits;
  • atomic rename/replacement;
  • file and parent-directory synchronization;
  • advisory shared/exclusive locking;
  • directory traversal;
  • detached helper execution;
  • process existence checks.

Linux builds define _POSIX_C_SOURCE=200809L. macOS builds define _DARWIN_C_SOURCE where required by the platform API.

Windows implementation

system_windows.c uses wide-character Windows APIs for canonical filesystem and process operations. It handles:

  • USERPROFILE resolution;
  • regular file, directory, link/reparse and other path kinds;
  • Windows read-only and executable conventions;
  • replace/move semantics and handle flushing;
  • native file locks;
  • temporary files and directories;
  • detached PowerShell helpers;
  • .cmd quoting and path conversion;
  • protected owner-private ACLs for the cup root;
  • \\?\/UNC long-path normalization and reparse-point checks.

Using wide APIs avoids making the internal path model depend on the active ANSI code page. The generated PE manifest declares longPathAware; native tests use paths beyond MAX_PATH rather than treating larger C buffers as sufficient.

Internal path representation

The portable core uses / as its path separator on every host. Windows paths received from native APIs are normalized when they enter the core; conversion to UTF-16, \ separators and long-path prefixes happens only at the native API boundary. This prevents mixed paths such as C:\Users\name/.cup/components.

Path identity follows host semantics. POSIX comparisons remain case-sensitive and do not treat \ as a separator. Windows comparisons accept both separator forms, ignore ASCII case and normalize \\?\ and \\?\UNC\ prefixes. Code that compares filesystem paths uses the path abstraction rather than strcmp.

Native Win32 filesystem calls receive UTF-16 paths with long-path prefixes when needed. Paths passed to external programs such as PowerShell use ordinary absolute Windows syntax without \\?\; the helper normalizes incoming long-path forms defensively before validating path identity.

Permissions

POSIX

The cup root is created with mode 0700 under a restrictive process umask. Installed executables and wrappers receive executable bits. Protected metadata receives write bits removed according to the project permission contract.

Windows

Windows does not use POSIX executable bits. The cup root uses a protected DACL restricted to the current user, Local System and Administrators. Executable validity is based on file type and expected extension/entry behavior. Protected metadata receives the read-only attribute.

Read-only protection is an accidental-modification guard, not a cryptographic integrity mechanism. See SECURITY.

Package archive validation applies both POSIX and Windows path rules on every host. A backslash or drive-qualified path cannot become safe merely because the archive is being extracted on Linux.

Relative internal symlinks are accepted only when normalization stays within the single package root. Hard links must reference an already extracted regular file. Platform filesystem inspection does not follow a canonical package-level link.

Locks and replacement

Both implementations expose the same SystemLockMode and SystemCommitState contracts. Native APIs differ, but higher layers receive the same semantic answers:

shared or exclusive lock
replacement not applied, applied or durable

Durability capabilities differ by filesystem and operating system. When a platform cannot prove the required synchronization after replacement, the operation remains recoverable rather than being reported as a normal success.

Detached helpers

Uninstall

POSIX copies and starts a shell helper. A private inherited socket confirms that the helper validated its inputs; EOF then identifies the exact lifetime of the parent process. Windows uses the equivalent two-boundary protocol with an inherited readiness pipe and an inherited waitable process handle. The PID is retained only as marker identity, so neither helper can attach to a reused PID. After the parent exits, the helper atomically detaches the root and deletes the detached tree.

cup update

The platform layer generates or starts a helper capable of waiting for the running binary, reacquiring the lock and replacing the complete canonical cup asset generation. The portable C layer has already selected and verified those assets.

See TRANSACTIONS.

Build matrix

Linux x64     GCC
Linux ARM64   GCC
macOS x64     Clang
macOS ARM64   Clang
Windows x64   MSYS2 UCRT64 GCC

macOS x64 and ARM64 currently build with deployment target 13.0. Windows x64 builds natively in MSYS2 UCRT64 with _WIN32_WINNT=0x0A00. These values are provisional CI compatibility baselines; they become public minimum-support claims only after native validation on the corresponding operating-system versions.

Official candidates are static with respect to project third-party dependencies according to the platform build model. Linux release executables are fully static. macOS retains only Apple system/framework dependencies, while Windows retains only allowlisted operating-system DLL imports. make check-binary verifies object format, architecture and the corresponding linked-binary policy for each supported platform.

Release-candidate transport

Official candidate tests run before publication and therefore serve the assembled assets from a loopback HTTP server. The runtime accepts that transport only when both the explicit insecure-test flag and a 127.0.0.1 or localhost base URL are present; normal downloads and every redirect remain HTTPS-only.

Test matrix

Source validation runs natively on all five supported platform identifiers. Release candidate binaries are also downloaded and tested on native runners.

Coverage and ASan/UBSan run natively on all five platform identifiers. Linux and Windows coverage use GCC/gcov, while macOS uses Clang source-based coverage. All sanitizer jobs use Clang/Compiler-RT. LeakSanitizer is enabled on Linux; macOS and Windows run ASan/UBSan without leak detection. Windows uses an isolated CLANG64 dependency graph. Linux source, integration and release builds use GCC, with a secondary Linux x64 Clang application/unit pass. Windows release and coverage builds remain UCRT64/GCC. Linux x64 additionally runs a static-runtime portability test that verifies the release binary policy, embedded-CA HTTPS validation and direct and proxied package downloads. Native platform suites remain separate requirements because their system-specific branches cannot be represented by a single aggregate report.

See TESTING and RELEASES.

Current limitations

The recognized set does not currently include Windows ARM64 or additional operating systems. A new identifier requires coordinated support in:

platform detection and validation
system implementation or build selection
catalog tuples
static dependency cup assets
release asset naming
installer detection
source and native test runners

Adding a catalog entry alone is not sufficient.

Implementation and verification

Platform-module responsibilities are listed in ARCHITECTURE. Native verification and candidate execution are described in TESTING and RELEASES.

  • ARCHITECTURE — host/target domain model;
  • INSTALLATION — platform installers;
  • STATE — platform-aware scopes and wrappers;
  • BUILD — compiler and linkage configuration.

Need help?
Please wait: the project is still pre-alpha!

Cup of Coffee is an open source project inspired by Cargo, Rustup Crates, and Conda-forge.