Linker does not link

5

I'm trying to compile a package; specifically, the plugin gkrellm-leds for gkrellm . I downloaded the sources from packages.ubuntu.com/source/zesty/gkrellm-leds .

After compiling and installing it, it does not work. The program that should use it, gkrellm , does not even show it as plugin available.

As it is not the first time these things happen to me, the first thing I did was

  

> ldd gkleds.so

     

linux-vdso.so.1 = > (0x00007ffe15def000)
      libc.so.6 = > /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2fc6f37000)
      /lib64/ld-linux-x86-64.so.2 (0x0000557eb4014000)

I know that this package uses the GTK-2.0 libraries, as well as others. In fact, the source code is full of calls to functions of these libraries.

The Makefile of the package is:

SHELL = /bin/sh
VPATH = src:src/pixmaps

GTK_INCLUDE = 'pkg-config gtk+-2.0 --cflags'
GTK_LIB = 'pkg-config gtk+-2.0 --libs'

X11_LIB = -L/usr/X11R6/lib -lX11 -lXtst

LIBS = $(GTK_LIB) $(X11_LIB)
DEFINES =
LFLAGS = -shared
INCLUDES = $(GTK_INCLUDE)
CFLAGS = -ansi -pedantic -Wall -O2 -fPIC 
CC = gcc

SRCS = gkleds.c
HDRS = gkleds.h
OBJS = gkleds.o
IMAGES = leds.xpm

DESTDIR = 

INSTALL_PROG = install

.PHONY : clean
.PHONY : install
.PHONY : uninstall
.PHONY : test

#=======================================================================
#=======================================================================

gkleds.so : $(OBJS)
    $(CC) $(LFLAGS) $(LIBS) -o $@ $< 

gkleds.o : $(SRCS) $(HDRS) $(IMAGES)
    $(CC) $(CFLAGS) $(INCLUDES) $(DEFINES) -c -o $@ $< 

test :
    $(MAKE) clean
    $(MAKE) DEFINES="-DGKLEDS_DEBUG"
    gkrellm --sync --demo -p gkleds.so
    $(MAKE) clean

