我想在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。 有人可以帮我吗?
有两个问题:
VTK 8.9以下,需要在调用
include(${VTK_USE_FILE})
后立即调用find_package(VTK REQUIRED)
。
我在 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 版本进行编译...
我无法在本地重现您的问题,因此无法保证。但我希望您的问题与我的问题足够相似,因此可以使用相同的解决方案来解决。祝你好运!