c-koi/gmic-qt

Cannot build gmic-qt 3.2.0 with cmake

Closed this issue · 15 comments

Hello :)

We've been trying to bump gmic-lib from 3.1.6 to gmic-lib 3.2.0 in NixOS (a linux distribution).

The build sadly fails on the FilterSyncRunner file:

FAILED: CMakeFiles/gmic_qt.dir/src/FilterSyncRunner.cpp.o 
/nix/store/iiq295j1z4q1sxmdbrl2j8ma3l5ns4wr-gcc-wrapper-11.3.0/bin/g++ -DGMIC_HOST=standalone -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT -DQT_WIDGETS_LIB -D_IS_LINUX_ -D_IS_UNIX_ -Dcimg_appname=\"gmic\" -Dcimg_display=1 -Dcimg_use_abort -Dcimg_use_cpp11=1 -Dcimg_use_curl -Dcimg_use_fftw3 -Dcimg_use_openmp -Dcimg_use_png -Dcimg_use_vt100 -Dcimg_use_zlib -Dgmic_community -Dgmic_gui -Dgmic_is_parallel -I/build/source/build -I/build/source -I/build/source/build/gmic_qt_autogen/include -I/build/source/src -isystem /nix/store/03svkk8l8dfcbabfl9637krwdkhqvyna-qtbase-5.15.8-dev/include/QtCore -isystem /nix/store/03svkk8l8dfcbabfl9637krwdkhqvyna-qtbase-5.15.8-dev/./mkspecs/linux-g++ -isystem /nix/store/03svkk8l8dfcbabfl9637krwdkhqvyna-qtbase-5.15.8-dev/include/QtWidgets -isystem /nix/store/03svkk8l8dfcbabfl9637krwdkhqvyna-qtbase-5.15.8-dev/include/QtGui -isystem /nix/store/03svkk8l8dfcbabfl9637krwdkhqvyna-qtbase-5.15.8-dev/include/QtNetwork -DNDEBUG -Ofast -fopenmp -fPIC -std=gnu++11 -MD -MT CMakeFiles/gmic_qt.dir/src/FilterSyncRunner.cpp.o -MF CMakeFiles/gmic_qt.dir/src/FilterSyncRunner.cpp.o.d -o CMakeFiles/gmic_qt.dir/src/FilterSyncRunner.cpp.o -c /build/source/src/FilterSyncRunner.cpp
/build/source/src/FilterSyncRunner.cpp: In member function 'void GmicQt::FilterSyncRunner::swapImages(gmic_library::gmic_list<float>&)':
/build/source/src/FilterSyncRunner.cpp:77:12: error: 'struct gmic_library::gmic_list<float>' has no member named 'swap'
   77 |   _images->swap(images);
      |            ^~~~
/build/source/src/FilterSyncRunner.cpp: In member function 'void GmicQt::FilterSyncRunner::run()':
/build/source/src/FilterSyncRunner.cpp:160:69: error: invalid user-defined conversion from 'gmic_library::gmic_image<char>' to 'char' [-fpermissive]
  160 |     gmicInstance.set_variable("_persistent", PersistentMemory::image());
      |                                              ~~~~~~~~~~~~~~~~~~~~~~~^~
