Reputation: 43
I want to run a simple VTK8.1.2 demo on Centos7.9-2009 to test the VTK package for my project. Here is the demo:
#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;
}
Here is the 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})
When I made the VTK package with the default GCC4.8.5. Demo ran smoothly.
cmake .. -DCMAKE_BUILD_TYPE=Release
But when I tried to compile the VTK package with GCC11.2. The program reported a lot of "undefined reference" errors while building.
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_C_COMPILER=/usr/local/gcc11.2/bin/gcc -DCMAKE_CXX_COMPILER=/usr/local/gcc11.2/bin/g++
The whole message is over 4000 lines but all are pretty much the same("xxx.so.1: undefined reference to xxx"), so I just paste part of it in here:
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()'
The only change is using GCC11.2 to make VTK instead of 4.8.5.
I checked the environment PATH and settings of Clion's toolchain, I'm sure it's the same GCC11.2 that I used to make VTK.
My project requires GCC11.2 so I can't go back to use 4.8.5. Can someone help me please?
Upvotes: 3
Views: 112
Reputation: 43
I finally solved this problem by downgrading GCC version to 7.5. I had to make a compromise because the project needs to progress. This can't really be considered a solution because the real reason for why higher version GCC doesn't work still remains unresolved.
Upvotes: 0
Reputation: 3637
There are two problems:
Below VTK 8.9, it's necessary to call include(${VTK_USE_FILE})
immediately after calling find_package(VTK REQUIRED)
.
I've encountered similar undefined reference problems on CentOS 7, which was solved by explicitly listing each VTK component in use.
Thus, the CMakeLists.txt
should be:
find_package(VTK REQUIRED COMPONENT
vtkCommonCore
# try listing more components here
)
include(${VTK_USE_FILE})
All available VTK components are documented on the official website. Furthermore, the relationship between a VTK class and a VTK component can be identified using VTK's source code file path. For example, vtkSmartPointerBase
is implemented by Common/Core/vtkSmartPointerBase.cxx
, so it belongs to the component vtkCommonCore
. Note that some high-level components already include its low-level components, so when you have a long list of undefined references, add as many components as necessary. When the build works, try removing them to shorten the list.
It's insightful to check the content of ${VTK_LIBRARIES}
to see the components found by VTK.
message(STATUS "VTK wants to link: ${VTK_LIBRARIES}")
Finally, note that both the call include(${VTK_USE_FILE})
and the vtk
suffix in component names have been deprecated in VTK 8.9. To avoid deprecation warnings, something similar to:
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()
The only other thing you should probably check is whether VTK binaries have been compiled using the same GCC version as your project...
I was unable to reproduce your problem locally, so there's no guarantee. But I hope that your problem is similar enough to my problem, and thus can be solved using the same solution. Good luck!
Upvotes: 0