CEP 30 - Virtual packages
| Title | Virtual packages |
| Status | Accepted |
| Author(s) | Jaime Rodríguez-Guerra <jaime.rogue@gmail.com> |
| Created | Dec 17, 2024 |
| Updated | Mar 4, 2026 |
| Discussion | https://github.com/conda/ceps/pull/103 |
| Implementation | https://github.com/conda/conda/tree/24.11.1/conda/plugins/virtual_packages, https://github.com/mamba-org/mamba/blob/libmamba-2.0.5/libmamba/src/core/virtual_packages.cpp, https://github.com/conda/rattler/tree/rattler-v0.28.8/crates/rattler_virtual_packages/src |
| Requires | CEP 33 |
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC2119 when, and only when, they appear in all capitals, as shown here.
Abstract
This CEP standardizes which virtual packages MUST be offered by conda install tools.
Motivation
Virtual packages are used to expose details of the system configuration to a conda client. They are commonly used as dependencies in regular packages to constrain on which systems they can be installed. Some examples include:
- On Linux, the minimum GNU
libcversion that must be available in the system via the__glibcvirtual package. - The oldest macOS version compatible with the package via the
__osxvirtual package. - Whether a
noarchpackage should be constrained to a single operating system via the__linux,__osxor__winvirtual packages (often with no version constraint). - The minimum CPU microarchitecture level that the binaries require via the
__archspecvirtual package. - The latest CUDA version compatible with the GPU driver via
__cuda.
Specification
A virtual package is defined as a package record with three fields: name, version and build string. These fields MUST comply with CEP 26. More specifically, the version field MUST follow the version string specifications as discussed in CEP 33, regardless of its origin (computed from a system property, overridden by the user or configuration, or provided by default by the tool).
Some general considerations:
- A virtual package name MUST start with double underscore (
__). - The version or build string of a virtual package MAY be overridden by the value of the
CONDA_OVERRIDE_{NAME}environment variable, with{NAME}being the uppercased name of the virtual package (excluding the leading underscores). Many exceptions apply, so please observe the details in the section below. - The build string SHOULD be zero (
0). Some exceptions apply. See below.
List of virtual packages
In alphabetical order, every conda client MUST support the following virtual packages:
__archspec__cuda__glibc__linux__osx__unix__win
__archspec
This virtual package MUST always be present.
The build string MUST reflect either:
- A fitting CPU microarchitecture in the
archspec/archspec-jsondatabase. In this case, the version number MUST be1. - The second component of the target platform string as is. In this case, the version number MUST be
0.
The build string MUST be overridable with the CONDA_OVERRIDE_ARCHSPEC environment variable, if set to a non-empty value that can be parsed as a build string. The version in this case MUST be 1.
When depending on __archspec, the version field MUST NOT be populated (i.e. it MUST be *).
__cuda
This virtual package MUST be present when the system exhibits NVIDIA GPU drivers compatible with the CUDA runtimes. For systems without such support, the virtual package MUST NOT be present.
When available, the version value MUST be set to the latest CUDA version supported by the detected drivers (i.e. the formatted value of cuDriverGetVersion()), constrained to the first two components (major and minor) and formatted as {major}.{minor}.
The build string MUST be 0.
If the CONDA_OVERRIDE_CUDA environment variable is set to a non-empty value that can be parsed as a version string, the __cuda virtual package MUST be exposed with that version.
__glibc
This virtual package MUST NOT be present if the target platform is not linux-*.
This virtual package MUST be present when the native and target platforms are both the same type of linux-* and GNU libc is installed in the system. The version value MUST be set to the system GNU libc version, constrained to the first two components (major and minor) formatted as {major}.{minor}. If the version cannot be estimated, the tool MUST set the version to a default value (e.g. 2.17) of its choice.
If the native platform does not match the target platform, the tool MAY export __glibc with its version field set to a default value (e.g. 2.17) of its choice.
If the CONDA_OVERRIDE_GLIBC environment variable is set to a non-empty value that complies with the version string specification and the target platform is linux-*, the tool MUST export __glibc with its version value set to the value of the environment variable.
The build string MUST always be 0.
The GNU
libcversion can be computed via:
- Python's
os.confstr("CS_GNU_LIBC_VERSION")getconf GNU_LIBC_VERSIONldd --version. Please verify that it references GNUlibcor GLIBC. For non-standard installs using a GLIBC compatibility layer, this may require locating the implementation and directly querying.- Dynamically load the
gnu_get_libc_versionsymbol fromlibc.so.6.
__linux
This virtual package MUST be present when the target platform is linux-*. Its version value MUST be set to the upstream (mainline) Linux kernel version, but it MUST exclude any and all distribution-specific components of the kernel version. If the version cannot be estimated (e.g. because the native platform is not Linux), the tool MUST set version to a fallback value of its choice. The build string MUST be 0.
The version MUST be overridable with the CONDA_OVERRIDE_LINUX environment variable, if set to a non-empty value that matches the regex "[0-9]+\.[0-9]+(\.[0-9]+)?(\.[0-9]+)?". The environment variable MUST be ignored when the target platform is not linux-*.
The Linux kernel version can be obtained via:
- Python's
platform.release()uname -rcat /proc/version
__osx
This virtual package MUST be present when the target platform is osx-*. Its version value MUST be set to the first two numeric components of the macOS version formatted as {major}.{minor}. If applicable, the SYSTEM_VERSION_COMPAT environment variable workaround MUST NOT be enabled; e.g. the version reported for Big Sur must be 11.x and not 10.16.
If the version cannot be estimated (e.g. because the native platform is not macOS), the fallback value MUST be set to 0. The build string MUST be 0.
The version MUST be overridable with the CONDA_OVERRIDE_OSX environment variable if set to a non-empty value that can be parsed as a version string. The environment variable MUST be ignored when the target platform is not osx-*.
The macOS version can be obtained via:
- Python's
platform.mac_ver()[0]SYSTEM_VERSION_COMPAT=0 sw_vers -productVersion
__unix
This virtual package MUST be present when the target platform is linux-*, osx-*, freebsd-*, or emscripten-*. It SHOULD be present for any other sufficiently POSIX-y platforms (e.g. using / as path delimiters, supporting fork(3), etc.). The version and build string fields MUST be set to 0.
The CONDA_OVERRIDE_UNIX environment variable MUST NOT have any effect.
__win
This virtual package MUST be present when the target platform is win-*. The version MUST be set to the first three numeric components of the Windows build version, formatted as {major}.{minor}.{micro}. If the version cannot be estimated (e.g. because the target platform does not match the native platform), the tool MUST set the version to a default value of its choice.
The version MUST be overridable with the CONDA_OVERRIDE_WIN environment variable if set to a non-empty value that can be parsed as a version string. The environment variable MUST be ignored when the target platform is not win-*.
The build string MUST be 0.
The version string
{major}.{minor}.{micro}can be obtained from:
- Python's
platform.win32_ver()- CMD's
ver- PowerShell's
[System.Environment]::OSVersion.Versionor(Get-CimInstance Win32_OperatingSystem).version- The command
wmic os get version- The
RtlGetVersionKernel Function- The
GetVersionExWWin32 APINote that
{micro}here refers to what Microsoft calls the "build" version component, not to be mistaken with thebuildstring of the virtual package.
Potential future work
This CEP focuses on the standardization of existing virtual package implementations.
The following items are not considered here, though they would be open for discussion in future CEP work:
- Additional OSes, like
__freebsdor__netbsd. - Coarse-grain architecture information, like
__x86_64or__arm64, or, more generally,__arch. - More
libcimplementations, like__musl.
Rejected ideas
In cross-platform solves, virtual packages are often missed, resulting in solver errors or unexpected solutions (see conda#13508, conda-libmamba-solver#368, conda-libmamba-solver#483). We chose not to add any UX requirements for tools, but we do suggest this aspect be considered while designing a client. For example:
- If the tool used a fallback default value instead of a computed one, it could also inform the user of that choice and its possible override options (e.g.
CONDA_OVERRIDE_{NAME}variables, CLI flags, configuration file, etc). - If the user provided an override that was not used, a warning could be emitted for clarity.
References
- Virtual packages implementation in
conda/conda24.11.1 - Virtual packages implementation in
libmamba2.0.5 - Virtual packages implementation in
rattler0.28.8 - ENH: make
__winversion usable for package metadata (conda/conda#14443) - Drop
CONDA_OVERRIDE_WINenvironment variable (mamba-org/mamba#2815) __archfeature request- Explanation about
__cudaversion value - Reference CPU detection implementation for
__archspecatarchspec.cpu.detect.host().
Appendix A: Naive target platform to __archspec mapping
These values may be used when no CPU autodetection features are available:
| Target platform | Reported archspec build string |
|---|---|
*-32 | x86 |
*-64 | x86_64 |
*-aarch64 | aarch64 |
*-arm64 | aarch64 |
*-armv6l | armv6l |
*-armv7l | armv7l |
*-ppc64 | ppc64 |
*-ppc64le | ppc64le |
*-riscv64 | riscv64 |
*-s390x | s390x |
*-wasm32 | wasm32 |
zos-z | z |
Copyright
All CEPs are explicitly CC0 1.0 Universal.