views:

2840

answers:

3

Hi,

I'm compiling and linking a cpp file against a pre-compiled library, and I'm getting an "undefined reference" error.

Firstly, this is the command (the library in question is quicknet3, the program I'm compiling is trapper):

g++ -w -g -I. -g -O3 -pipe -Wall -I/home/install/x86_64/include/quicknet3 -L/home/install/x86_64/lib -lquicknet3 -lintvec -lfltvec -o trapper trapper.cpp CMyException.cpp

Here's the undefined reference error:

/tmp/ccFuVczF.o: In function 'main': trapper.cpp:1731: undefined reference to 'QN_InFtrLabStream_PFile::QN_InFtrLabStream_PFile(int, char const*, _IO_FILE*, int)'

The call in trapper.cpp (line 1731) is:

IN_PFILE = new QN_InFtrLabStream_PFile(0, "", fp, 1);

where fp is a FILE *, assigned as the result of an fopen call beforehand.

The constructor being called is defined in the relevant header file (QN_Pfile.h), as follows:

class QN_InFtrLabStream_PFile : public QN_InFtrLabStream
{
public:
QN_InFtrLabStream_PFile(int a_debug, const char* a_dbgname, FILE* a_file, int a_indexed);
(... other declarations ...) }

The definition of the constructor is indeed given in QN_Pfile.cc:

QN_InFtrLabStream_PFile::QN_InFtrLabStream_PFile(int a_debug,const char* a_dbgname, FILE* a_file, int a_indexed) : log(a_debug, "QN_InFtrLabStream_PFile", a_dbgname),file(a_file),indexed(a_indexed),buffer(NULL),sentind(NULL) {
(... the usual constructor stuff :P ...) }

I compiled the quicknet3 library myself, without error, and installed it to /home/install/x86_64/lib/libquicknet3.a

So, I can't understand why the call from trapper.cpp is unable to find the reference to this constructor definition. The g++ arguments of -L/home/install/x86_64/lib -lquicknet3 should do the trick, right?

Any ideas?

Thanks, Roy

+3  A: 

I notice that you're mixing FILE* and _IO_FILE*. I'm not familiar with the latter, are you sure they're one and the same?

therefromhere
Not really, but if this were the problem, wouldn't the error message be more like "no matching function for call..."? Anyway, Aaron's suggestion didn't work (casting to FILE*)
+1  A: 

FILE is a typedef of _IO_FILE. Your linker is treating it as a unique type.

You could try:

IN_PFILE = new QN_InFtrLabStream_PFile(0, "", (FILE *)fp, 1);

to see if this resolve your constructor.

(FILE is defined in stdio.h, _IO_FILE in libio.h if you're interested)

Aaron Saarela
Hi, thanks Aaron, I tried this but it didn't work.
+1  A: 

A quick workaround is to add /home/install/x86_64/lib/libquicknet3.a to g++ commandline.

I you want to investigate further, if g++ is picking another copy of libquicknet3, you can pass -v to g++ so it will output its searching paths.

Ismael
This works. But why?? Shouldn't "-L/home/n4739094/install/x86_64/lib -lquicknet3" have exactly the same effect as /home/n4739094/install/x86_64/lib/libquicknet3.a? I tried using -v but couldn't make any sense of its "searching paths" - any hints? Thanks :)
Using -lquicknet is telling the linker that search libquicknet3.a in the libraries path, which includes your home directory, my guess is that the linker is using a copy in another path, unfortunately the gcc docs at hand don't tell me which is the search order.
Ismael
Ismael
Hi Ismael, following is the collect2 line in the output of the make command - as you can see, LIBRARY_PATH is not mentioned. Also, of all the paths specified with -L, libquicknet3.a is only found in /home/n4739094/install/x86_64/lib.
`/usr/libexec/gcc/x86_64-redhat-linux/4.3.0/collect2 --eh-frame-hdr --build-id -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o trapper /usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-redhat-linux/4.3.0/crtbegin.o -L/home/n4739094/install/x86_64/lib -L/usr/lib/gcc/x86_64-redhat-linux/4.3.0 -L/usr/lib/gcc/x86_64-redhat-linux/4.3.0 -L/usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64
-L/usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../.. -lquicknet3 -lintvec -lfltvec /tmp/ccU6Az7j.o /tmp/ccBAv9uQ.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-redhat-linux/4.3.0/crtend.o /usr/lib/gcc/x86_64-redhat-linux/4.3.0/../../../../lib64/crtn.o`