Browse Source

Support conditional compilation of RomFS

If the user tries to open the RomFS when one has not been added, it will
result in a segfault (libctru doesn't verify the RomFS actually is
configured). This avoids that scenario when used in conjunction with
cargo-3ds.

An alternative approach would be to do as libctru does and read the 3dsx
file header, and use that to determine if RomFS is enabled at runtime.
This would require more code, but it would be more accurate and
compatible (wouldn't require a tool like cargo-3ds to ensure the RomFS
is added).
pull/14/head
AzureMarker 3 years ago
parent
commit
39de31a662
No known key found for this signature in database
GPG Key ID: 47A133F3BF9D03D3
  1. 7
      ctru-rs/Cargo.toml
  2. 32
      ctru-rs/build.rs
  3. 5
      ctru-rs/examples/file-explorer.rs
  4. 0
      ctru-rs/romfs/test-file.txt
  5. 17
      ctru-rs/src/lib.rs
  6. 14
      ctru-rs/src/romfs.rs

7
ctru-rs/Cargo.toml

@ -19,5 +19,12 @@ libc = { git = "https://github.com/Meziu/libc.git" } @@ -19,5 +19,12 @@ libc = { git = "https://github.com/Meziu/libc.git" }
bitflags = "1.0.0"
widestring = "0.2.2"
[build-dependencies]
toml = "0.5"
[dev-dependencies]
ferris-says = "0.2.1"
[features]
default = ["romfs"]
romfs = []

32
ctru-rs/build.rs

@ -0,0 +1,32 @@ @@ -0,0 +1,32 @@
use std::path::PathBuf;
fn main() {
// Open Cargo.toml
let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
let manifest_path = format!("{manifest_dir}/Cargo.toml");
let manifest_str = std::fs::read_to_string(&manifest_path)
.unwrap_or_else(|e| panic!("Could not open {manifest_path}: {e}"));
let manifest_data: toml::Value =
toml::de::from_str(&manifest_str).expect("Could not parse Cargo manifest as TOML");
// Find the romfs setting and compute the path
let romfs_dir_setting = manifest_data
.as_table()
.and_then(|table| table.get("package"))
.and_then(toml::Value::as_table)
.and_then(|table| table.get("metadata"))
.and_then(toml::Value::as_table)
.and_then(|table| table.get("cargo-3ds"))
.and_then(toml::Value::as_table)
.and_then(|table| table.get("romfs_dir"))
.and_then(toml::Value::as_str)
.unwrap_or("romfs");
let romfs_path = PathBuf::from(format!("{manifest_dir}/{romfs_dir_setting}"));
// Check if the romfs path exists so we can compile the module
if romfs_path.exists() {
println!("cargo:rustc-cfg=romfs_exists");
}
println!("cargo:rerun-if-changed={}", manifest_dir);
}

5
ctru-rs/examples/file-explorer.rs

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
use ctru::applets::swkbd::{Button, Swkbd};
use ctru::console::Console;
use ctru::romfs::RomFS;
use ctru::services::hid::KeyPad;
use ctru::services::{Apt, Hid};
use ctru::Gfx;
@ -15,7 +14,9 @@ fn main() { @@ -15,7 +14,9 @@ fn main() {
let apt = Apt::init().unwrap();
let hid = Hid::init().unwrap();
let gfx = Gfx::default();
let _romfs = RomFS::new().unwrap();
#[cfg(all(feature = "romfs", romfs_exists))]
let _romfs = ctru::romfs::RomFS::new().unwrap();
FileExplorer::init(&apt, &hid, &gfx).run();
}

0
romfs/test-file.txt → ctru-rs/romfs/test-file.txt

17
ctru-rs/src/lib.rs

@ -34,11 +34,26 @@ pub mod console; @@ -34,11 +34,26 @@ pub mod console;
pub mod error;
pub mod gfx;
pub mod sdmc;
pub mod romfs;
pub mod services;
pub mod srv;
pub mod thread;
#[cfg(all(feature = "romfs", romfs_exists))]
pub mod romfs;
#[cfg(not(all(feature = "romfs", romfs_exists)))]
pub mod romfs {
//! The RomFS folder has not been detected and/or the `romfs` feature has not been enabled.
//!
//! Configure the path in Cargo.toml (the default path is "romfs"). Paths are relative to the
//! `CARGO_MANIFEST_DIR` environment variable, which is the directory containing the manifest of
//! your package.
//!
//! ```toml
//! [package.metadata.cargo-3ds]
//! romfs_dir = "romfs"
//! ```
}
pub use crate::error::{Error, Result};
pub use crate::gfx::Gfx;

14
ctru-rs/src/romfs.rs

@ -1,3 +1,15 @@ @@ -1,3 +1,15 @@
//! This module only gets compiled if the configured RomFS directory is found and the `romfs`
//! feature is enabled.
//!
//! Configure the path in Cargo.toml (the default path is "romfs"). Paths are relative to the
//! `CARGO_MANIFEST_DIR` environment variable, which is the directory containing the manifest of
//! your package.
//!
//! ```toml
//! [package.metadata.cargo-3ds]
//! romfs_dir = "romfs"
//! ```
use std::ffi::CStr;
#[non_exhaustive]
@ -21,4 +33,4 @@ impl Drop for RomFS { @@ -21,4 +33,4 @@ impl Drop for RomFS {
let mount_name = CStr::from_bytes_with_nul(b"romfs\0").unwrap();
unsafe { ctru_sys::romfsUnmount(mount_name.as_ptr()) };
}
}
}

Loading…
Cancel
Save