I am developing some library using Gtkmm4. This libraries purpose is to replace the removed API of Gtkmm3 (such as Gtk::Window::move
). Especially for this particular function, i need to use gdk_x11_surface_move
. The linker says undefined reference to gdk_x11_surface_move
. My library libgdp.so
links to following Gtk libraries:
$ ldd libgdp.so.1 | grep gtk
libgtkmm-4.0.so.0 => /home/user/.local/built/lib/libgtkmm-4.0.so.0 (0x00007f981fb5a000)
libgtk-4.so.1 => /home/user/.local/built/lib/libgtk-4.so.1 (0x00007f981d57a000)
And in that libgtk-4.so.1
, gdk_x11_surface_move
is defined:
$ nm /home/user/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000461cc0 t gdk_x11_surface_move
0000000000462730 T gdk_x11_surface_move_to_current_desktop
0000000000462540 T gdk_x11_surface_move_to_desktop
Interesting / important might be following output, where gdk_x11_surface_move
is not present:
$ nm -D /home/papa/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000462730 T gdk_x11_surface_move_to_current_desktop
0000000000462540 T gdk_x11_surface_move_to_desktop
In my code i am using gdk_x11_surface_move
like this:
#include <window.hpp>
...
void Window::move(int x, int y) {
auto surface = this->get_surface().get();
gdk_x11_surface_move(surface, x, y);
}
...
...
extern "C" {
void gdk_x11_surface_move(Gdk::Surface *surface, int x, int y);
}
...
I just do not understand why I cannot use that function in my library, even though it is defined / available in the Gtk library. Can you find a solution ? If you need any more details, please let me know by writing me a comment !
EDIT The library gets linked with following command:
/bin/bash ./libtool --tag=CXX --silent --mode=link g++ -g -O2 -version-info 1:0: -L/home/user/.local/built/lib -o libgdp.la -rpath /home/user/.local/built/lib src/libgdp_la-logger.lo src/libgdp_la-window.lo src/libgdp_la-utils.lo -L/home/user/.local/built/lib -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -L/home/user/.local/built/lib
and the application with the following command which throws the error:
g++ -g -O2 -L/home/user/.local/built/lib -o gdp-screenshot src/gdp_screenshot-main.o src/gdp_screenshot-application.o src/gdp_screenshot-prefswindow.o src/gdp_screenshot-savewindow.o src/gdp_screenshot-screenshot.o -L/home/user/.local/built/lib -L/home/user/Programme/c++/GDP-Gtk/libgdp/.libs -lgdp -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lX11 -L/home/user/.local/built/lib -lgtkmm-4.0 -lpangomm-2.48 -lgiomm-2.68 -lglibmm-2.68 -lcairomm-1.16 -lsigc-3.0 -lgtk-4 -lpangocairo-1.0 -lpango-1.0 -lharfbuzz -lgdk_pixbuf-2.0 -lcairo-gobject -lcairo -lgraphene-1.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -L/home/user/.local/built/lib -lfribidi -L/home/user.local/built/lib -lglibmm-2.4 -lgobject-2.0 -lglib-2.0 -lsigc-2.0 -L/home/user/.local/built/lib
/home/user/Programme/c++/GDP-Gtk/libgdp/.libs/libgdp.so: warning: undefined reference to »gdk_x11_surface_move(Gdk::Surface*, int, int)«
collect2: error: ld returned 1 exit status
Makefile:525: recipe for target 'gdp-screenshot' failed
and in fact is thrown in the phase where the application that uses the libgdp.so
library is linked. The library itself compiles and links fine.
I just do not understand why I cannot use that function in my library, even though it is defined / available in the Gtk library.
$ nm /home/user/.local/built/lib/libgtk-4.so.1 --defined-only | grep x11_surface_move
0000000000461cc0 t gdk_x11_surface_move
You are correct that the function is defined in libgtk-4.so.1
, but you are mistaken in that it is available: t
in nm
output means it's a local function. Such functions can't be called from outside.
There are a few reasons why a function may get local linkage:
static
in the file where it is defined.-fvisibility=hidden
) or link time (using linker version script).The fix depends on why the function is local. For 1) above, removing static
qualifier will do. For 2), you may need to add __attribute__((visibility("default")))
, or you may need to edit the linker version script.