Link C++ library into cmake project

Hello everyone,

I created an MVC in a python notebook and then I want to translate it to C++.
In order to do that, I followed the building instructions and I successfully compiled simpeITK. I am using CLion as an IDE.

I included the headers and I linked some static libraries but, I am still getting undefined references. Please, see below my CMake file.

cmake_minimum_required(VERSION 3.17)
project(untitled1)

set(CMAKE_CXX_STANDARD 20)
include_directories( /home/kasco/SimpleITK-build/include/SimpleITK-2.1 )
add_executable(untitled1 main.cpp test.cpp)
target_link_libraries (untitled1
        /home/kasco/SimpleITK-build/lib/libSimpleITKIO-2.1.a
        /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a
        /home/kasco/SimpleITK-build/lib/libSimpleITKBasicFilters0-2.1.a
        /home/kasco/SimpleITK-build/lib/libSimpleITKBasicFilters1-2.1.a)

I also tried including all the .a files but it still throwing errors.

/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o): in function `_GLOBAL__sub_I_sitkProcessObject.cxx':
sitkProcessObject.cxx:(.text.startup+0x31): undefined reference to `itk::AnyEvent::~AnyEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0x4b): undefined reference to `itk::AbortEvent::~AbortEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0x65): undefined reference to `itk::DeleteEvent::~DeleteEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0x7f): undefined reference to `itk::EndEvent::~EndEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0x99): undefined reference to `itk::IterationEvent::~IterationEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0xb3): undefined reference to `itk::ProgressEvent::~ProgressEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0xcd): undefined reference to `itk::StartEvent::~StartEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0xe7): undefined reference to `itk::UserEvent::~UserEvent()'
/usr/bin/ld: sitkProcessObject.cxx:(.text.startup+0x101): undefined reference to `itk::MultiResolutionIterationEvent::~MultiResolutionIterationEvent()'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x10): undefined reference to `typeinfo for itk::Command'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x40): undefined reference to `itk::LightObject::Delete()'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x50): undefined reference to `itk::Object::Register() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x58): undefined reference to `itk::Object::UnRegister() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x68): undefined reference to `itk::Object::SetReferenceCount(int)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x80): undefined reference to `itk::Object::PrintSelf(std::ostream&, itk::Indent) const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x88): undefined reference to `itk::LightObject::PrintHeader(std::ostream&, itk::Indent) const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x90): undefined reference to `itk::LightObject::PrintTrailer(std::ostream&, itk::Indent) const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0x98): undefined reference to `itk::LightObject::InternalClone() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xa0): undefined reference to `itk::Object::DebugOn() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xa8): undefined reference to `itk::Object::DebugOff() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xb0): undefined reference to `itk::Object::GetMTime() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xb8): undefined reference to `itk::Object::GetTimeStamp() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xc0): undefined reference to `itk::Object::Modified() const'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel.ro+0xd8): undefined reference to `itk::Object::SetTimeStamp(itk::TimeStamp const&)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x0): undefined reference to `vtable for itk::MultiResolutionIterationEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x8): undefined reference to `vtable for itk::UserEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x10): undefined reference to `vtable for itk::StartEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x18): undefined reference to `vtable for itk::ProgressEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x20): undefined reference to `vtable for itk::IterationEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x28): undefined reference to `vtable for itk::EndEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x30): undefined reference to `vtable for itk::DeleteEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x38): undefined reference to `vtable for itk::AbortEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkProcessObject.cxx.o):(.data.rel+0x40): undefined reference to `vtable for itk::AnyEvent'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkExceptionObject.cxx.o): in function `itk::simple::GenericException::GenericException(itk::simple::GenericException const&)':
sitkExceptionObject.cxx:(.text+0x1b4): undefined reference to `itk::ExceptionObject::ExceptionObject(itk::ExceptionObject const&)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkExceptionObject.cxx.o): in function `itk::simple::GenericException::GenericException(char const*, unsigned int)':
sitkExceptionObject.cxx:(.text+0x226): undefined reference to `itk::ExceptionObject::ExceptionObject(char const*, unsigned int, char const*, char const*)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkExceptionObject.cxx.o): in function `itk::simple::GenericException::GenericException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int)':
sitkExceptionObject.cxx:(.text+0x357): undefined reference to `itk::ExceptionObject::ExceptionObject(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkExceptionObject.cxx.o): in function `itk::simple::GenericException::GenericException(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
sitkExceptionObject.cxx:(.text+0x56a): undefined reference to `itk::ExceptionObject::ExceptionObject(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, unsigned int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkObjectOwnedBase.cxx.o): in function `itk::simple::ObjectOwnedBase::SetOwnedByObjects(bool)':
sitkObjectOwnedBase.cxx:(.text+0x4e5): undefined reference to `itk::OutputWindowDisplayWarningText(char const*)'
/usr/bin/ld: /home/kasco/SimpleITK-build/lib/libSimpleITKCommon-2.1.a(sitkObjectOwnedBase.cxx.o): in function `itk::simple::ObjectOwnedBase::ExecuteCallbacks()':
sitkObjectOwnedBase.cxx:(.text+0x9e8): undefined reference to `itk::OutputWindowDisplayWarningText(char const*)'
collect2: error: ld returned 1 exit status
make[3]: *** [CMakeFiles/untitled1.dir/build.make:167: untitled1] Error 1
make[2]: *** [CMakeFiles/Makefile2:96: CMakeFiles/untitled1.dir/all] Error 2
make[1]: *** [CMakeFiles/Makefile2:103: CMakeFiles/untitled1.dir/rule] Error 2
make: *** [Makefile:138: untitled1] Error 2

I intend to embed the IO and the registration libraries into my software. I want to link the minimum libraries as possible.

Am I missing something in the CMake file?

Thanks

Yes. You need to use CMake’s find_package for SimpleITK. Something like the following:

find_package(SimpleITK REQUIRED)

add_executable ( SimpleGaussianFunctional SimpleGaussianFunctional.cxx )
target_link_libraries ( SimpleGaussianFunctional ${SimpleITK_LIBRARIES} )

The proper include paths come as part of the interface for the SimpleITK libraries.

2 Likes

Hi @blowekamp,

Thanks for your swift reply :slight_smile:

Your suggestion worked like a charm for me. Additionally, I also tried to include the simpleITK library on a project using the Visual Studio Community (Windows 10) but, I got the same errors. I went to the project properties and included the lib folder path and the include folder path like I normally do to import a external static lib.

What am I missing to properly include the simpleITK library on Visual Studio Community?

Thanks

Using CMake to configure a project is the support way to use the library.

The manual configuration for Visual Studio for SimpleITK and ITK is not documented and is unsupported. You would need to build a VS project with CMake, and then manual copy the necessary configuration fields over. In the future, changes or updates to SimpleITK, ITK, or other dependencies would not get propagated and would have to be manually updated.

1 Like

Okay… I got it :slight_smile: thanks very much @blowekamp .

I just noticed that I also need to integrate the ITK library alongside the simpleITK.

I need the ITK library to make an interface with openCV in my application. To do so, I need the itk::OpenCVImageBridge from itkOpenCVImageBridge.h.

Including the header “itkImage.h” is ok but, importing the header “itkOpenCVImageBridge.h”) fails.

fatal error: itkOpenCVImageBridge.h: No such file or directory

My Cmake looks like this now:

cmake_minimum_required(VERSION 3.17)
project(imageregistrationapi)

set(CMAKE_CXX_STANDARD 20)

set(ITK_DIR SimpleITK-build/ITK-build)
find_package(SimpleITK REQUIRED)
find_package(ITK REQUIRED)
message(STATUS "ITK_LIBRARIES: ${ITK_LIBRARIES}")
message(STATUS "SimpleITK_LIBRARIES: ${SimpleITK_LIBRARIES}")
include(${ITK_USE_FILE})
include_directories( SimpleITK-build/include/SimpleITK-2.1 )
add_executable(imageregistrationapi main.cpp ImageRegister.cpp ImageRegister.h)
target_link_libraries ( imageregistrationapi ${SimpleITK_LIBRARIES} ${ITK_LIBRARIES} )

I am probably missing something again on the Cmake file.

Did you enable the “Module_ITKVideoBridgeOpenCV” module when ITK was built?

2 Likes

Thanks @blowekamp! I wasn’t enabling this on the CMake. Problem fixed :wink:

1 Like