[SOLVED] C++ problem when linking on Debian 12 / bookworm, OCC 7.6

Hello,

After trying by several days I just can't understand why my compilation is not working on Debian 12 but it works on Archlinux. If you can help me it will be really appreciated !!

Here is a minimal example of what I' m trying to compile:

#include <iostream>
#include <IFSelect_ReturnStatus.hxx>	// TKXSBase
#include <STEPControl_Reader.hxx>		// TKDESTEP

int main(int argc, char *argv[]) {
	
	STEPControl_Reader step_reader = STEPControl_Reader();
    
    IFSelect_ReturnStatus status = step_reader.ReadFile("/home/cadweb/Documents/CAD-files/PRIVATE/Fouga.stp");

	if (IFSelect_RetDone != status){
		std::cout << "    Error: file not read, status=" << status<< std::endl;
		return 1;
	};
	
	
	return 0;
};

and I' m able to create the object with g++:

g++ -c -I/usr/include/opencascade -L/usr/lib/x86_64-linux-gnu/ -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKDE -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKDESTEP -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel test.cpp test.cpp

(I know that there are much more libraries than needed)

but when I try to create the bin, it fails:

g++ -I/usr/include/opencascade/ -L/usr/lib/x86_64-linux-gnu/ -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKXDESTEP -lTKXDESTEP -lTKSTEP -lTKSTEPBase -lTKSTEPAttr -lTKSTEP209 -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel test.cpp -o test
In file included from /usr/include/opencascade/NCollection_Sequence.hxx:20,
                 from /usr/include/opencascade/TColStd_SequenceOfTransient.hxx:19,
                 from /usr/include/opencascade/XSControl_Reader.hxx:25,
                 from /usr/include/opencascade/STEPControl_Reader.hxx:24,
                 from test.cpp:6:
/usr/include/opencascade/NCollection_StlIterator.hxx:30:15: warning: ‘template<class _Category, class _Tp, class _Distance, class _Pointer, class _Reference> struct std::iterator’ is deprecated [-Wdeprecated-declarations]
   30 |   public std::iterator<Category, ItemType, ptrdiff_t,
      |               ^~~~~~~~
In file included from /usr/include/c++/12/string:45,
                 from /usr/include/c++/12/bits/locale_classes.h:40,
                 from /usr/include/c++/12/bits/ios_base.h:41,
                 from /usr/include/c++/12/ios:42,
                 from /usr/include/c++/12/ostream:38,
                 from /usr/include/c++/12/iostream:39,
                 from test.cpp:3:
/usr/include/c++/12/bits/stl_iterator_base_types.h:127:34: note: declared here
  127 |     struct _GLIBCXX17_DEPRECATED iterator
      |                                  ^~~~~~~~
