# Can't compile RTK Python Wrapper - How do other ITK Modules address this exporting problem?

**URL:** <https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534>\
**Category:** Engineering\
**Tags:** itk, rtk, python\
**Created:** [November 30, 2022, 8:51pm UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534 "2022-11-30T20:51:39Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![eric](https://discourse.itk.org/user_avatar/discourse.itk.org/eric/32/2034_2.png) [@eric](https://discourse.itk.org/u/eric)\
**Post date:** [November 30, 2022, 8:51pm UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534/1 "2022-11-30T20:51:40Z")

</div>

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](https://discourse.itk.org/t/solved-disable-python-wrapping-for-a-specific-remote-module/4055). That solution works, but does not sit well with me.  
There are many opened issues on RTK on this [here](https://github.com/RTKConsortium/RTK/issues/351) or related to this [here](https://github.com/RTKConsortium/RTK/issues/446) and [here](https://github.com/RTKConsortium/RTK/issues/447).

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:

```auto
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](https://github.com/RTKConsortium/RTK/issues/351).

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:

```auto
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,

```cpp
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](https://en.cppreference.com/w/cpp/language/pimpl) 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.

---

<div class="post-metadata">

**Author:** ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)\
**Post date:** [December 1, 2022, 6:10am UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534/2 "2022-12-01T06:10:21Z")

</div>

Thanks for your efforts. Can you provide a CMake script to be able to reproduce the issue? For example, are you building it from ITK or externally?  
I guess we would have to reproduce the problem and investigate it (maybe @LucasGandel may be able to help). Have you looked at what’s done in GPUCommon? CudaCommon is originally copy/pasted from there and adapted for Cuda…  
Last point: we are almost ready to merge [ENH: Remove ITKCudaCommon from the source tree by AlexyPellegrini · Pull Request #492 · RTKConsortium/RTK · GitHub](https://github.com/RTKConsortium/RTK/pull/492) which will finalize the CudaCommon module split from RTK. It would be nice to know if the problem is still there after.

---

<div class="post-metadata">

**Author:** ![eric](https://discourse.itk.org/user_avatar/discourse.itk.org/eric/32/2034_2.png) [@eric](https://discourse.itk.org/u/eric)\
**Post date:** [December 1, 2022, 11:38am UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534/3 "2022-12-01T11:38:44Z")

</div>

I never realized CudaCommon was part only part of RTK. That would explain why I could only find references to it in RTK.

For the CMake script, I’m not sure what format would be best for it, but I’m currently trying to add support for RTK and python wrapping to the [conan-center](https://conan.io/center/itk?tab=recipe) recipe.  
These are the essential cmake settings that I was using/adding to the recipe and was enough to reproduce the problem.

```auto
BUILD_SHARED_LIBS=ON
Module_RTK=ON
RTK_BUILD_APPLICATIONS =ON
RTK_USE_CUDA = ON
ITK_WRAP_PYTHON = ON

```

For reproducing the issue, I see github actions to build python wheels for RTK, but that I don’t understand what is going on there. Presumably, you will be able to see the build issue there as well, but I don’t see any output for the windows builds with cuda and python packages.

---

<div class="post-metadata">

**Author:** ![eric](https://discourse.itk.org/user_avatar/discourse.itk.org/eric/32/2034_2.png) [@eric](https://discourse.itk.org/u/eric)\
**Post date:** [December 1, 2022, 2:04pm UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534/4 "2022-12-01T14:04:59Z")

</div>

@simon.rit  
There are 2 other solutions that I was thinking of that would work better than using PIMPL, as I was starting to look in to it more, PIMPL wouldn’t work very well in this scenario.

The first one is very quick and dirty, and actually works is to just link force allow the linking:

```auto
if(WIN32)
target_link_options(RTK
    INTERFACE "/force" # for cuda rtk linking
)
endif()

```

This shoudn’t break any existing install base as I found this gem in our cmake files. So presumably, everyone is doing something similar on windows when RTK is compiled as a shared library or no one on windows is compiling it as a shared library.

The other option is to move everything into header-only classes and remove the need for `RTK_EXPORT`. It would require more effort, but I suspect that there was a reason that this was done in the first place that I just don’t see at the moment.

---

<div class="post-metadata">

**Author:** ![simon.rit](https://discourse.itk.org/letter_avatar_proxy/v4/letter/s/f08c70/32.png) [@simon.rit](https://discourse.itk.org/u/simon.rit)\
**Post date:** [January 19, 2025, 3:07pm UTC](https://discourse.itk.org/t/cant-compile-rtk-python-wrapper-how-do-other-itk-modules-address-this-exporting-problem/5534/5 "2025-01-19T15:07:31Z")

</div>

I never took care of this issue but, as pointed out in a recent [comment](https://github.com/RTKConsortium/RTK/issues/351#issuecomment-2598453750), RTK has undergone quite many changes. Can you still reproduce this issue now that [CudaCommon](https://github.com/RTKConsortium/ITKCudaCommon) has been split from RTK?