clean:
    rm -rf *.o *.so* *~ \#*
    rm -rf src/*~ src/\#*

install : gkleds.so
    @ if [ "$$UID" -ne 0 ]; \
        then PLUGIN_DIR=$$HOME/.gkrellm2/plugins; \
    elif [ -e /usr/bin/gkrellm ]; \
        then PLUGIN_DIR=/usr/lib/gkrellm2/plugins; \
    else \
        PLUGIN_DIR=/usr/local/lib/gkrellm2/plugins; \
    fi; \
    $(INSTALL_PROG) -d $(DESTDIR)/$$PLUGIN_DIR; \
    $(INSTALL_PROG) -s gkleds.so $(DESTDIR)/$$PLUGIN_DIR; \
    printf "\ngkleds installed in $$PLUGIN_DIR\n"

All compilation dependencies are correctly installed, as well as the corresponding pkg-config :

  

> pkg-config gtk+-2.0 --cflags

     

-pthread -I / usr / include / gtk-2.0 -I / usr / lib / x86_64-linux-gnu / gtk-2.0 / include -I / usr / include / gio-unix-2.0 / -I / usr / include / cairo -I / usr / include / pango-1.0 -I / usr / include / atk-1.0 -I / usr / include / cairo -I / usr / include / pixman-1 -I / usr / include / libpng16 -I / usr / include / gdk-pixbuf-2.0 -I / usr / include / libpng16 -I / usr / include / pango-1.0 -I / usr / include / harfbuzz -I / usr / include / pango-1.0 -I /usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu / glib-2.0 / include -I / usr / include / freetype2

     

> pkg-config gtk+-2.0 --libs

     

-lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 - lfontconfig -lfreetype

Anyway, to make sure, I dump the results of pkg-config in a separate file, extra.mk , and I modified the original Makefile to include mine, adding include extra.mk and eliminating the definitions of GTK_INCLUDE and GTK_LIB .

After that small modification, when doing make , apart from several irrelevant warnings , the following is shown:

  

gcc -DGKLEDS_DEBUG -ansi -pedantic -Wall -O2 -fPIC -pthread -I / usr / include / gtk-2.0 -I / usr / lib / x86_64-linux-gnu / gtk-2.0 / include -I / usr /include/gio-unix-2.0/ -I / usr / include / cairo -I / usr / include / pango-1.0 -I / usr / include / atk-1.0 -I / usr / include / cairo -I / usr / include / pixman-1 -I / usr / include / libpng16 -I / usr / include / gdk-pixbuf-2.0 -I / usr / include / libpng16 -I / usr / include / pango-1.0 -I / usr / include / harfbuzz -I / usr / include / pango-1.0 -I / usr / include / glib-2.0 -I / usr / lib / x86_64-linux-gnu / glib-2.0 / include -I / usr / include / freetype2 -c - or gkleds.o src / gkleds.c   ...
  ... VARIOUS WARNINGS ...
  ...
  gcc -shared -lgtk-x11-2.0 -lgdk-x11-2.0 -lpangocairo-1.0 -latk-1.0 -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lpangoft2-1.0 -lpango-1.0 -lgobject-2.0 -lglib-2.0 - lfontconfig -lfreetype -lX11 -lXtst -o gkleds.so gkleds.o

You can see how, in the last part, it calls gcc with the correct options and libraries.

However, if I do it again

  

> ldd gkleds.so

     

linux-vdso.so.1 = > (0x00007ffe15def000)
  libc.so.6 = > /lib/x86_64-linux-gnu/libc.so.6 (0x00007f2fc6f37000)
  /lib64/ld-linux-x86-64.so.2 (0x0000557eb4014000)

It still does not show dependencies of the GTK or any other, apart from the default added by the gcc .

  • Why are references not included in the external libraries used by the package?
  • How do I solve it?
  • asked by Trauma 29.05.2017 в 07:52
    source

    1 answer

    5

    Okay. It is already solved.

    Searching on Google, I ended up finding a question on StackOverflow:

    gcc build links but shared library does not appear with ldd

    The accepted response indicates

      

    Most Linux distributions (I assume you are using Linux based on the output of ldd) seem to configure gcc as to pass - needed to ld by default (e.g., see here for Debian). This means the final library / executable will only depend on a library (i.e., have a DT_NEEDED tag for that library) if some symbol of that library is actually used by the library / executable.

    Which, in translation very free on my part:

      

    Some distributions set gcc to use by default the --as--needed option when calling ld . This tells the linker that does not include any references to lines that are not called directly by the executable .

    In my case, what I am trying to compile is a library ; is not an executable and, with the option --as-needed , the linker directly obvious any reference to external libraries. They are supposed to be referenced in the executable that uses us.

    The solution has been simple. I changed the Makefile :

    gkleds.so : $(OBJS)
      $(CC) $(LFLAGS) $(LIBS) -o $@ $<
    

    for

    gkleds.so : $(OBJS)
      $(CC) -Wl,--no-as-needed gkleds.so : $(OBJS)
    

    With this modification, the option --as-needed is reversed ; We force the linker to include any reference to external libraries.

    After doing make , the result is as expected:

      

    > ldd gkleds.so

         

    linux-vdso.so.1 = > (0x00007ffe22f5c000)
          libgtk-x11-2.0.so.0 = > /usr/lib/x86_64-linux-gnu/libgtk-x11-2.0.so.0 (0x00007ff78143a000)
          libgdk-x11-2.0.so.0 = > /usr/lib/x86_64-linux-gnu/libgdk-x11-2.0.so.0 (0x00007ff781185000)
          libpangocairo-1.0.so.0 = > /usr/lib/x86_64-linux-gnu/libpangocairo-1.0.so.0 (0x00007ff780f78000)
      ...

    If dependencies are indicated for libraries. After installing it again, if is displayed in the list of plugins available in gkrellm , and it works correctly.

    Ubuntu artful update (10-10-17)

    In this version, with gcc -v

      

    gcc version 7.2.0 (Ubuntu 7.2.0-8ubuntu3)

    gcc does not recognize the --no-as-needed option. It is necessary to indicate explicitly that the option is for the linker . For this, and starting from the Makefile original , the modification has to be made as follows:

    • Original line:

      LFLAGS = -shared
      
    • Line modified :

      LFLAGS = -shared -Xlinker --no-as-needed
      
    answered by 29.05.2017 / 09:37
    source