Linking errors from MATLAB Mex library

c++, linker-errors, macos, matlab, mex

Solution

It seems like the issue is that some template code is in .cpp files.

- Remove the `#include instances.inc` declarations from the `.cpp` files.

- Move all code from QPBO.cpp, QPBO_extra.cpp, QPBO_maxflow.cpp and QPBO_postprocessing.cpp to the header file qpbo.h.

- You'll have now a single .cpp file qpbo_wrapper_mex.cpp and a single header qpbo.h

mex the file (in matlab) using:

>> mex -O -largeArrayDims qpbo_wrapper_mex.cpp

Should work...

Problem

I am having troubling compiling a MATLAB Mex library - specifically, the 'Correlation Clustering Optimization' code from this website. I am trying to compile on an OSX machine, and am using the supplied `mexall` function. This runs the following line: ``` mex -O -largeArrayDims CXXFLAGS="\$CXXFLAGS -Wno-write-strings" QPBO.cpp QPBO_extra.cpp QPBO_maxflow.cpp QPBO_wrapper_mex.cpp QPBO_postprocessing.cpp -output QPBO_wrapper_mex ``` The error occurs at linking time with the following output to the MATLAB command line: ``` ld: duplicate symbol QPBO<int>::GetMaxEdgeNum() in QPBO_extra.o and QPBO.o collect2: ld returned 1 exit status mex: link of ' "QPBO_wrapper_mex.mexmaci64"' failed. ``` Judging from this, the function `GetMaxEdgeNum` is appearing in both `QPBO_extra.o` and `QPBO.o`. However, it is only actually defined in a header file, `QPBO.h`. I therefore suspect that both source files which include it are including it as a symbol in their object files, causing a problem at link time. (Further information: Each source file also includes a file `#include "instances.inc"` at the very end of the file. `instances.inc` apparently seems to include some specific instantiations of the templated `QPBO`.) Is there an obvious mistake I am making here? What can I do to increase my chances of being able to compile this code? EDIT This is the definition of the problematic `GetMaxEdgeNum` function in `QPBO.h`: ``` template <typename REAL> inline int QPBO<REAL>::GetMaxEdgeNum() { return (int)(arc_max[0]-arcs[0])/2; } ``` EDIT 2 Some more details about my machine: - OSX 10.6.8 - MATLAB R2012a (also have R2011b) - g++ 4.2 or g++ 4.0 (or g++ 4.6 via MacPorts) I've added some details on what I really want from an answer in my 'bounty description' below. EDIT 3 There's a bit of consensus that `instances.inc` may be causing the trouble. This is included at the end of each `cpp` file, and it contains the following: ``` #include "QPBO.h" #ifdef _MSC_VER #pragma warning(disable: 4661) #endif // Instantiations template class QPBO<int>; template class QPBO<float>; template class QPBO<double>; template <> inline void QPBO<int>::get_type_information(char*& type_name, char*& type_format) { type_name = "int"; type_format = "d"; } template <> inline void QPBO<float>::get_type_information(char*& type_name, char*& type_format) { type_name = "float"; type_format = "f"; } template <> inline void QPBO<double>::get_type_information(char*& type_name, char*& type_format) { type_name = "double"; type_format = "Lf"; } ```

Original source