Plan
We propose to update ITK to support customizing the ITK namespace.
Motivation
These change will allow importing itk python modules into application themselves built against ITK and ensure filter execution return valid results.
While prior outstanding efforts (PR-3156, PR-3330 , PR-3478 and many more) helped to allow importing itk modules into application like Slicer, the root issue is that symbols are bound to the one already available in the ITK libraries loaded by Slicer.
Running the application, specifying LD_DEBUG_OUTPUT=/tmp/reloc-bindings LD_DEBUG=reloc,bindings
and importing itk
allows to confirm this.
Here is a portion of the output illustrating that the symbol itk::Object::New()
is resolved against libITKCommon-5.3.so.1
built by Slicer instead of _ITKCommonPython.so
library provided in the wheel.
2595154: binding file
/home/jcfr/Downloads/itk-wheels-installed/lib/python3.9/site-packages/itk/_ITKCommonPython.so [0]
to
/home/jcfr/Projects/Slicer-Debug/ITK-build/lib/./libITKCommon-5.3.so.1 [0]: normal symbol `itk::Object::New()'
And here the expected symbol that should be resolved against:
$ readelf --wide -s _ITKCommonPython.so | c++filt | ack "itk::Object::New"
13688: 0000000002d9f8a0 315 FUNC GLOBAL DEFAULT 9 itk::Object::New()
For more details, see The LD_DEBUG environment variable | B. Nikolic Software and Computing Blog
Proposed solution
Similarly to the namespace support available in Qt (See qtnamespacemacros.h), we are considering introducing macros like the following:
#define ITK_NAMESPACE itk // default namespace that can be configured
#define ITK_BEGIN_NAMESPACE namespace ITK_NAMESPACE {
#define ITK_END_NAMESPACE }
Consider solution
We also considered creating a monolithic itk module (e.g _ITKPython.so
) but that would increase its size and would lead to similar issue for ITK based modules.
Next steps
The ITK fork integrated in Slicer will be used to test and develop the namespace support.
We will also plan to provide scripts and instruction to (1) update existing code and (2) developer ITK classes and (3) use ITK classes to be compatible with arbitrary value of ITK_NAMESPACE