Linking of extern C library fails

Hi there,

I'm building a crate to interact with databases, where one part interacts with the ODBC standard. I am aware that there are already some crates implementing a FFI or a safe wrapper around ODBC - but that's not what I am looking for right now. My problem is, that the linking to libodbc fails with the following error:

error: could not find native static library `odbc`, perhaps an -L flag is missing?

error: could not compile `libdb` due to previous error;

Caused by:
  process didn't exit successfully: `rustc --crate-name libdb --edition=2021 
src/ --error-format=json --json=diagnostic-rendered-ansi 
--crate-type lib --emit=dep-info,metadata,link -C embed-bitcode=no -C 
debuginfo=2 -C metadata=1946af203ef2d111 -C extra-filename=-1946af203ef2d111 
--out-dir /home/name/Projects/Rust/libdb/target/debug/deps 
-C incremental=/home/name/Projects/Rust/libdb/target/debug/incremental 
-L dependency=/home/name/Projects/Rust/libdb/target/debug/deps 
--extern libbase=/home/name/Projects/Rust/libdb/target/debug/deps/liblibbase-9108370a2a82ae19.rmeta 
-L native=/usr/lib64 -L native=../zlib` (exit status: 1)

#[link(name = "odbc", kind = "static")]
extern "C" {
    pub(crate) fn SQLAllocHandle(handleType: SQLSMALLINT, inputHandle: SQLHANDLE, outputHandlePtr: SQLHANDLE) -> SQLRETURN;

fn main() {
    // tried this with `/usr/lib`, `/usr/lib64`, `.` (placed inside my project dir)
    // relative path to my custom unixodbc compilation dir - nothing worked
    // println!("cargo:rustc-link-lib=static=odbc");

I installed unixodbc via pacman on my arch machine, the ODBC libraries are present in /usr/lib and /usr/lib64. I also downloaded the source code and compiled it directly, linking to the output directory of the build - still the same error message.
I don't know what I'm doing wrong right now, since my crate libbase correctly links to libz the same way (my library depends on this crate as can be seen in the compiler output).

Any help is appreciated - thanks!
Best regards

Hm interesting: I removed the static linking: #[link(name = "odbc")] and now I can compile and use the library in a binary crate for testing. I still don't get what I am doing wrong, since static linking should be possible on Linux, but not on Windows - odbc-sys does it this way:

    all(not(windows), feature = "static", not(feature = "iodbc")),
    link(name = "odbc", kind = "static")

Are you sure library which you use is called libodbc.a and not something like libunixobdc.a or libobdcmain.a ?

Linker would add lib prefix and .a or .so suffix but wouldn't do fuzzy matching to find the proper name of the library for you.

If it does it that way then there are file named libodbc.lib somewhere.

That's quirk of Linux linker.

On Windows you have to specify which library you are importing functions from and if other libraries are providing these functions — they are ignored.

On Linux linker is not so picky and if some other crate loads odbc library properly - it would be available for your code, too.

Don't rely on it, look for the proper name of library to specify in name. It would be something like odbcMAIN or odbcinst or something like this.

Note that would be, most likely, a symlink and copying it around may make it invalid. If linker could find that symlink but the actual library (named like wouldn't be there, then message would be the same as if doesn't exist.

1 Like

the problem was, that the unixodbc package comes only with shared libraries. that's why the dynamic linking worked in the end. there are simply no static libraries included. my custom build of unixodbc also didn't produce any .a output files, since static library output is disabled by default.

$ ./configure --enable-static=yes
$ make 

This produced the desired libodbc.a file in the end. :slight_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.