/usr/bin/ld: /tmp/ccHxsSPs.o: warning: relocation against `_ZTV16XSControl_Reader' in read-only section `.text._ZN16XSControl_ReaderD2Ev[_ZN16XSControl_ReaderD5Ev]'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `main':
test.cpp:(.text+0x24): undefined reference to `STEPControl_Reader::STEPControl_Reader()'
/usr/bin/ld: test.cpp:(.text+0x3d): undefined reference to `XSControl_Reader::ReadFile(char const*)'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `NCollection_BaseSequence::operator delete(void*)':
test.cpp:(.text._ZN24NCollection_BaseSequencedlEPv[_ZN24NCollection_BaseSequencedlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `XSControl_Reader::operator delete(void*)':
test.cpp:(.text._ZN16XSControl_ReaderdlEPv[_ZN16XSControl_ReaderdlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `XSControl_Reader::~XSControl_Reader()':
test.cpp:(.text._ZN16XSControl_ReaderD2Ev[_ZN16XSControl_ReaderD5Ev]+0xf): undefined reference to `vtable for XSControl_Reader'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `STEPControl_Reader::operator delete(void*)':
test.cpp:(.text._ZN18STEPControl_ReaderdlEPv[_ZN18STEPControl_ReaderdlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<NCollection_BaseAllocator>::EndScope()':
test.cpp:(.text._ZN11opencascade6handleI25NCollection_BaseAllocatorE8EndScopeEv[_ZN11opencascade6handleI25NCollection_BaseAllocatorE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<TopLoc_SListNodeOfItemLocation>::EndScope()':
test.cpp:(.text._ZN11opencascade6handleI30TopLoc_SListNodeOfItemLocationE8EndScopeEv[_ZN11opencascade6handleI30TopLoc_SListNodeOfItemLocationE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<TopoDS_TShape>::EndScope()':
test.cpp:(.text._ZN11opencascade6handleI13TopoDS_TShapeE8EndScopeEv[_ZN11opencascade6handleI13TopoDS_TShapeE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `NCollection_Sequence<opencascade::handle<Standard_Transient> >::Clear(opencascade::handle<NCollection_BaseAllocator> const&)':
test.cpp:(.text._ZN20NCollection_SequenceIN11opencascade6handleI18Standard_TransientEEE5ClearERKNS1_I25NCollection_BaseAllocatorEE[_ZN20NCollection_SequenceIN11opencascade6handleI18Standard_TransientEEE5ClearERKNS1_I25NCollection_BaseAllocatorEE]+0x22): undefined reference to `NCollection_BaseSequence::ClearSeq(void (*)(NCollection_SeqNode*, opencascade::handle<NCollection_BaseAllocator>&))'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<XSControl_WorkSession>::EndScope()':
test.cpp:(.text._ZN11opencascade6handleI21XSControl_WorkSessionE8EndScopeEv[_ZN11opencascade6handleI21XSControl_WorkSessionE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `NCollection_Sequence<TopoDS_Shape>::Clear(opencascade::handle<NCollection_BaseAllocator> const&)':
test.cpp:(.text._ZN20NCollection_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI25NCollection_BaseAllocatorEE[_ZN20NCollection_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI25NCollection_BaseAllocatorEE]+0x22): undefined reference to `NCollection_BaseSequence::ClearSeq(void (*)(NCollection_SeqNode*, opencascade::handle<NCollection_BaseAllocator>&))'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<NCollection_BaseAllocator>::BeginScope()':
test.cpp:(.text._ZN11opencascade6handleI25NCollection_BaseAllocatorE10BeginScopeEv[_ZN11opencascade6handleI25NCollection_BaseAllocatorE10BeginScopeEv]+0x23): undefined reference to `Standard_Transient::IncrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `opencascade::handle<Standard_Transient>::EndScope()':
test.cpp:(.text._ZN11opencascade6handleI18Standard_TransientE8EndScopeEv[_ZN11opencascade6handleI18Standard_TransientE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter() const'
/usr/bin/ld: /tmp/ccHxsSPs.o: in function `STEPControl_Reader::~STEPControl_Reader()':
test.cpp:(.text._ZN18STEPControl_ReaderD2Ev[_ZN18STEPControl_ReaderD5Ev]+0xf): undefined reference to `vtable for STEPControl_Reader'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

I just don' t understand why it fails on Debian, I'm able to find the header files, and the library files...

ls -la /usr/include/opencascade/
total 45664
drwxr-xr-x  2 root root 516096 Oct 17 09:48 .
drwxr-xr-x 56 root root   4096 Oct 17 09:47 ..
-rw-r--r--  1 root root   5912 Jul 22  2022 Adaptor2d_Curve2d.hxx
-rw-r--r--  1 root root   5073 Jul 22  2022 Adaptor2d_Line2d.hxx
-rw-r--r--  1 root root   6942 Jul 22  2022 Adaptor2d_OffsetCurve.hxx
-rw-r--r--  1 root root   5931 Jul 22  2022 Adaptor3d_Curve.hxx
-rw-r--r--  1 root root   8053 Jul 22  2022 Adaptor3d_CurveOnSurface.hxx
-rw-r--r--  1 root root   7901 Jul 22  2022 Adaptor3d_HSurfaceTool.hxx
....
ls -la /usr/lib/x86_64-linux-gnu/ | grep STEP
lrwxrwxrwx  1 root root        17 May 23  2023 libTKSTEP209.so -> libTKSTEP209.so.7
lrwxrwxrwx  1 root root        21 May 23  2023 libTKSTEP209.so.7 -> libTKSTEP209.so.7.6.3
-rw-r--r--  1 root root    710832 May 23  2023 libTKSTEP209.so.7.6.3
lrwxrwxrwx  1 root root        18 May 23  2023 libTKSTEPAttr.so -> libTKSTEPAttr.so.7
lrwxrwxrwx  1 root root        22 May 23  2023 libTKSTEPAttr.so.7 -> libTKSTEPAttr.so.7.6.3
-rw-r--r--  1 root root   1898672 May 23  2023 libTKSTEPAttr.so.7.6.3
lrwxrwxrwx  1 root root        18 May 23  2023 libTKSTEPBase.so -> libTKSTEPBase.so.7
lrwxrwxrwx  1 root root        22 May 23  2023 libTKSTEPBase.so.7 -> libTKSTEPBase.so.7.6.3
-rw-r--r--  1 root root   2762928 May 23  2023 libTKSTEPBase.so.7.6.3
lrwxrwxrwx  1 root root        14 May 23  2023 libTKSTEP.so -> libTKSTEP.so.7
lrwxrwxrwx  1 root root        18 May 23  2023 libTKSTEP.so.7 -> libTKSTEP.so.7.6.3
-rw-r--r--  1 root root   3569856 May 23  2023 libTKSTEP.so.7.6.3
lrwxrwxrwx  1 root root        17 May 23  2023 libTKXDESTEP.so -> libTKXDESTEP.so.7
lrwxrwxrwx  1 root root        21 May 23  2023 libTKXDESTEP.so.7 -> libTKXDESTEP.so.7.6.3
-rw-r--r--  1 root root    817328 May 23  2023 libTKXDESTEP.so.7.6.3

Thank you,

Dmitrii Pasukhin's picture

Hello.

It is a OCCT 7.8 but for some reason it used headers for 7.5. Please check the versions.

g++ -c -I/opt/occt751/include/opencascade -L/opt/occt781/lib -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKDE -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKDESTEP -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel test.cpp test.cpp

Do you have the same OCCT on both OS? They are compiled by you or by package?

On Debian there are no any other versions of OCCT? To be honest not clear where is the issue :(

Best regards, Dmitrii.

Rafael SM's picture

Hello @Dmitrii,

Yes, I have multiple versions, but that was a mistake when making the post. I have OCC 7.5.1 in /opt/occt751 and OCC 7.8.1 in /opt/occt781, both compiled by my self and they work okay ( I use them with pythonocc-core).

But since I had too many troubles by trying to compile my binary (the 7.8.1, same as arch), I tried to compile the binary with the one provided by debian (7.6).

When making the post, I had /opt/occt751/lib on my ld path: /etc/ld.so.conf.d/occt.conf so I have just removed them and it seems OK:

ldconfig -v | grep STEP
ldconfig: Can't stat /usr/local/lib/x86_64-linux-gnu: No such file or directory
ldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than once
(from /etc/ld.so.conf.d/x86_64-linux-gnu.conf:4 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
ldconfig: Path `/lib/x86_64-linux-gnu' given more than once
(from <builtin>:0 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
ldconfig: Path `/usr/lib/x86_64-linux-gnu' given more than once
(from <builtin>:0 and /etc/ld.so.conf.d/x86_64-linux-gnu.conf:3)
ldconfig: Path `/usr/lib' given more than once
(from <builtin>:0 and <builtin>:0)
    libTKSTEP209.so.7 -> libTKSTEP209.so.7.6.3
    libTKSTEPBase.so.7 -> libTKSTEPBase.so.7.6.3
    libTKSTEP.so.7 -> libTKSTEP.so.7.6.3
ldconfig: /lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 is the dynamic linker, ignoring

    libTKSTEPAttr.so.7 -> libTKSTEPAttr.so.7.6.3
    libTKXDESTEP.so.7 -> libTKXDESTEP.so.7.6.3

and the command to compile the object was/is:

g++ -c -I/usr/include/opencascade/ -L/usr/lib/x86_64-linux-gnu/ -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKDE -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKXDESTEP -lTKXDESTEP -lTKSTEP -lTKSTEPBase -lTKSTEPAttr -lTKSTEP209 -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel test.cpp

Do you think that the versions are getting mixed up? Maybe I'll create a VM with only one version,

Thank you,

Rafael

gkv311 n's picture

Do you think that the versions are getting mixed up?

When you have multiple local library builds installed into different locations - you have more or less good control over linking with them. But when you also have the same library installed system-wide (e.g. from Debian repository) - the chances to have building environment messed up grow high.

First of all, before OCCT 7.7 (#0032856), the OCCT libraries on Linux have SONAME that includes only major version 7, so that although you see so.7.6.3 files, the actual dependency was so.7.

As consequence, OCCT 7.5.1 and OCCT 7.6.3 available in common LD_LIBRARY_PATH space will DO conflict with each other, and successful running will depend on folders configuration order. That should be less of the problem for OCCT 7.8.1 as it should have SONAME something like .so.7.8 by default (configurable via BUILD_SOVERSION_NUMBERS in CMake).

Note that building process on Linux might look confusing, as you may put -L folder correctly, but still see unrefined reference issues while building application. This is because ld evaluates references of executable (after it actually has been built and linked) through runtime paths like LD_LIBRARY_PATH. Last time I was able to workaround this issue by adding -rpath-link option with the same folder as passed to -L with OCCT libraries. You may find a short description about the difference between -L, -rpath and -rpath-link here.

So the simplest suggestion is to avoid installing libraries system-wide within building environment, but it should be possible to deal with it ;).

Rafael SM's picture

Thank you @gkv311, this will help me a lot in my dev environements where I have multiple OCC versions !

Rafael SM's picture

I finally found the problem... (I'm a noob compiling c++) but it seems that under Debian, the order of the g++ arguments its more important than under arch...

Under Debian, this command will fail:

g++ -I/usr/include/opencascade/ -L/usr/lib/x86_64-linux-gnu/ -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKDE -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKDESTEP -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel test.cpp -o test 
/usr/bin/ld: /tmp/ccgdZdUc.o: warning: relocation against `_ZTV16XSControl_Reader' in read-only section `.text._ZN16XSControl_ReaderD2Ev[_ZN16XSControl_ReaderD5Ev]'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `main':
test.cpp:(.text+0x24): undefined reference to `STEPControl_Reader::STEPControl_Reader()'
/usr/bin/ld: test.cpp:(.text+0x3d): undefined reference to `STEPControl_Reader::ReadFile(char const*)'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `NCollection_BaseSequence::operator delete(void*)':
test.cpp:(.text._ZN24NCollection_BaseSequencedlEPv[_ZN24NCollection_BaseSequencedlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `XSControl_Reader::operator delete(void*)':
test.cpp:(.text._ZN16XSControl_ReaderdlEPv[_ZN16XSControl_ReaderdlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `XSControl_Reader::~XSControl_Reader()':
test.cpp:(.text._ZN16XSControl_ReaderD2Ev[_ZN16XSControl_ReaderD5Ev]+0xf): undefined reference to `vtable for XSControl_Reader'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `STEPControl_Reader::operator delete(void*)':
test.cpp:(.text._ZN18STEPControl_ReaderdlEPv[_ZN18STEPControl_ReaderdlEPv]+0x14): undefined reference to `Standard::Free(void*)'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `STEPControl_Reader::~STEPControl_Reader()':
test.cpp:(.text._ZN18STEPControl_ReaderD2Ev[_ZN18STEPControl_ReaderD5Ev]+0xf): undefined reference to `vtable for STEPControl_Reader'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `NCollection_Sequence<opencascade::handle<Standard_Transient> >::Clear(opencascade::handle<NCollection_BaseAllocator> const&)':
test.cpp:(.text._ZN20NCollection_SequenceIN11opencascade6handleI18Standard_TransientEEE5ClearERKNS1_I25NCollection_BaseAllocatorEE[_ZN20NCollection_SequenceIN11opencascade6handleI18Standard_TransientEEE5ClearERKNS1_I25NCollection_BaseAllocatorEE]+0x22): undefined reference to `NCollection_BaseSequence::ClearSeq(void (*)(NCollection_SeqNode*, opencascade::handle<NCollection_BaseAllocator>&))'
/usr/bin/ld: /tmp/ccgdZdUc.o: in function `NCollection_Sequence<TopoDS_Shape>::Clear(opencascade::handle<NCollection_BaseAllocator> const&)':
test.cpp:(.text._ZN20NCollection_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI25NCollection_BaseAllocatorEE[_ZN20NCollection_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI25NCollection_BaseAllocatorEE]+0x22): undefined reference to `NCollection_BaseSequence::ClearSeq(void (*)(NCollection_SeqNode*, opencascade::handle<NCollection_BaseAllocator>&))'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status

But this will succeed:

g++ test.cpp -o test -I/usr/include/opencascade/ -L/usr/lib/x86_64-linux-gnu/ -lTKBO -lTKHLR -lTKCAF -lTKService -lTKV3d -lTKVCAF -lTKGeomAlgo -lTKXCAF -lTKDE -lTKCDF -lTKGeomBase -lTKShHealing -lTKMesh -lTKG2d -lTKG3d -lTKTopAlgo -lTKDESTEP -lTKLCAF -lTKBRep -lTKMath -lTKXSBase -lTKernel  
Dmitrii Pasukhin's picture

I guess it is just different versions of GCC :) arch maintaining their repo with latest versions. Usually I downloaded or build specific version of compiler manually ;) (clang or GCC)

Great that issue is resolved!

Best regards, Dmitrii.