Eyescale/Equalizer

Building on Linux / Mac

Opened this issue · 14 comments

Hello.
I am having trouble building Equalizer on Linux and Mac. I followed the simple commands provided:

git clone --recursive https://github.com/Eyescale/Equalizer.git
mkdir Equalizer/build
cd Equalizer/build
cmake -GNinja -DCLONE_SUBPROJECTS=ON ..
ninja

However, this results in errors. First there are many warnings in the CMake process, but it eventually writes build files, stating: Equalizer [2.1.0-27-g72ad80d] without Deflect hwloc MAGELLAN OpenCV OpenSceneGraph Qt5Core Qt5Gui Qt5Widgets VRPN ZeroEQ ZeroBuf GLEW_MX hwloc.

Then running ninja fails to build Equalizer:

In file included from ../Servus/servus/serializable.cpp:22:
../Servus/servus/uint128_t.h: In function ‘servus::uint128_t servus::operator+(const servus::uint128_t&, const uint64_t&)’:
../Servus/servus/uint128_t.h:304:24: error: implicitly-declared ‘constexpr servus::uint128_t::uint128_t(const servus::uint128_t&)’ is deprecated [-Werror=deprecated-copy]
  304 |     uint128_t result = a;
      |                        ^
../Servus/servus/uint128_t.h:103:16: note: because ‘servus::uint128_t’ has user-provided ‘servus::uint128_t& servus::uint128_t::operator=(const servus::uint128_t&)’
  103 |     uint128_t& operator=(const servus::uint128_t& rhs)
      |

I also just wanted to verify that Equalizer is the right tool for the job I am looking to do. I have an OpenGL 4.1 application (uses geometry and tessellation shaders), and I am wanting to enable distributed rendering to take advantage of multiple GPUs / multiple compute nodes so that my application can render larger data sets. Does Equalizer allow me to use OpenGL 4.1 and my own custom shaders?

eile commented

Hi, these errors are triggered by a new compiler version. I haven't worked on the project for a few years now, so this is expected. In this case, you just need to explicitly define the copy assignment. If you send me a PR I'll merge it.

Yes, Equalizer allows you to write any custom GL code, it's one of the core design principles.

Great, thanks!
Not being super familiar with updates to submodules when forking and sending PRs, I'm running into some issues. If I make edits directly in my forked Equalizer clone then try to commit, it says there are no changes to commit (since the changes are in the submodules). Do you have any recommendations on how I should make the edits?

eile commented

First commit the submodule (go into the subdir, add your user remote, create branch and push to user). Submit a PR on these, I'll merge, and then we can update the submodule references in Equalizer.

I've made patches for 2 of the submodules that were pretty straight forward. However, I'm now running into other issues that seem a bit more complex.

The first is the following with the Luncbox module:

../Lunchbox/lunchbox/fork.cpp:136:32: error: passing argument 3 to restrict-qualified parameter aliases with argument 2 [-Werror=restrict]
  136 |     ::sigaction(SIGCHLD, &act, &act);
      |                          ~~~~  ^~~~
cc1plus: all warnings being treated as errors

I'm not sure how to override the restrict type to allow the same pointer to be passed in for both the second and third arguments.

The second is the following with the Collage module:

../co/dataIStream.h:220:9: error: no matching function for call to ‘co::DataIStream::_readSerializable(co::ObjectVersion&, boost::is_base_of<servus::Serializable, co::ObjectVersion>)’
  220 |         _readSerializable(value, boost::is_base_of<servus::Serializable, T>());
      |         ^~~~~~~~~~~~~~~~~
../co/dataIStream.h:225:10: note: candidate: ‘template<class T> void co::DataIStream::_readSerializable(T&, const true_type&)’
  225 |     void _readSerializable(T& value, const boost::true_type&);
      |          ^~~~~~~~~~~~~~~~~
../co/dataIStream.h:225:10: note:   template argument deduction/substitution failed:
../co/dataIStream.h:220:9: note:   cannot convert ‘boost::is_base_of<servus::Serializable, co::ObjectVersion>()’ (type ‘boost::is_base_of<servus::Serializable, co::ObjectVersion>’) to type ‘const true_type&’ {aka ‘const boost::integral_constant<bool, true>&’}
  220 |         _readSerializable(value, boost::is_base_of<servus::Serializable, T>());
      |         ^~~~~~~~~~~~~~~~~

...

../co/dataOStream.h:241:9: error: no matching function for call to ‘co::DataOStream::_writeSerializable(const co::ObjectVersion&, boost::is_base_of<servus::Serializable, co::ObjectVersion>)’
  241 |         _writeSerializable(value, boost::is_base_of<servus::Serializable, T>());
      |         ^~~~~~~~~~~~~~~~~~
../co/dataOStream.h:246:10: note: candidate: ‘template<class T> void co::DataOStream::_writeSerializable(const T&, const true_type&)’
  246 |     void _writeSerializable(const T& value, const boost::true_type&);
      |          ^~~~~~~~~~~~~~~~~~
../co/dataOStream.h:246:10: note:   template argument deduction/substitution failed:
../co/dataOStream.h:241:9: note:   cannot convert ‘boost::is_base_of<servus::Serializable, co::ObjectVersion>()’ (type ‘boost::is_base_of<servus::Serializable, co::ObjectVersion>’) to type ‘const true_type&’ {aka ‘const boost::integral_constant<bool, true>&’}
  241 |         _writeSerializable(value, boost::is_base_of<servus::Serializable, T>());
      |         ^~~~~~~~~~~~~~~~~~

