| # Contributing to `libc` | |
| Welcome! If you are reading this document, it means you are interested in contributing | |
| to the `libc` crate. | |
| ## v0.2 changes | |
| If you want to add your changes to v0.2, please submit them to the `libc-0.2` branch. | |
| If you want to add any breaking changes, it should be submitted to the main branch, | |
| which has changes for v0.3. | |
| We will support and make a new release for v0.2 until we make the first release of v0.3. | |
| ## Adding an API | |
| Want to use an API which currently isn't bound in `libc`? It's quite easy to add | |
| one! | |
| The internal structure of this crate is designed to minimize the number of | |
| `#[cfg]` attributes in order to easily be able to add new items which apply | |
| to all platforms in the future. As a result, the crate is organized | |
| hierarchically based on platform. Each module has a number of `#[cfg]`'d | |
| children, but only one is ever actually compiled. Each module then reexports all | |
| the contents of its children. | |
| This means that for each platform that libc supports, the path from a | |
| leaf module to the root will contain all bindings for the platform in question. | |
| Consequently, this indicates where an API should be added! Adding an API at a | |
| particular level in the hierarchy means that it is supported on all the child | |
| platforms of that level. For example, when adding a Unix API it should be added | |
| to `src/unix/mod.rs`, but when adding a Linux-only API it should be added to | |
| `src/unix/linux_like/linux/mod.rs`. | |
| If you're not 100% sure at what level of the hierarchy an API should be added | |
| at, fear not! This crate has CI support which tests any binding against all | |
| platforms supported, so you'll see failures if an API is added at the wrong | |
| level or has different signatures across platforms. | |
| New symbol(s) (i.e. functions, constants etc.) should also be added to the | |
| symbols list(s) found in the `libc-test/semver` directory. These lists keep | |
| track of what symbols are public in the libc crate and ensures they remain | |
| available between changes to the crate. If the new symbol(s) are available on | |
| all supported Unixes it should be added to `unix.txt` list<sup>1</sup>, | |
| otherwise they should be added to the OS specific list(s). | |
| With that in mind, the steps for adding a new API are: | |
| 1. Determine where in the module hierarchy your API should be added. | |
| 2. Add the API, including adding new symbol(s) to the semver lists. | |
| 3. Send a PR to this repo. | |
| 4. Wait for CI to pass, fixing errors. | |
| 5. Wait for a merge! | |
| <sup>1</sup>: Note that this list has nothing to do with any Unix or Posix | |
| standard, it's just a list shared between all OSs that declare `#[cfg(unix)]`. | |
| ## Test before you commit | |
| We have two automated tests running on [GitHub Actions](https://github.com/rust-lang/libc/actions): | |
| 1. [`libc-test`](https://github.com/gnzlbg/ctest) | |
| - `cd libc-test && cargo test` | |
| - Use the `skip_*()` functions in `build.rs` if you really need a workaround. | |
| 2. Style checker | |
| - [`sh ci/style.sh`](https://github.com/rust-lang/libc/blob/main/ci/style.sh) | |
| ## Breaking change policy | |
| Sometimes an upstream adds a breaking change to their API e.g. removing outdated items, | |
| changing the type signature, etc. And we probably should follow that change to build the | |
| `libc` crate successfully. It's annoying to do the equivalent of semver-major versioning | |
| for each such change. Instead, we mark the item as deprecated and do the actual change | |
| after a certain period. The steps are: | |
| 1. Add `#[deprecated(since = "", note="")]` attribute to the item. | |
| - The `since` field should have a next version of `libc` | |
| (e.g., if the current version is `0.2.1`, it should be `0.2.2`). | |
| - The `note` field should have a reason to deprecate and a tracking issue to call for comments | |
| (e.g., "We consider removing this as the upstream removed it. | |
| If you're using it, please comment on #XXX"). | |
| 2. If we don't see any concerns for a while, do the change actually. | |
| ## Supported target policy | |
| When Rust removes a support for a target, the libc crate also may remove the support anytime. | |
| ## Releasing your change to crates.io | |
| Now that you've done the amazing job of landing your new API or your new | |
| platform in this crate, the next step is to get that sweet, sweet usage from | |
| crates.io! The only next step is to bump the version of libc and then publish | |
| it. If you'd like to get a release out ASAP you can follow these steps: | |
| 1. Increment the patch version number in `Cargo.toml` and `libc-test/Cargo.toml`. | |
| 1. Send a PR to this repository. It should [look like this][example-pr], but it'd | |
| also be nice to fill out the description with a small rationale for the | |
| release (any rationale is ok though!). | |
| 1. Once merged, the release will be tagged and published by one of the libc crate | |
| maintainers. | |
| [example-pr]: https://github.com/rust-lang/libc/pull/2120 |