esp-idf-sys 0.38.0

Bindings for ESP-IDF (Espressif's IoT Development Framework)
#![cfg(any(feature = "binstart", feature = "libstart"))]

// When compiling a binary Rust crate in STD (e.g. in Cargo-first builds) and NOT doing
// any tricks like using #[no_main] or #[start], the Rust compiler will autogenerate
// a C function with the signature as below which will be proxying
// the real Rust main function of your binary crate
//
// So to bridge this function with the real C "app_main()" entrypoint
// that ESP-IDF expects it is enough to implement app_main() and call in it
// the "main" C function autogenerated by the Rust compiler
//
// See https://github.com/rust-lang/rust/issues/29633 for more information
#[cfg(all(feature = "std", feature = "binstart"))]
extern "C" {
    fn main(p1: isize, p2: *const *const u8) -> isize;
}

// When compiling a static Rust library crate (e.g. by using a PIO->Cargo or a CMake->Cargo) build,
// there is no main function that the Rust compiler expects, nor autogeneration of a callable
// wrapper around it.
//
// In that case (and if the "libstart" feature is enabled), it is _us_ (not the Rust compiler)
// expecting the user to define a rust #[no_mangle] "main" function and it is our code below which is explicitly
// calling it from app_main(). If the user does not define a main() runction in Rust, there will
// be a linkage error instead of the nice Rust syntax error for binary crates.
//
// Another restriction of the "libstart" feature is that the Rust main function will always have one
// fixed signature: "fn main() -> ()" - as opposed to the flexibility of main() in binary crates
// where it can have quite a few different returning types
//
// When compiling a binary Rust crate in no_std, we end up in identical situation:
// - There is no Rust "lang = start" item defined
// - As such, there is no magic C "main" function defined for, which would proxy our binary crate main
#[cfg(any(all(not(feature = "std"), feature = "binstart"), feature = "libstart"))]
extern "Rust" {
    fn main();
}

#[no_mangle]
pub extern "C" fn app_main() {
    // Make sure the ESP-IDF patches implemented in Rust are linked to the
    // final executable
    crate::link_patches();

    // Bind the C standard streams to their POSIX file descriptors (0, 1 and 2),
    // which ESP-IDF does not do, and which - among others - the Rust Standard
    // Library relies on for its `stdin`/`stdout`/`stderr` (and thus for
    // `println!` et al.); see the documentation of this function for details
    crate::restore_posix_stdio_fds();

    unsafe {
        #[cfg(all(feature = "std", feature = "binstart"))]
        main(0, &[core::ptr::null()] as *const *const u8);

        #[cfg(any(all(not(feature = "std"), feature = "binstart"), feature = "libstart"))]
        main();
    }
}