I am trying to link to the static libraries that DPDK depends on, using build.rs. I successfully did it for a C source file using a Makefile. However, when I do it for a Rust source file that calls a C file (via bindgen-generated FFI bindings to the C functions that it calls) via a build.rs script, I get this:
error: overriding linking modifiers from command line is not supported
where link_paths were obtained by a previous call to the pkg-config crate with ".statik(true)" to find the static libraries that DPDK depends on. I did this same step from my Makefile, when I just had a C source file, and it worked.
Here is what's directly after my cc::Build::new invocation:
for lib in libdpdk.libs {
if lib.ends_with(".a") {
let lib = lib.trim_start_matches(":");
println!("cargo::rustc-link-lib=static:+whole-archive,+verbatim={lib}");
} else {
println!("cargo::rustc-link-lib={lib}");
}
}
for path in libdpdk.link_paths {
let path = path.to_string_lossy();
println!("cargo:rustc-link-search=native={path}");
}
Does anyone know why I would be getting the error about overriding linking modifiers from the command line?
Is it possible that the lib path contains some surprising extra content that may confuse the parser? (maybe pkg-config file stuffed extra linker args there?)
Try building with cargo build -vvv, so it will print everything it gets.
@tectonicboy, do you mind sharing what solution you are coming up with?
I'm dealing with issues related to wanting to call fortranc (something similar to cc) in build.rs to build a static library that is used only during test, not to be linked in the crate otherwise.
To do this, AFAIU, reading about several projects that face the same (basically, can't test cfg!("test") in build.rs), their solution seemed to have a separate empty crate, which would have that bundle modifier, and have the main crate depend on it as dev-dependency.
I end up with the same message.
let mut build = fortranc::Build::new();
let target_dir = PathBuf::from(std::env::var("CARGO_TARGET_DIR").unwrap_or_else(|_| "target".to_string()));
let profile = env::var("PROFILE").unwrap_or_else(|_| "debug".to_string());
let fortran_mod_dir = format!("{}/gfortran/mod",target_dir.join(profile.clone()).display());
create_dir_all(fortran_mod_dir.clone()).unwrap();
let test_lib = NativeLibrary{
name : "test_fortran_lib",
files : vec![
"src/test_logical.f90"
]
};
for f in &test_lib.files {
println!("cargo:rerun-if-changed={}", f);
}
build
.files(test_lib.files)
.flag(format!("-J{}", fortran_mod_dir))
.compile(test_lib.name);
println!("cargo:rustc-link-lib=static:-bundle={}", test_lib.name);