Summary

This proposes a new cfg: target_abi, which specifies certain aspects of the target’s Application Binary Interface (ABI). This also adds a CARGO_CFG_TARGET_ABI environment variable for parity with other CARGO_CFG_TARGET_* variables.

Motivation

Certain targets are only differentiated by their ABI. For example: the ios OS in combination with the macabi ABI denotes targeting Mac Catalyst (iOS on macOS). The non-macabi x86_64-apple-ios target is not for Mac Catalyst and instead is for the iOS simulator, which is a very different environment.

It is not currently possible to #[cfg] against a certain target ABI without a build.rs script to emit a custom cfg based on the TARGET environment variable. This is not ideal because:

  • Adding a build script increases compile time and makes a crate incompatible with certain build systems.

  • Checking TARGET is error prone, mainly because the ABI often follows target_env without separation.

Guide-level explanation

This would act like existing target_* configurations.

For example: if one had a module with bindings to Apple’s AppKit, this feature could be used to ensure the module is available when targeting regular macOS and Mac Catalyst.

#[cfg(any(
    target_os = "macos",
    all(
        target_os = "ios",
        target_abi = "macabi",
    ),
))]
pub mod app_kit;

This configuration option would also be usable as #[cfg_attr(target_abi = "...", attr)].

Reference-level explanation

target_abi is a key-value option set once with the target’s ABI. The value is similar to the fourth element of the platform’s target triple. It often comes after the target_env value. Embedded ABIs such as gnueabihf will define target_env as "gnu" and target_abi as "eabihf".

Example values:

  • ""
  • "abi64"
  • "eabi"
  • "eabihf"
  • "macabi"

Drawbacks

  • Additional metadata for the compiler to keep track of.

  • Like other cfgs, this can be manipulated at build time to be a value that mismatches the actual target.

Rationale and alternatives

We can keep the existing work-around of checking the TARGET environment variable in a build.rs script. However, this is not ideal because:

  • Adding a build script increases compile time and makes a crate incompatible with certain build systems.

  • Checking TARGET is error prone, mainly because the ABI often follows target_env without separation.

Prior art

Unresolved questions

None.

Future possibilities

None.