6 releases (stable)
1.2.3 | Jan 28, 2022 |
---|---|
1.2.1 | Nov 15, 2021 |
1.2.0 | Apr 27, 2021 |
1.2.0-alpha.1 |
|
0.1.1 |
|
#64 in FFI
4,000 downloads per month
Used in 9 crates
(6 directly)
17KB
246 lines
OpenMP library linkage for Rust programs
This crate allows using OpenMP-dependent C code with Rust. It makes Cargo link to OpenMP, so that C static libraries linked with Rust programs can use OpenMP.
It can't be used with pure Rust programs (Rayon is a better choice for Rust).
NB: This crate can't automatically enable OpenMP for C code compiled from build scripts. You also need to pass the appropriate OpenMP-enabling flag to the C compiler (see usage below). It may be necessary to perform cargo clean
and rebuild if settings don't take effect.
Requirements
- Rust 1.45 or later
- OpenMP libraries and headers
- in a directory printed by
cc -print-search-dirs
, or - provided by the
libomp
Brew formula or Macport installed to standard prefix on macOS, or vcomp.dll
et al. with MSVC on Windows, or- at locations specified in
LIBRARY_PATH
andCFLAGS
respectively at compile time:LIBRARY_PATH="<path containing libomp.{so|dylib|lib|a}>:<other library paths>" CFLAGS="-I<path containing omp.h> <other C flags>"
- in a directory printed by
- OpenMP-enabling flag set for any C code linked with the Rust program
Usage
1. Adding Rust dependency
Add openmp-sys
as a runtime dependency (e.g. cargo install cargo-edit; cargo add openmp-sys
) and then add to your lib.rs
:
extern crate openmp_sys;
This is required even in Rust 2018, because openmp_sys
won't get linked if it's not mentioned anywhere in the source code.
2. Configuring C compiler
The C code being linked must be compiled with an OpenMP-enabling flag. If you add openmp-sys
also as a dev-depenency, it will set DEP_OPENMP_FLAG
env var for your build.rs
script with an appropriate flag (or sometimes, flags) such as -fopenmp
or /openmp
, depending on the target compiler. If you're compiling C code with the cc
crate, then set the flag this way:
let mut cc_build = cc::Build::new();
env::var("DEP_OPENMP_FLAG").unwrap().split(" ").for_each(|f| { cc_build.flag(f); });
Picky linkers
The openmp-sys
crate automatically tells Cargo to link lib(g)omp as appropriate. However, some linkers are picky about the order in which libraries are specified, and the automatic trick is not enough.
If you get linker errors about missing libgomp.so
, try linking to it again after telling Cargo to link your C code. This library provides a list of Cargo instructions for this in DEP_OPENMP_CARGO_LINK_INSTRUCTIONS
var:
cc_build.compile("libexample.a");
if let Some(link) = env::var_os("DEP_OPENMP_CARGO_LINK_INSTRUCTIONS") {
for i in env::split_paths(&link) {
println!("cargo:{}", i.display());
}
}
Static linking
Optionally, you can enable static
feature or set OPENMP_STATIC=1
env var to link OpenMP statically, so that executables using it are usable on machines without a compiler installed.
[dependencies.openmp-sys]
features = ["static"]
version = "1.2"
Custom CC
It's possible to specify another C compiler at build time with the CC
environment variable. However, Cargo will still default to cc
while linking, regardless of what is chosen while compiling. If necessary, set CARGO_TARGET_<triple>_LINKER
or the respective item in ~/.cargo/config
to override this.
macOS
On macOS, both Apple Clang and original Clang are supported, provided that a copy of libomp
is available (as mentioned in the requirements above). This is not needed when using GCC, as it comes bundled with libgomp
. If your program requires GCC, it is sufficient to do CC=<gcc exe name> cargo build
.
Static linking is recommended on macOS.
Dependencies
~0–280KB