This is a question where I feel I don’t know quite enough to ask the right question, so if I’m doing it wrong feel free to enlighten me.
I recently discovered the joy of Address Sanitizer for debugging memory issues (which I sadly still make). The problem with Address Sanitizer is that all your code has to be compiled with it, but it entails a significant performance hit (https://github.com/google/sanitizers/wiki/AddressSanitizerPerformanceNumbers) which means you don’t want to leave it on all the time. If you don’t compile and link all code with Address Sanitizer, then it will hit false positives almost immediately upon program start (often in std::!).
My approach in projects where everything is compiled from source is to add the following in CMakeLists:
I then mostly develop in Release mode, and if I hit a problem I recompile in RelWithDebInfo.
This doesn’t work well in projects with an externally compiled library - e.g. ITK. If I want to take this approach, I either have to remember to go off and rebuild ITK with Address Sanitizer, or I need to keep two copies of ITK compiled, one with Address Sanitizer and one without, and swap which one I’m linking to in my project based on the build type.
I think I could make the second approach work, but then I started wondering whether it is actually possible to consume ITK purely as source-code in my project? I.e. don’t build ITK as a separate library then link it to my project, but build it all within my project as a single step? I am aware that this may not be optimal either, as every time I switch between Release and RelWithDebInfo it will require rebuilding a lot of files. But given ITK is a lot of template header code anyway, this may not be so bad.
Does anyone have any opinions on how best to approach this? Thanks in advance.
I suspect this is a use case for a CMake Superbuild so that your itk is configured in the same way as your general project, passing the flags to the ITK build.
Super-Builds are an odd one. I don’t think they are widely used outside of the ITK sphere? ANTs is the only project I’ve actually encountered one on before now. I’ve been put off them because they seem like yet another layer of complication for a C++ build. I guess the root cause of this is the lack of proper package management system in C++?
I found a minimal example which looks easier to work with than PlusBuild or Slicer: https://github.com/Sarcasm/cmake-superbuild. However I’m also tempted to look into conan or another package manager as well, if I find the time.
If another example will help, SimpleITK also uses a Superbuild to build ITK:
It’s a little different in that the top level CMakeLists.txt is a normal project. But if you configure with the “Superbuild” directory, then it build ITK and SWIG.
@matt.mccormick In terms of minimising compile-time, I think you are right. The question is whether there is a way to write my CMakeLists.txt (in my project) to pick the ITK directory depending on the build type, rather than having to change a variable manually. Otherwise I’ll forget to change it!
That’s an interesting idea. I don’t think it would play well with the VSCode CMake plug-in (which assumes a single build directory). I’ll have a try though…