Компиляция программы и сопоставление всех библиотек и путей включения

Я пытаюсь скомпилировать программу OpenCascade.

Вот ссылка на программу: https://www.opencascade.com/content/unable-convert-step-file-stl-file (это ошибочная программа, но это начало)

Я должен связать все библиотеки, пути к библиотекам и включить пути к gcc (флаги -L, -l, -I). У меня установлен OpenCascade, и вот папка установки.

введите здесь описание изображения

Большинство из этих папок, которые вы видите, имеют папки bin, include и lib.

Должен ли я связать их все с компилятором, чтобы программа скомпилировалась?

Это единственные включения, которые использует программа:

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

РЕДАКТИРОВАТЬ: «TopoDS_Shape.hxx» и «StAPI_Writer.hxx» расположены по этому пути C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc.

'STEPControl_Reader.hxx' также существует в том же каталоге, я не знаю, почему первоначальный автор поместил его в свой локальный каталог.

РЕДАКТИРОВАТЬ 2: я также прочитал эту ветку форума: https://forum.freecadweb.org/viewtopic.php?t=15993 но мне это совсем не помогло. Он использует Linux, и структура каталогов include и lib не одинакова.

РЕДАКТИРОВАНИЕ ПОСЛЕ ПОПЫТКИ КОМПИЛЯЦИИ:

  • Я поставил win64\vc14\bin в %PATH%

  • Я понял часть -I, так как все три заголовочных файла находятся в одном каталоге. (C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\inc)

  • Для расположения импортных библиотек я использовал C:\OpenCASCADE-7.4.0-vc14-64\opencascade-7.4.0\win64\vc14\lib. Думаю, мне не нужно переименовывать его в gcc\lib, верно? Я не собирал OCCT сам, я скачал бинарник с их сайта. Имя двоичного файла было opencascade-7.4.0-vc14-64. Я так понимаю я в порядке? Хотя я использую gcc.

  • Я выяснил название библиотек для трех заголовочных файлов из онлайн-документа. STEPControl_Reader использует TKSTEP, TopoDS_Shape использует TKBRep, StlAPI_Writer использует TKSTL.

Поэтому я дал эту команду:

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

Вот что я получил:

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.

КОМПИЛЯЦИОННЫЙ ЭКСПЕРИМЕНТ 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)

