SimpleITK compiled with modern Apple Clang compiler requires either an old SDK ~10.6 for GNU’s stdlibc++, or required C++11 enabled. I am not sure how the defaults have changed recently for Slicer…
Did anything relevant change recently in Slicer?
Here’s relevant system info:
$ cmake --version
cmake version 3.9.1
CMake suite maintained and supported by Kitware (kitware.com/cmake).
$ gcc -v
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 9.0.0 (clang-900.0.37)
Thread model: posix
$ qmake -v
QMake version 2.01a
Using Qt version 4.8.7 in /usr/local/lib
For this case with OS X 10.11 SDK, and clang C+11 should be enabled for SimpleITK. This should happen automatically. This should be indicated in the configuration file by the following entry in the SimpleITK’s CMakeCache.txt:
If I switch to VTKv8, I get compile error in LibArchive
[ 11%] Building C object libarchive/CMakeFiles/archive_static.dir/archive_read_disk_posix.c.o
/Users/fedorov/build/Slicer-Release/LibArchive/libarchive/archive_read_disk_posix.c:1984:6: error: 'futimens' is only available on macOS 10.13 or newer
if (futimens(fd, timespecs) == 0)
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/usr/include/sys/stat.h:373:5: note: 'futimens' has been explicitly marked partial here
int futimens(int __fd, const struct timespec __times) __API_AVAILABLE(macosx(10.13), ios(11.0), tvos(11.0), watchos(4.0));
/Users/fedorov/build/Slicer-Release/LibArchive/libarchive/archive_read_disk_posix.c:1984:6: note: enclose 'futimens' in a __builtin_available check to silence this warning
if (futimens(fd, timespecs) == 0)
1 error generated.
Now for the slicer superbuild, is CMAKE_CXX_STANDARD:STRING=98 explicitly set or is in coming from the above patch when CMAKE_CXX_STANDARD is not defined and some kind of default is being set?
Currently SimpleITK just adds --stdc++=11 to the CMAKE_CXX_FLAGS since it (previously) works with all version of CMake. But is appears the CMAKE_CXX_STANDARD variable are overriding it. Atleast in these try compiles.
Further experimentation yields that if SimpleITK is configured with the CMAKE_CXX_STANDARD flags must not be null for CMAKE. Therefor I presume Slicers Superbuild is explicitly setting the standard. ( Why not c++03?)
I would consider not passing these CMAKE_CXX_STANDARD flags for this problematic case to SimpleITK. When on OS X, and the standard version is less that 11 and the OS X SDK is greater that 10.7? These flags should not be passed. This will enable SimpleITK to set the flag as need.
While SimpleITK could manipulate the CMAKE_CXX_STANARD flag for this case, because older cmake’s try_compile does not respect this option it would yield inconsistent and trouble prone behavior. There are a lot of factors that effect this situation… I’ll have to think about it further…
Compiling ITK with C++98 while compiling SimpleITK C++11, is not ideal, but all the tests seem to pass for the wrapping. The problem may be if SimpleITK C++ interface is used with this mixed standard configuration.
(Jean Christophe Fillion Robin (Kitware))
Compiling ITK with C++98 while compiling SimpleITK C++11, is not ideal, but all the tests seem to pass for the wrapping.
Thanks for the details answer. Things are now clearer.
Since c++11 is a hard requirement for SimpleITK. I will update Slicer build system to not pass the CMAKE_CXX_STANDARD related options if building with C++98 (aka Qt4). That way the builtin logic of SimpleITK will be used to initialize the flags and always use c+11 …
Why not c++03?
My understand is that c++98 matches the case where nothing was explicitly specified. And this seems to be a reasonable choice.
Currently, Slicer is explicitly requesting C++98, and SimpleITK will not override that request even though it is not compatible in this configuration. I think that is reasonable behavior for SimpleITK when CMAKE_CXX_STANDARD(_REQUIRED is explicitly set, but for Slicer as a whole it does not work well.
I think that the GCC compilers default to the GNU dialect, and GCC 6 version default to gnu++14. So these options selected are having an effect. While on MSVC there does not seem to be a way to specify the C++ standard, it is just evolving with the releases.
While the logic needed to determine if C++11 is needed for SimpleITK can easily be said as: “If using libc++ then C++11 is required”, or “SimpleITK requires C++98 with TR1 or C++11”, it is harder to detect this case in CMake because of the interdependency of the ways to set C++ version, the OS X Deployment Target, and the CXX command line flags ( -stdlib=, -std=). I do have a try compile which checks for libc++ without C++11:https://github.com/SimpleITK/SimpleITK/blob/next/CMake/sitk_check_cxx11_required.cxx#L4
I have created a pull request that improves the situation in SimpleITK:
It handles CMake CXX standard flags for older versions of CMake and gives better error messages when the C++ version is not able to be set as needed. For this case it would produce the following message:
CMake Error at CMake/sitkCheckCXX11.cmake:110 (message):
SimpleITK requires usage of C++11 or C++ Technical Report 1 (TR1), but were
neither able to detect TR1 nor automatically enable C++11. Please review
your configuration settings and enable C++11.