In file included from /build/source/src/FilterSyncRunner.cpp:35:
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:118:5: note: candidate is: 'gmic_library::gmic_image<T>::operator T*() [with T = char]' (near match)
  118 |     operator T*() {
      |     ^~~~~~~~
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:118:5: note:   no known conversion from 'char*' to 'char'
In file included from /build/source/src/FilterSyncRunner.cpp:35:
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:389:63: note:   initializing argument 2 of 'const char* gmic::set_variable(const char*, char, const char*, double, const unsigned int*)'
  389 |   const char *set_variable(const char *const name, const char operation='=', const char *const value=0,
      |                                                    ~~~~~~~~~~~^~~~~~~~~~~~~
/build/source/src/FilterSyncRunner.cpp:165:46: error: 'struct gmic_library::gmic_image<char>' has no member named 'move_to'
  165 |     gmicInstance.get_variable("_persistent").move_to(*_persistentMemoryOuptut);
      |                                              ^~~~~~~
/build/source/src/FilterSyncRunner.cpp:167:20: error: no matching function for call to 'gmic_library::gmic_list<float>::assign()'
  167 |     _images->assign();
      |     ~~~~~~~~~~~~~~~^~
In file included from /build/source/src/FilterSyncRunner.cpp:35:
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:151:19: note: candidate: 'gmic_library::gmic_list<T>& gmic_library::gmic_list<T>::assign(unsigned int) [with T = float]'
  151 |     gmic_list<T>& assign(const unsigned int n);
      |                   ^~~~~~
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:151:19: note:   candidate expects 1 argument, 0 provided
/build/source/src/FilterSyncRunner.cpp:168:24: error: no matching function for call to 'gmic_library::gmic_list<char>::assign()'
  168 |     _imageNames->assign();
      |     ~~~~~~~~~~~~~~~~~~~^~
In file included from /build/source/src/FilterSyncRunner.cpp:35:
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:151:19: note: candidate: 'gmic_library::gmic_list<T>& gmic_library::gmic_list<T>::assign(unsigned int) [with T = char]'
  151 |     gmic_list<T>& assign(const unsigned int n);
      |                   ^~~~~~
/nix/store/hdjr32qnmgqmysllvq6v5ds09mhvz5ja-gmic-3.2.0-dev/include/gmic.h:151:19: note:   candidate expects 1 argument, 0 provided
ninja: build stopped: subcommand failed.

It seems like the gmic library changed its gmic_list API recently.

Yes the API has changed, but the code of the G'MIC-Qt plug-in as well.
Did you also update the code of the plug-in ?

Yes, we bumped to the v.3.2.0 tag.

Looking at the source code, the culprit seems to be this swap() call here: https://github.com/c-koi/gmic-qt/blob/master/src/FilterSyncRunner.cpp#L77

There's no such function anymore in the gmic 3.2.0 codebase: https://github.com/GreycLab/gmic/blob/master/src/gmic.h#L137

That being said, I can't find the swap operation either on the 3.1.9 codebase https://github.com/GreycLab/gmic/blob/v.218/src/gmic.h#L105 . I assume I'm missing something here 🤔

Here, swap() refers to CImgList<>::swap(), which are methods of the CImg Library (defined in file CImg.h). These methods exist in the library since a long time
(see: http://cimg.eu/reference/structcimg__library_1_1CImgList.html#a6c12806e432683b06fbc8919daa0a3d7).

Could it be be that CImg has not been updated from your side?

Nix packs the latest stable version 3.2.0 (freshly updated last week from 3.1.6).

EDIT: Sorry, I misread the log without realizing hydra was still building the old gmic-qt package, I removed my comment regarding hydra's error message.

^ please ignore the above message. This is the pre-bump build log. I'll paste the new one once the recently merged NixOS/nixpkgs#211600 (containing the gmic-qt update) hits our CI.

[edit]: np Tobias :)


Ack for the CImgList reference. I'll try digging more into that soon. The issue probably comes from our end.

Here's the full build log: https://pastebin.aquilenet.fr/?0aa186b0b11956fc#DwxVLPoTs4Ae2SyFqnxJ9BLc6eLGDNAavCy4QcqdJpiH

We're building the package with these dependencies in scope:

bash-5.2-p15
pkg-config-wrapper-0.29.2
zlib-1.2.13
fftw-double-3.3.10
ninja-1.11.1
cmake-3.24.3
cimg-3.2.0
openexr-2.5.8
libjpeg-turbo-2.1.4
libpng-apng-1.6.39
libtiff-4.5.0
graphicsmagick-1.3.39
gmic-3.2.0
qtbase-5.15.8
qttools-5.15.8
curl-7.87.0
opencv-3.4.18

Ah I see you are using cmake.
I'm not sure this is working anymore. I use qmake to build the plug-in.
I'll try to see if I get the same errors.

OK, this doesn't work for me, for another reason:

Building for target host application: gimp
CMake Error at CMakeLists.txt:145 (find_package):
  Could not find a package configuration file provided by "Gmic" with any of
  the following names:

    GmicConfig.cmake
    gmic-config.cmake

  Add the installation prefix of "Gmic" to CMAKE_PREFIX_PATH or set
  "Gmic_DIR" to a directory containing one of the above files.  If "Gmic"
  provides a separate development package or SDK, be sure it has been
  installed.


-- Configuring incomplete, errors occurred!

I have no clue how to make it work, I must say :)

Ack. No worries :)

I'll migrate this to qmake tonight. Thanks for the help!

Isn't qmake deprecated in qt6?

Yes, that’s one of the reasons I switched the Nixpkgs build to CMake in the first place. In addition to qmake having even worse developer experience than CMake.

So we need to appeal to @dtschump to do the qmake -> cmake move then.

@peterhoeg I am completely unable to do this, I have never been interested in cmake (and I honestly don't have the time to spend on it). Maybe @c-koi could help, he knows cmake surely a lot more than me.
Or anyone else interested, of course ;)

The issue is that GMic will now substitute CImg definitions with its own broken stubs when gmic_core preprocessor variable is not defined.

That is the case when building gmic-qt with -DENABLE_SYSTEM_GMIC=on since d7cb84a.

Unfortunately, it is hard to tell why that decision was made on gmic side due to horrible engineering practices. git blame just points to https://github.com/GreycLab/gmic/blame/c3b2009a44bbf5afa993e4674624564c801bbbec/src/gmic.h#L81.

Unfortunately, it is hard to tell why that decision was made on gmic side due to horrible engineering practices.

Honestly, this is a very awkward way to approach the discussion.
This decision was made for certain reasons, which you may find wrong (but I doubt you have all the cards in your hands to properly analyze the situation as a whole). In any case, it is a decision that has been made and it will probably not be reversed.
Your opinion on this issue is therefors irrelevant. I'd prefer we try to move forward rather than questioning what has already been done, and which works for other contexts than the compilation of the plug-in.

I, for one, will not participate in this kind of discussion if it goes in this direction.

Sorry, I could have probably phrased that better. I have only mentioned the practice of destroying git repository history because it is harmful to trying to debug issues like this. I was hoping that by bringing out this problem we could not repeat it in the future.


I tried digging deeper starting with v.3.1.0 tag but it looks like the #ifndef gmic_core was already there in 3.1.0. Since 3.1.5 compiled successfully for us, the issue is probably something different.