Link error on declaring metrics in two different classes

Hi everyone,

I’m stuck on a compilation issue using visual studio (2017 or 2019). I need to implement two classes: one using GradientDifferenceImageToImageMetric and another one using MeanSquaresImageToImageMetricv4. But, when I am trying to build my application I get the following error:

1>main.cpp
1>ITKOptimizers-5.0.lib(ITKOptimizers-5.0.dll) : error LNK2005: "protected: virtual void __cdecl itk::CostFunctionTemplate<double>::PrintSelf(class std::basic_ostream<char,struct std::char_traits<char> > &,class itk::Indent)const " (?PrintSelf?$CostFunctionTemplateNitkMEBAXAEAV?$basic_ostreamDU?$char_traitsDstdstdVIndent2Z) déjà défini(e) dans itkTransformInitialization.obj
1>\ClinicalValidation\build\Debug\ImageRegistration.exe : fatal error LNK1169: one or more multiply defined symbols found

Here the minimal code to reproduce this issue:

//itkTransformInitialization.h
#ifndef itkTransformInitialization_h
#define itkTransformInitialization_h

#include <itkMeanSquaresImageToImageMetricv4.h>

class itkTransformInitialization
{
public:
itkTransformInitialization()
  {
  using InternalPixelType = float;
  using InternalImageType = itk::Image< InternalPixelType, 2 >;
  using MetricType = itk::MeanSquaresImageToImageMetricv4<InternalImageType, InternalImageType >;
  MetricType::Pointer metric = MetricType::New();
}
  ~itkTransformInitialization(){}
};
#endif
//itkTransformOptimization.h
#ifndef itkTransformOptimization_h
#define itkTransformOptimization_h

#include <itkGradientDifferenceImageToImageMetric.h>

class itkTransformOptimization
{
public:
  itkTransformOptimization()
 {
  using InternalPixelType = float;
  using InternalImageType = itk::Image< InternalPixelType, 3 >;
  using OptimMetricType =  itk::GradientDifferenceImageToImageMetric< InternalImageType, InternalImageType >;
  OptimMetricType::Pointer metric = OptimMetricType::New();
 }
  ~itkTransformOptimization(){}
};
#endif
//main.cpp
#include "itkTransformInitialization.h"
#include "itkTransformOptimization.h"

#include <iostream>

int main( int argc, char** argv )
{
  std::cerr << "Include success" << std::endl;
  return 1;
}

Does anyone have an idea of how to fix it? Thx.

How does you CMakeLists.txt look like?

My CmakeLists is very simple:

cmake_minimum_required(VERSION 2.8)
 
PROJECT(ImageRegistration)

find_package(ITK REQUIRED)
include(${ITK_USE_FILE})

set( ImageRegistration_SRCS
  main.cpp
  itkTransformOptimization.cxx
  itkTransformInitialization.cxx
  )
 
add_executable(ImageRegistration ${ImageRegistration_SRCS})
target_link_libraries(ImageRegistration ${ITK_LIBRARIES})

The problem comes from both itkTransformOptimization.cxx and itkTransformInitialization.cxx instantiating CostFunctionTemplate, thus leading to duplicate definition error. If you put all these definitions into one file (main.cpp) the error should go away.