# Pre-RFC: \`min\_target\_api\_version\`

**URL:** <https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339>\
**Category:** language design\
**Created:** [November 5, 2020, 9:59am UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339 "2020-11-05T09:59:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![rylev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rylev/32/5366_2.png) [@rylev](https://internals.rust-lang.org/u/rylev)\
**Post date:** [November 5, 2020, 9:59am UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/1 "2020-11-05T09:59:22Z")

</div>

Linked [here](https://gist.github.com/rylev/1efe2dffcfc088b66519b70f0cb9286f) is a draft RFC for a new `cfg` predicate `min_target_api_version` which allows for conditional compilation depending on a minimum API set version. For example, on Windows if you only want certain code to run on Windows 10 you could write `#[cfg(min_target_api_version = "10.0.10240")]`. You can find more motivation and examples in the linked draft RFC. There are explicit open questions listed in the RFC, but any and all feedback is welcome.

There is also a Zulip thread for this RFC which you can find [here](https://rust-lang.zulipchat.com/#narrow/stream/242869-t-compiler.2Fwindows/topic/(Pre-RFC.3F).20target-api.2Fos-version). Feedback is also welcome there.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [November 5, 2020, 12:45pm UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/2 "2020-11-05T12:45:53Z")

</div>

It would be useful for macOS too.

C compilers for macOS support env var `MACOSX_DEPLOYMENT_TARGET` (AKA `-mmacosx-version-min`) that is in the form of "10.x" or "10.x.y". It affects availability of system APIs, opts-in to new API behaviors, and makes the linker use new executable formats not compatible with older systems.

Currently core-foundation-sys uses Cargo features to select deployment target, which can be out of sync with the actual target, and it's a bit clumsy compared to Apple's convention:

> <https://github.com/servo/core-foundation-rs/blob/d107afb70531132af2879f0b153a74ae5bdb5fce/core-foundation-sys/Cargo.toml#L14-L15>

---

<div class="post-metadata">

**Author:** ![chrisd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/chrisd/32/7232_2.png) [@chrisd](https://internals.rust-lang.org/u/chrisd)\
**Post date:** [November 13, 2020, 10:15am UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/3 "2020-11-13T10:15:31Z")

</div>

It would be good if we could nail down how to do platform versioning. Should it be in the form `x.y.z`? Or should it be more like a list of versions? Or could it be a mix of both (i.e. `x.y.z` is the canonical form but there are text aliases)? If a list, where should platform versioning live? In rustc itself? What about json targets?

* * *

On the Windows side, this is what [using the Windows Headers](https://docs.microsoft.com/en-us/windows/win32/winprog/using-the-windows-headers) to do conditional compilation looks like in C++.

```rust
// The application sets a preprocessor macro with 
// the version, using a predefined constant or a literal value.
#define WINVER _WIN32_WINNT_WIN8 

// Then a library can conditionally compile based on that,
// again using either a constant or a literal value.
#if (WINVER >= 0x0601)
    // `_WIN32_WINNT_WIN8` is defined as 0x0602
	// so this section will be compiled.
#endif

```

For reference, the runtime equivalent to that code is simply:

```rust
if (IsWindows7OrGreater()) {
	// If, at runtime, Windows 7 or greater is detected
	// then this will run.
}

```

---

<div class="post-metadata">

**Author:** ![rylev](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rylev/32/5366_2.png) [@rylev](https://internals.rust-lang.org/u/rylev)\
**Post date:** [November 24, 2020, 1:47pm UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/4 "2020-11-24T13:47:42Z")

</div>

The versioning scheme is first predicated on whether we truely want this to be cross platform. I'm thoroughly on the side of making this feature work in conjunction with target platform, but there are some that would rather this be `min_windows_api_version` and only available on Windows related targets. If this is just a feature for Windows, then I'm confident that the `x.y.z` form which is used by Windows itself along with textual aliases, would be the right choice.

However, with cross platform support this is complicated, especially when considering custom targets. We could require built in compiler support to establish canonical ordering at the expense supporting custom targets.

So the questions as I see them are:

- Do we support targets other than Windows related targets? If not, then I propose the `x.y.z` canonical form.
- If yes, do we support custom targets? If yes, then I'm not sure how exactly to handle this.
- If no:
  - Does the compiler hard code the odering?
  - What happens when the compiler does not recognize a form? Presumably the compiler should not rely on direct matching but rather a per target type schema (e.g., in the case of windows `x.y.z` but in other target type's maybe another schema).

---

<div class="post-metadata">

**Author:** ![yoshuawuyts](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/yoshuawuyts/32/3712_2.png) [@yoshuawuyts](https://internals.rust-lang.org/u/yoshuawuyts)\
**Post date:** [November 24, 2020, 2:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/5 "2020-11-24T14:20:34Z")

</div>

> [@rylev](#):
>
> Do we support targets other than Windows related targets?

I would like for this feature to be designed to eventually be available on non-Windows targets as well. For example on Linux it would become possible to use the newer `io_uring` APIs without needing to ship a fallback implementation.

This seems like a general-purpose mechanism to narrow down the compilation target, much like `-C target-cpu` allows us to target specific processors, and [`#[cfg(version = "")]`](https://github.com/rust-lang/rust/issues/64796) will allow us to target specific Rust versions.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [February 22, 2021, 2:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-min-target-api-version/13339/6 "2021-02-22T14:20:43Z")

</div>

Closed on February 22, 2021, 2:20pm UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
