35p
35p

Reputation: 43

VTK project report "undefined reference" errors

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

Answers (2)

35p
35p

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:

  1. Below VTK 8.9, it's necessary to call include(${VTK_USE_FILE}) immediately after calling find_package(VTK REQUIRED).

  2. 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

Related Questions