What I would like to do is build ITK once, and then each member of the team can just copy the built version for building our projects linking to ITK, rather than everyone building locally. However I have not been able to get this to work with both Debug and Release builds, though I’ve tried a few things. I hope there is something basic I am missing and someone can help me with that.
I originally tried setting CMAKE_INSTALL_PREFIX to some directory, going through the ITK build process with cmake and Visual Studio, and distributing the output in CMAKE_INSTALL_PREFIX. Then, in the CMakeLists.txt of our project linking to ITK, ITK_DIR is set to this output dir, e.g.
set(ITK_DIR “thirdparty/ITK_5.0.1/lib/cmake/ITK-5.0”).
The problem is, this will only be a single build type, release or debug. So when building our project in VS, we get build errors if, say ITK was built as release and we try to build debug. The only workaround was to have both and comment out one at a time, e.g. #set(ITK_DIR “thirdparty/ITK_5.0.1_release/lib/cmake/ITK-5.0”)
set(ITK_DIR “thirdparty/ITK_5.0.1_debug/lib/cmake/ITK-5.0”)
and go through build process again. But this is pretty awkward, ideally we could build either by simply switching within Visual Studio.
The next attempt was to simply copy the entire ITK build directory after building both debug and release, so in our project CMakeLists.txt something like
set(ITK_DIR “thirdparty/InsightToolkit-5.0.1/build”)
This worked for whoever built it, but when transferring to someone else, because the build has many references to absolute paths of the original builders ITK location, the build fails since the second person won’t have that path.
It doesn’t seem like an odd thing to be doing, is there some standard approach to do this?
Debug-mode builds should not be distributed. Visual Studio runtime license agreement specifically prohibits this. Internally in your group you can of course share anything, and there you can also ensure that developers install ITK build into the exact same location, so no relocation of the build tree is needed.
Instead of these hacks, I would recommend to build in release mode with debug information enabled (RelWithDebInfo), which is an optimized build that can be debugged. The only disadvantage compared to regular debug builds is that some variables may be optimized out by the compiler and execution order of lines may differ from the source code, so debugging can be sometimes confusing.
When doing RelWithDebInfo you can change CMAKE_CXX_FLAGS_RELWITHDEBINFO from default value of /MD /Zi /O2 /Ob1 /DNDEBUG to something closer to DEBUG, such as /MD /Zi /O1 /Ob0 /DNDEBUG to make debugging easier (at the expense of somewhat slower code).
Thanks for the info! I tried using RelWithDebInfo build instead, but when building our project I still get mismatch errors (error LNK2038: mismatch detected for ‘_ITERATOR_DEBUG_LEVEL’: value ‘0’ doesn’t match value ‘2’). I think the core issue is different notions of build steps between visual studio and, say, gcc, and cmake is more aligned with the others. Anyway I guess it’s not really an ITK issue, I need to dig into cmake to see if there is a workaround. Thanks again for the assistance.
If you build RelWithDebInfo, you cannot link Debug against it. Maybe the other 3 build types, and easily only RelWithDebInfo.
But this gives the flexibility to dial up or down debugging options in your application which you link against ITK. And since ITK is mostly a templated library, those settings matter a lot more than the ones ITK was built with. Because only IOs, some common classes and very few other things are actually compiled during ITK compile. Most filters and other processing-heavy things are compiled during application compile time.