G'MIC: lookup symbol err on openSUSE darktable master build

darktable: symbol lookup error:
/usr/lib64/darktable/plugins/liblut3d.so: undefined symbol: _ZN12cimg_library8CImgListIfE6assignEj

ldd /usr/lib64/darktable/plugins/liblut3d.so |grep libgmic
libgmic.so.1 => /usr/lib64/libgmic.so.1 (0x00007f7f6169f000)

objdump -T /usr/lib64/libgmic.so.1 | grep _ZN12cimg_library8CImgListIfE6assignEj

blank output

gladiac:
so, liblut3d uses a symbol which is not provided by libgmic.so.1
it is strange that that the symbol isn’t there
ag cimg src/iop/lut3dgmic.cpp
doesn’t show anything, so I have no idea where this is coming from

@David_Tschumperle

Looks like:

gmic_list<T>& assign(const unsigned int n);

is not exported by libgmic.so.1

gmic 2.8.1

That is strange.
The example file use_libgmic.cpp does use this (line.74), and it seems to work here, on Ubuntu 19.10.

Here, I have:

$ nm /usr/lib/libgmic.so.1 | grep _ZN12cimg_library8CImgListIfE6assignEj
00000000000f7b30 W _ZN12cimg_library8CImgListIfE6assignEj
0000000000361350 W _ZN12cimg_library8CImgListIfE6assignEjjjjj

darktable master openSUSE Tumbleweed
build git359.7a75382d0-2301.1 also fails with:
darktable: symbol lookup error: /usr/lib64/darktable/plugins/liblut3d.so: undefined symbol: _ZN12cimg_library8CImgListIfE6assignEj

nm /usr/lib64/libgmic.so.1 |grep _ZN12cimg_library8CImgListIfE6assignEj
nm: /usr/lib64/libgmic.so.1: no symbols

I don’t know why you don’t have these symbols. I’ve never run OpenSUSE, so I can’t really tell what is going on. Maybe the compiler performs some automatic optimizations (inlining) and thinks the method doesn’t require to be exported.
Maybe we can add some syntax to the G’MIC code to explicitly force it to be exported in the shared library.

This : https://gcc.gnu.org/wiki/Visibility
Probably is a part of the solution.

If I download use_libgmic.cpp and try to compile it, I get:

g++ use_libgmic.cpp -o use_libgmic -lgmic
/tmp/ccUAkm1b.o:use_libgmic.cpp:function main: error: undefined reference to 'cimg_library::CImgList<float>::assign(unsigned int)'
/tmp/ccUAkm1b.o:use_libgmic.cpp:function main: error: undefined reference to 'cimg_library::CImg<float>::assign(unsigned int, unsigned int, unsigned int, unsigned int)'
/tmp/ccUAkm1b.o:use_libgmic.cpp:function main: error: undefined reference to 'cimg_library::CImgList<float>::assign(unsigned int)'
collect2: error: ld returned 1 exit status

So, yes there is clearly an issue to fix.
I guess we have to add some compiler directives beside the definition of assign() to export it explicitly. I suppose the compiler has transformed it to an inline function, or something similar.
Anyway, as I can’t reproduce the same behavior right now, it’s kind of annoying.

cmake -DENABLE_DYNAMIC_LINKING=ON -DBUILD_LIB_STATIC=OFF is used to build libgmic …

Ok, if I do:

cmake -DENABLE_DYNAMIC_LINKING=ON -DBUILD_LIB_STATIC=OFF and then install it. I can link use_libgmic.cpp.

So this could be link time optimizations or something like that.

That’s it!

-flto=auto removes those symbols!

3 Likes

maybe instead of removing LTO we could fix the exporting of symbols or so? maybe it needs fat LTO as we do for static libraries to make it work properly?

Adding -ffat-lto-objects doesn’t fix it …

@David_Tschumperle

I got an explanation from Richie:

cimg_library::CImgList<float>::assign(unsigned int)

is a template without an explicit initialization. This means there is no guarantee that there will be an instantiation.

So the the gmic header should have an extern template instantiation.

I’m not a C++ developer so I don’t really have an idea what that means. If you can tell me how to do it, I could test it.

I think I’ve an idea on how to do this. Will try today and let you know when it’s ready for testing.

This patch may work: https://github.com/dtschump/gmic/commit/bb3d0c59b5a819f1ef47ae6732f72e038c4522e3

I’m currently building new pre-release source package with version number 2.8.3, should be available in 30 mn or so.

When gmic is executed for generating the manpage, it fails with:

LD_LIBRARY_PATH=/home/asn/workspace/package/obs/home:gladiac:branches:graphics/gmic/gmic-2.8.2/obj /home/asn/workspace/package/obs/home:gladiac:branches:graphics/gmic/gmic-2.8.2/obj/gmic
/home/asn/workspace/package/obs/home:gladiac:branches:graphics/gmic/gmic-2.8.2/obj/gmic: symbol lookup error: /home/asn/workspace/package/obs/home:gladiac:branches:graphics/gmic/gmic-2.8.2/obj/gmic: undefined symbol: _ZN4gmic13search_sortedIN12cimg_library8CImgListIcEEEEbPKcRKT_jRj

I’ve applied the patch to 2.8.2 …

Would not be also a good idea to make libgmic able to provide its version to cmake as other libraries ?