user1584421
user1584421

Reputation: 3863

Compiling a program and linking all libraries and include paths

I am trying to compile an OpenCascade program.

Here is the link to the program: https://www.opencascade.com/content/unable-convert-step-file-stl-file (It's an erroneous program but it's a start)

I am supposed to link all libraries, library paths and include paths to gcc (-L, -l, -I flags). I have OpenCascade installed and here is the folder of the installation.

enter image description here

Most of these folders you see have a bin, include and lib folder.

Do i have to link all of them to the compiler, for the program to compile?

These are the only includes that the program uses:

#include "STEPControl_Reader.hxx"
#include <TopoDS_Shape.hxx>
#include <StlAPI_Writer.hxx>

EDIT: 'TopoDS_Shape.hxx' and 'StAPI_Writer.hxx' are located in this path C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc.

'STEPControl_Reader.hxx' as well exists in the same directory, i don't know why Original Author had it in his local directory.

EDIT 2: I also read this forum thread: https://forum.freecadweb.org/viewtopic.php?t=15993 but it did not help me at all. He is using linux and the structure of the include and lib directories is not the same.

EDIT AFTER COMPILATION ATTEMPT:

I therefore issued this command:

gcc -I C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc -L C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\win64\vc14\lib -l TKSTEP -l TKBRep -l TKSTL testCode.c

This is what i got:

In file included from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Integer.hxx:18,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Address.hxx:18,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d.hxx:21,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/STEPCon
trol_Reader.hxx:20,
                 from testCode.c:2:
C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standard_Std.hxx:20:10: fatal
 error: type_traits: No such file or directory
 #include <type_traits>
          ^~~~~~~~~~~~~
compilation terminated.

COMPILATION EXPERIMENT 2:

C:\Users\User1\Desktop\OPENCAS>g++ -I C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7
.4.0\inc -L C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\win64\vc14\lib -l TKS
TEP -l TKBRep -l TKSTL testCode.cpp
testCode.cpp: In function 'Standard_Integer main(int, char**)':
testCode.cpp:26:3: error: 'cout' was not declared in this scope
   cout << argv[2] << endl;
   ^~~~
testCode.cpp:26:3: note: suggested alternative:
In file included from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Stream.hxx:20,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_OStream.hxx:19,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_ExtCharacter.hxx:28,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_PrimitiveTypes.hxx:27,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Transient.hxx:20,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d.hxx:91,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/STEPCon
trol_Reader.hxx:20,
                 from testCode.cpp:2:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86
_64-w64-mingw32/8.1.0/include/c++/iostream:61:18: note:   'std::cout'
   extern ostream cout;  /// Linked to standard output
                  ^~~~
testCode.cpp:26:22: error: 'endl' was not declared in this scope
   cout << argv[2] << endl;
                      ^~~~
testCode.cpp:26:22: note: suggested alternative:
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-re
v0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Stream.hxx:20,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_OStream.hxx:19,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_ExtCharacter.hxx:28,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_PrimitiveTypes.hxx:27,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d_Transient.hxx:20,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/Standar
d.hxx:91,
                 from C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc/STEPCon
trol_Reader.hxx:20,
                 from testCode.cpp:2:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86
_64-w64-mingw32/8.1.0/include/c++/ostream:590:5: note:   'std::endl'
     endl(basic_ostream<_CharT, _Traits>& __os)

