Xenotoad
Xenotoad

Reputation: 362

c++ - Undefined Reference to Existing Function

Alright, I'm developing a small network library to use in another application of mine. I've got a function declared in NetStream.h like so:

class NetStream;
class NetStream {
public:
  static NetStream *connect(char *ip, char *port, char** error);
  ...
}

In my NetStream.cpp, I've got it defined with the same prototype:

NetStream* NetStream::connect(char *ip, char *port, char** error) {
  ...
}

When I objdump my libNetLib.a, I can see that NetStream::connect is defined:

$ objdump -Ct NetLib/libNetLib.a | grep 'connect' #demangled names
000000000000031a g     F .text  00000000000001b4 NetStream::connect(char*, char*, char**)
0000000000000000         *UND*  0000000000000000 connect

$ objdump -t NetLib/libNetLib.a | grep 'connect' #mangled names
000000000000031a g     F .text  00000000000001b4 _ZN9NetStream7connectEPcS0_PS0
0000000000000000         *UND*  0000000000000000 connect

In a the object file in the application that uses my NetLib, objdump reveals that it's importing a function with the same prototype:

$ objdump -Ct connection.cpp.o | grep 'connect'
...
0000000000000000         *UND*  0000000000000000 NetStream::connect(char*, char*, char**)
...

$ objdump -t connection.cpp.o | grep 'connect'
...
0000000000000000         *UND*  0000000000000000 _ZN9NetStream7connectEPcS0_PS0_
...

But when I link the application with g++ 4.9.2, I get this error:

connection.cpp:(.text+0x52): undefined reference to `NetStream::connect(char*, char*, char**)'

This happens when CMake tries to link it, and when I link it with the following command:

$ g++ connection.cpp.o -L NetStream.cpp.o -o /tmp/tst

I get the same undefined reference (and a bunch of other undefined references because there's other things to be linked in, too, that I didn't link there).

I've looked around a bit and seen that this is usually caused when const pointers in function prototypes differ, but there's no const here.

What's the real problem here?

Upvotes: 0

Views: 1923

Answers (2)

Employed Russian
Employed Russian

Reputation: 213955

g++ connection.cpp.o -L NetStream.cpp.o -o /tmp/tst

This command line is completely bogus. Try this instead:

g++ connection.cpp.o -LNetLib -lNetLib -o /tmp/tst

or this:

g++ connection.cpp.o NetLib/libNetLib.a -o /tmp/tst

Update:

What is the real problem here?

The real problem is that your link command line is incorrect (as stated above).

I can't really compile my code like that ...

Compilation is not the problem here, linking is.

Presumably you can't construct correct link command because you are using CMake, and it is CMake that constructs bogus link command line.

Since we know that CMake works, we must assume that it is your CMakefile that is the root cause. Unfortunately, you haven't shown your CMakefile.

You should ask a separate question, like this: "I have the following CMakefile, which results in the following link line, which this answer tells me is bogus. What is wrong with my CMakefile?"

Upvotes: 3

Peter
Peter

Reputation: 36637

You really need to look up the meaning of command line options for g++, because you are badly misusing them.

-Ldirectory tells the linker to look in directory for library files. Unless you have a directory named "NetStream.cpp.o" (which is pretty unlikely) and you specify libraries in that directory to link (which you haven't) your command line is gibberish.

Your command line is effectively telling the linker to look in a directory for library files, but not giving any information about libraries to be linked against. So your "NetLib.a" is not even accessed by the linker.

Assuming you have a library named NetLib.a in a directory (relative to the working directory when g++ is invoked) named NetLib then - as Employed Russian has pointed out - you either need to do "g++ connection.cpp.o -LNetLib -lNetLib -o /tmp/tst" to link against the library or "g++ connection.cpp.o NetLib/libNetLib.a -o /tmp/tst".

Upvotes: 3

Related Questions