I'm currently trying to use a library previously written by me (matrix.c) within another self-written library (Quaternion.c) by calling it through a header file using the standard method of using a "matrix.h" file with function prototypes from the "matrix.c" file.
"matrix.c" is functional, but when I attempt to compile "Quaternion.c" in MSYS2 MinGW64, using:
gcc -c matrix.c
gcc -c Quaternion.c
gcc matrix.o Quaternion.o -o Quaternion -lgsl
I'm getting this error:
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: Quaternion.o:Quaternion.c:(.text+0x0): multiple definition of `my_handler'; matrix.o:matrix.c:(.text+0x0): first defined here
collect2.exe: error: ld returned 1 exit status
I defined a custom error handler in the GSL "errono.h", and I'm assuming that's the source of the error:
void my_handler (const char * reason, const char * file, int line, int gsl_errno){
if(gsl_errno == 3 || gsl_errno == 7 || gsl_errno == 8 || gsl_errno == 10){
printf("Fatal memory-based error %d, resetting\n", gsl_errno);
exit(0);
//Reset Chip
}
if(gsl_errno == 1 || gsl_errno == 2 || gsl_errno == 4){
printf("User error %d (%s), ignoring calculation and moving forward\n", gsl_errno, reason);
// Return/ignore calculation
}
else
printf("Unexpected error %d, ignoring and moving forward\n", gsl_errno);
// Return/ignore calculation
}
I can't wrap my head around this error because the gsl library is a single source that I've already edited. If somebody could explain why my compilation method (I'm thinking that's what it is) is resulting in the re-definition of that handler, it would be appreciated.
Move the code quote into one of the .c files.
Then only provide the prototype in the .h file.
void my_handler (const char * reason, const char * file, int line, int gsl_errno);
Otherwise the function is defined once for each .c file which gets compiled and does a #include
of that header. In your case probably twice.
A reinclusiong guard would not help in this case, because it still happens once per compiled .c file. But having a guard is still a good idea, I assume you have.