flint3-sys 3.5.0

Rust bindings to the FLINT C library
Documentation
# flint3-sys

[FLINT](https://flintlib.org/) bindings for the Rust programming language, using [bindgen](https://github.com/rust-lang/rust-bindgen).

Since the FLINT API evolves quickly, this crate always compiles FLINT from source and never attempts to use a system library.

## Versioning

This crate follows FLINT's versioning, except for the patch version, which may increase faster.


## Optional Features

- `gmp-mpfr-sys`: Enables a dependency on the [gmp-mpfr-sys]https://crates.io/crates/gmp-mpfr-sys crate and builds FLINT against GMP and MPFR libraries compiled by it. If this feature is **not** enabled, there is a system dependency on GMP and MPFR.

- `force-bindgen`: Adds [bindgen]https://github.com/rust-lang/rust-bindgen as a build dependency and regenerates the bindings. Useful for maintenance (see below). This takes a long time (5-10 minutes).

## Metadata

This crate passes the following metadata to its dependents:

- `DEP_FLINT_LIB_DIR`: Path to the directory containing `libflint.a`.
- `DEP_FLINT_INCLUDE_DIR`: Path to the directory containing FLINT headers, such as `DEP_FLINT_INCLUDE_DIR/flint/flint.h`.

This is useful for crates that need to compile a C library depending on FLINT. See the [Cargo book](https://doc.rust-lang.org/cargo/reference/build-scripts.html#the-links-manifest-key) for more details.

## Licensing

This crate is distributed under the MIT license.  
Note that FLINT itself is licensed under the LGPLv3.


## Why not [flint-sys]https://crates.io/crates/flint-sys?

There seems to be too much manual work which makes the maintenance hard and the package often outdated. 


## Architecture

Creating a `*-sys` crate involves several design decisions, as outlined by [Kornel](https://kornel.ski/rust-sys-crate).

### Build from Source?

While FLINT is available via many package managers, using the system library can introduce issues due to FLINT's unstable API.

Using *pkg-config* to link against a system-installed FLINT is straightforward, but building against it requires running *bindgen* on the system headers. This:

- Is slower (since *bindgen* is not multithreaded),
- Results in unpredictable APIs,
- May miss AVX2 optimizations, which are often not enabled in precompiled packages.

For these reasons, this crate builds FLINT from source.

For FLINT's dependencies (GMP and MPFR), you may choose to compile them from source (using the *gmp-mpfr-sys* feature) or rely on the system libraries. Compiling from source typically yields better performance.  
Note: *flint3-sys* does not expose any part of the GMP or MPFR APIs.

### *bindgen* in `build.rs`?

There are two approaches:

1. Run *bindgen* upstream and ship the generated bindings.
2. Run *bindgen* in the build script.

By default, the first option is used as it's much faster. However, it may lead to desynchronization: the headers used to generate the bindings are not necessarily the ones you'll have after building FLINT. Parts of FLINT's headers are generated by its `./configure` script, so constants like `FLINT_HAVE_FFT_SMALL` might not match.

To regenerate bindings manually, enable the *force-bindgen* feature.

### Pipeline

1. Build FLINT, with the usual procedure (`./configure --prefix=OUT_DIR`, `make`, `make install`)
2. Run *bindgen*, or simply copy the pregenerated files in the directory `./bindgen`
3. Compile the `flintextern.c` file generated by bindgen which contains the inline functions.


## Maintenance

To update the bundled version of FLINT:

1. Update the `./flint` submodule.
2. Run `KEEP_BINDGEN_OUTPUT=1 cargo build -F force-bindgen` to regenerate `./bindgen/flint.rs` and `./bindgen/flintextern.c`.
3. Test thoroughly.
4. Commit the changes.