undefined reference to `sd_bus_open_system`

Hello there, I am trying to link against the systemd library but it doesnt quite work.

this is the error i get

= note: /usr/bin/ld: /home/xzi/Desktop/systemd/try_systemd_in_c/target/debug/build/try_systemd_in_c-0dd165c122cb0752/out/libmylib.a(2e40c9e35e9506f4-service.o): in function `doesServiceExist':
          /home/xzi/Desktop/systemd/try_systemd_in_c/src/service.c:12:(.text.doesServiceExist+0x4e): undefined reference to `sd_bus_open_system'
          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
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#rustc-link-lib)

my build.rs file

fn main() {
    let lib_dir = "/usr/lib/x86_64-linux-gnu";
    println!("cargo:rustc-link-search=native={}", lib_dir);
    println!("cargo:rustc-link-lib=dylib=systemd");

    println!("cargo:rerun-if-changed=src/service.c"); 
    println!("cargo:rerun-if-env-changed=CC");

    cc::Build::new()
        .file("src/service.c")
        .include("/usr/include/systemd")
        .compile("mylib");

        println!("cargo:rustc-link-lib=static=mylib");

}```
my service.c file
```C
#include <stdio.h>
#include <stdbool.h>
#include <systemd/sd-bus.h>

bool doesServiceExist(const char* service_name) {
    sd_bus_error error = SD_BUS_ERROR_NULL;
    sd_bus_message *m = NULL;
    sd_bus *bus = NULL;
    int r;

    r = sd_bus_open_system(&bus);
    if (r < 0) {
        fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
        return false;
    } else {
        return true;
    }

}

and finally, my main.rs file.

use std::ffi::CString;

extern "C" {
    fn doesServiceExist(service_name: *const i8) -> bool;
}

fn main() {
    let c_service_name = CString::new("oneday").expect("CString::new failed : (");

    let result = unsafe { doesServiceExist(c_service_name.as_ptr()) };

    if result {
        println!("true");
    } else {
        println!("AHHHHHHH");
    }
    
}```

## Steps i have taken to trouble shoot the issue
- make sure that systemd dev is installed 
Using the following commands.
`sudo apt install libsystemd-dev` & `sudo apt install systemd-dev`
- compile the C source code with gcc 
`gcc -c -o service service.c -lsystemd`
which worked successfully.
- make sure that the .so file for libsystemd exists
```shell
xzi@xzi-VMware-Virtual-Platform:/usr/lib/x86_64-linux-gnu$ ls libsystemd.so
libsystemd.so
  • make sure that the headers exist in the given location
xzi@xzi-VMware-Virtual-Platform:/usr/include/systemd$ ls
sd-bus.h           _sd-common.h  sd-event.h  sd-id128.h    sd-messages.h
sd-bus-protocol.h  sd-daemon.h   sd-gpt.h    sd-journal.h  sd-path.h
sd-bus-vtable.h    sd-device.h   sd-hwdb.h   sd-login.h

Specs

  • rustc 1.79.0 (129f3b996 2024-06-10)
  • OS: Ubuntu 24.04 LTS x86_64 (running on vmware)

thank you in advance

What is the full linker invocation? It should be printed right before the error you posted.

By the way you shouldn't need the println!("cargo:rustc-link-search=native={}", lib_dir);. /usr/lib/x86_64-linux-gnu is in the default search path of the linker already on Debian based systems (including Ubuntu) and is likely incorrect on other distros (which would have the correct location in the default search path).

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.