OptimoJoe / Optizelle

Optizelle [op-tuh-zel] is an open source software library designed to solve general purpose nonlinear optimization problems.
www.optimojoe.com/products/optizelle
63 stars 13 forks source link

Build failure: redefinition of structs #47

Closed Dapid closed 8 years ago

Dapid commented 8 years ago

I am getting the following errors when compiling. I am using release mode, and I have manually included the --std=c++11 flag. The OS is Fedora 22, GCC 5.1.1, (c)cmake 3.3.2:

Scanning dependencies of target equality_constrained
[ 41%] Building CXX object src/unit/restart/CMakeFiles/equality_constrained.dir/equality_constrained.cpp.o
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:21:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,XX> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:38:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,YY> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:55:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,ZZ> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
src/unit/restart/CMakeFiles/constrained.dir/build.make:62: recipe for target 'src/unit/restart/CMakeFiles/constrained.dir/constrained.cpp.o' failed
make[2]: *** [src/unit/restart/CMakeFiles/constrained.dir/constrained.cpp.o] Error 1
CMakeFiles/Makefile2:392: recipe for target 'src/unit/restart/CMakeFiles/constrained.dir/all' failed
make[1]: *** [src/unit/restart/CMakeFiles/constrained.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:21:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,XX> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:38:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,YY> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:7:0:
/home/david/gits/Optizelle/src/unit/restart/restart.h:55:16: error: redefinition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,ZZ> {
                ^
In file included from /home/david/gits/Optizelle/src/unit/restart/equality_constrained.cpp:4:0:
/home/david/gits/Optizelle/src/cpp/optizelle/vspaces.h:184:16: error: previous definition of ‘struct Optizelle::json::Serialization<Real, Optizelle::Rm>’
         struct Serialization <Real,Rm> {
                ^
[ 42%] Linking CXX executable simple_equality
[ 42%] Built target simple_equality
[ 44%] Linking CXX executable simple_constrained
src/unit/restart/CMakeFiles/equality_constrained.dir/build.make:62: recipe for target 'src/unit/restart/CMakeFiles/equality_constrained.dir/equality_constrained.cpp.o' failed
make[2]: *** [src/unit/restart/CMakeFiles/equality_constrained.dir/equality_constrained.cpp.o] Error 1
CMakeFiles/Makefile2:429: recipe for target 'src/unit/restart/CMakeFiles/equality_constrained.dir/all' failed
make[1]: *** [src/unit/restart/CMakeFiles/equality_constrained.dir/all] Error 2
[ 44%] Built target simple_constrained
[ 45%] Linking CXX executable sdpa_sparse_format
[ 45%] Built target sdpa_sparse_format
Makefile:160: recipe for target 'all' failed
make: *** [all] Error 2
josyoun commented 8 years ago

Quick question: Are you compiling develop or master? Short answer is that I believe this has been fixed on develop and I can port that to master. Long answer, this arises from a bug with alias templates in GCC that was resolved between GCC 4.8 and GCC 4.9 and above. Consider the program:

#include <iostream>
#include <typeinfo>
#include <cstdlib>

template <typename U,template <typename> class T>
struct foo{
    static void print() {
        std::cerr << "Undefined for type: "<< typeid(T <U>).name()
            << std::endl;
        exit(EXIT_FAILURE);
    }
};

// Create a dummy templated class
template <typename T>
struct bar {};

// Create a template alias based on this class
template <typename T> using bar_alias = bar <T>;

template <typename T>
struct foo <T,bar> {
    static void print() {
        std::cout << "This is bar" << std::endl;
    }
};

int main() {
    foo <double,bar>::print();
    foo <double,bar_alias>::print();
}

In GCC 4.9, this produces:

$ ./alias_template
This is bar
This is bar

In GCC 4.8 this produces:

$ ./alias_template
This is bar
Undefined for type: 3barIdE

Anyway, the result from GCC 4.9 and later is the correct result. Prior to my use of newer versions of GCC, I didn't know this was the case and I used an old work around that was incorrect, which I'm pretty sure is what the error above is. Technically, that code I attached is something slightly different, but I believe it to be a manifestation of the same bug.

I do have a fix and I can back port it into master. That being said, my preference would be to just fix up a couple of existing documentation issues and then do a new release, which would also fix things. In the immediate future:

By the way, develop is now using C++14, so your CMake options will need to change slightly. In terms of when there's a new release, I do intend to do so soon. I could probably do that this week.

Dapid commented 8 years ago

I was compiling master, sorry I forgot to specify, and thank you for your detailed explanation. You know you are doing fancy stuff when you start hitting compiler bugs... Indeed, disabling the unit tests works on master.

On a side note: in both master and develop I had to manually set the C++ flavour flag, shouldn't they be there by default? I have the environment variable $CCFLAGS set to my architecture, and Cmake is picking it up, which is nice, but I wonder if it is overriding the setting.

I am not planning to use it in the immediate future, so I can wait for the new release. Also, I can test it in my boxes to make sure it runs smoothly before the release.

josyoun commented 8 years ago

Sounds great. I'm grinding through some code at the moment, but I'll send a message by in the next few days.

josyoun commented 8 years ago

Good call on the autodetect C++ versions. I updated the CMake scripts to auto set the C++14 compiler flags in commit 37bf35d230222236e653bece7f23b64d70c2c549. It looks like this came out with CMake 3.1 and I updated all of the required versions accordingly.

I'll wait to close this issue out when everything is pushed to master.

josyoun commented 8 years ago

I'm going to close this out since the issue was fixed and open a new ticket with the list of things I need to do before pushing everything to master. Mostly, I'm trying to stay organized.