When writing code to use the Wayland Client API, Rust seems unable to find the wl_display_get_registry
symbol. An objdump of the file also is unable to find the symbol. However, a C program compiled with GCC is able to find the symbol.
Why can the C program find the symbol, but Rust cannot? How can I fix the Rust program to find the symbol?
OS: Ubuntu 18.04 LTS
Rust
Build
rustc -o wayland main.rs
Output
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-Wl,--as-needed" "-Wl,-z,noexecstack" "-m64" "-L" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "wayland.main0.rcgu.o" "wayland.main1.rcgu.o" "wayland.main2.rcgu.o" "wayland.main3.rcgu.o" "wayland.main4.rcgu.o" "-o" "wayland" "wayland.crate.allocator.rcgu.o" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "-L" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-l" "wayland-client" "-Wl,--start-group" "-Wl,-Bstatic" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-2da986ecbb2c5327.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libpanic_unwind-57f46841c9a9f4ee.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_jemalloc-23263fe5893322f6.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libunwind-6ed5262c9a0a3e5a.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc_system-99c162b689d43349.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liblibc-cd415b85dd267875.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/liballoc-3876ac10aa96a1e3.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd_unicode-598b0e9aca382e9a.rlib" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcore-4eabb2b1c31071b8.rlib" "-Wl,--end-group" "/home/myrddin/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libcompiler_builtins-d7a656735ceeae9e.rlib" "-Wl,-Bdynamic" "-l" "dl" "-l" "rt" "-l" "pthread" "-l" "pthread" "-l" "gcc_s" "-l" "c" "-l" "m" "-l" "rt" "-l" "pthread" "-l" "util" "-l" "util"
= note: wayland.main3.rcgu.o: In function `main::main':
main3-317d481089b8c8fe83113de504472633.rs:(.text._ZN4main4main17h52709beaa06fe157E+0x109): undefined reference to `wl_display_get_registry'
collect2: error: ld returned 1 exit status
Code
pub enum WLDisplay {}
pub enum WLRegistry {}
#[link(name = "wayland-client")]
extern "C" {
pub fn wl_display_connect(name: *const ::std::os::raw::c_char) -> *mut WLDisplay;
pub fn wl_display_disconnect(display: *mut WLDisplay) -> ();
pub fn wl_display_get_registry(display: *mut WLDisplay) -> *mut WLRegistry;
}
fn main() {
let display: *mut WLDisplay;
let registry: *mut WLRegistry;
unsafe {
display = wl_display_connect(::std::ptr::null());
if display.is_null() == true {
eprintln!("Unable to connect to the Wayland display server.");
return;
}
println!("Connected to Wayland display server.");
println!("Retrieving the registry from the Wayland display.");
registry = wl_display_get_registry(display);
if registry.is_null() == true {
eprintln!("Unable to retrieve registry.");
} else {
println!("Registry retrieved.");
}
wl_display_disconnect(display);
println!("Disconnected from Wayland display server.");
}
}
C
Build
gcc -o wayland -lwayland-client main.c
Output
Connected to Wayland display server.
Retrieving the registry from the Wayland display.
Registry retrieved.
Disconnected from Wayland display server.
Code
#include <stdio.h>
#include <wayland-client.h>
int main()
{
struct wl_display *display;
struct wl_registry *registry;
display = wl_display_connect(NULL);
if (display == NULL)
{
fprintf(stderr, "Unable to connect to the Wayland display server.\n");
return 1;
}
fprintf(stdout, "Connected to Wayland display server.\n");
fprintf(stdout, "Retrieving the registry from the Wayland display.\n");
registry = wl_display_get_registry(display);
if (registry == NULL)
{
fprintf(stderr, "Unable to retrieve registry.\n");
}
else
{
fprintf(stdout, "Registry retrieved.\n");
}
wl_display_disconnect(display);
fprintf(stdout, "Disconnected from Wayland display server.\n");
return 0;
}
objdump
Command
objdump -TC /usr/lib/x86_64-linux-gnu/libwayland-client.so | grep "wl_display*"
Output
0000000000005f60 g DF .text 0000000000000275 Base wl_display_connect
0000000000006960 g DF .text 0000000000000078 Base wl_display_flush
0000000000006a90 g DF .text 000000000000000c Base wl_display_dispatch
00000000000067b0 g DF .text 0000000000000042 Base wl_display_cancel_read
00000000000068c0 g DF .text 000000000000000c Base wl_display_dispatch_pending
0000000000006800 g DF .text 00000000000000bf Base wl_display_dispatch_queue_pending
00000000000061e0 g DF .text 0000000000000057 Base wl_display_disconnect
0000000000006be0 g DF .text 00000000000000fc Base wl_display_roundtrip_queue
00000000000068d0 g DF .text 000000000000002c Base wl_display_get_error
0000000000005610 g DF .text 0000000000000031 Base wl_display_create_queue
0000000000006740 g DF .text 0000000000000052 Base wl_display_prepare_read_queue
0000000000006900 g DF .text 0000000000000051 Base wl_display_get_protocol_error
0000000000005dc0 g DF .text 0000000000000194 Base wl_display_connect_to_fd
00000000000069e0 g DF .text 00000000000000ac Base wl_display_dispatch_queue
0000000000006ce0 g DF .text 000000000000000c Base wl_display_roundtrip
0000000000006250 g DF .text 00000000000004f0 Base wl_display_read_events
0000000000006240 g DF .text 0000000000000004 Base wl_display_get_fd
000000000020dce0 g DO .data.rel.ro 0000000000000028 Base wl_display_interface
00000000000067a0 g DF .text 000000000000000c Base wl_display_prepare_read