Skip to content

Commit

Permalink
static rlib linking for fabric_rust_pal
Browse files Browse the repository at this point in the history
  • Loading branch information
youyuanwu committed Jan 23, 2024
1 parent 3f2bef6 commit 35edf50
Show file tree
Hide file tree
Showing 13 changed files with 120 additions and 61 deletions.
39 changes: 1 addition & 38 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,49 +68,12 @@ add_custom_target(force_clean
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

add_custom_target(build_rust_sample_echomain ALL
COMMAND ${cargo_exe} build -p samples_echomain
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS build_fabric_rust_pal
)

add_custom_target(build_fabric_rust_pal ALL
COMMAND ${cargo_exe} build -p pal
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)

set(_pkg_root ${CMAKE_BINARY_DIR}/echoapp_root)
set(_pkg_src ${CMAKE_CURRENT_SOURCE_DIR}/crates/samples/echomain)
if(WIN32)
set(_pkg_exe ${CMAKE_CURRENT_SOURCE_DIR}/target/debug/samples_echomain.exe)
add_custom_command(TARGET build_rust_sample_echomain POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_src}/manifests/ServiceManifest.xml ${_pkg_root}/EchoAppServicePackage/ServiceManifest.xml
)
else()
set(_pkg_exe ${CMAKE_CURRENT_SOURCE_DIR}/target/debug/samples_echomain)
set(_pal_so ${CMAKE_CURRENT_SOURCE_DIR}/target/debug/libfabric_rust_pal.so)
add_custom_command(TARGET build_rust_sample_echomain POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pal_so} ${_pkg_root}/EchoAppServicePackage/Code/libfabric_rust_pal.so
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_src}/manifests/ServiceManifest.Linux.xml ${_pkg_root}/EchoAppServicePackage/ServiceManifest.xml
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/scripts/ld_entrypoint.sh
${_pkg_root}/EchoAppServicePackage/Code/ld_entrypoint.sh
)
endif(WIN32)
# shared files
add_custom_command(TARGET build_rust_sample_echomain POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_src}/manifests/ApplicationManifest.xml ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_exe} ${_pkg_root}/EchoAppServicePackage/Code/echomain.exe # note the rename
)

add_subdirectory(crates/samples/echomain)
if(WIN32) #linux is not tested
add_subdirectory(crates/samples/echo2)
add_subdirectory(crates/samples/kvstore)
Expand Down
2 changes: 0 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion crates/fabric/base/build.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// use std::{env, path::{Path, PathBuf}};

use std::path::Path;

fn main() {
Expand All @@ -8,6 +10,9 @@ fn main() {

// On linux, for windows-rs to work we need have a pal shared lib.
// No need to have search dir since it is in the target dir
println!("cargo:rustc-link-lib=dylib=fabric_rust_pal");
// let outdir = PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap());

// println!("cargo:rustc-link-search={}", outdir.as_path().display());
// println!("cargo:rustc-link-lib=static=fabric_rust_pal");
}
}
4 changes: 4 additions & 0 deletions crates/fabric/base/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,7 @@ pub mod Microsoft;
pub use Microsoft::ServiceFabric::*;

pub use fabric_metadata;

// In linux force to pull in pal lib for linking
#[cfg(target_os = "linux")]
extern crate fabric_rust_pal;
2 changes: 0 additions & 2 deletions crates/fabric/pal/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@ edition = "2021"
[lib]
name = "fabric_rust_pal"
path = "src/lib.rs"
crate-type = ["cdylib"]


# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

Expand Down
6 changes: 4 additions & 2 deletions crates/fabric/pal/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# pal (Platform Abstraction Layer)
This crate provides a single shared library for linux environment.
This crate fills windows api needed for windows-rs to work in linux environment.
It contains bare minimum WIN32 API substitute on linux to make windows-rs crate COM support working.
Service Fabric Rust app and test all requires this pal shared library to work.
So make sure the rust executable can load this lib, i.e. this lib is in `LD_LIBRARY_PATH`.
This crate is forced to be linked with fabric_base crate.

Originally this crate is a shared lib, but it is a rlib now to avoid dynamic loading and packaging.
46 changes: 44 additions & 2 deletions crates/fabric/pal/src/pal.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#[allow(non_camel_case_types, non_snake_case, dead_code)]
#![allow(non_camel_case_types, non_snake_case, dead_code)]
use std::ffi::c_void;

