Some `extern` functions couldn't be found

Hi everyone,

I got the error when tried to link my shared library (or to be exactly, when I tried to link one of the extern functions). This is my function in c++:

extern "C" void test_srp6(
    const char* N_str,
    const char* g_str,
    const char* B_str,
    const char* s_str,
    const char* username_str,
    const char* password_str
) {
    BigNum N(N_str);
    BigNum g(g_str);
    BigNum s(s_str);
    BigNum B(B_str);
    std::string username(username_str);
    std::string password(password_str);

    SRP6 client(N, g, s, B, username, password);
    client.calculate_session_key();
}

this is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.22)
project(libsrp6)

set(CMAKE_CXX_STANDARD 17)

add_library(libsrp6 SHARED libsrp6.cpp BigNum.cpp BigNum.h)
set_target_properties(libsrp6 PROPERTIES OUTPUT_NAME "srp6")
install(TARGETS libsrp6 DESTINATION ${CMAKE_SOURCE_DIR})

This is my build.rs:

fn main() {
    let dst = cmake::Config::new("libsrp6").build();

    println!("cargo:rustc-link-search=native={}", dst.display());
    println!("cargo:rustc-link-lib=static=libsrp6");
    println!("cargo:rustc-link-lib=dylib=ssl");
    println!("cargo:rustc-link-lib=dylib=crypto");
    println!("cargo:rustc-link-lib=dylib=stdc++");
}

this is extern function in Rust code:

extern "C" {
    #[link(name="libsrp6", kind="dylib")]
    fn test_srp6(
        N_str: *const c_char,
        g_str: *const c_char,
        B_str: *const c_char,
        s_str: *const c_char,
        username_str: *const c_char,
        password_str: *const c_char
    );
}

On compile I got the error:

error: linking with `cc` failed: exit status: 1
...undefined reference to `test_srp6'
          collect2: error: ld returned 1 exit status
          
  = note: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified

Could somebody explain what did I miss ?

In build.rs, you say that libsrp6 is linked statically. In #[link] attribute, you say that the same library is linked dynamically. How it should actually by linked? What do you compile your C++ code to - *.a or *.so?

1 Like

I compile it to *.so, yep, it should be dylib. But changing build.rs considering this mistake:

fn main() {
    let dst = cmake::Config::new("libsrp6").build();

    println!("cargo:rustc-link-search=native={}", dst.display());
    println!("cargo:rustc-link-lib=dylib=libsrp6");
    println!("cargo:rustc-link-lib=dylib=ssl");
    println!("cargo:rustc-link-lib=dylib=crypto");
    println!("cargo:rustc-link-lib=dylib=stdc++");
}

changed nothing. The error is still same.

I made small repo to reproduce this problem, probably this could help to find a solution: GitHub - sergio-ivanuzzo/reproduce-cpp-to-rust

You likely need to replace libsrp6 with srp6. The linker already adds the lib prefix and .so suffix. Your current code would cause the linker to search for liblibsrp6.so instead of libsrp6.so.

1 Like

Unfortunately, this not helped:

extern "C" {
    #[link(name="srp6", kind="dylib")]
    fn test_srp6(
        // ...
    );
}

fn main() {
    let dst = cmake::Config::new("libsrp6").build();

    // ...
    println!("cargo:rustc-link-lib=dylib=srp6");
    // ...
}

I found what the issue it was. Missed build param in Cargo.toml. So, build.rs was not worked.
Thanks to all for you time and responses.

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.