КОМПИЛЯЦИОННЫЙ ЭКСПЕРИМЕНТ 3 (после замены cout и endl на std::cout и 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

person user1584421    schedule 18.08.2020    source источник
comment
Проверьте инструкции по использованию вашей установки MinGW (TDM, MSYS2, я не знаю) - компилятор не нашел собственные заголовки C++.   -  person gkv311    schedule 19.08.2020
comment
Я не понял, что ты сказал. Где такие инструкции?   -  person user1584421    schedule 19.08.2020
comment
Скажите, пожалуйста, в первую очередь, откуда взялся компилятор gcc в вашей системе - в случае с Windows вариантов много.   -  person gkv311    schedule 19.08.2020
comment
Честно говоря, я не знаю. У меня был gcc в течение многих лет, может быть, через Cygwin. Затем я попытался собрать OCE, поэтому я установил MinGW, MSYS2.. Так что я не знаю, что сказать. Вы имеете в виду, что я набираю gcc --version? Это то, о чем вы спрашиваете?   -  person user1584421    schedule 19.08.2020
comment
Cygwin, MinGW, MinGW-w64, MSYS2 (включая MinGW-w64) — это очень разные варианты сборки проектов с использованием GCC на платформе Windows — так что да, вы должны указать, что вы на самом деле используете (с версией), чтобы получить помощь, MinGW устарел и не может использоваться для сборки современных проектов (MinGW-w64 более поздний), Cygwin очень специфичен.   -  person gkv311    schedule 19.08.2020
comment
И вам придется начать с создания самого OCCT с использованием MinGW по выбору, прежде чем создавать свой проект. dev.opencascade.org/index.php?q=node/1152   -  person gkv311    schedule 19.08.2020
comment
Теперь я вижу, что в вашей команде вы говорите gcc ... testCode.c. Вы не можете построить код C++ с помощью компилятора C - переименуйте исходный файл в .cpp или .cxx и вместо этого используйте компилятор g++.   -  person gkv311    schedule 19.08.2020
comment
Я переименовал в cpp и использовал g++. Это результат g++ --version. g++ (x86_64-posix-seh-rev0, создан проектом MinGW-W64) 8.1.0. Почему я должен создавать OCCT самостоятельно? Я попытался запустить простую программу step2stl, и мне сказали собрать ее самостоятельно с github. После ошибок, которые, вероятно, не исправить, потому что OCE плохо поддерживается, я решил скачать OCCT и попробовать эту программу там или сделать ее самостоятельно. Теперь мне снова нужно строить OCCT?   -  person user1584421    schedule 19.08.2020
comment
Я отредактировал вопрос с результатом g++.   -  person user1584421    schedule 19.08.2020
comment
Компилятор предлагает вместо cout/endl использовать в коде приложения пару std::cout/std::endl.   -  person gkv311    schedule 19.08.2020
comment
Спасибо. Я выложил новые результаты. Теперь у меня что-то работает. Потому что теперь у меня есть только отсутствующие ссылки. Это означает, что мне не хватает файлов библиотеки.   -  person user1584421    schedule 19.08.2020
comment
Почему я должен создавать OCCT самостоятельно? . Потому что нет общедоступных сборок MinGW OCCT. В цитатах упоминается сборка Visual Studio 2015 (vc14), которая не может быть связана/запущена с приложением GCC из-за различий в реализации C++ в разделяемых/статических библиотеках.   -  person gkv311    schedule 19.08.2020
comment
CMake создает эти файлы проекта, не сохраняя структуру проектов OCCT, и полагается на файлы Makefile. В качестве предварительного условия для построения OCCT необходимо построить его зависимости. Удачи с этим. Могу ли я использовать Visual Studio для компиляции программы? Существуют ли общие рекомендации, как это сделать?   -  person user1584421    schedule 20.08.2020
comment
Я не знаю, можно ли построить конкретную программу с помощью Visual Studio или нет. Если проект небольшой, то, скорее всего, его портирование на VS не потребует особых усилий, если вы уже знакомы с VS. Что касается создания самого OCCT, существует общее руководство по использованию CMake и даже готовых сторонних библиотек DLL для MinGW: dev.opencascade.org/doc/overview/html/, opencascade.com/content/3rd-party-components   -  person gkv311    schedule 20.08.2020
comment
Если создание конкретного проекта STEP to STL не является вашей реальной целью, вы можете рассмотреть возможность выполнения той же задачи в готовых приложениях, таких как DRAWEXE или CAD Assistant.   -  person gkv311    schedule 20.08.2020
comment
Моя цель состоит в том, чтобы иметь программу STEP to STL, чтобы ее можно было вызывать либо из компилятора, либо из vid nodejs через ffi.   -  person user1584421    schedule 20.08.2020


Ответы (1)


Должен ли я связать их все с компилятором, чтобы программа скомпилировалась?

OCCT — это фреймворк, состоящий из наборов инструментов (библиотек), сгруппированных в модули. Возможна ссылка на весь OCCT framework (все библиотеки), но в этом случае неиспользуемые библиотеки станут бесполезной обузой. Вместо этого предпочтительно связывать и отправлять только те наборы инструментов, которые действительно используются приложением, а также их вложенные зависимости.

Связывание и компиляция — это два разных этапа процесса сборки, так что:

  • Вам необходимо передать расположение файлов заголовков в компилятор с помощью аргумента -I, которым обычно является папка inc, содержащая все файлы заголовков общедоступных классов OCCT. Это может отличаться в пользовательских сборках.
  • Вам необходимо передать расположение библиотек импорта в компоновщик с помощью аргумента -L, который обычно равен win64/vc14/lib для версии и win64. /vc14/libd для отладочной версии библиотек, где win64 указывает платформу (64-разрядная версия Windows), а vc14 указывает компилятор (Visual Studio 2015); это будет gcc вместо vc14 в случае MinGW.
  • Вам необходимо передать имена библиотек импорта в компоновщик с помощью аргумента -l (в качестве альтернативы, это может быть полный путь к каждой библиотеке, чтобы пропустить -L аргумент).
  • Аналогичные папки win64/vc14/bin и win64/vc14/bind содержат файлы библиотеки DLL, необходимые для запуска приложения. Необходимые библиотеки DLL следует либо скопировать в папку приложения, либо поместить в переменную среды %PATH% в Windows.

Компилятор и конфигурация, используемые для сборки OCCT, должны соответствовать конфигурации для сборки самого приложения. Например. вы не можете использовать OCCT, созданный Visual Studio, для создания приложения с использованием MinGW - они используют двоичные несовместимые форматы внутренних компонентов C++.

Примечание: на платформе Windows связывание с библиотекой, не разрешающей какие-либо символы в приложении, недопустимо — дополнительные библиотеки DLL не будут помещаться в зависимости приложения, необходимые для запуска приложения. Это отличается на других платформах (Linux / UNIX), где связанная библиотека будет помещена в зависимость, даже если она фактически не используется.

Выяснение того, какие библиотеки необходимы вашему приложению, может оказаться сложной задачей без изучения структуры инфраструктуры OCCT. Следующие советы могут быть полезными:

  1. Первым шагом для определения необходимых библиотек является проверка местонахождения классов OCCT, используемых в вашем проекте. Это можно сделать двумя способами:

    • 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
    • В исходном коде OCCT выполните grep все файлы с именем PACKAGES в папке src для получения требуемого имени пакета (которое можно легко разложить по имени класса STEPControl_Reader -› STEPControl — это пакет). В этом конкретном случае вы найдете пакет STEPControl в файле src/TKSTEP/PACKAGES и имя папки TKSTEP. будет именем набора инструментов/библиотеки, на которое вам нужно установить ссылку.
  2. На следующем шаге вам потребуется определить другие наборы инструментов OCCT, которые приложение использует неявно. Например, большинство классов OCCT наследуют класс Standard_Transient, определенный в библиотеке TKernel. Попробуйте собрать свое приложение и проверьте ошибки компоновщика — они должны содержать пути к методам класса из фреймворка OCCT. Выведите имена классов -> Имена пакетов и повторите первый шаг, чтобы определить имя набора инструментов.

  3. В качестве альтернативы шагу 2 взгляните на граф зависимостей уже выведенных наборов инструментов OCCT в Документация Doxygen или в файле src/ToolkitName/EXTERNLIB. Зависимости TKSTEP в OCCT Doxygen

  4. Наконец, вам может понадобиться связать и скопировать сторонние библиотеки, используемые самим OCCT, такие как FreeType, FreeImage и другие. Список будет зависеть от используемых компонентов OCCT и сторонних разработчиков, включенных при создании самого OCCT (большинство из них являются необязательными).

person gkv311    schedule 18.08.2020
comment
Спасибо. Пробовал компилировать, но не получилось. Я не могу понять сообщение об ошибке. - person user1584421; 19.08.2020