Skip to content

Commit e5523e7

Browse files
committed
Link statically
Pull Request resolved: #2085 Link everything into monarch statically, or dlopen it. This makes the rdma related libraries and libc++ linked statically for increased portability. This means monarch built with rdma support and with a different version of libc++ than the current system can still be used. By building rdma-core from source, we can also make sure Dennis' 64-bit patch is applied. Total size of our so is 63MB now with no uncommon deps: ``` (monarch) [zdevito@devgpu014 /data/users/zdevito/fbsource/fbcode/monarch]$ ldd ./python/monarch/_rust_bindings.so linux-vdso.so.1 (0x00007f347a684000) libpython3.11.so.1.0 => /home/zdevito/local/miniconda3/envs/monarch/lib/libpython3.11.so.1.0 (0x00007f3477200000) libgcc_s.so.1 => /home/zdevito/local/miniconda3/envs/monarch/lib/libgcc_s.so.1 (0x00007f347a664000) libm.so.6 => /lib64/libm.so.6 (0x00007f3477125000) libc.so.6 => /lib64/libc.so.6 (0x00007f3476e00000) /lib64/ld-linux-x86-64.so.2 (0x00007f347a686000) libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f347a64a000) libdl.so.2 => /lib64/libdl.so.2 (0x00007f347a645000) libutil.so.1 => /lib64/libutil.so.1 (0x00007f347a640000) (monarch) [zdevito@devgpu014 /data/users/zdevito/fbsource/fbcode/monarch]$ du -h ./python/monarch/_rust_bindings.so 63M ./python/monarch/_rust_bindings.so ``` ghstack-source-id: 328274952 Differential Revision: [D88540873](https://our.internmc.facebook.com/intern/diff/D88540873/)
1 parent bca67e4 commit e5523e7

File tree

11 files changed

+441
-32
lines changed

11 files changed

+441
-32
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,3 @@ docs/_build/**
3333
docs/build/**
3434
docs/**/generated/**
3535
*/sg_execution_times.rst
36-
nccl/**

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ members = [
1717
"monarch_rdma",
1818
"monarch_tensor_worker",
1919
"monarch_types",
20+
"monarch_cpp_static_libs",
2021
"nccl-sys",
2122
"ndslice",
2223
"preempt_rwlock",

build_utils/src/lib.rs

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,100 @@ pub fn print_cuda_lib_error_help() {
276276
eprintln!("Or: export CUDA_LIB_DIR=/usr/lib64");
277277
}
278278

279+
/// Emit cargo directives to statically link libstdc++
280+
///
281+
/// This finds the GCC library path containing libstdc++.a and emits the
282+
/// appropriate cargo directives to link it statically. This avoids runtime
283+
/// dependency on system libstdc++.so which can cause GLIBCXX version conflicts.
284+
///
285+
/// Uses the `cc` crate to detect the C++ compiler, ensuring we use the same
286+
/// compiler that `cc::Build` and `cxx_build` would use.
287+
pub fn link_libstdcpp_static() {
288+
// Use cc crate to get the C++ compiler, same as cc::Build and cxx_build use
289+
let compiler = cc::Build::new().cpp(true).get_compiler();
290+
let gcc_lib_path = std::process::Command::new(compiler.path())
291+
.args(["-print-file-name=libstdc++.a"])
292+
.output()
293+
.ok()
294+
.and_then(|output| {
295+
if output.status.success() {
296+
String::from_utf8(output.stdout).ok().and_then(|s| {
297+
let path = PathBuf::from(s.trim());
298+
path.parent().map(|p| p.to_path_buf())
299+
})
300+
} else {
301+
None
302+
}
303+
});
304+
if let Some(gcc_lib_path) = gcc_lib_path {
305+
println!("cargo:rustc-link-search=native={}", gcc_lib_path.display());
306+
}
307+
println!("cargo:rustc-link-lib=static=stdc++");
308+
}
309+
310+
/// Configuration for rdma-core static libraries from monarch_cpp_static_libs.
311+
///
312+
/// Use `CppStaticLibsConfig::from_env()` to get the paths, then use the include
313+
/// paths for bindgen/cc, and call `emit_link_directives()` to link.
314+
pub struct CppStaticLibsConfig {
315+
pub rdma_include: String,
316+
pub rdma_lib_dir: String,
317+
pub rdma_util_dir: String,
318+
}
319+
320+
impl CppStaticLibsConfig {
321+
/// Load configuration from DEP_* environment variables set by monarch_cpp_static_libs.
322+
///
323+
/// The monarch_cpp_static_libs crate must be listed as a build-dependency.
324+
pub fn from_env() -> Self {
325+
Self {
326+
rdma_include: std::env::var("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_INCLUDE")
327+
.expect("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_INCLUDE not set - add monarch_cpp_static_libs as build-dependency"),
328+
rdma_lib_dir: std::env::var("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_LIB_DIR")
329+
.expect("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_LIB_DIR not set - add monarch_cpp_static_libs as build-dependency"),
330+
rdma_util_dir: std::env::var("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_UTIL_DIR")
331+
.expect("DEP_MONARCH_CPP_STATIC_LIBS_RDMA_UTIL_DIR not set - add monarch_cpp_static_libs as build-dependency"),
332+
}
333+
}
334+
335+
/// Emit all cargo link directives for static linking of rdma-core.
336+
///
337+
/// This emits search paths and link-lib directives for:
338+
/// - libmlx5.a
339+
/// - libibverbs.a
340+
/// - librdma_util.a
341+
pub fn emit_link_directives(&self) {
342+
// Emit link search paths
343+
println!("cargo::rustc-link-search=native={}", self.rdma_lib_dir);
344+
println!("cargo::rustc-link-search=native={}", self.rdma_util_dir);
345+
346+
// Use whole-archive for rdma-core static libraries
347+
println!("cargo::rustc-link-arg=-Wl,--whole-archive");
348+
println!("cargo::rustc-link-lib=static=mlx5");
349+
println!("cargo::rustc-link-lib=static=ibverbs");
350+
println!("cargo::rustc-link-arg=-Wl,--no-whole-archive");
351+
352+
// rdma_util helper library
353+
println!("cargo::rustc-link-lib=static=rdma_util");
354+
}
355+
}
356+
357+
/// Convenience function to set up rdma-core static linking.
358+
///
359+
/// Returns the config with include paths, and emits all link directives.
360+
/// The monarch_cpp_static_libs crate must be listed as a build-dependency.
361+
///
362+
/// Example:
363+
/// ```ignore
364+
/// let config = build_utils::setup_cpp_static_libs();
365+
/// // Use config.rdma_include for bindgen/cc
366+
/// ```
367+
pub fn setup_cpp_static_libs() -> CppStaticLibsConfig {
368+
let config = CppStaticLibsConfig::from_env();
369+
config.emit_link_directives();
370+
config
371+
}
372+
279373
#[cfg(test)]
280374
mod tests {
281375
use super::*;

monarch_cpp_static_libs/Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# @generated by autocargo from //monarch/monarch_cpp_static_libs:monarch_cpp_static_libs
2+
3+
[package]
4+
name = "monarch_cpp_static_libs"
5+
version = "0.0.1"
6+
authors = ["Facebook"]
7+
edition = "2021"
8+
license = "MIT"
9+
description = "Builds static rdma-core libraries from source"
10+
links = "monarch_cpp_static_libs"
11+
12+
[build-dependencies]
13+
build_utils = { path = "../build_utils" }

0 commit comments

Comments
 (0)