COMPILATION EXPERIMENT 3 (after changing cout and endl to std::cout and std::endl)

  C:\Users\User1\Desktop\OPENCAS>g++ -I C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7
    .4.0\inc -L C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\win64\vc14\lib -l TKS
    TEP -l TKBRep -l TKSTL testCode.cpp
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x27): undefine
    d reference to `STEPControl_Reader::STEPControl_Reader()'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x3a): undefine
    d reference to `XSControl_Reader::ReadFile(char const*)'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x49): undefine
    d reference to `STEPControl_Reader::NbRootsForTransfer()'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x58): undefine
    d reference to `XSControl_Reader::TransferRoots()'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x6b): undefine
    d reference to `XSControl_Reader::OneShape() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0x77): undefine
    d reference to `StlAPI_Writer::StlAPI_Writer()'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text+0xa0): undefine
    d reference to `StlAPI_Writer::Write(TopoDS_Shape const&, char const*)'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN24NCollectio
    n_BaseSequencedlEPv[_ZN24NCollection_BaseSequencedlEPv]+0x11): undefined referen
    ce to `Standard::Free(void*)'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI25NCollection_BaseAllocatorE8EndScopeEv[_ZN11opencascade6handleI25NColl
    ection_BaseAllocatorE8EndScopeEv]+0x23): undefined reference to `Standard_Transi
    ent::DecrementRefCounter() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI30TopLoc_SListNodeOfItemLocationE8EndScopeEv[_ZN11opencascade6handleI30
    TopLoc_SListNodeOfItemLocationE8EndScopeEv]+0x23): undefined reference to `Stand
    ard_Transient::DecrementRefCounter() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI13TopoDS_TShapeE8EndScopeEv[_ZN11opencascade6handleI13TopoDS_TShapeE8En
    dScopeEv]+0x23): undefined reference to `Standard_Transient::DecrementRefCounter
    () const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN20NCollectio
    n_SequenceIN11opencascade6handleI18Standard_TransientEEE5ClearERKNS1_I25NCollect
    ion_BaseAllocatorEE[_ZN20NCollection_SequenceIN11opencascade6handleI18Standard_T
    ransientEEE5ClearERKNS1_I25NCollection_BaseAllocatorEE]+0x1f): undefined referen
    ce to `NCollection_BaseSequence::ClearSeq(void (*)(NCollection_SeqNode*, opencas
    cade::handle<NCollection_BaseAllocator>&))'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI21XSControl_WorkSessionE8EndScopeEv[_ZN11opencascade6handleI21XSControl
    _WorkSessionE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::Dec
    rementRefCounter() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN20NCollectio
    n_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI25NCollection_BaseAlloc
    atorEE[_ZN20NCollection_SequenceI12TopoDS_ShapeE5ClearERKN11opencascade6handleI2
    5NCollection_BaseAllocatorEE]+0x1f): undefined reference to `NCollection_BaseSeq
    uence::ClearSeq(void (*)(NCollection_SeqNode*, opencascade::handle<NCollection_B
    aseAllocator>&))'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI25NCollection_BaseAllocatorE10BeginScopeEv[_ZN11opencascade6handleI25NC
    ollection_BaseAllocatorE10BeginScopeEv]+0x23): undefined reference to `Standard_
    Transient::IncrementRefCounter() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.text$_ZN11opencascad
    e6handleI18Standard_TransientE8EndScopeEv[_ZN11opencascade6handleI18Standard_Tra
    nsientE8EndScopeEv]+0x23): undefined reference to `Standard_Transient::Decrement
    RefCounter() const'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.rdata$.refptr._ZTV18
    STEPControl_Reader[.refptr._ZTV18STEPControl_Reader]+0x0): undefined reference t
    o `vtable for STEPControl_Reader'
    C:\Users\User1\AppData\Local\Temp\ccCCS9c3.o:testCode.cpp:(.rdata$.refptr._ZTV16
    XSControl_Reader[.refptr._ZTV16XSControl_Reader]+0x0): undefined reference to `v
    table for XSControl_Reader'
    collect2.exe: error: ld returned 1 exit status

Upvotes: 1

Views: 1887

Answers (1)

gkv311
gkv311

Reputation: 2982

Do i have to link all of them to the compiler, for the program to compile?

OCCT is a framework, it consists of Toolkits (libraries) grouped into Modules. It is possible linking to the whole OCCT framework (all libraries), but in this case unused libraries will become a useless burden. Instead, it is preferred linking to and shipping only Toolkits that application actually use, as well as their nested dependencies.

Linkage and compilation are two different steps of building process, so that:

  • You need passing location of header files to compiler via -I argument, which is usually an inc folder containing all header files of public OCCT classes. This might be different in custom builds.
  • You need passing location of import libraries to linker via -L argument, which is usually win64/vc14/lib for Release and win64/vc14/libd for Debug version of libraries, where win64 indicates platform (64-bit Windows) and vc14 indicates compiler (Visual Studio 2015); it will be gcc instead of vc14 in case of MinGW.
  • You need passing names of import libraries to linker via -l argument (alternatively, it might be a full path to each library to skip -L argument).
  • Similar folders win64/vc14/bin and win64/vc14/bind contain DLL library files necessary for starting application. Necessary DLLs should be either copied to application folder or put into %PATH% environment variable on Windows.

Compiler and configuration used for building OCCT should match configuration for building application itself. E.g. you cannot use OCCT built by Visual Studio for building application using MinGW - they use binary incompatible formats of C++ internals.

Note: on Windows platform linking to a library not resolving any symbols in application is a no-op - extra DLL will not be put into application dependencies necessary to start application. This is different on other platforms (Linux / UNIX), where linked library will be put into dependency even if it is not actually used.

Figuring out which libraries are necessary to your application might be tricky without investigation of OCCT framework structure. The following tips might be helpful:

  1. The first step to determine the libraries you need is checking residence of OCCT classes used by your project. This can be done in two ways:

    • Find classes (like STEPControl_Reader) within generated Doxygen documentation and weed out Toolkit from path to class like "Module DataExchange -> Toolkit TKSTEP -> Package STEPControl". TKSTEP is the library name you will need to link (e.g. -lTKSTEP). STEPControl_Reader class in OCCT Doxygen
    • Within OCCT source code, grep all files named PACKAGES within src folder for required package name (which can be easily decomposed from class name STEPControl_Reader -> STEPControl is a package). In this particular case you will find package STEPControl in file src/TKSTEP/PACKAGES, and the folder name TKSTEP will be a Toolkit / library name you need linking to.
  2. At next step you will need determining other OCCT Toolkits which application uses implicitly. For instance, most OCCT classes inherit Standard_Transient class which is defined in TKernel library. Try building your application and check linker errors - they should contain paths to class methods from OCCT framework. Deduce class names -> Package names and repeat first step to determine Toolkit name.

  3. As a shortcut alternative to step 2, take a look onto dependency graph of already deduced OCCT Toolkits within Doxygen documentation or within src/ToolkitName/EXTERNLIB file. TKSTEP dependencies in OCCT Doxygen

  4. Finally, you might need linking and copying 3rd-party libraries used by OCCT itself like FreeType, FreeImage and others. The list will depend on used OCCT components and 3rd-parties enabled while building OCCT itself (most of them are optional).

Upvotes: 1

Related Questions