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:
HOMEresolution;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:
USERPROFILEresolution;- 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;
.cmdquoting 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.
Links and archive paths
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.
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.
Related documents
- 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.