Your build script could be failing. You can’t rely on print! or println! macros. It’s better to panic with a message. Also regarding rustc-flags, I’m not sure these are passed to the linker. Why not use rustc-link-lib?
I also noticed a lib name discrepancy "tcl_tk_sys", it could just be a typo. It’s also unusual to see "so numbers" passed directly outside the context of dl-loading.
I've mainly seen rustc-link-lib used for linking instead of rustc-flags=-l. I'm not sure if there's a material difference between these two.
When developing build scripts, build with cargo build -vvv. Otherwise Cargo "eats" script's output and you won't see what is happening.
You can also use:
println!("cargo:warning=Could not find Tcl or Tk via pkgconfig")
to make the text visible to users on failure. However, failure happens only if your build script returns failing exit code (e.g. panics). If you just set the flags and hope for the best, it will fail at link time with a horrible unreadable huge dump of hundreds of command-line flags. It's better to complain loudly early.
Cargo prints warning lines even without -vvvif your script panics. Your script doesn't panic, and falls back to flags that will fail at link time, which is too late to correlate that failure with your script, so user will not get the warning.
I suggest: don't print the link directives unless you've proven that they will work. Check if the files exist, or require an explicit opt-in, e.g. env var for TCL_LIB_DIR that you set as the search path first.
Don't set up linking for failure, because that's an error you can't handle in your script, and that error is handled very very poorly by Rust (it basically does nothing about it, and lets system linker just tell "f*** you" to the user).
use pkg_config;
fn main() {
let mut config = pkg_config::Config::new();
let epec = config.exactly_version("8.6");
if epec.probe("tcl").is_ok(){
panic!("Could not find tcl8.6 using pkg-config");
}
if epec.probe("tk").is_ok(){
panic!("Could not find tk8.6 using pkg-config");
}
}
In your code is_ok() makes the condition backwards. Also epec.probe("tk").expect("Could not find tcl8.6 using pkg-config") does the same thing, but shorter.
It is possible that you have the library, but don't have .pc files that describe where it's installed. That's tough, because just setting the linker flag doesn't give you any chance to handle the case when the library is missing.
I suggest:
if pkg_config_didnt_work {
if let Ok(dir) = std::env::var("TCL_LIB_DIR") {
println!("cargo:rustc-link-search={}", dir);
println!("cargo:rustc-link-lib=dylib=tcl8.6");
} else {
panic!("Can't find tcl via pkg-config. Set TCL_LIB_DIR env var for manual dir");
}
}