diff --git a/src/core_ffi/CMakeLists.txt b/src/core_ffi/CMakeLists.txt index 9c112b4..dd88c5d 100644 --- a/src/core_ffi/CMakeLists.txt +++ b/src/core_ffi/CMakeLists.txt @@ -17,8 +17,10 @@ endif() if (KLSK_RUST_FFI) # just for IDE highlight add_library(klotski_rust - rust_ffi/src/demo.cc - rust_ffi/target/cxxbridge/klotski/src/common_code.rs.cc + rust_ffi/adapter/common_code.cc + rust_ffi/target/cxxbridge/rust_ffi/src/common_code.rs.cc ) - target_include_directories(klotski_rust PRIVATE rust_ffi/target/cxxbridge) + target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + target_include_directories(klotski_rust PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/rust_ffi/target/cxxbridge) + target_link_libraries(klotski_rust PRIVATE klotski_core) endif() diff --git a/src/core_ffi/rust_ffi/adapter/common_code.cc b/src/core_ffi/rust_ffi/adapter/common_code.cc new file mode 100644 index 0000000..553c352 --- /dev/null +++ b/src/core_ffi/rust_ffi/adapter/common_code.cc @@ -0,0 +1,15 @@ +#include "rust_ffi/include/common_code.h" + +#include + +using klotski::ffi::RsCommonCode; + +rust::String RsCommonCode::to_string() const noexcept { + return codec::CommonCode::unsafe_create(code).to_string(); +} + +// TODO: it seems that cxx.rs not support `std::optional` +RsCommonCode klotski::ffi::from_string(rust::Str s) { + std::string_view sv {s.data(), s.length()}; + return {codec::CommonCode::from_string(sv)->unwrap()}; // TODO: value check +} diff --git a/src/core_ffi/rust_ffi/build.rs b/src/core_ffi/rust_ffi/build.rs index 80737d0..384a3f9 100644 --- a/src/core_ffi/rust_ffi/build.rs +++ b/src/core_ffi/rust_ffi/build.rs @@ -1,8 +1,33 @@ +use cxx_build::CFG; + +// NOTE: add `CC=clang-20 CXX=clang++-20 CXXFLAGS="-stdlib=libc++"` for cargo command +// we should keep cxx crate using clang for `cxx.cc` + +// NOTE: also, `RUSTFLAGS="-C linker=clang-20"` should be add to cargo env for using lld + fn main() { + CFG.include_prefix = "rust_ffi"; + + // std::env::set_var("CC", "clang-20"); + // std::env::set_var("CXX", "clang++-20"); + cxx_build::bridge("src/common_code.rs") - .file("src/demo.cc") + .file("adapter/common_code.cc") + .flag("-std=c++23") + .flag("-fno-rtti") + .flag("-fno-exceptions") + // .flag("-stdlib=libc++") + .include("../../core") + // .cpp_set_stdlib("c++") + // .cpp_link_stdlib("c++") .compile("klotski"); - println!("cargo:rerun-if-changed=src/demo.cc"); + println!("cargo:rustc-link-search=native=../../../cmake-build-release/src/core"); + println!("cargo:rustc-link-lib=static=klotski_core"); + + println!("cargo:rustc-link-arg=-fuse-ld=lld-20"); + println!("cargo:rustc-link-arg=-stdlib=libc++"); + + println!("cargo:rerun-if-changed=adapter/common_code.cc"); println!("cargo:rerun-if-changed=src/common_code.rs"); } diff --git a/src/core_ffi/rust_ffi/include/common_code.h b/src/core_ffi/rust_ffi/include/common_code.h new file mode 100644 index 0000000..c40e175 --- /dev/null +++ b/src/core_ffi/rust_ffi/include/common_code.h @@ -0,0 +1,9 @@ +#pragma once + +#include "rust_ffi/src/common_code.rs.h" + +namespace klotski::ffi { + +RsCommonCode from_string(rust::Str s); + +} // namespace klotski::ffi diff --git a/src/core_ffi/rust_ffi/src/common_code.rs b/src/core_ffi/rust_ffi/src/common_code.rs index f3fd878..b454f35 100644 --- a/src/core_ffi/rust_ffi/src/common_code.rs +++ b/src/core_ffi/rust_ffi/src/common_code.rs @@ -1,18 +1,37 @@ -#[cxx::bridge] -pub mod ffi { +#[cxx::bridge(namespace = "klotski::ffi")] +mod ffi { #[derive(Debug)] - pub struct CommonCode { + struct RsCommonCode { code: u64 } - extern "Rust" {} - unsafe extern "C++" { - include!("klotski/src/klotski.h"); + include!("rust_ffi/include/common_code.h"); + + fn to_string(self: &RsCommonCode) -> String; + + fn from_string(s: &str) -> RsCommonCode; + } +} + +pub use ffi::RsCommonCode as CommonCode; - // fn unwrap(self: &CommonCode) -> u64; +impl CommonCode { + pub fn unsafe_create(code: u64) -> CommonCode { + CommonCode { code } + } + + pub fn unwrap(self: &CommonCode) -> u64 { + self.code + } + + pub fn from_string(s: &str) -> CommonCode { + ffi::from_string(s) + } +} - // fn from_string(s: &str) -> CommonCode; - fn from_string() -> CommonCode; +impl PartialEq for CommonCode { + fn eq(&self, other: &Self) -> bool { + self.code == other.code } } diff --git a/src/core_ffi/rust_ffi/src/demo.cc b/src/core_ffi/rust_ffi/src/demo.cc deleted file mode 100644 index 860aa39..0000000 --- a/src/core_ffi/rust_ffi/src/demo.cc +++ /dev/null @@ -1,8 +0,0 @@ -#include "klotski/src/klotski.h" -#include "klotski/src/common_code.rs.h" - -#include - -CommonCode from_string() { - return CommonCode {}; -} diff --git a/src/core_ffi/rust_ffi/src/klotski.h b/src/core_ffi/rust_ffi/src/klotski.h deleted file mode 100644 index 15d701d..0000000 --- a/src/core_ffi/rust_ffi/src/klotski.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "klotski/src/common_code.rs.h" - -CommonCode from_string(); diff --git a/src/core_ffi/rust_ffi/src/main.rs b/src/core_ffi/rust_ffi/src/main.rs index 9e82f72..8222a48 100644 --- a/src/core_ffi/rust_ffi/src/main.rs +++ b/src/core_ffi/rust_ffi/src/main.rs @@ -1,12 +1,11 @@ mod common_code; -use common_code::ffi::CommonCode; +use common_code::CommonCode; fn main() { - // let code = CommonCode { code: 123 }; - // let val = code.unwrap(); - // println!("val = {}", val); + let code = CommonCode::from_string("1A9BF0C"); + println!("code: {:?}", code.unwrap()); + println!("str: {}", code.to_string()); - let code = common_code::ffi::from_string(); - println!("code = {:?}", code); + println!("{}", code == CommonCode::unsafe_create(0x1A9BF0C00)); }