Unify includes and add bindgen in build.rs
This commit is contained in:
parent
fb8d6d0bb5
commit
e122545cf4
@ -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"
|
@ -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
4
cvode-5-sys/src/include.h
Normal file
4
cvode-5-sys/src/include.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include <cvode/cvode.h>
|
||||||
|
#include <nvector/nvector_serial.h>
|
||||||
|
#include <sunlinsol/sunlinsol_dense.h>
|
||||||
|
#include <sunmatrix/sunmatrix_dense.h>
|
@ -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
@ -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) };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user