This question is related to Trouble with undefined symbols in Rust's ffi when using a C/Fortran library
I have a library pfapack
to interface in Rust. The problem is this library is pretty niche, so it will not be found on a user's machine often. The best way to use it would be to just add it to the Cargo.toml
and it compiles for the project.
I want to output the object files in OUT_DIR so that crates that import pfapack-sys
can link to the compiled library. To build the source, I have a makefile that I call from a build.rs
.
I first used the OUT_DIR environment variable inside the makefile to output it directly to the OUT_DIR. Here is the example makefile:
CC = gcc
CFLAGS = -O3
C_DIR = $(OUT_DIR)/c_interface
OBJECTS= $(C_DIR)/skpfa.o $(C_DIR)/skpf10.o $(C_DIR)/skbpfa.o $(C_DIR)/skbpf10.o $(C_DIR)/sktrf.o $(C_DIR)/sktrd.o $(C_DIR)/skbtrd.o
all: $(OBJECTS)
$(AR) rvu $(C_DIR)/libcpfapack.a $(OBJECTS)
clean:
rm -f *.o
rm -f libcpfapack.a
.SUFFIXES: .o .c
.c.o:
$(CC) $(CFLAGS) -c $< -o $(C_DIR)/$@
And here is the build script:
// build script
use std::process::Command;
use std::path::Path;
use std::env;
fn main() {
let out_dir = env::var("OUT_DIR").unwrap();
let out_dir = Path::new(&out_dir);
let c_interface = out_dir.join(Path::new("c_interface"));
let fortran = out_dir.join(Path::new("fortran"));
// Compile source
Command::new("make").output()
.expect("Failed to make");
println!("cargo:rustc-link-search={}", c_interface.display());
println!("cargo:rustc-link-search={}", fortran.display());
println!("cargo:rustc-link-lib=gfortran");
println!("cargo:rustc-link-lib=lapack");
println!("cargo:rustc-link-lib=blas");
}
The reasoning here is that adding the path to this directory will allow the other package to link the libpfapack.a
and libcpfapack.a
static libraries.
The thing is, I can't seem to be able to link to these libraries from another crate, using rustc-link-lib=pfapack
. Am I tackling this the right way? Can I use the build script this way?