Enable bindgen during cargo build (#9)

* Add "std" feature to rustlib to allow using std in Xtensa projects
* Fix cargo target in CMakeLists.txt
* Use std feature when building for Xtensa
* Use std ffi aliases when building with std feature
* Add custom ffi aliases when building without std feature
* Add no_std attribute and panic handler when building without std feature
This commit is contained in:
Robert Cottrell 2021-06-15 10:48:12 +01:00 committed by GitHub
parent d797b1e692
commit a0641abd8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 30 additions and 41 deletions

View File

@ -4,9 +4,11 @@ idf_component_register(SRCS "main.c"
set(CARGO_BUILD_TYPE "release") set(CARGO_BUILD_TYPE "release")
set(CARGO_BUILD_ARG "--release") set(CARGO_BUILD_ARG "--release")
if(CONFIG_IDF_TARGET_ARCH_RISCV) if(CONFIG_IDF_TARGET_ARCH_RISCV)
set(CARGO_TARGET "riscv32i-unknown-elf") set(CARGO_TARGET "riscv32i-unknown-none-elf")
set(CARGO_FEATURES_ARG "")
elseif(CONFIG_IDF_TARGET_ARCH_XTENSA) elseif(CONFIG_IDF_TARGET_ARCH_XTENSA)
set(CARGO_TARGET "xtensa-${CONFIG_IDF_TARGET}-none-elf") set(CARGO_TARGET "xtensa-esp32-none-elf")
set(CARGO_FEATURES_ARG "--features=std")
endif() endif()
set(RUST_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}/../rustlib") set(RUST_PROJECT_DIR "${CMAKE_CURRENT_LIST_DIR}/../rustlib")
@ -19,7 +21,7 @@ ExternalProject_Add(
BUILD_COMMAND ${CMAKE_COMMAND} -E env BUILD_COMMAND ${CMAKE_COMMAND} -E env
CARGO_BUILD_TARGET=${CARGO_TARGET} CARGO_BUILD_TARGET=${CARGO_TARGET}
CARGO_BUILD_TARGET_DIR=${RUST_BUILD_DIR} CARGO_BUILD_TARGET_DIR=${RUST_BUILD_DIR}
cargo build ${CARGO_BUILD_ARG} cargo build ${CARGO_BUILD_ARG} ${CARGO_FEATURES_ARG}
DOWNLOAD_COMMAND "" DOWNLOAD_COMMAND ""
CONFIGURE_COMMAND "" CONFIGURE_COMMAND ""
INSTALL_COMMAND "" INSTALL_COMMAND ""

View File

@ -8,10 +8,12 @@ edition = "2018"
crate-type = ["staticlib"] crate-type = ["staticlib"]
#crate-type = ["rlib", "staticlib"] #crate-type = ["rlib", "staticlib"]
[build-dependencies] [build-dependencies]
bindgen = "0.58" bindgen = "0.58"
[features]
std = []
[profile.dev] [profile.dev]
# Optimization level 1 is similar to "g" in gcc/clang, although for some reason # Optimization level 1 is similar to "g" in gcc/clang, although for some reason
# Cargo doesn't support that flag. # Cargo doesn't support that flag.

View File

@ -1,3 +0,0 @@
/* automatically generated by rust-bindgen 0.58.1 */
pub const true_ : u32 = 1 ; pub const false_ : u32 = 0 ; pub const __bool_true_false_are_defined : u32 = 1 ; extern "C" { pub fn validate_param_in_c (param : :: std :: os :: raw :: c_int , value : :: std :: os :: raw :: c_int) -> bool ; }

View File

@ -1,40 +1,32 @@
use std::env; use std::env;
use std::fs;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
fn main() { fn main() {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
// let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()); let cargo_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
// fs::remove_dir_all(&out_dir).unwrap();
// fs::create_dir_all(&out_dir).unwrap();
// run_cbindgen(&cargo_dir, &out_dir); run_cbindgen(&cargo_dir, &out_dir);
run_bindgen(&target, &out_dir); run_bindgen(&target, &out_dir);
} }
// fn run_cbindgen(_cargo_dir: &Path, _out_dir: &Path) { fn run_cbindgen(_cargo_dir: &Path, _out_dir: &Path) {
// TODO: Run cbindgen // TODO: Run cbindgen
// } }
fn run_bindgen(target: &str, out_dir: &Path) { fn run_bindgen(target: &str, out_dir: &Path) {
// if target == "xtensa-esp32-none-elf" {
// env::set_var("LLVM_CONFIG_PATH", "/usr/local/xtensa/llvm/bin/llvm-config");
// }
let mut builder = bindgen::Builder::default(); let mut builder = bindgen::Builder::default();
builder = builder.header("../main/CApi.h"); builder = builder.header("../main/CApi.h");
builder = builder.use_core();
builder = builder.ctypes_prefix("ffi");
println!("Target: {}", target);
match target { match target {
"riscv32i-unknown-none-elf" => { "riscv32i-unknown-none-elf" => {
builder = builder.clang_arg("--target=riscv32"); builder = builder.clang_arg("--target=riscv32");
builder = builder.use_core();
builder = builder.ctypes_prefix("crate::ffi");
} }
"xtensa-esp32-none-elf" => { "xtensa-esp32-none-elf" => {
// Make sure that LLVM_CONFIG_PATH has been set to point to the
// Xtensa build of llvm-config.
builder = builder.clang_arg("--target=xtensa-esp32-elf"); builder = builder.clang_arg("--target=xtensa-esp32-elf");
} }
_ => { _ => {

View File

@ -1,8 +1,12 @@
// #![no_std] #![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
use core::panic::PanicInfo; use core::panic::PanicInfo;
pub mod ffi { /// Create aliases for FFI types for esp32c3, which doesn't have std.
#[cfg(not(feature = "std"))]
mod ffi {
#![allow(dead_code)]
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
@ -15,28 +19,20 @@ pub mod sys {
#![allow(non_upper_case_globals)] #![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
#![allow(non_snake_case)] #![allow(non_snake_case)]
use crate::ffi;
include!(concat!(env!("OUT_DIR"), "/bindings.rs")); include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
} }
use crate::sys::*;
// #[panic_handler]
// fn panic(_info: &PanicInfo) -> ! {
// loop {}
// }
#[no_mangle] #[no_mangle]
pub extern "C" fn add_in_rust(x: i32, y: i32) -> i32 { pub extern "C" fn add_in_rust(x: i32, y: i32) -> i32 {
extern "C" {
fn validate_param_in_c(param: i32, value: i32) -> i32;
}
unsafe { unsafe {
validate_param_in_c(0, x); sys::validate_param_in_c(0, x);
validate_param_in_c(2, y); sys::validate_param_in_c(2, y);
} }
x + y x + y
} }
#[cfg(not(feature = "std"))]
#[panic_handler]
fn panic(_info: &PanicInfo) -> ! {
loop {}
}