Hi Everyone,
I hope this is the right place to have this discussion.
I’ve been trying to compile RTK with Cuda and Python wrapping on windows for a while and the last time I tried, I was suggested to just disable the python wrapping for RTK over here. That solution works, but does not sit well with me.
There are many opened issues on RTK on this here or related to this here and here.
I’ve finally tracked down the problem @simon.rit (see below), but I’m not sure what’s the best path forward and I’m looking for suggestions form the community to understand what others have done.
For my specific case, I’m trying to build ITK/RTK on Windows as shared libraries, with cuda enabled for RTK and with python wrapping enabled.
So here’s the problem as it stands: when you try to compile it with these settings, you get multiple link errors. The very first one is this:
itkRTK-5.1.lib(itkRTK-5.1.dll) : error LNK2005: "public: class std::vector<class itk::Matrix<double,3,4>,class std::allocator<class itk::Matrix<double,3,4> > > const & __cdecl rtk::ProjectionGeometry<3>::GetMatrices(void)const " (?GetMatrices@?$ProjectionGeometry@$02@rtk@@QEBAAEBV?$vector@V?$Matrix@N$02$03@itk@@V?$allocator@V?$Matrix@N$02$03@itk@@@std@@@std@@XZ) already defined in rtkProjectionGeometryPython.cpp.obj
but you can find the rest of them posted here.
While trying to resolve it, I came to understand that __declspec(dllexport)
(aka RTK_EXPORT
) also exports the base classes. So in the case of RTK, rtk::ProjectionGeometry
is not exported and is tagged with ITK_TEMPLATE_EXPORT
, but that it’s derived classes like rtk::ThreeDCircularProjectionGeometry
and rtk::Reg23ProjectionGeometry
are exported.
So adding the RTK_EXPORT
to rtk::ProjectionGeometry
is easy enough and resolves the first issue.
The second error is this:
itkRTK-5.1.lib(itkRTK-5.1.dll) : error LNK2005: "public: class itk::CudaImage<float,3> * __cdecl itk::ImageSource<class itk::CudaImage<float,3> >::GetOutput(void)" (?GetOutput@?$ImageSource@V?$CudaImage@M$02@itk@@@itk@@QEAAPEAV?$CudaImage@M$02@2@XZ) already defined in itkImageSourceRTKPython.cpp.obj
So based on the first solution, the first obvious solution is to also to export class itk::CudaImage<float,3>
, but that’s not actually viable as it will likely cause the same error, but with the itkCudaCommon
library.
The other solution, would be to not export it in the first place. Looking at the RTK code base, it’s implicitly exported throughout the code base by way of exporting a derived class in which one of the template parameter is itk::CudaImage<float,3>
. For example,
class RTK_EXPORT CudaConstantVolumeSource
: public itk::CudaImageToImageFilter<itk::CudaImage<float, 3>,
itk::CudaImage<float, 3>,
ConstantImageSource<itk::CudaImage<float, 3>>>{
...
}
I assume that this is not a new problem, but I can’t find what other ITK developers have done in this situation. As far as I can tell, on public github, there’s only RTK that’s using itk::CudaImage
so I don’t know what other terms I can search for.
What would be the right approach here to not force export the itk::CudaImage
class and the itk::CudaImageToImageFilter
? If it was me, I would just use the PIMPL idiom here to not expose those classes, but it would require extensive modifications and I’m hoping to avoid that.
So finally, is there a built-in ITK way of doing this that I’m not aware of?
If not, @simon.rit, are you ok with the proposed change of moving to a PIMPL based code structure? I’m more than happy to submit the PR, but I would prefer to get the approval first than to have it rejected later.