Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
073cbae
mfem-sys: Store information from cmake directly in the struct
Chris00 Feb 1, 2025
af3ff3e
Use autocxx to generate most bindings on mfem-sys
Chris00 Feb 3, 2025
1a8c723
Require Rust version ≥ 1.77
Chris00 Feb 4, 2025
9007b6a
Declare Operator as an opaque type for autocxx
Chris00 Feb 4, 2025
609b957
Add continuous integration and fix errors
Chris00 Feb 5, 2025
0323010
Use std::mem::transmute (the other location is deprecated)
Chris00 Feb 5, 2025
58597d6
Require that MFEM be compiled with double precision
Chris00 Feb 6, 2025
ad42ad0
Fix the Windows linking problem by using a commit past v4.7
Chris00 Feb 5, 2025
ca54baf
Require a recent cxx version
Chris00 Feb 7, 2025
99d9d5a
mfem-sys: Store information from cmake directly in the struct
Chris00 Feb 1, 2025
a4d03a5
Use autocxx to generate most bindings on mfem-sys
Chris00 Feb 3, 2025
ef6142a
cleanup
mkovaxx Feb 5, 2025
bc46bab
Allow the MFEM library to be compiled with single precision
Chris00 Feb 9, 2025
ab1b442
Be relax with the documentation coming from C++
Chris00 Feb 9, 2025
001b49f
Use a more sensible macro to guard the ffi_autocxx header
Chris00 Feb 9, 2025
cd1781a
Make the example work in precision f32 and f64
Chris00 Feb 9, 2025
8f6bc0f
mfem-sys: Add casting functions
Chris00 Feb 10, 2025
6f71f03
Fix call to RecoverFEMSolution
Chris00 Feb 10, 2025
e1be1bd
Update mfem-cpp to version 4.8-rc0
Chris00 Feb 11, 2025
d2eaa3e
mfem submodule at v4.8-rc0
mkovaxx Feb 13, 2025
631853a
Document unsafe functions in mfem-sys example
Chris00 Feb 13, 2025
045b2c6
mfem-sys: Use the conversion functions in the example
Chris00 Feb 13, 2025
e4a40e7
WIP: higher level interface (#18)
Chris00 Apr 23, 2025
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
9 changes: 6 additions & 3 deletions .github/workflows/ci.yml → .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ jobs:
rustup component add clippy
- run: cargo clippy -p mfem-sys --features bundled -- -D warnings
- run: cargo build -p mfem-sys --features bundled
- run: cargo run -p mfem-sys --features bundled --example ex1 -- --mesh crates/mfem-cpp/mfem/data/escher.mesh
- run: cargo run -p mfem-sys --features bundled --example ex1_sys -- --mesh data/square.mesh
- run: cargo run -p mfem --features bundled --example ex1 -- --mesh data/square.mesh

build-osx:
runs-on: macos-latest
Expand All @@ -39,7 +40,8 @@ jobs:
rustup update ${{ matrix.rust }}
rustup default ${{ matrix.rust }}
- run: cargo build -p mfem-sys --features bundled
- run: cargo run -p mfem-sys --features bundled --example ex1 -- --mesh crates/mfem-cpp/mfem/data/escher.mesh
- run: cargo run -p mfem-sys --features bundled --example ex1_sys -- --mesh data/square.mesh
- run: cargo run -p mfem --features bundled --example ex1 -- --mesh data/square.mesh

build-windows:
runs-on: windows-latest
Expand All @@ -56,7 +58,8 @@ jobs:
rustup update ${{ matrix.rust }}
rustup default ${{ matrix.rust }}
- run: cargo build -p mfem-sys --features bundled
- run: cargo run -p mfem-sys --features bundled --example ex1 --verbose -- --mesh crates/mfem-cpp/mfem/data/escher.mesh
- run: cargo run -p mfem-sys --features bundled --example ex1_sys -- --mesh data/square.mesh
- run: cargo run -p mfem --features bundled --example ex1 -- --mesh data/square.mesh

fmt:
name: Rust fmt
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
target/
Cargo.lock
.DS_Store
/*.mesh
/*.gf
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "crates/mfem-cpp/mfem"]
path = crates/mfem-cpp/mfem
url = git@github.com:mfem/mfem.git
url = https://github.com/mfem/mfem.git
9 changes: 3 additions & 6 deletions crates/mfem-cpp/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description = "Static build of MFEM for use as a Rust dependency"
readme = "README.md"
authors = ["Mate Kovacs <mkovaxx@gmail.com>"]
license = "MIT"
version = "0.3.0+mfem-4.7.0"
version = "0.3.0+mfem-4.8-rc0"
edition = "2021"
repository = "https://github.com/mkovaxx/mfem-rs"

Expand All @@ -13,8 +13,5 @@ repository = "https://github.com/mkovaxx/mfem-rs"
[build-dependencies]
cmake = "0.1"

# Adding an empty workspace table so `mfem-cpp` doesn't believe
# it's in the parent workspace. This crate is excluded from
# the top-level workspace because it takes quite awhile to
# build and the crate doesn't change very often.
#[workspace]
[features]
precision-f32 = []
12 changes: 8 additions & 4 deletions crates/mfem-cpp/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,15 @@ const LIB_DIR: &str = "lib";
const INCLUDE_DIR: &str = "include";

fn main() {
let dst = cmake::Config::new("mfem")
.define("BUILD_LIBRARY_TYPE", "Static")
let mut conf = cmake::Config::new("mfem");
conf.define("BUILD_LIBRARY_TYPE", "Static")
.define("INSTALL_DIR_LIB", LIB_DIR)
.define("INSTALL_DIR_INCLUDE", INCLUDE_DIR)
.build();
.define("INSTALL_DIR_INCLUDE", INCLUDE_DIR);
#[cfg(not(feature = "precision-f32"))]
conf.define("MFEM_PRECISION", "double");
#[cfg(feature = "precision-f32")]
conf.define("MFEM_PRECISION", "single");
let dst = conf.build();

println!("cargo:rustc-env=MFEM_PATH={}", dst.display());
}
2 changes: 1 addition & 1 deletion crates/mfem-cpp/mfem
Submodule mfem updated 1048 files
7 changes: 5 additions & 2 deletions crates/mfem-sys/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@ license = "MIT"
version = "0.2.0"
edition = "2021"
repository = "https://github.com/mkovaxx/mfem-rs"
rust-version = "1.77"

[dependencies]
cxx = "1"
cxx = "1.0.157"
autocxx = "0.28"

[build-dependencies]
cmake = "0.1"
cxx-build = "1"
autocxx-build = "0.28"
mfem-cpp = { version = "0.3", path = "../mfem-cpp", optional = true }
semver = "1.0.22"

[features]
bundled = ["mfem-cpp"]
bundled-f32 = ["mfem-cpp/precision-f32"]

[dev-dependencies]
clap = { version = "4.5.4", features = ["derive"] }
14 changes: 6 additions & 8 deletions crates/mfem-sys/MFEM/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
cmake_minimum_required (VERSION 3.5 FATAL_ERROR)
cmake_minimum_required (VERSION 3.12 FATAL_ERROR)
project (MfemPackageConfig)

set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE "BOTH" CACHE PATH "")

message(STATUS "Looking for mfem ...")
set(MFEM_DIR "" CACHE PATH "Path to the MFEM build or install prefix.")
if (MFEM_DIR)
find_package(mfem REQUIRED NAMES MFEM HINTS "${MFEM_DIR}"
"${MFEM_DIR}/lib/cmake/mfem" NO_DEFAULT_PATH)
else()
find_package(mfem REQUIRED NAMES MFEM)
find_package(MFEM REQUIRED CONFIG)

if (NOT DEFINED MFEM_INCLUDE_DIRS)
set(MFEM_INCLUDE_DIRS "")
endif()

file (WRITE ${CMAKE_BINARY_DIR}/mfem_info.txt
Expand All @@ -18,6 +16,6 @@ file (WRITE ${CMAKE_BINARY_DIR}/mfem_info.txt
"INCLUDE_DIRS=${MFEM_INCLUDE_DIRS}\n"
"LIBRARY_DIR=${MFEM_LIBRARY_DIR}\n"
"CXX_FLAGS=${MFEM_CXX_FLAGS}\n"
)
)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit


install (FILES ${CMAKE_BINARY_DIR}/mfem_info.txt TYPE DATA)
91 changes: 42 additions & 49 deletions crates/mfem-sys/build.rs
Original file line number Diff line number Diff line change
@@ -1,49 +1,47 @@
/// The list of used MFEM libraries which needs to be linked with.
fn main() {
let target = std::env::var("TARGET").expect("No TARGET environment variable defined");
let is_windows = target.to_lowercase().contains("windows");

let mfem_config = MfemConfig::detect();
let mut mfem_config = MfemConfig::detect();

println!(
"cargo:rustc-link-search=native={}",
mfem_config.library_dir.to_str().unwrap()
mfem_config.library_dir.display()
);

for lib in mfem_config.mfem_libs {
#[cfg(feature = "bundled")]
println!("cargo:rustc-link-lib=static={lib}");
#[cfg(not(feature = "bundled"))]
println!("cargo:rustc-link-lib={lib}");
}

if is_windows {
println!("cargo:rustc-link-lib=dylib=user32");
}

let mut build = cxx_build::bridge("src/lib.rs");

if let "windows" = std::env::consts::OS {
let current = std::env::current_dir().unwrap();
build.include(current.parent().unwrap());
}

mfem_config.include_dirs.push("src".into());
mfem_config.include_dirs.push("include".into()); // for cxx.
let mut build = autocxx_build::Builder::new("src/lib.rs", &mfem_config.include_dirs)
.build()
.expect("autocxx builder");
build
.cpp(true)
.std("c++14")
.flag_if_supported("-w")
.includes(mfem_config.include_dirs)
.include("include");
.flag_if_supported("-std=c++14")
.flag_if_supported("-O3")
.flag_if_supported("-w");
for f in mfem_config.cxx_flags {
build.flag_if_supported(&f);
}
if let "windows" = std::env::consts::OS {
let current = std::env::current_dir().unwrap();
build.include(current.parent().unwrap());
}

build.compile("wrapper");
build.compile("mfem-sys");

println!("cargo:rustc-link-lib=static=wrapper");
println!("cargo:rustc-link-lib=static=mfem-sys");

println!("cargo:rerun-if-changed=src/lib.rs");
println!("cargo:rerun-if-changed=include/wrapper.hpp");
println!("cargo:rerun-if-changed=src/ffi_autocxx.hpp");
println!("cargo:rerun-if-changed=src/ffi_cxx.hpp");
println!("cargo:rerun-if-changed=MFEM/CMakeLists.txt ");
}

#[derive(Debug)]
Expand All @@ -62,76 +60,71 @@ impl MfemConfig {
// Pre-installed MFEM will be checked for compatibility using semver rules.
let version_req = semver::VersionReq::parse(">=4.6").expect("Invalid version constraint");

println!("cargo:rerun-if-env-changed=DEP_MFEM_ROOT");

// Add path to bundled MFEM
#[cfg(feature = "bundled")]
#[cfg(any(feature = "bundled", feature = "bundled-f32"))]
{
std::env::set_var("DEP_MFEM_ROOT", mfem_cpp::mfem_path().as_os_str());
// For the `register_dep` of `cmake` to set
// `CMAKE_PREFIX_PATH` to the right directory.
std::env::set_var("DEP_MFEM_ROOT", mfem_cpp::mfem_path().as_os_str())
}
println!("cargo:rerun-if-env-changed=DEP_MFEM_ROOT");

let dst =
std::panic::catch_unwind(|| cmake::Config::new("MFEM").register_dep("mfem").build());

#[cfg(feature = "bundled")]
#[cfg(any(feature = "bundled", feature = "bundled-f32"))]
let dst = dst.expect("Bundled MFEM not found.");

#[cfg(not(feature = "bundled"))]
let dst = dst.expect("Pre-installed MFEM not found. You can use `bundled` feature if you do not want to install MFEM system-wide.");
#[cfg(not(any(feature = "bundled", feature = "bundled-f32")))]
let dst = dst.expect("Pre-installed MFEM not found. You can use MFEM_DIR to point to its location. Alternatively, you can use `bundled` feature if you do not want to install MFEM system-wide.");

let cfg = std::fs::read_to_string(dst.join("share").join("mfem_info.txt"))
.expect("Something went wrong when detecting MFEM.");

let mut version: Option<semver::Version> = None;
let mut mfem_libs: Vec<String> = vec![];
let mut include_dirs: Vec<std::path::PathBuf> = vec![];
let mut library_dir: Option<std::path::PathBuf> = None;
let mut cxx_flags: Vec<String> = vec![];
let mut mfem_config = MfemConfig {
mfem_libs: vec![],
include_dirs: vec![],
library_dir: std::path::PathBuf::new(),
cxx_flags: vec![],
};

for line in cfg.lines() {
if let Some((var, val)) = line.split_once('=') {
match var {
// Keep in sync with "MFEM/CMakeLists.txt".
"VERSION" => version = semver::Version::parse(val).ok(),
"MFEM_LIBRARIES" => {
for l in val.split(" ") {
// FIXME: Right delim?
mfem_libs.push(l.into());
for l in val.split(";") {
mfem_config.mfem_libs.push(l.into());
}
}
"INCLUDE_DIRS" => {
for d in val.split(";") {
include_dirs.push(d.into());
mfem_config.include_dirs.push(d.into());
}
}
"LIBRARY_DIR" => library_dir = val.parse().ok(),
"LIBRARY_DIR" => mfem_config.library_dir = val.into(),
"CXX_FLAGS" => {
for f in val.split(" ") {
cxx_flags.push(f.into());
mfem_config.cxx_flags.push(f.into());
}
}
_ => (),
}
}
}

if let (Some(version), Some(library_dir)) = (version, library_dir) {
if let Some(version) = version {
if !version_req.matches(&version) {
#[cfg(feature = "bundled")]
#[cfg(any(feature = "bundled", feature = "bundled-f32"))]
panic!("Bundled MFEM found but version is not met (found {} but {} required). Please fix MFEM_VERSION in build script of `mfem-sys` crate or submodule mfem in `mfem-cpp` crate.",
version, version_req);

#[cfg(not(feature = "bundled"))]
#[cfg(not(any(feature = "bundled", feature = "bundled-f32")))]
panic!("Pre-installed MFEM found but version is not met (found {} but {} required). Please provide required version or use `bundled` feature.",
version, version_req);
}

Self {
mfem_libs,
include_dirs,
library_dir,
cxx_flags,
}
mfem_config
} else {
panic!("MFEM found but something went wrong during configuration.");
}
Expand Down
Loading