Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Features to support libc #557

Closed
joshlf opened this issue Oct 27, 2023 · 1 comment
Closed

Features to support libc #557

joshlf opened this issue Oct 27, 2023 · 1 comment
Labels
customer-request Documents customer requests. experience-hard This issue is hard, and requires a lot of experience google-20%-project Potential 20% project for a Google employee help wanted Extra attention is needed

Comments

@joshlf
Copy link
Member

joshlf commented Oct 27, 2023

See also: #1769

Prototyped in rust-lang/libc#3407 and rust-lang/libc#3914. MSRV bump in rust-lang/libc#3924.

There are two approaches we could take: try to support version 0.2 (the current version train) or only try to support 1.0 (the next version train).

Version-agnostic considerations

libc almost never releases breaking changes, so if we were to introduce a dependency on zerocopy 0.7, we would never be able to upgrade that dependency to 0.8. Thus, we have two options:

  • Explicitly mark the feature as unstable (eg, name it unstable-zerocopy)
    • This would cause semver issues even for users who understand the risks
  • Introduce one feature per zerocopy semver train (ie, one for 0.7.X, one for 0.8.X, etc)

The second is the better option. What it would take to support differs by libc version; see the discussion below.

Regardless of version, we will need to be able to support an attribute that instructs our derives to rename zerocopy internally (described in #11). This would allow us to write code like:

#[cfg_attr(feature = "zerocopy_0_7", derive(zerocopy_0_7::FromBytes))]
#[cfg_attr(feature = "zerocopy_0_8", derive(zerocopy_0_8::FromBytes))]
#[zerocopy(crate = "zerocopy_0_7", derive-version = "0.7")]
#[zerocopy(crate = "zerocopy_0_8", derive-version = "0.8")]
struct Foo {
    ...
}

Version 1.0 considerations

libc is currently working on a 1.0 release, which will have a much higher MSRV than 0.2. 0.2's current MSRV makes this very tricky (see the discussion below); simply waiting for 1.0 would allow us to sidestep much of that complexity.

Version 0.2 considerations

Proc macro derive naming and imports

Since the MSRV is 1.13, the "edition" is 2015, in which proc macro derives are imported like so:

#[macro_use]
extern crate zerocopy;

This brings all exported macros into the global macro namespace. There is no way to rename macros at import time.

In order to work around this, we would need to dynamically change the edition. Luckily, zerocopy's MSRV is 1.61, which supports more recent editions. Thus, we know that a user can only depend on libc's zerocopy feature using 1.61 or greater. In libc's build.rs, we could detect the Rust version and, for sufficiently recent versions, emit the --edition 2021 rustc flag.

In libc's source code, we again know that zerocopy is only enabled on recent Rust versions, and thus that the edition is 2021. Thus, we could use more recent edition features under #[cfg(feature = "zerocopy-0-7")].

Depending on multiple crate versions

There are multiple options to support this.

Direct

This depends on libc's MSRV being increased to 1.31.

It was only in Rust 1.31 that it became possible to depend directly on multiple versions of a crate like so:

[dependencies]
foo_01 = { package = "foo", version = "0.1.0" }
foo_02 = { package = "foo", version = "0.2.0" }

Even if the zerocopy features are never used on libc's MSRV of 1.13, the Cargo.toml file still needs to parse on 1.13, which this syntax wouldn't.

Facade crates

This depends on libc's MSRV being increased to 1.30.

If libc increases their MSRV to 1.30 instead of 1.31, we would could use a "facade crate" trick: we could upload a facade crate named zerocopy-0-7 with the following Cargo.toml:

[package]
name = "zerocopy-0-7"
version = "1.0.0"
license = "BSD-2-Clause OR Apache-2.0 OR MIT"
repository = "https://github.com/google/zerocopy"
edition = "2018"

[dependencies]
zerocopy = "0.7.0"
zerocopy-derive = "0.7.0"

...and the following src/lib.rs:

pub use zerocopy::*;
pub use zerocopy_derive::{
    AsBytes as AsBytes_0_7, FromBytes as FromBytes_0_7, FromZeroes as FromZeroes_0_7,
    Unaligned as Unaligned_0_7,
};

We would do the same for other version trains (e.g., 0.8) as they are published.

@joshlf joshlf added the customer-request Documents customer requests. label Oct 27, 2023
@joshlf joshlf added google-20%-project Potential 20% project for a Google employee help wanted Extra attention is needed experience-hard This issue is hard, and requires a lot of experience labels May 7, 2024
joshlf added a commit to joshlf/libc that referenced this issue Sep 14, 2024
This permits `Cargo.toml` to include optional dependencies. On
toolchains earlier than 1.31, the optional dependency syntax is not
supported. With the MSRV at 1.31, any optional dependency may be
supported even if *its* MSRV is higher than *our* MSRV since only users
using a more recent toolchain will enable that dependency.

In particular, this paves the way for adding an optional `zerocopy`
dependency (prototyped in rust-lang#3407 and rust-lang#3914; see also google/zerocopy#557),
which permits many uses of libc to no longer require `unsafe` code.
joshlf added a commit to joshlf/libc that referenced this issue Sep 14, 2024
This permits `Cargo.toml` to include optional dependencies. On
toolchains earlier than 1.31, the optional dependency syntax is not
supported. With the MSRV at 1.31, any optional dependency may be
supported even if *its* MSRV is higher than *our* MSRV since only users
using a more recent toolchain will enable that dependency.

In particular, this paves the way for adding an optional `zerocopy`
dependency (prototyped in rust-lang#3407 and rust-lang#3914; see also google/zerocopy#557),
which permits many uses of libc to no longer require `unsafe` code.
joshlf added a commit to joshlf/libc that referenced this issue Sep 14, 2024
This permits `Cargo.toml` to include optional dependencies. On
toolchains earlier than 1.31, the optional dependency syntax is not
supported. With the MSRV at 1.31, any optional dependency may be
supported even if *its* MSRV is higher than *our* MSRV since only users
using a more recent toolchain will enable that dependency.

In particular, this paves the way for adding an optional `zerocopy`
dependency (prototyped in rust-lang#3407 and rust-lang#3914; see also google/zerocopy#557),
which permits many uses of libc to no longer require `unsafe` code.
joshlf added a commit to joshlf/libc that referenced this issue Sep 14, 2024
This permits `Cargo.toml` to include optional dependencies. On
toolchains earlier than 1.31, the optional dependency syntax is not
supported. With the MSRV at 1.31, any optional dependency may be
supported even if *its* MSRV is higher than *our* MSRV since only users
using a more recent toolchain will enable that dependency.

In particular, this paves the way for adding an optional `zerocopy`
dependency (prototyped in rust-lang#3407 and rust-lang#3914; see also google/zerocopy#557),
which permits many uses of libc to no longer require `unsafe` code.
@joshlf
Copy link
Member Author

joshlf commented Oct 2, 2024

Closing per rust-lang/libc#3317 (comment)

@joshlf joshlf closed this as completed Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
customer-request Documents customer requests. experience-hard This issue is hard, and requires a lot of experience google-20%-project Potential 20% project for a Google employee help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

1 participant