mirror of
https://github.com/logos-messaging/libchat.git
synced 2026-06-28 03:59:27 +00:00
Remove requirement for build.rs in chat-cli
This commit is contained in:
parent
7c1d691cc2
commit
bbf6a12b3f
@ -1,15 +0,0 @@
|
||||
fn main() {
|
||||
println!("cargo::rustc-check-cfg=cfg(logos_delivery)");
|
||||
|
||||
let Some(lib_dir) = std::env::var("DEP_LOGOSDELIVERY_LIB_DIR").ok() else {
|
||||
return;
|
||||
};
|
||||
|
||||
println!("cargo:rustc-cfg=logos_delivery");
|
||||
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
||||
match target_os.as_str() {
|
||||
"macos" | "linux" => println!("cargo:rustc-link-arg=-Wl,-rpath,{lib_dir}"),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@ -179,73 +179,6 @@ where
|
||||
result
|
||||
}
|
||||
|
||||
fn run_logos_delivery(cli: Cli) -> Result<()> {
|
||||
{
|
||||
eprintln!("Starting logos-delivery node (preset={})...", cli.preset);
|
||||
eprintln!("This may take a few seconds while connecting to the network.");
|
||||
|
||||
let logos_cfg = P2pConfig {
|
||||
preset: cli.preset.clone(),
|
||||
tcp_port: cli.port,
|
||||
..Default::default()
|
||||
};
|
||||
let delivery = P2pTransport(
|
||||
EmbeddedP2pDeliveryService::start(logos_cfg)
|
||||
.context("failed to start logos-delivery")?,
|
||||
);
|
||||
|
||||
eprintln!("Node connected. Initializing chat client...");
|
||||
|
||||
let data_dir = cli
|
||||
.db
|
||||
.as_ref()
|
||||
.and_then(|p| p.parent())
|
||||
.map(|p| p.to_path_buf())
|
||||
.unwrap_or_else(|| cli.data.clone());
|
||||
|
||||
let (client, events) = match cli.db {
|
||||
Some(ref path) => {
|
||||
let db_str = path
|
||||
.to_str()
|
||||
.context("db path contains non-UTF-8 characters")?
|
||||
.to_string();
|
||||
|
||||
logos_chat::ChatClientBuilder::new()
|
||||
.storage_config(logos_chat::StorageConfig::Encrypted {
|
||||
path: db_str,
|
||||
key: "chat-cli".to_string(),
|
||||
})
|
||||
.transport(delivery)
|
||||
.build()
|
||||
.map_err(|e| anyhow::anyhow!("{e:?}"))
|
||||
.context("failed to open persistent client")?
|
||||
}
|
||||
None => logos_chat::ChatClientBuilder::new()
|
||||
.transport(delivery)
|
||||
.build()
|
||||
.map_err(|e| anyhow::anyhow!("{e:?}"))
|
||||
.context("failed to open chat client")?,
|
||||
};
|
||||
|
||||
let mut app = ChatApp::new(client, events, &cli.name, &data_dir)?;
|
||||
|
||||
if cli.smoketest {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let mut terminal = ui::init().context("failed to initialize terminal")?;
|
||||
let result = run_app(&mut terminal, &mut app);
|
||||
ui::restore().context("failed to restore terminal")?;
|
||||
return result;
|
||||
}
|
||||
|
||||
#[cfg(not(logos_delivery))]
|
||||
anyhow::bail!(
|
||||
"logos-delivery transport is not available in this build.\n\
|
||||
Build with LOGOS_DELIVERY_LIB_DIR set to enable it."
|
||||
)
|
||||
}
|
||||
|
||||
fn run_app<I, T, R, S>(terminal: &mut ui::Tui, app: &mut ChatApp<I, T, R, S>) -> Result<()>
|
||||
where
|
||||
I: IdentityProvider + Send,
|
||||
|
||||
@ -1,32 +1,88 @@
|
||||
use std::fs;
|
||||
use std::process::Command;
|
||||
|
||||
fn main() {
|
||||
println!("cargo:rerun-if-env-changed=LOGOS_DELIVERY_LIB_DIR");
|
||||
println!("cargo::rustc-check-cfg=cfg(logos_delivery)");
|
||||
|
||||
let feature_enabled = std::env::var("CARGO_FEATURE_EMBEDDED_P2P_DELIVERY").is_ok();
|
||||
if !feature_enabled {
|
||||
if std::env::var_os("CARGO_FEATURE_EMBEDDED_P2P_DELIVERY").is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
let lib_dir = std::env::var("LOGOS_DELIVERY_LIB_DIR")
|
||||
// Locate the native library: explicit override first, then build via nix.
|
||||
let Some(lib_dir) = std::env::var("LOGOS_DELIVERY_LIB_DIR")
|
||||
.ok()
|
||||
.or_else(nix_build_logos_delivery);
|
||||
|
||||
let Some(lib_dir) = lib_dir else {
|
||||
// Feature is on but no library path — enable compilation, skip linking.
|
||||
println!("cargo:rustc-cfg=logos_delivery");
|
||||
.or_else(nix_build_logos_delivery)
|
||||
else {
|
||||
// Feature is on but the native library is unavailable (e.g. `cargo
|
||||
// check` on a machine without nix). Skip the cfg so the FFI module is
|
||||
// not compiled — this keeps `cargo check` working without producing
|
||||
// unresolved symbols at link time. `EmbeddedP2pDeliveryService` is
|
||||
// simply absent until the library can be found.
|
||||
return;
|
||||
};
|
||||
|
||||
println!("cargo:rustc-cfg=logos_delivery");
|
||||
println!("cargo:rustc-link-search=native={lib_dir}");
|
||||
println!("cargo:rustc-link-lib=dylib=logosdelivery");
|
||||
println!("cargo:LIB_DIR={lib_dir}");
|
||||
|
||||
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
|
||||
let target_os = std::env::var("CARGO_CFG_TARGET_OS").unwrap_or_default();
|
||||
|
||||
// The shipped library carries a relocatable install name (@rpath on macOS,
|
||||
// $ORIGIN soname on Linux), which would force every downstream BINARY to
|
||||
// inject its own RPATH. Cargo propagates `rustc-link-search` and
|
||||
// `rustc-link-lib` across crates, but NOT `rustc-link-arg` (the rpath) — so
|
||||
// that relocatable name is exactly what makes consumers need their own
|
||||
// build.rs. Instead, stamp a private copy with an ABSOLUTE install name;
|
||||
// the propagating search + lib directives are then sufficient and consumers
|
||||
// need zero build-script glue.
|
||||
match target_os.as_str() {
|
||||
"macos" | "linux" => println!("cargo:rustc-link-arg=-Wl,-rpath,{lib_dir}"),
|
||||
"macos" => stamp_absolute_macos(&lib_dir, &out_dir),
|
||||
"linux" => stamp_absolute_linux(&lib_dir, &out_dir),
|
||||
other => panic!("unsupported OS for logos-delivery transport: {other}"),
|
||||
}
|
||||
|
||||
println!("cargo:rustc-link-search=native={out_dir}");
|
||||
println!("cargo:rustc-link-lib=dylib=logosdelivery");
|
||||
}
|
||||
|
||||
/// Copy `liblogosdelivery.dylib` into `OUT_DIR` and rewrite its install name to
|
||||
/// the absolute store path. The consumer records that absolute path, so dyld
|
||||
/// loads the original file directly — whose own `@loader_path` RPATH resolves
|
||||
/// `librln.dylib` beside it — with no RPATH needed on the consumer.
|
||||
fn stamp_absolute_macos(lib_dir: &str, out_dir: &str) {
|
||||
let src = format!("{lib_dir}/liblogosdelivery.dylib");
|
||||
let dst = format!("{out_dir}/liblogosdelivery.dylib");
|
||||
copy_writable(&src, &dst);
|
||||
run("install_name_tool", &["-id", &src, &dst]);
|
||||
println!("cargo:rerun-if-changed={src}");
|
||||
}
|
||||
|
||||
/// Linux equivalent: an absolute `DT_SONAME` is recorded verbatim in the
|
||||
/// consumer's `DT_NEEDED`, so `ld.so` loads it by path with no RPATH. Requires
|
||||
/// `patchelf` at build time (provided by the nix devshell).
|
||||
fn stamp_absolute_linux(lib_dir: &str, out_dir: &str) {
|
||||
let src = format!("{lib_dir}/liblogosdelivery.so");
|
||||
let dst = format!("{out_dir}/liblogosdelivery.so");
|
||||
copy_writable(&src, &dst);
|
||||
run("patchelf", &["--set-soname", &src, &dst]);
|
||||
println!("cargo:rerun-if-changed={src}");
|
||||
}
|
||||
|
||||
fn copy_writable(src: &str, dst: &str) {
|
||||
fs::copy(src, dst).unwrap_or_else(|e| panic!("copy {src} -> {dst}: {e}"));
|
||||
// Store-sourced files are read-only; make the copy writable so its install
|
||||
// name / soname can be rewritten.
|
||||
let mut perms = fs::metadata(dst).unwrap().permissions();
|
||||
perms.set_readonly(false);
|
||||
fs::set_permissions(dst, perms).unwrap();
|
||||
}
|
||||
|
||||
fn run(cmd: &str, args: &[&str]) {
|
||||
let status = Command::new(cmd)
|
||||
.args(args)
|
||||
.status()
|
||||
.unwrap_or_else(|e| panic!("failed to run `{cmd}`: {e}"));
|
||||
assert!(status.success(), "`{cmd} {args:?}` failed with {status}");
|
||||
}
|
||||
|
||||
fn nix_build_logos_delivery() -> Option<String> {
|
||||
@ -35,7 +91,7 @@ fn nix_build_logos_delivery() -> Option<String> {
|
||||
|
||||
println!("cargo:rerun-if-changed={flake_root}/flake.lock");
|
||||
|
||||
let output = std::process::Command::new("nix")
|
||||
let output = Command::new("nix")
|
||||
.args(["build", ".#logos-delivery", "--no-link", "--print-out-paths"])
|
||||
.current_dir(&flake_root)
|
||||
.output()
|
||||
|
||||
@ -8,5 +8,5 @@ pub use contact_registry::http::{HttpRegistry, HttpRegistryError};
|
||||
pub use storage::*;
|
||||
pub use wakeup::*;
|
||||
|
||||
#[cfg(feature = "embedded_p2p_delivery")]
|
||||
#[cfg(logos_delivery)]
|
||||
pub use delivery::{EmbeddedP2pDeliveryService, P2pConfig};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user