VTK项目报告“未定义的引用”错误

问题描述 投票:0回答:1

我想在Centos7.9-2009上运行一个简单的VTK8.1.2演示来测试我的项目的VTK包。这是演示:

#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>

int main() {
    auto sphereSource = vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetRadius(5.0);

    auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(sphereSource->GetOutputPort());

    auto actor = vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    auto renderer = vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground(0.1, 0.2, 0.4);

    auto renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);

    auto interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);

    renderWindow->Render();
    interactor->Start();

    return 0;
}

这是 CMakeLists:

cmake_minimum_required(VERSION 3.22)
project(test)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -gdwarf-4")

find_package(VTK REQUIRED PATHS)

add_executable(test main.cpp)

target_link_libraries(test PRIVATE ${VTK_LIBRARIES})
target_include_directories(test PRIVATE ${VTK_INCLUDE_DIRS})

当我用默认的GCC4.8.5制作VTK包时。演示运行顺利。

cmake .. -DCMAKE_BUILD_TYPE=Release

但是当我尝试用GCC11.2编译VTK包时。程序在构建时报告了很多“未定义的引用”错误。

cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/local/gcc11.2/bin/gcc -DCMAKE_CXX_COMPILER=/usr/local/gcc11.2/bin/g++

整条消息超过 4000 行,但几乎都是一样的(“xxx.so.1:对 xxx 的未定义引用”),所以我只将其中的一部分粘贴到这里:

CMakeFiles/test.dir/main.cpp.o:main.cpp:(.text.unlikely+0x38): more 
undefined references to 
`vtkSmartPointerBase::~vtkSmartPointerBase()' follow
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkSmartPointer.h:155: undefined reference to 
`vtkSphereSource::New()'
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkSmartPointer.h:207: undefined reference to 
`vtkSmartPointerBase::vtkSmartPointerBase(vtkObjectBase*, vtkSmartPointerBase::NoReference const&)'
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkSmartPointer.h:155: undefined reference to 
`vtkPolyDataMapper::New()'
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkSmartPointer.h:207: undefined reference to 
`vtkSmartPointerBase::vtkSmartPointerBase(vtkObjectBase*, vtkSmartPointerBase::NoReference const&)'
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkAlgorithm.h:455: undefined reference to 
`vtkAlgorithm::GetOutputPort(int)'
/home/Code/VTK/VTK-8.1.2/installation/include/vtk-8.1/vtkSmartPointer.h:155: undefined reference to 
`vtkActor::New()'

唯一的变化是使用 GCC11.2 来制作 VTK,而不是 4.8.5。

我检查了Clion工具链的环境PATH和设置,我确信它与我用来制作VTK的GCC11.2相同。

我的项目需要GCC11.2,所以我不能回去使用4.8.5。 有人可以帮我吗?

c++ cmake linker-errors vtk undefined-reference
1个回答
0
投票

有两个问题:

  1. VTK 8.9以下,需要在调用

    include(${VTK_USE_FILE})
    后立即调用
    find_package(VTK REQUIRED)

  2. 我在 CentOS 7 上遇到过类似的未定义引用问题,这是通过显式列出正在使用的每个 VTK 组件来解决的。

因此,

CMakeLists.txt
应该是:

find_package(VTK REQUIRED COMPONENT
  vtkCommonCore
  # try listing more components here
)
include(${VTK_USE_FILE})

所有可用的 VTK 组件都记录在官方网站上。此外,可以使用VTK的源代码文件路径来识别VTK类和VTK组件之间的关系。例如,

vtkSmartPointerBase
是由
Common/Core/vtkSmartPointerBase.cxx
实现的,因此它属于组件
vtkCommonCore
。请注意,某些高级组件已经包含其低级组件,因此当您有一长串未定义的引用时,请根据需要添加尽可能多的组件。当构建工作时,尝试删除它们以缩短列表。

查看

${VTK_LIBRARIES}
的内容,看到VTK找到的组件,很有见地。

message(STATUS "VTK wants to link: ${VTK_LIBRARIES}")

最后,请注意,组件名称中的

include(${VTK_USE_FILE})
调用和
vtk
后缀在 VTK 8.9 中已被弃用。为了避免弃用警告,类似于:

find_package(VTK REQUIRED)

if (${VTK_VERSION} VERSION_GREATER "9")
    find_package(VTK REQUIRED COMPONENTS CommonCore IOXML InteractionWidgets NO_MODULE)
else()
    find_package(VTK REQUIRED COMPONENTS vtkCommonCore vtkIOXML vtkInteractionWidgets NO_MODULE)
    include(${VTK_USE_FILE})
endif()

您可能应该检查的唯一另一件事是 VTK 二进制文件是否已使用与您的项目相同的 GCC 版本进行编译...

我无法在本地重现您的问题,因此无法保证。但我希望您的问题与我的问题足够相似,因此可以使用相同的解决方案来解决。祝你好运!

© www.soinside.com 2019 - 2024. All rights reserved.