Unify includes and add bindgen in build.rs

This commit is contained in:
Arthur Carcano 2021-05-15 11:36:24 +02:00
parent fb8d6d0bb5
commit e122545cf4
10 changed files with 62 additions and 22169 deletions

View File

@ -7,3 +7,7 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
[build-dependencies]
bindgen = "0.58.1"
anyhow = "1.0.40"

View File

@ -1,5 +1,23 @@
fn main() -> () { use bindgen::builder;
use std::env;
use std::path::Path;
fn main() -> anyhow::Result<()> {
for lib in &["sundials_cvodes", "sundials_nvecserial"] { for lib in &["sundials_cvodes", "sundials_nvecserial"] {
println!("cargo:rustc-link-lib={}", lib); println!("cargo:rustc-link-lib={}", lib);
} }
let out_dir = env::var_os("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("generated.rs");
let bindings = builder()
.header("src/include.h")
.generate()
.map_err(|()| anyhow::anyhow!("Couldn't generate bindings."))?;
// Write the generated bindings to an output file.
bindings.write_to_file(dest_path)?;
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/include.h");
Ok(())
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,4 @@
#include <cvode/cvode.h>
#include <nvector/nvector_serial.h>
#include <sunlinsol/sunlinsol_dense.h>
#include <sunmatrix/sunmatrix_dense.h>

View File

@ -5,7 +5,4 @@
improper_ctypes improper_ctypes
)] )]
pub mod cvode; include!(concat!(env!("OUT_DIR"), "/generated.rs"));
pub mod nvector_serial;
pub mod sunlinsol_dense;
pub mod sunmatrix_dense;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,9 @@
use std::{convert::TryInto, pin::Pin}; use std::{convert::TryInto, pin::Pin};
use std::{ffi::c_void, intrinsics::transmute, os::raw::c_int, ptr::NonNull}; use std::{ffi::c_void, intrinsics::transmute, os::raw::c_int, ptr::NonNull};
use cvode::SUNMatrix;
use cvode_5_sys::{ use cvode_5_sys::{
cvode::{self, realtype, SUNLinearSolver}, realtype, SUNLinearSolver, SUNMatrix,
nvector_serial::N_VGetArrayPointer, N_VGetArrayPointer,
}; };
mod nvector; mod nvector;
@ -17,8 +16,8 @@ pub type Realtype = realtype;
#[repr(u32)] #[repr(u32)]
#[derive(Debug)] #[derive(Debug)]
pub enum LinearMultistepMethod { pub enum LinearMultistepMethod {
ADAMS = cvode::CV_ADAMS, ADAMS = cvode_5_sys::CV_ADAMS,
BDF = cvode::CV_BDF, BDF = cvode_5_sys::CV_BDF,
} }
#[repr(C)] #[repr(C)]
@ -117,8 +116,8 @@ macro_rules! wrap {
#[repr(u32)] #[repr(u32)]
pub enum StepKind { pub enum StepKind {
Normal = cvode::CV_NORMAL, Normal = cvode_5_sys::CV_NORMAL,
OneStep = cvode::CV_ONE_STEP, OneStep = cvode_5_sys::CV_ONE_STEP,
} }
#[derive(Debug)] #[derive(Debug)]
@ -134,7 +133,7 @@ fn check_non_null<T>(ptr: *mut T, func_id: &'static str) -> Result<NonNull<T>> {
} }
fn check_flag_is_succes(flag: c_int, func_id: &'static str) -> Result<()> { fn check_flag_is_succes(flag: c_int, func_id: &'static str) -> Result<()> {
if flag == cvode::CV_SUCCESS as i32 { if flag == cvode_5_sys::CV_SUCCESS as i32 {
Ok(()) Ok(())
} else { } else {
Err(Error::ErrorCode { flag, func_id }) Err(Error::ErrorCode { flag, func_id })
@ -169,13 +168,13 @@ impl<UserData, const N: usize> Solver<UserData, N> {
) -> Result<Self> { ) -> Result<Self> {
assert_eq!(y0.len(), N); assert_eq!(y0.len(), N);
let mem: CvodeMemoryBlockNonNullPtr = { let mem: CvodeMemoryBlockNonNullPtr = {
let mem_maybenull = unsafe { cvode::CVodeCreate(method as c_int) }; let mem_maybenull = unsafe { cvode_5_sys::CVodeCreate(method as c_int) };
check_non_null(mem_maybenull as *mut CvodeMemoryBlock, "CVodeCreate")?.into() check_non_null(mem_maybenull as *mut CvodeMemoryBlock, "CVodeCreate")?.into()
}; };
let y0 = NVectorSerialHeapAlloced::new_from(y0); let y0 = NVectorSerialHeapAlloced::new_from(y0);
let matrix = { let matrix = {
let matrix = unsafe { let matrix = unsafe {
cvode_5_sys::sunmatrix_dense::SUNDenseMatrix( cvode_5_sys::SUNDenseMatrix(
N.try_into().unwrap(), N.try_into().unwrap(),
N.try_into().unwrap(), N.try_into().unwrap(),
) )
@ -184,9 +183,9 @@ impl<UserData, const N: usize> Solver<UserData, N> {
}; };
let linsolver = { let linsolver = {
let linsolver = unsafe { let linsolver = unsafe {
cvode_5_sys::sunlinsol_dense::SUNDenseLinearSolver( cvode_5_sys::SUNDenseLinearSolver(
y0.as_raw() as _, y0.as_raw(),
matrix.as_ptr() as _, matrix.as_ptr(),
) )
}; };
check_non_null(linsolver, "SUNDenseLinearSolver")? check_non_null(linsolver, "SUNDenseLinearSolver")?
@ -195,46 +194,46 @@ impl<UserData, const N: usize> Solver<UserData, N> {
let res = Solver { let res = Solver {
mem, mem,
y0, y0,
sunmatrix: matrix.as_ptr() as _, sunmatrix: matrix.as_ptr(),
linsolver: linsolver.as_ptr() as _, linsolver: linsolver.as_ptr(),
atol, atol,
user_data, user_data,
}; };
{ {
let flag = unsafe { let flag = unsafe {
cvode::CVodeInit( cvode_5_sys::CVodeInit(
mem.as_raw(), mem.as_raw(),
Some(std::mem::transmute(f)), Some(std::mem::transmute(f)),
t0, t0,
res.y0.as_raw() as _, res.y0.as_raw(),
) )
}; };
check_flag_is_succes(flag, "CVodeInit")?; check_flag_is_succes(flag, "CVodeInit")?;
} }
match &res.atol { match &res.atol {
&AbsTolerance::Scalar(atol) => { &AbsTolerance::Scalar(atol) => {
let flag = unsafe { cvode::CVodeSStolerances(mem.as_raw(), rtol, atol) }; let flag = unsafe { cvode_5_sys::CVodeSStolerances(mem.as_raw(), rtol, atol) };
check_flag_is_succes(flag, "CVodeSStolerances")?; check_flag_is_succes(flag, "CVodeSStolerances")?;
} }
AbsTolerance::Vector(atol) => { AbsTolerance::Vector(atol) => {
let flag = let flag =
unsafe { cvode::CVodeSVtolerances(mem.as_raw(), rtol, atol.as_raw() as _) }; unsafe { cvode_5_sys::CVodeSVtolerances(mem.as_raw(), rtol, atol.as_raw()) };
check_flag_is_succes(flag, "CVodeSVtolerances")?; check_flag_is_succes(flag, "CVodeSVtolerances")?;
} }
} }
{ {
let flag = unsafe { let flag = unsafe {
cvode::CVodeSetLinearSolver( cvode_5_sys::CVodeSetLinearSolver(
mem.as_raw(), mem.as_raw(),
linsolver.as_ptr() as _, linsolver.as_ptr(),
matrix.as_ptr() as _, matrix.as_ptr(),
) )
}; };
check_flag_is_succes(flag, "CVodeSetLinearSolver")?; check_flag_is_succes(flag, "CVodeSetLinearSolver")?;
} }
{ {
let flag = unsafe { let flag = unsafe {
cvode::CVodeSetUserData( cvode_5_sys::CVodeSetUserData(
mem.as_raw(), mem.as_raw(),
std::mem::transmute(res.user_data.as_ref().get_ref()), std::mem::transmute(res.user_data.as_ref().get_ref()),
) )
@ -251,10 +250,10 @@ impl<UserData, const N: usize> Solver<UserData, N> {
) -> Result<(Realtype, &[Realtype; N])> { ) -> Result<(Realtype, &[Realtype; N])> {
let mut tret = 0.; let mut tret = 0.;
let flag = unsafe { let flag = unsafe {
cvode::CVode( cvode_5_sys::CVode(
self.mem.as_raw(), self.mem.as_raw(),
tout, tout,
self.y0.as_raw() as _, self.y0.as_raw(),
&mut tret, &mut tret,
step_kind as c_int, step_kind as c_int,
) )
@ -266,9 +265,9 @@ impl<UserData, const N: usize> Solver<UserData, N> {
impl<UserData, const N: usize> Drop for Solver<UserData, N> { impl<UserData, const N: usize> Drop for Solver<UserData, N> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { cvode::CVodeFree(&mut self.mem.as_raw()) } unsafe { cvode_5_sys::CVodeFree(&mut self.mem.as_raw()) }
unsafe { cvode::SUNLinSolFree(self.linsolver) }; unsafe { cvode_5_sys::SUNLinSolFree(self.linsolver) };
unsafe { cvode::SUNMatDestroy(self.sunmatrix) }; unsafe { cvode_5_sys::SUNMatDestroy(self.sunmatrix) };
} }
} }

View File

@ -5,25 +5,25 @@ use std::{
ptr::NonNull, ptr::NonNull,
}; };
use cvode_5_sys::{cvode::realtype, nvector_serial}; use cvode_5_sys::realtype;
#[repr(transparent)] #[repr(transparent)]
#[derive(Debug)] #[derive(Debug)]
pub struct NVectorSerial<const SIZE: usize> { pub struct NVectorSerial<const SIZE: usize> {
inner: nvector_serial::_generic_N_Vector, inner: cvode_5_sys::_generic_N_Vector,
} }
impl<const SIZE: usize> NVectorSerial<SIZE> { impl<const SIZE: usize> NVectorSerial<SIZE> {
pub unsafe fn as_raw(&self) -> nvector_serial::N_Vector { pub unsafe fn as_raw(&self) -> cvode_5_sys::N_Vector {
std::mem::transmute(&self.inner) std::mem::transmute(&self.inner)
} }
pub fn as_slice(&self) -> &[realtype; SIZE] { pub fn as_slice(&self) -> &[realtype; SIZE] {
unsafe { transmute(nvector_serial::N_VGetArrayPointer_Serial(self.as_raw())) } unsafe { transmute(cvode_5_sys::N_VGetArrayPointer_Serial(self.as_raw())) }
} }
pub fn as_slice_mut(&mut self) -> &mut [realtype; SIZE] { pub fn as_slice_mut(&mut self) -> &mut [realtype; SIZE] {
unsafe { transmute(nvector_serial::N_VGetArrayPointer_Serial(self.as_raw())) } unsafe { transmute(cvode_5_sys::N_VGetArrayPointer_Serial(self.as_raw())) }
} }
} }
@ -49,7 +49,7 @@ impl<const SIZE: usize> DerefMut for NVectorSerialHeapAlloced<SIZE> {
impl<const SIZE: usize> NVectorSerialHeapAlloced<SIZE> { impl<const SIZE: usize> NVectorSerialHeapAlloced<SIZE> {
pub fn new() -> Self { pub fn new() -> Self {
let raw_c = unsafe { nvector_serial::N_VNew_Serial(SIZE.try_into().unwrap()) }; let raw_c = unsafe { cvode_5_sys::N_VNew_Serial(SIZE.try_into().unwrap()) };
Self { Self {
inner: NonNull::new(raw_c as *mut NVectorSerial<SIZE>).unwrap(), inner: NonNull::new(raw_c as *mut NVectorSerial<SIZE>).unwrap(),
} }
@ -64,6 +64,6 @@ impl<const SIZE: usize> NVectorSerialHeapAlloced<SIZE> {
impl<const SIZE: usize> Drop for NVectorSerialHeapAlloced<SIZE> { impl<const SIZE: usize> Drop for NVectorSerialHeapAlloced<SIZE> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { nvector_serial::N_VDestroy(self.as_raw()) } unsafe { cvode_5_sys::N_VDestroy(self.as_raw()) }
} }
} }