I'm getting multiple definition errors and don't understand why.
I'm compiling C code with g++ on Cygwin. I'm using a unit test framework (google test, which is C++, and that's why I'm not using gcc). The unit test source file #includes the .c file (fileA.c) containing the function I want to unit test, essentially making it an extension of said file, and I compile the unit test source file. The function under test calls functions declared in fileB.h and defined in fileB.c. It's a bit like Override a function call in C. I'm not showing the include guards, but essentially the stripped down code looks like this:
fileB.h
typedef void * pClass; // to hide the "class" in the .c file
extern pClass pObject1;
void do_something_with_object( void * );
fileB.c
#include "FileB.h"
typedef struct myclass {
int stuff;
} myclass;
myclass Obj1 = { initial_value };
void *pObj1 = &Obj1;
void do_something_with_object( void *arg) {
// do stuff, casting to myclass and verifying it's the right kind
}
fileA.h
#include "fileB.h"
void myfunc( void );
fileA.c
#include "fileA.h"
void myfunc( void ) {
do_something_with_object( pObj1 );
}
utest_fileA.cpp
#include "../fileA.c"
// google test infrastructure stuff not shown
TEST(testname, testcase) {
myfunc();
}
fileB's sybols are linked into a static library that contains all the production code. The static library was compiled with g++ so there are no extern "C"
issues. The makefile for utest_fileA.cpp statically links in this library. So far so good. Now, I want to provide my own fake version of do_something_with_object so I can spy on what's passed in to make sure myfunc calls do_something_with_object with the correct parameter. I don't want to modify the production code just to support this unit test. So, I create a fake version of do_something_with_object further up in the compilation unit for my unit test source:
static void * myspy;
void do_something_with_object( void * arg) {
myspy = arg;
}
The idea is that the unit test will use the fake definition, and since it has a definition it won't bother looking for it in the static library, and there will be no conflict. Usually this works. But in the case I'm up against right now, I get multiple definition errors for do_something_with_object(), finding the fake one first and then the real one. I don't see anything different from the cases where this works, but clearly I'm missing something. What could be causing this? What should I look for? It's failing when trying to link utest_fileA.o with libMyLib.a. It uses the -static flag. I tried some things I saw suggested elsewhere on stackoverflow, like -z muldefs, but Cygwin didn't like that, and I really would like to understand what's going on.