views:

1712

answers:

3

I've tried looking at similar problems, but could not easily find one that helped my problem.

I've created a project in C++ and am working on UNIX to compile, link, and run it. My specific problem is an undefined reference to a method I declare in a separate file.

In the file SharedCache.cpp, I have the following method:

int SharedCache::replaceLine(ullong address){
 int evictPID = -1;

 int cacheSet = calcCacheSet( address );
 //random uniformly-distributed value for cache line
 float numLines = static_cast<float>(CACHE_LINES_PER_SET);
 uint cacheLine = static_cast<uint>(uniformDistr( numLines ));

 if(cache[cacheSet][cacheLine] != NULL){
  evictPID = cache[cacheSet][cacheLine]->PID;
 }

 uint PID= calcPID(address);
 uint tag= calcTag(address);

 cache[cacheSet][cacheLine]->setLine(PID, tag); //mutex method

 return PID;
}

The line uint cacheLine = static_cast<uint>( uniformDistr( numLines )); makes a call to the function I want to use from another file. The linker error is an undefined reference to this method.

uniformDistr( float ); is declared in the header distributions.h and defined in distributions.cpp. In my project options I set the linker flag -distributions and I also compiled the distributions.cpp to make sure a distributions.o file exists to link with.

From here, I don't know where to go, because this has not solved the problem.

A: 

Did you add the distributions.cpp to your makefile? Also I believe the required linker flag is -ldistributions.

rlbond
I tried -ldistributions and that case created a configure error while -distributions did not, so I don't think that is it. Also, I am using KDevelop which deals with makefile's on its own. I've let it rebuild the makefile, but there is not exact place for me to add distributions.cpp.
+2  A: 

I've not used KDevelop, however, on the command line you would just add distributions.o as an input file to the linking process. No need for dashes or leaving off the .o extension.

Alternatively, can you just add distributions.cpp to your KDevelop project? That way it should get compiled and linked automatically (this is how it works in things like Visual Studio or Eclipse).

Anthony Cramp
*sigh* I thought it was in the project, but I guess it wasn't. That's what I get for trying to pick up KDevelop on the fly. Sorry everyone
+2  A: 

Without more precise information on which compiler/linker commands were invoked and the exact error outputs, it is difficult to provide a good answer.

However, from your description of what you did, it seems that you are not passing distributions.o to the linker. Unlike other languages where the compiler/linker search for object files to link in automatically, C++ linkers require an explicit specification of the objects to link together.

Your use of -ldistributions here is incorrect: the -l flag is used to link to a static or dynamic library (respectively .a and .so files on Linux), whereas you want to specify another object file that the linker should consider. Specifying -ldistributions makes the linker look for distributions.a or distributions.so in the standard library locations.

Basically, your linker invocation now looks something like this (probably with many more flags and libraries):

gcc -o my_program SharedCache.o -ldistributions

To correctly link the distributions code in, you need to make it look something like (again, many flags and libraries probably missing compared to the real thing):

gcc -o my_program SharedCache.o distributions.o

This should resolve the missing symbols issue and produce a working binary (or at the very least a different error ;-) ). How to do this in KDevelop however I do not know.

David Anderson