use libc::{__errno_location, malloc};
Expand All @@ -11,6 +11,9 @@ use windows::{

static DUMMY_HEAP: isize = 0x01020304;

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn GetLastError() -> u32 {
let pe = __errno_location();
Expand All @@ -21,6 +24,9 @@ pub unsafe extern "system" fn GetLastError() -> u32 {
}
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn SetLastError(dwerrcode: u32) {
let pe = __errno_location();
Expand All @@ -29,11 +35,17 @@ pub unsafe extern "system" fn SetLastError(dwerrcode: u32) {
}
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn GetProcessHeap() -> isize {
return DUMMY_HEAP;
DUMMY_HEAP
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn HeapAlloc(heap: isize, _flags: u32, len: usize) -> *mut c_void {
if heap != DUMMY_HEAP {
Expand All @@ -47,6 +59,9 @@ pub unsafe extern "system" fn HeapAlloc(heap: isize, _flags: u32, len: usize) ->
p
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn HeapFree(heap: isize, _flags: u32, ptr: *const c_void) -> i32 {
if heap != DUMMY_HEAP {
Expand All @@ -58,21 +73,33 @@ pub unsafe extern "system" fn HeapFree(heap: isize, _flags: u32, ptr: *const c_v
1 // success
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn GetErrorInfo(_reserved: u32, _info: *mut *mut c_void) -> HRESULT {
HRESULT(0)
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn SetErrorInfo(_reserved: u32, _info: *const c_void) -> HRESULT {
HRESULT(0)
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn LoadLibraryA(_name: PCSTR) -> isize {
0
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn LoadLibraryExA(
_lplibfilename: PCSTR,
Expand All @@ -82,24 +109,39 @@ pub unsafe extern "system" fn LoadLibraryExA(
windows::Win32::Foundation::HMODULE(0)
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn FreeLibrary(_library: isize) -> i32 {
0
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn GetProcAddress(_library: isize, _name: PCSTR) -> *const c_void {
std::ptr::null()
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn SysFreeString(_bstr: *const u16) {}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn SysStringLen(_bstr: *const u16) -> u32 {
0
}

/// # Safety
///
/// safe
#[no_mangle]
pub unsafe extern "system" fn FormatMessageW(
_flags: u32,
Expand Down
23 changes: 11 additions & 12 deletions crates/fabric/rs/src/debug/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
use log::info;

#[cfg(target_os = "windows")]
pub fn wait_for_debugger() {
if cfg!(windows) {
loop {
if unsafe { windows::Win32::System::Diagnostics::Debug::IsDebuggerPresent().as_bool() }
{
info!("Debugger found.");
break;
} else {
info!("Waiting for debugger.");
std::thread::sleep(std::time::Duration::from_secs(5));
}
loop {
if unsafe { windows::Win32::System::Diagnostics::Debug::IsDebuggerPresent().as_bool() } {
log::info!("Debugger found.");
break;
} else {
log::info!("Waiting for debugger.");
std::thread::sleep(std::time::Duration::from_secs(5));
}
}
}

#[cfg(target_os = "linux")]
pub fn wait_for_debugger() {}
1 change: 0 additions & 1 deletion crates/samples/echo2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"
[dependencies]
log = "0.4"
env_logger = "*"
ctrlc = { version = "3.0", features = ["termination"] }
tokio = { version = "1", features = ["full"] }
windows-core = "0.51"
async-trait = "0.1"
Expand Down
23 changes: 23 additions & 0 deletions crates/samples/echomain/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
add_custom_target(build_rust_sample_echomain ALL
COMMAND ${cargo_exe} build -p samples_echomain
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
DEPENDS build_fabric_rust_pal
)

set(_pkg_root ${CMAKE_BINARY_DIR}/echoapp_root)
set(_pkg_src ${CMAKE_SOURCE_DIR}/crates/samples/echomain)
if(WIN32)
set(_pkg_exe ${CMAKE_SOURCE_DIR}/target/debug/samples_echomain.exe)
else()
set(_pkg_exe ${CMAKE_SOURCE_DIR}/target/debug/samples_echomain)
endif(WIN32)
# shared files
add_custom_command(TARGET build_rust_sample_echomain POST_BUILD
COMMAND ${CMAKE_COMMAND} -E make_directory ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_src}/manifests/ApplicationManifest.xml ${_pkg_root}
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_exe} ${_pkg_root}/EchoAppServicePackage/Code/echomain.exe # note the rename
COMMAND ${CMAKE_COMMAND}
-E copy_if_different ${_pkg_src}/manifests/ServiceManifest.xml ${_pkg_root}/EchoAppServicePackage/ServiceManifest.xml
)
1 change: 0 additions & 1 deletion crates/samples/kvstore/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ edition = "2021"
[dependencies]
log = "0.4"
env_logger = "*"
ctrlc = { version = "3.0", features = ["termination"] }
tokio = { version = "1", features = ["full"] }
windows-core = "0.51"
async-trait = "0.1"
Expand Down
16 changes: 16 additions & 0 deletions docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,19 @@ Use vscode dev container. It has all deps installed.
* gcc ld linker has problems with SF .so so we use lld from clang which is configured in .cargo config.
* fabric_pal.so is needed to be able to provide windows C functions needed by windows-rs. Code is checked-in in /bintemp folder.

* WSL
Install SF in WSL maybe slow due to windows paths in /mnt/c are searched.
Change the following to remove /mnt/c etc paths
```sh
$ sudo nano /etc/wsl.conf
```
add section
```conf
# This removes windows path
[interop]
appendWindowsPath = false
# This do not mount windows drive
[automount]
enabled = false
```
Mount is needed to use vscode wsl. So after install sf the automount section needs to be removed to use vscode wsl.
11 changes: 11 additions & 0 deletions scripts/ld_entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,17 @@
#!/usr/bin/env bash

# entry point to set up ld path to be the current dir and then launch the exe.
# this was used to make *.so libs available to load in the code package.
# currently this is not used.

# use it in service manifest:
# <EntryPoint>
# <ExeHost>
# <Program>ld_entrypoint.sh</Program>
# <Arguments>-e echomain.exe</Arguments>
# <ConsoleRedirection FileRetentionCount="5" FileMaxSizeInKb="2048"/>
# </ExeHost>
# </EntryPoint>

SCRIPT=$(realpath -s "$0")
SCRIPTPATH=$(dirname "$SCRIPT")
Expand Down

0 comments on commit 35edf50

Please sign in to comment.