[Insight-developers] CMake questions related to SimpleITK C# wrapping
Dan Mueller
dan.muel at gmail.com
Sat Jun 18 01:17:07 EDT 2011
Hi Insight Developers,
I have found some time here and there to fix/improve SimpleITK C#
wrapping -- I can now generate SimpleITK C# wrappers on Windows using
.NET or Mono, and on Linux using Mono.
However, I still have a number of minor issues for which I need some advice:
1. LIBRARY_OUTPUT_DIRECTORY in Visual Studio:
At CMake configure/generate time, I add a custom command (via the
swig_add_module macro):
swig_add_module(SimpleITKCSharpNative csharp SimpleITK.i)
For various reasons I need to force the output directory:
set_target_properties(SimpleITKCSharpNative PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${CSHARP_BINARY_DIRECTORY})
where CSHARP_BINARY_DIRECTORY = /SimpleITK/Build/Wrapping/CSharpBinaries
Under Linux the C# binary is nicely created in:
/SimpleITK/Build/Wrapping/CSharpBinaries
However, under Windows (using Visual Studio 10 generator) the binary
is created in:
/SimpleITK/Build/Wrapping/CSharpBinaries/Release
(notice the configuration name "Release" at the end).
Why is $(Configuration) added to the library output path? Can I prevent this?
(This is not a big deal, but it requires yet another "if (WIN32)"
check in the CMakeLists.txt which I'd prefer to avoid...)
2. Determining the platform in Linux:
On Windows using Visual Studio generator, there is a VS macro
$(PlatformShortName) which allows me to detect the platform name (x86
or x64), eg:
add_custom_command(
COMMENT "Compiling C# ${type} ${name}"
OUTPUT ${name}.${output}
COMMAND ${CSHARP_COMPILER}
ARGS /t:${type} /out:${name}.${output}
/platform:$(PlatformShortName) ${refs} ${sources} # <<< Use platform
here
WORKING_DIRECTORY ${CSHARP_BINARY_DIRECTORY}
DEPENDS "${sources_dep}"
)
Is there an equivalent to $(PlatformShortName) in UNIX make files? How
can I determine the platform at CMake configuration/generation time
and/or compile time under Linux?
3. PixelIDValueEnum is too complex for some parsers/compilers:
sitkPixelIDValues.h defines the following enum:
enum PixelIDValueEnum {
sitkUnknown = -1,
sitkUInt8 = PixelIDToPixelIDValue< BasicPixelID<uint8_t>
>::Result, // Unsigned 8 bit integer
sitkInt8 = PixelIDToPixelIDValue< BasicPixelID<int8_t> >::Result,
// Signed 8 bit integer
sitkUInt16 = PixelIDToPixelIDValue< BasicPixelID<uint16_t>
>::Result, // Unsigned 16 bit integer
...
}
I get a number of strange issues related to the (complex) nature of
the templated code assigning the enum values.
These issues are two fold:
(a) the SWIG parser does not seem to be able to determine the integer
enum value. Here is the invalid C# code it generates:
public enum PixelIDValueEnum {
sitkUnknown = -1,
sitkUInt8 = PixelIDToPixelIDValue<(BasicPixelID<(uint8_t)>)>::Result,
sitkInt8 = PixelIDToPixelIDValue<(BasicPixelID<(int8_t)>)>::Result,
...
}
SWIG should be generating code like this (and does so nicely for other
simpler SimpleITK enums):
public enum PixelIDValueEnum {
sitkUnknown = -1,
sitkUInt8 = 1,
sitkInt8 = 2,
...
}
Fortunately I can turn on "type safe enum" wrapping, which generates
valid (but not so nice) C# code like this:
public sealed class PixelIDValueEnum {
public static readonly PixelIDValueEnum sitkUnknown = new
PixelIDValueEnum("sitkUnknown", SimpleITKPINVOKE.sitkUnknown_get());
public static readonly PixelIDValueEnum sitkUInt8 = new
PixelIDValueEnum("sitkUInt8", SimpleITKPINVOKE.sitkUInt8_get());
public static readonly PixelIDValueEnum sitkInt8 = new
PixelIDValueEnum("sitkInt8", SimpleITKPINVOKE.sitkInt8_get());
...
}
(b) When compiling SimpleITK on Linux, I get lots of warnings stemming
from PixelIDValueEnum:
gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4)
In file included from
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.h:145:0,
from /home/dan/ITK/SimpleITK/Code/Common/sitkImage.cxx:2:
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx: In
member function ‘void
itk::simple::detail::MemberFunctionFactory<TMemberFunctionPointer>::Register(MemberFunctionType,
TImageType*) [with TImageType = itk::Image<signed char, 3u>,
TMemberFunctionPointer = void (itk::simple::Image::*)(unsigned int,
unsigned int, unsigned int), MemberFunctionType = void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)]’:
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx:41:7:
instantiated from ‘typename
itk::simple::EnableIf<itk::simple::IsInstantiated<typename
itk::simple::PixelIDToImageType<TPixelIDType,
VImageDimension>::ImageType>::Value>::Type
itk::simple::detail::MemberFunctionInstantiater<TMemberFunctionFactory,
VImageDimension, TAddressor>::operator()(TPixelIDType*) const [with
TPixelIDType = itk::simple::BasicPixelID<signed char>,
TMemberFunctionFactory =
itk::simple::detail::MemberFunctionFactory<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
unsigned int VImageDimension = 3u, TAddressor =
itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
typename itk::simple::EnableIf<itk::simple::IsInstantiated<typename
itk::simple::PixelIDToImageType<TPixelIDType,
VImageDimension>::ImageType>::Value>::Type = void]’
/home/dan/ITK/SimpleITK/Code/Common/Ancillary/TypeList.h:306:5:
instantiated from ‘void typelist::Visit<TTypeList>::operator()(const
Predicate&) [with Predicate =
itk::simple::detail::MemberFunctionInstantiater<itk::simple::detail::MemberFunctionFactory<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
3u, itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)> >,
TTypeList = typelist::TypeList<itk::simple::BasicPixelID<signed char>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned char>,
typelist::TypeList<itk::simple::BasicPixelID<short int>,
typelist::TypeList<itk::simple::BasicPixelID<short unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<int>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<float>,
typelist::TypeList<itk::simple::BasicPixelID<double>,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<float> >,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<double> >,
typelist::TypeList<itk::simple::VectorPixelID<signed char>,
typelist::TypeList<itk::simple::VectorPixelID<unsigned char>,
typelist::TypeList<itk::simple::VectorPixelID<short int>,
typelist::TypeList<itk::simple::VectorPixelID<short unsigned int>,
typelist::TypeList<itk::simple::VectorPixelID<float>,
typelist::TypeList<itk::simple::VectorPixelID<double>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned char>,
typelist::TypeList<itk::simple::LabelPixelID<short unsigned int>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned int>,
typelist::NullType> > > > > > > > > > > > > > > > > > >]’
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx:106:3:
instantiated from ‘void
itk::simple::detail::MemberFunctionFactory<TMemberFunctionPointer>::RegisterMemberFunctions()
[with TPixelIDTypeList =
typelist::TypeList<itk::simple::BasicPixelID<signed char>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned char>,
typelist::TypeList<itk::simple::BasicPixelID<short int>,
typelist::TypeList<itk::simple::BasicPixelID<short unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<int>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<float>,
typelist::TypeList<itk::simple::BasicPixelID<double>,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<float> >,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<double> >,
typelist::TypeList<itk::simple::VectorPixelID<signed char>,
typelist::TypeList<itk::simple::VectorPixelID<unsigned char>,
typelist::TypeList<itk::simple::VectorPixelID<short int>,
typelist::TypeList<itk::simple::VectorPixelID<short unsigned int>,
typelist::TypeList<itk::simple::VectorPixelID<float>,
typelist::TypeList<itk::simple::VectorPixelID<double>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned char>,
typelist::TypeList<itk::simple::LabelPixelID<short unsigned int>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned int>,
typelist::NullType> > > > > > > > > > > > > > > > > > >, unsigned int
VImageDimension = 3u, TAddressor =
itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
TMemberFunctionPointer = void (itk::simple::Image::*)(unsigned int,
unsigned int, unsigned int)]’
/home/dan/ITK/SimpleITK/Code/Common/sitkImage.cxx:541:96:
instantiated from here
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx:86:7:
warning: case value ‘2’ not in enumerated type ‘itk::Image<signed
char, 3u>::<anonymous enum>’
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx: In
member function ‘void
itk::simple::detail::MemberFunctionFactory<TMemberFunctionPointer>::Register(MemberFunctionType,
TImageType*) [with TImageType = itk::Image<signed char, 2u>,
TMemberFunctionPointer = void (itk::simple::Image::*)(unsigned int,
unsigned int, unsigned int), MemberFunctionType = void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)]’:
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx:41:7:
instantiated from ‘typename
itk::simple::EnableIf<itk::simple::IsInstantiated<typename
itk::simple::PixelIDToImageType<TPixelIDType,
VImageDimension>::ImageType>::Value>::Type
itk::simple::detail::MemberFunctionInstantiater<TMemberFunctionFactory,
VImageDimension, TAddressor>::operator()(TPixelIDType*) const [with
TPixelIDType = itk::simple::BasicPixelID<signed char>,
TMemberFunctionFactory =
itk::simple::detail::MemberFunctionFactory<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
unsigned int VImageDimension = 2u, TAddressor =
itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
typename itk::simple::EnableIf<itk::simple::IsInstantiated<typename
itk::simple::PixelIDToImageType<TPixelIDType,
VImageDimension>::ImageType>::Value>::Type = void]’
/home/dan/ITK/SimpleITK/Code/Common/Ancillary/TypeList.h:306:5:
instantiated from ‘void typelist::Visit<TTypeList>::operator()(const
Predicate&) [with Predicate =
itk::simple::detail::MemberFunctionInstantiater<itk::simple::detail::MemberFunctionFactory<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
2u, itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)> >,
TTypeList = typelist::TypeList<itk::simple::BasicPixelID<signed char>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned char>,
typelist::TypeList<itk::simple::BasicPixelID<short int>,
typelist::TypeList<itk::simple::BasicPixelID<short unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<int>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<float>,
typelist::TypeList<itk::simple::BasicPixelID<double>,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<float> >,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<double> >,
typelist::TypeList<itk::simple::VectorPixelID<signed char>,
typelist::TypeList<itk::simple::VectorPixelID<unsigned char>,
typelist::TypeList<itk::simple::VectorPixelID<short int>,
typelist::TypeList<itk::simple::VectorPixelID<short unsigned int>,
typelist::TypeList<itk::simple::VectorPixelID<float>,
typelist::TypeList<itk::simple::VectorPixelID<double>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned char>,
typelist::TypeList<itk::simple::LabelPixelID<short unsigned int>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned int>,
typelist::NullType> > > > > > > > > > > > > > > > > > >]’
/home/dan/ITK/SimpleITK/Code/Common/sitkMemberFunctionFactory.txx:106:3:
instantiated from ‘void
itk::simple::detail::MemberFunctionFactory<TMemberFunctionPointer>::RegisterMemberFunctions()
[with TPixelIDTypeList =
typelist::TypeList<itk::simple::BasicPixelID<signed char>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned char>,
typelist::TypeList<itk::simple::BasicPixelID<short int>,
typelist::TypeList<itk::simple::BasicPixelID<short unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<int>,
typelist::TypeList<itk::simple::BasicPixelID<unsigned int>,
typelist::TypeList<itk::simple::BasicPixelID<float>,
typelist::TypeList<itk::simple::BasicPixelID<double>,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<float> >,
typelist::TypeList<itk::simple::BasicPixelID<std::complex<double> >,
typelist::TypeList<itk::simple::VectorPixelID<signed char>,
typelist::TypeList<itk::simple::VectorPixelID<unsigned char>,
typelist::TypeList<itk::simple::VectorPixelID<short int>,
typelist::TypeList<itk::simple::VectorPixelID<short unsigned int>,
typelist::TypeList<itk::simple::VectorPixelID<float>,
typelist::TypeList<itk::simple::VectorPixelID<double>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned char>,
typelist::TypeList<itk::simple::LabelPixelID<short unsigned int>,
typelist::TypeList<itk::simple::LabelPixelID<unsigned int>,
typelist::NullType> > > > > > > > > > > > > > > > > > >, unsigned int
VImageDimension = 2u, TAddressor =
itk::simple::Image::AllocateMemberFunctionAddressor<void
(itk::simple::Image::*)(unsigned int, unsigned int, unsigned int)>,
TMemberFunctionPointer = void (itk::simple::Image::*)(unsigned int,
unsigned int, unsigned int)]’
I'm not sure anything can be done to help SWIG or gcc with the
PixelIDValueEnum complexities, but I thought I should mention it...
4. Process for contributing changes:
I guess this is a question for the SimpleITK people...
What is the process to contribute these changes? I have cloned the
SimpleITK.git repository and have made the changes against this. Do I
simply push them to gerrit for review?
5. SimpleITK stability:
At the moment there is only one C# example.
How stable is SimpleITK? Is it stable enough that I can spend some
time writing more C# examples? Or will things change?
Thanks in advance for any advice.
Regards, Dan
More information about the Insight-developers
mailing list