【问题标题】:Compiling a program and liniking all libraries and include paths编译程序并链接所有库和包含路径
【发布时间】:2026-01-25 20:45:02
【问题描述】:

我正在尝试编译一个 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 使用 TKSTEPTopoDS_Shape 使用 TKBRepStlAPI_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(将coutendl改为std::coutstd::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

【问题讨论】:

  • 查看有关如何使用 MinGW 安装的说明(TDM、MSYS2,我不知道) - 编译器没有找到自己的 C++ 头文件。
  • 我没听懂你在说什么。这些说明在哪里?
  • 请先告诉你系统上 gcc 编译器的来源是什么——在 Windows 的情况下有很多选项。
  • 老实说我不知道​​。我有多年的 gcc,也许是通过 Cygwin。然后,我尝试构建 OCE,所以我安装了 MinGW,MSYS2.. 所以我不知道该说什么。你的意思是我输入 gcc --version 吗?这是你要问的吗?
  • Cygwin、MinGW、MinGW-w64、MSYS2(包括 MinGW-w64)——这些是在 Windows 平台上使用 GCC 构建项目的非常不同的选项——所以是的,你应该告诉你实际使用的是什么(有版本)以获得一些帮助,MinGW 已经过时并且不能用于构建现代项目(MinGW-w64 是更新的),Cygwin 非常具体。

标签: gcc compilation include-path lib opencascade


【解决方案1】:

我是否必须将它们全部链接到编译器才能编译程序?

OCCT 是一个框架,它由分组为模块的工具包(库)组成。可以链接到整个 OCCT 框架(所有库),但在这种情况下,未使用的库将成为无用的负担。相反,最好只链接和传送应用程序实际使用的工具包,以及它们的嵌套依赖项。

链接和编译是构建过程的两个不同步骤,因此:

  • 您需要通过-I 参数将头文件的位置传递给编译器,这通常是一个包含所有公共头文件的inc 文件夹OCCT 课程。这在自定义构建中可能有所不同。
  • 您需要通过 -L 参数将导入库的位置传递给 linker,这通常是 win64/vc14/lib 用于发布和 win64/vc14/libd 表示库的调试版本,其中 win64 表示平台(64 位 Windows),vc14 表示编译器(Visual Studio 2015) ;如果是 MinGW,它将是 gcc 而不是 vc14
  • 您需要通过 -l 参数将导入库的名称传递给 linker(或者,它可能是每个库的完整路径以跳过 -L 参数)。
  • 类似的文件夹 win64/vc14/binwin64/vc14/bind 包含启动应用程序所需的 DLL 库文件。必要的 DLL 应复制到应用程序文件夹或放入 Windows 上的 %PATH% 环境变量中。

用于构建 OCCT 的编译器和配置应与构建应用程序本身的配置相匹配。例如。您不能使用 Visual Studio 构建的 OCCT 来使用 MinGW 构建应用程序 - 它们使用 C++ 内部的二进制不兼容格式。

注意:在 Windows 平台上,链接到库而不解析应用程序中的任何符号是无操作的 - 额外的 DLL 不会被放入启动应用程序所需的应用程序依赖项中。这在其他平台(Linux / UNIX)上是不同的,链接库即使没有实际使用也会被依赖。

如果不研究 OCCT 框架结构,确定您的应用程序需要哪些库可能会很棘手。以下提示可能会有所帮助:

  1. 确定您需要的库的第一步是检查项目使用的 OCCT 类的位置。这可以通过两种方式完成:

    • 在生成的Doxygen documentation 中查找类(如 STEPControl_Reader)并从路径中清除 Toolkit 到类,如“Module DataExchange -> Toolkit TKSTEP -> Package STEPControl”。 TKSTEP 是您需要链接的库名称(例如 -lTKSTEP)。
    • 在 OCCT 源代码中,在 src 文件夹中对所有名为 PACKAGES 的文件进行 grep,以获取所需的包名(可以从类名 STEPControl_Reader轻松分解) > -> STEPControl 是一个包)。在这种特殊情况下,您将在文件 src/TKSTEP/PACKAGES 中找到包 STEPControl,文件夹名称为 TKSTEP将是您需要链接到的工具包/库名称。
  2. 下一步,您需要确定应用程序隐式使用的其他 OCCT 工具包。例如,大多数 OCCT 类继承了 TKernel 库中定义的 Standard_Transient 类。尝试构建您的应用程序并检查链接器错误 - 它们应该包含来自 OCCT 框架的类方法的路径。推断类名 -> 包名并重复第一步以确定工具包名称。

  3. 作为第 2 步的替代方法,查看 Doxygen documentationsrc/ToolkitName/EXTENLIB 文件中已推导出的 OCCT 工具包的依赖关系图。

  4. 最后,您可能需要链接和复制 OCCT 本身使用的第 3 方库,如 FreeType、FreeImage 等。该列表将取决于使用的 OCCT 组件和在构建 OCCT 本身时启用的第 3 方(其中大部分是可选的)。

【讨论】:

  • 谢谢。我尝试了编译,但失败了。我无法理解错误消息。