Skip to content

Commit

Permalink
fix: Fix rust binding generation error for lwext4
Browse files Browse the repository at this point in the history
When the target is riscv64gc-unknown-none-elf, bindgen cannot correctly
generate the c binding. We temporarily switch the target to the default
x86_64-unknow-linux-gnu, and switch to the old value after completing
the generation.
  • Loading branch information
Godones committed Feb 3, 2024
1 parent 899828f commit f671b4d
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 8,872 deletions.
2 changes: 1 addition & 1 deletion lwext4-rs/src/dir.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::block::CName;
use crate::error::{Error, Result};
use crate::types::FileType;
use crate::types::*;
use crate::File;
use alloc::string::{String, ToString};
use core::ffi::CStr;
Expand Down
2 changes: 1 addition & 1 deletion lwext4-rs/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::block::CName;
use crate::error::{errno_to_result, Error, Result};
use crate::types::{FileAttr, FileTimes, Metadata, OpenFlags, Permissions, Time};
use alloc::string::ToString;

use alloc::string::String;
use core::ptr::null_mut;
use embedded_io::{ErrorType, Read, Seek, SeekFrom, Write};
use lwext4_sys::ext4::*;
Expand Down
2 changes: 2 additions & 0 deletions lwext4-rs/src/mkfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use core::fmt::Debug;
use core::mem::transmute;
use core::pin::Pin;
use core::ptr::null_mut;
use crate::alloc::string::ToString;
use alloc::string::String;
use lwext4_sys::ext4::{ext4_fs, ext4_mkfs, ext4_mkfs_info, ext4_mkfs_read_info, ext4_sblock};
pub struct BuildExtFs<T: BlockDeviceInterface> {
raw_fs: ext4_fs,
Expand Down
7 changes: 7 additions & 0 deletions lwext4-rs/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use core::fmt::{Debug, Formatter};
use core::ops::{Deref, DerefMut};
use lwext4_sys::ext4::*;

pub const S_IFIFO:u32 = 4096;
pub const S_IFCHR:u32 = 8192;
pub const S_IFBLK:u32 = 24576;
pub const S_IFDIR:u32 = 16384;
pub const S_IFREG:u32 = 32768;
pub const S_IFLNK:u32 = 40960;
pub const S_IFSOCK:u32 = 49152;
bitflags! {
pub struct DebugFlags: u32 {
const BALLOC = DEBUG_BALLOC;
Expand Down
2 changes: 1 addition & 1 deletion lwext4-sys/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1 @@
./lwext4
./src/ext4.rs
4 changes: 1 addition & 3 deletions lwext4-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,4 @@ edition = "2021"


[build-dependencies]
bindgen = "0.65"
fs_extra = "1.2.0"
make-cmd = "0.1.0"
bindgen = "0.65"
136 changes: 70 additions & 66 deletions lwext4-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,82 +1,86 @@
use fs_extra::dir::CopyOptions;
use make_cmd::make;
use std::path::PathBuf;
use std::{env, fs};
use std::path::PathBuf;
use std::process::Command;

fn main() {
println!("cargo:rerun-if-changed=./lwext4");
println!("cargo:rerun-if-changed=./ext4.h");

std::process::Command::new("git")
.arg("clone")
.arg("https://github.com/gkostka/lwext4.git")
.output()
.unwrap();

let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
fs_extra::dir::remove(&out_dir).unwrap();
fs::create_dir_all(&out_dir).unwrap();
let lwext4_dir = out_dir.join("lwext4");
let mut copy_options = CopyOptions::new();
copy_options.copy_inside = true;
copy_options.overwrite = true;
fs_extra::dir::copy("./lwext4", &out_dir, &copy_options).unwrap();
make()
.current_dir(&lwext4_dir)
.arg("generic")
let lwext4 = out_dir.join("lwext4");
if !lwext4.exists(){
fs::create_dir_all(lwext4.clone()).unwrap();
let cp = Command::new("git")
.current_dir(out_dir.clone())
.arg("clone")
.arg("https://github.com/os-module/lwext4-c.git")
.arg("lwext4")
.status()
.expect("failed to clone lwext4");
assert_eq!(cp.success(),true);
}
let os = env::var("CARGO_CFG_TARGET_OS").unwrap();
if os == "none"{
build_for_none(&lwext4);
}else {
build_for_os(&lwext4);
}
println!("cargo:rustc-link-lib=static=lwext4");
println!("cargo:rerun-if-changed={}",PathBuf::from("ext4.h").canonicalize().unwrap().display());
}

fn build(lwext4:&PathBuf,lwext4_build:&PathBuf,build_arg:&str){
let make = Command::new("make")
.current_dir(&lwext4)
.arg(build_arg)
.status()
.unwrap();
let build_generic_dir = lwext4_dir.join("build_generic");
make()
.current_dir(&build_generic_dir)
.expect("failed to build lwext4");
assert!(make.success());
let make = Command::new("make")
.current_dir(lwext4_build)
.arg("lwext4")
.status()
.unwrap();
println!(
"cargo:rustc-link-search={}",
fs::canonicalize(build_generic_dir.join("src"))
.unwrap()
.to_str()
.unwrap()
);
println!("cargo:rustc-link-lib=static=lwext4");
.expect("failed to build lwext4");
assert!(make.success());
}

fn build_for_os(lwext4:&PathBuf){
let lwext4_build = lwext4.join("build_generic");
let lib_path = lwext4.join("build_generic/src/liblwext4.a");
if !lwext4_build.exists() || !lib_path.exists(){
build(lwext4,&lwext4_build,"generic");
generates_bindings(&lwext4,"build_generic");
}
println!("cargo:rustc-link-search=native={}",lwext4_build.join("src").canonicalize().unwrap().display());
}

fs_extra::dir::copy(
lwext4_dir.join("include"),
&build_generic_dir,
&copy_options,
)
.unwrap();
// let bindings = bindgen::builder()
// .header(
// build_generic_dir
// .join("include")
// .join("ext4.h")
// .to_str()
// .unwrap(),
// )
// .clang_arg(format!(
// "-I{}",
// dbg!(build_generic_dir.join("include").to_str().unwrap())
// ))
// .use_core()
// .parse_callbacks(Box::new(bindgen::CargoCallbacks))
// .generate()
// .unwrap();
// bindings.write_to_file("src/ext4.rs").unwrap();

// let path = OpenOptions::new()
// .read(true)
// .open("./ext4.h");
/// When the target is riscv64gc-unknown-none-elf,
/// bindgen cannot correctly generate the c binding.
/// We temporarily switch the target to the default x86_64-unknow-linux-gnu,
/// and switch to the old value after completing the generation.
fn build_for_none(lwext4:&PathBuf){
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
let lwext4_build = lwext4.join(format!("build_musl-generic-{}",arch));
let lib_path = lwext4.join(format!("build_musl-generic-{}/src/liblwext4.a",arch));
if !lwext4_build.exists() || !lib_path.exists(){
build(lwext4,&lwext4_build,format!("musl-generic-{}",arch).as_str());
let target = env::var("TARGET").unwrap();
env::set_var("TARGET","x86_64-unknown-linux-gnu");
generates_bindings(&lwext4,format!("build_musl-generic-{}",arch).as_str());
env::set_var("TARGET",target);
}
println!("cargo:rustc-link-search=native={}",lwext4_build.join("src").canonicalize().unwrap().display());
}


fn generates_bindings(lwext4: &PathBuf, build_dir:&str) {
let bindings = bindgen::builder()
.header("./ext4.h")
.clang_arg(format!(
"-I{}",
dbg!(build_generic_dir.join("include").to_str().unwrap())
))
.clang_arg(format!("-I{}/include",lwext4.display()))
.clang_arg(format!("-I{}/{}/include",lwext4.display(),build_dir))
.use_core()
.layout_tests(false)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
.generate()
.unwrap();
bindings.write_to_file("src/ext4.rs").unwrap()
bindings.write_to_file("src/ext4.rs").unwrap();
}

Loading

0 comments on commit f671b4d

Please sign in to comment.