0

in my current project I´m working with the arpackpp interface. The entire library is written in .h files, so that there is no need to compile the library. The problem I'm facing now - when I include some of the arpackpp header files in some of my files, which are not the main.cpp, I get the following errors:

/.../Files/Includes/../../../arpack++/include/arerror.h:163: multiple definition of ArpackError::Set(ArpackError::ErrorCode, std::string const&)' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd::iterator_traits::iterator_category std::__iterator_category(char* const&)': /.../Files/Includes/../../../arpack++/include/arerror.h:163: multiple definition of ArpackError::code' /.../Files/Includes/../../../arpack++/include/arerror.h:163: first defined here /tmp/ccruWhMn.o: In functionstd::vector >::max_size() const':

for several arpackpp functions when linking all the .o files. As I have read in several threads the problem is that I actually include the instantiation of the functions, which should be normally avoided. Because I don't want to change the whole library I included all classes and functions using arpackpp classes in main.cpp, which is getting quite messy. Is there a workaround to this problem? And why doesn't include guards (#ifndef...#endif) prevent this problem?

dimmigen
  • 3
  • 6
  • could you perhaps elaborate on your errors... "multiple definitions of ..." could mean a number of things? You can do so by editing your question. – silvergasp Jul 29 '16 at 09:30

2 Answers2

1

First of all, include guards do not help at this point as they only prevent multiple inclusions of a header in a "subtree" of your project files' dependency graph. In other words: If you include a header in two totally separated files of the same project, the c++ preprocessor will replace the #include <header.h> twice and independently by the code specified in the header. This is perfectly fine as long as the header only contains declarations.

In your case (and in the case of many other header-only libraries), definitions are provided in the headers as well. So unfortunately (as far as I know), there is no elegant way other than including definition-containing files once in your project. https://github.com/m-reuter/arpackpp/blob/master/include/README explicitly states which files contain definitions.

Some libraries, however, provide preprocessor macros to trigger the inclusion of definitions for the provided header files (e.g. https://github.com/nothings/stb). Maybe arpackpp provides similar mechanisms.

Felix Lauer
  • 201
  • 1
  • 10
  • Thanks for the answer. With arkcpp did you mean arpackpp? Or is this a name of a different cpp library? A quick Google research did not turn up anything related to the topic. – dimmigen Aug 02 '16 at 09:35
  • Sorry, just a typo. Of course I mean arpackpp :). I'll correct the typo in my answer. – Felix Lauer Aug 03 '16 at 07:31
0

In general the easiest way to the work with header only libraries is to extend your code only using headers. Provided you use the correct header guards, this would remove the issue of multiple definitions of your code. If you have a large base of existing code then I would suggest that you rename all your *.cpp files to *.hpp (c++ header files) and then add suitable header guards. Furthermore a convenient way of handling this code of base is to create an additional header file config.hpp and include all your other headers in that file. Then in your main.c it is a simple matter of including the config.hpp file.

e.g.

// Config.hpp ------------------------------------------------=
#include "example.hpp"
#include "example1.hpp"
#include "example2.hpp"
// etc.

// main.cpp --------------------------------------------------=
#include "Config.hpp"

int main() {
  // Your code here.
  return 0;
}

Furthermore if you wanted to continue with your project structure it would be a simple matter of separating all your code into functions that needed to access arpackcpp directly. Then include them all into one *.cpp file, and compile into a *.o and link.

silvergasp
  • 1,517
  • 12
  • 23
  • Thanks for the answer. Changing my files to hpp did help. The only inconvenience i face is that my make file won't recognice any chances within my *.hpp files. – dimmigen Aug 02 '16 at 09:23
  • Your second suggestion didn't work for me. When including the config.hpp I got the same error messages as before. Could you explain to me what the difference is when including only the config.hpp? – dimmigen Aug 02 '16 at 09:33
  • @dimmigen Say you have a number of functions that only use the arpack library. If you put all of those into a `some.c` file `#include "arpack"` only in the `some.c` file and not in the corresponding `some.h` file. This will essentially mean that you are only using the header based functions once. – silvergasp Aug 03 '16 at 12:23