Again, I'm not quite sure how to handle this error (seems to be a data type mismatch).

I see that the error in Lunchbox has actually already been addressed in its 'master' branch, so Equalizer / Collage would just have to update their references to a later commit for the submodule.

I think the same goes for the Pression submodule - no problems on 'master' but some errors when compiling as part of Equalizer / Collage.

The error in Collage seems to stem from the following in co/dataOStream.h:

/** Write a non-plain data item. */
template <class T>
void _write(const T& value, const boost::false_type&)
{   
    _writeSerializable(value, boost::is_base_of<servus::Serializable, T>());
}

But _writeSerializable() only has a definition for boost::is_base_of evaluating to a true_type. So what is the intended outcome when boost::is_base_of evaluates to false_type?

I made a pull request for Collage - adding an empty function for when boost::is_base_of evaluates to false_type. This enables successful compilation, but please check and ensure this is the intended effect of the code.

Hello.
It's been a bit since I've heard anything. I just wanted to recap what I've done and check to see if there is anything else that needs to be done before merging the PRs into the submodules and updating the references for Equalizer?

To fix compiler errors:

  • Accept PR for Servus
  • Accept PR for vmmlib
  • Accept PR for Collage
  • Update reference to Lunchbox to latest 'master' (fix already implemented, but Equalizer references an older commit)
  • Update reference to Pression to latest 'master' (fix already implemented, but Equalizer references an older commit)

Hi. I'm also trying to build Equalizer (on Fedora 32), and I've got the same errors about _writeSerializable() and _readSerializable().
It was first caught when building Collage, and I added some operator>> and operator<< on ObjectVersion and uint128_t, because I thought that they were missing.
But I now got a lot of such build errors when building Equalizer. And so I wonder if adding the missing operator<< and operator>> is the intended fix... (or possibily inherit from servus::Serializable and add the missing _fromBinary and _toBinary).
So, perhaps your empty function is the right way ?

Additional question: how was that whole whole stuff able to build in 2019 ???

Hi. I'm also trying to build Equalizer (on Fedora 32), and I've got the same errors about _writeSerializable() and _readSerializable(). It was first caught when building Collage, and I added some operator>> and operator<< on ObjectVersion and uint128_t, because I thought that they were missing. But I now got a lot of such build errors when building Equalizer. And so I wonder if adding the missing operator<< and operator>> is the intended fix... (or possibily inherit from servus::Serializable and add the missing _fromBinary and _toBinary). So, perhaps your empty function is the right way ?

Additional question: how was that whole whole stuff able to build in 2019 ???

I also use vs2019, which is the same as your compilation error. How do you solve it?

Woh, it was 2 years ago...

I just had a look to the workdir where I tried to build Equalizer in 2020. I see several changes. Most of them is adding a copy constructor to 'trivially copyable' types (used by read/writeSerializable(), IIRC).

There are binaries in the build/ directory, so I guess that the compilation was a success, but I do not remember if it was running as expected. I reinstalled Fedora since then, and so some system libraries are now missing to run Equalizer.

I'll try to have a look next week.

Sorry for the delay.

I tried to build Equalizer on my Fedora 36 with my previous patches, and I confirm that all the libs and the main Equalizer project build without errors, and that eqPly runs with a 2-windows configuration as well as with a 2-nodes configuration.

The main issue is about making some types being trivially copyable, so that the SFINAE definitions of _readSerializable() and _writeSerializable() succeed in finding the right implementation. I guess that they were some changes on the way the compilers define trivially copyable types...

I'm currently pushing the needed patches on some forks, and I'll let you know the build recipe during the beginning of the next week.

The error in Collage seems to stem from the following in co/dataOStream.h:

/** Write a non-plain data item. */
template <class T>
void _write(const T& value, const boost::false_type&)
{   
    _writeSerializable(value, boost::is_base_of<servus::Serializable, T>());
}

But _writeSerializable() only has a definition for boost::is_base_of evaluating to a true_type. So what is the intended outcome when boost::is_base_of evaluates to false_type?

For the record, in dataOStream.h, we have:

    template <class T>
    DataOStream& operator<<(const T& value)
    {
        _write(value, boost::has_trivial_copy<T>());
        return *this;
    }

we then have 2 specialization of _write():

    /** Write a plain data item. */
    template <class T>
    void _write(const T& value, const boost::true_type&)
    {
        _write(&value, sizeof(value));
    }

    /** Write a non-plain data item. */
    template <class T>
    void _write(const T& value, const boost::false_type&)
    {
        _writeSerializable(value, boost::is_base_of<servus::Serializable, T>());
    }

The first one is called when T is trivially copyable (a simple copy is made), the second one when T is not trivially copyable.
The second specialization of _write() checks if T is derived from servus::Serializable(), but we only have one spezialisation of _writeSerializable():

    template <class T>
    void _writeSerializable(const T& value, const boost::true_type&);

This, if T is not trivially copyable AND does not derive from servus::Serializable, then it fails to compile.
Given that it was compiling some years ago, my guess was that some 'simple' types are no more considered has trivially copyable...

Yes, you are right. In the wins, I use Visual Studuio 2013 to compile Equalizer without any problems, But when I using Visual Stuido 2019, the error reported is exactly the same as what you said.