0

I have downloaded the library libcomplearn and want to test it in a small example program. But when I link it I get the error undefined reference to ‘function’.

I installed the library to a specific path.

OS: Debian

test.c

#include <stdio.h>
#include "complearn.h"
#include "complearn/complearn-ncd.h"

int main(const int argc, const char * const argv[])
{
    printf("Number from my library\n");

    CompLearnNcd *ncd = complearn_ncd_top();
    return 0;
}

Makefile

FILES = test
LIBPATH = /try/libcomplearn/lib/pkgconfig
OUTPUT = TK_1
LIBNAME = complearn
#--------------------------------------------------

CC = gcc

CFLAGS = -c -Wall `export PKG_CONFIG_PATH=$(LIBPATH) && pkg-config --cflags $(LIBNAME)`
LDFLAGS = -static `export PKG_CONFIG_PATH=$(LIBPATH) && pkg-config --libs --static $(LIBNAME) -llzma`

all: Release

Debug: CFLAGS += -g
Debug: $(OUTPUT)

Release: $(OUTPUT)

$(OUTPUT): $(OUTPUT).o
    @echo "started...."
    $(CC) -o $(OUTPUT) $(OUTPUT).o $(LDFLAGS)
    @echo "done...."

$(OUTPUT).o: $(FILES).c
    $(CC) $(CFLAGS) $(FILES).c -o $(OUTPUT).o

clean:
    rm -f $(OUTPUT).o $(OUTPUT)

Output

gcc -c -Wall `export PKG_CONFIG_PATH=/try/libcomplearn/lib/pkgconfig && 
pkg-config --cflags complearn` test.c -o TK_1.o
test.c: In function ‘main’:
test.c:9:19: warning: unused variable ‘ncd’ [-Wunused-variable]
 CompLearnNcd *ncd = complearn_ncd_top();
               ^~~
started....
gcc -o TK_1 TK_1.o -static `export                 
PKG_CONFIG_PATH=/try/libcomplearn/lib/pkgconfig && pkg-config --libs --    
static complearn -llzma`
Unknown option -llzma
/usr/bin/ld: TK_1.o: in function `main':
test.c:(.text+0x1c): undefined reference to `complearn_ncd_top'
collect2: error: ld returned 1 exit status
make: *** [makefile:28: TK_1] Error 1

I also tried with the command:

gcc test.c `-L/try/libcomplearn/lib/ -llzma` `pkg-config --cflags --libs glib-2.0` 
roschach
  • 8,390
  • 14
  • 74
  • 124
garafa
  • 3
  • 2
  • When you add custom header file you must compile this to .o file and every .o file to executable or (bad way) include .c. – Igor Galczak Mar 14 '19 at 09:17
  • your LDFLAGS are not correct. – alinsoar Mar 14 '19 at 09:44
  • Blaze Yes, it’s in there, but it’s the same for all other functions. IgorGalczak There is nothing customized in the headers. I just corrected one include but before installing the library – garafa Mar 14 '19 at 09:46
  • @alinsoar Thanks for the hint. Do you have a suggestion? – garafa Mar 14 '19 at 09:50
  • I had similar problems in the past, just try to pass "-llzma" as the last option. I don't know why, but gcc (ld) complains if the libraries linking options are before the object file (or source file in your example). [link](https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc) – Meher Khiari Mar 14 '19 at 10:07

2 Answers2

1

You say:

I also tried with the command:

gcc test.c `-L/try/libcomplearn/lib/ -llzma` `pkg-config --cflags --libs glib-2.0`

which indicates that you do not understand back-ticks, since:

`-L/try/libcomplearn/lib/ -llzma`

is not a meaningful use of them. Take the time now to learn their use.

The cause of your linkage failure is the setting:

LDFLAGS = -static `export PKG_CONFIG_PATH=$(LIBPATH) && pkg-config --libs --static $(LIBNAME) -llzma`

in the makefile.

Here you have -llzma within the back-tick expansion:

`export PKG_CONFIG_PATH=$(LIBPATH) && \
    pkg-config --libs --static $(LIBNAME) -llzma`

To expand this, the shell executes:

export PKG_CONFIG_PATH=$(LIBPATH)
pkg-config --libs --static $(LIBNAME) -llzma

-llzma is a meaningless option to the pkg-config command, so it fails, as you see it complain in the make output:

Unknown option -llzma

Just like:

$ pkg-config --cflags --libs zlib -llzma
Unknown option -llzma

As a result, the required linkage options that should be output by:

pkg-config --libs --static $(LIBNAME)

are not output and are not interpolated into the value of LDFLAGS. So the linkage fails:

test.c:(.text+0x1c): undefined reference to `complearn_ncd_top'

because libcomplearn has not been linked. Correct the setting of your LDFLAGS to:

LDFLAGS = -static `export PKG_CONFIG_PATH=$(LIBPATH) && pkg-config --libs --static $(LIBNAME)` -llzma

with -llzma following after the back-tick expansion.

Mike Kinghan
  • 55,740
  • 12
  • 153
  • 182
  • Thank you very much for your help. It solved a lot of problems and I got the point of back-ticks. But I have now the error cannot find -llzma. Is then here maybe the linux version a problem? – garafa Mar 14 '19 at 13:15
  • @garafa Glad that helped and welcome to Stackoverflow! Here is [our way of saying "Thanks"](https://stackoverflow.com/help/someone-answers). There certainly is a linux `liblzma` but you probably just haven't installed the dev package: `sudo apt install liblzma-dev`. If you still have problems then [ask a new question](https://stackoverflow.com/questions/ask). (One question at a time on SO). – Mike Kinghan Mar 14 '19 at 14:19
0

From Why does the order in which libraries are linked sometimes cause errors in GCC?

The order of the -l options is very important. Just pass -llzma as the last linking option.

Meher Khiari
  • 111
  • 9