Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,5 @@ trace = []
malloc = []
software-intrinsics = []
multiversion = []

unstable-disable-block-count-check = []
68 changes: 48 additions & 20 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,61 @@
use std::env;
use std::path::PathBuf;
use std::process::Command;

fn main() -> Result<(), Box<dyn std::error::Error>> {
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());

// Patch lfs.h to remove the lfs_util import because clang fails to locate the
// libraries for the custom target (especially string.h)
// Compilation before that succeeds because it's using gcc,
// which comes as a distribution with these utils.
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
// but not string.h
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
println!("cargo::rerun-if-changed=littlefs/lfs.h");
let out_lfs_h = out_path.join("lfs.h");
std::fs::write(
&out_lfs_h,
lfs_h.replace(
r##"#include "lfs_util.h""##,
"#include <stdint.h>\n#include <stdbool.h>",
),
)
.expect("Failed to write lfs.h");

// maybe patch lfs.c to remove the mount check for the block count
println!("cargo::rerun-if-changed=littlefs/lfs.c");
let out_lfs_c = out_path.join("lfs.c");
if cfg!(feature = "unstable-disable-block-count-check") {
println!("cargo::rerun-if-changed=remove-mount-check.patch");
assert!(
Command::new("patch")
.args([
"littlefs/lfs.c",
"-o",
out_lfs_c.to_str().unwrap(),
"remove-mount-check.patch"
])
.spawn()
.unwrap()
.wait()
.unwrap()
.success(),
"Failed to apply patch"
)
} else {
std::fs::copy("littlefs/lfs.c", out_path.join("lfs.c")).unwrap();
}

let mut builder = cc::Build::new();
let builder = builder
.flag("-std=c99")
.flag("-DLFS_NO_DEBUG")
.flag("-DLFS_NO_WARN")
.flag("-DLFS_NO_ERROR")
.file("littlefs/lfs.c")
.include(&out_path)
.include("littlefs")
.file(out_lfs_c)
.file("littlefs/lfs_util.c")
.file("string.c");

Expand All @@ -29,25 +76,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {

builder.compile("lfs-sys");

// Patch lfs.h to remove the lfs_util import because clang fails to locate the
// libraries for the custom target (especially string.h)
// Compilation before that succeeds because it's using gcc,
// which comes as a distribution with these utils.
// Turns out lfs_utils is not used in lfs.h, and clang properly finds stdint.h and stdbool,
// but not string.h
let lfs_h = std::fs::read_to_string("littlefs/lfs.h").expect("Reading lfs.h succeeds");
println!("cargo::rerun-if-changed=littlefs/lfs.h");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
let out_lfs_h = out_path.join("lfs.h");
std::fs::write(
&out_lfs_h,
lfs_h.replace(
r##"#include "lfs_util.h""##,
"#include <stdint.h>\n#include <stdbool.h>",
),
)
.expect("Failed to write lfs.h");

let bindgen = bindgen::Builder::default()
.header(out_lfs_h.into_os_string().into_string().unwrap())
.clang_arg("-std=c99")
Expand Down
31 changes: 31 additions & 0 deletions remove-mount-check.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
--- lfs.c 2025-04-14 12:03:45.959258416 +0200
+++ lfs.c.patched 2025-04-14 12:03:23.044370382 +0200
@@ -4521,15 +4521,20 @@
}

// this is where we get the block_count from disk if block_count=0
- if (lfs->cfg->block_count
- && superblock.block_count != lfs->cfg->block_count) {
- LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
- superblock.block_count, lfs->cfg->block_count);
- err = LFS_ERR_INVAL;
- goto cleanup;
- }
+ //
+ // if (lfs->cfg->block_count
+ // && superblock.block_count != lfs->cfg->block_count) {
+ // LFS_ERROR("Invalid block count (%"PRIu32" != %"PRIu32")",
+ // superblock.block_count, lfs->cfg->block_count);
+ // err = LFS_ERR_INVAL;
+ // goto cleanup;
+ // }

- lfs->block_count = superblock.block_count;
+ if (lfs->cfg->block_count) {
+ lfs->block_count = lfs->cfg->block_count;
+ } else {
+ lfs->block_count = superblock.block_count;
+ }

if (superblock.block_size != lfs->cfg->block_size) {
LFS_ERROR("Invalid block size (%"PRIu32" != %"PRIu32")",
Loading