How to build ITKElastix with ITK 5.3.0 with Python bindings in Linux?

Continuing the discussion from Update remote module in ITK:

Continuing the discussion from how to build ITK 5.3.0 with Python bindings in Linux?:

Hello.

I am trying to build ITKElastix offline from source with ITK 5.3.0 (the latest release). I already have an installation of Elasitx on my system.

I built ITK like this

_build_itk() {
  echo "==> Starting _build_itk()"
  _confopts=(
    -DCMAKE_INSTALL_PREFIX:FILEPATH=/usr
    -DITK_LEGACY_SILENT:BOOL=ON
    -DBUILD_SHARED_LIBS:BOOL=ON

    # Custom compilation
    # [2024-04-08] Clang is required (for CastXML. Both need to
    # be compiled with it)
    -DCMAKE_C_COMPILER:FILEPATH=/usr/lib/llvm14/bin/clang
    -DCMAKE_CXX_COMPILER:FILEPATH=/usr/lib/llvm14/bin/clang++
    -DCMAKE_BUILD_TYPE:STRING=None # Avoid DNDEBUG
    -DCMAKE_C_FLAGS:STRING="${CFLAGS}"
    -DCMAKE_CXX_FLAGS:STRING="-std=c++20 ${CPPFLAGS}"
    -DITK_C_OPTIMIZATION_FLAGS:STRING="${COPTFLAGS}"
    -DITK_CXX_OPTIMIZATION_FLAGS:STRING="${CXXOPTFLAGS}"

    -DBUILD_TESTING:BOOL=OFF
    -DBUILD_EXAMPLES:BOOL=OFF

    -DITK_USE_SYSTEM_LIBRARIES:BOOL=ON
    -DITK_USE_SYSTEM_EXPAT:BOOL=ON
    -DITK_USE_SYSTEM_FFTW:BOOL=ON
    -DITK_USE_SYSTEM_GDCM:BOOL=ON
    -DITK_USE_SYSTEM_HDF5:BOOL=ON
    -DITK_USE_SYSTEM_JPEG:BOOL=ON
    -DITK_USE_SYSTEM_PNG:BOOL=ON
    -DITK_USE_SYSTEM_TIFF:BOOL=ON
    -DITK_USE_SYSTEM_ZLIB:BOOL=ON
    -DITK_USE_MKL:BOOL=OFF

    # Python
    -DITK_WRAP_PYTHON:BOOL=ON
    -DITK_WRAP_SWIGINTERFACE:BOOL=ON
    -DITK_USE_SYSTEM_SWIG:BOOL=ON
    -DITK_WRAP_CASTXML:BOOL=ON
    -DITK_USE_SYSTEM_CASTXML:BOOL=ON

    -DITK_BUILD_DEFAULT_MODULES:BOOL=ON

    -B build -S "${_base}" -Wno-dev
  )
  cmake "${_confopts[@]}"

  cmake --build build 2>&1 | tee compilation.log
}

I got the sources for v0.17.1 (595fb32bbbec405ba6e38fa59a3064172b526a2e) of ITKElastix
There is Elastix on the system already, and it would be nice if I don’t have to rebuild it. Thus, I commented these lines out of CMakeLists.txt

# set(elastix_GIT_REPOSITORY "https://github.com/SuperElastix/elastix.git")
# set(elastix_GIT_TAG "b9b8e20aef83f94ed38a81cc38625a1bfddf1053")
# FetchContent_Declare(
#   elx
#   GIT_REPOSITORY ${elastix_GIT_REPOSITORY}
#   GIT_TAG ${elastix_GIT_TAG})
# FetchContent_GetProperties(elx)
# if(NOT elx_POPULATED)
#   FetchContent_Populate(elx)
#   # Use CMake's FindOpenCL.cmake, which is backend agnostic
#   file(REMOVE ${elx_SOURCE_DIR}/CMake/FindOpenCL.cmake)
#   if(ELASTIX_USE_OPENCL)
#     find_package(OpenCL REQUIRED)
#     set(OPENCL_INCLUDE_DIRS ${OpenCL_INCLUDE_DIRS} CACHE PATH "OpenCL include directories")
#     set(OPENCL_LIBRARIES ${OpenCL_LIBRARIES} CACHE FILEPATH "OpenCL library")
#   endif()
#   add_subdirectory(${elx_SOURCE_DIR} ${elx_BINARY_DIR})
# endif()
# set(Elastix_DIR "${elx_BINARY_DIR}")

I am trying to build ITKElastix like this

_build_elastix() {
  echo "==> Starting _build_elastix()"
  _build_dir="${srcdir}"/build_elastix
  # [[ ! -d ${_build_dir}/_deps/elx-src ]] && mkdir -p ${_build_dir}/_deps/elx-src

  CONFOPTS=(
    # -DFETCHCONTENT_FULLY_DISCONNECTED:BOOL=ON
    # -DFETCHCONTENT_QUIET:BOOL=OFF
    # -DITK_FORBID_DOWNLOADS:BOOL=ON

    # Custom compilation
    # [2024-04-08] Clang is required (for CastXML. Both need to
    # be compiled with it)
    -DCMAKE_C_COMPILER:FILEPATH=/usr/lib/llvm14/bin/clang
    -DCMAKE_CXX_COMPILER:FILEPATH=/usr/lib/llvm14/bin/clang++

    -DITK_WRAP_PYTHON:BOOL=ON
    -DITK_WRAP_SWIGINTERFACE:BOOL=ON
    -DITK_USE_SYSTEM_SWIG:BOOL=ON
    -DITK_WRAP_CASTXML:BOOL=ON
    -DITK_USE_SYSTEM_CASTXML:BOOL=ON

    -DBUILD_TESTING:BOOL=OFF
    -DBUILD_EXAMPLES:BOOL=OFF

    -DITK_USE_SYSTEM_LIBRARIES:BOOL=ON
    -DITK_USE_SYSTEM_EXPAT:BOOL=ON
    -DITK_USE_SYSTEM_FFTW:BOOL=ON
    -DITK_USE_SYSTEM_GDCM:BOOL=ON
    -DITK_USE_SYSTEM_HDF5:BOOL=ON
    -DITK_USE_SYSTEM_JPEG:BOOL=ON
    -DITK_USE_SYSTEM_PNG:BOOL=ON
    -DITK_USE_SYSTEM_TIFF:BOOL=ON
    -DITK_USE_SYSTEM_ZLIB:BOOL=ON
    -DITK_USE_MKL:BOOL=OFF

    # https://discourse.itk.org/t/update-remote-module-in-itk/2615/3
    -DITK_DIR:PATH="${srcdir}"/build

    -DCMAKE_CXX_FLAGS:STRING="-std=c++20"
    -DCMAKE_BUILD_TYPE:STRING=None
    # -S "${srcdir}"/itk-elastix
    # -B "${_build_dir}"
  )
  [[ ! -d "${_build_dir}" ]] && mkdir "${_build_dir}"
  cd "${_build_dir}"
  cmake ${CONFOPTS[@]} "${srcdir}"/itk-elastix
  make -s
}

I was bitten by a bug which complained about =lomp, for which I managed to work around by replacing =lomp (there is a space before = which is relevant) from build_elastix/Wrapping/Modules/Elastix/CMakeFiles/ElastixCastXML.dir/build.make with -fopenmp=lomp (is there a patch for this that I can use?)

Thanks.
Error: itk-log (15.0 KB)

ITK 5.3.0
Elastix 5.1.0-1

Based on is_integral_v-related error messages, it looks like #include <type_traits> is missing somewhere. Possibly some other headers too. I am unsure about OpenMP-related errors. Perhaps @Niels_Dekker or someone else has an idea?

1 Like

Looking at the log file (itk-log):


/usr/include/Core/Install/elxConversion.h:95:24: error: no template named 'is_integral_v' in namespace 'std'; did you mean 'is_integral'?
    static_assert(std::is_integral_v<TInteger>, "An integer type expected!");
                  ~~~~~^~~~~~~~~~~~~
                       is_integral
/usr/lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/type_traits:441:12: note: 'is_integral' declared here
    struct is_integral

However, elxConversion.h does have #include <type_traits>

std::is_integral_v was introduced with C++17 (and is still there with C++20) So I think it has somehow picked the wrong C++ standard version. (Possibly accidentally still C++14?) Would it help if you would explicitly set the CMake variable CXX_STANDARD? Or CMAKE_CXX_STANDARD?

2 Likes

Thank you both. I did some grepping, and found that almost every cmake file had both -std=c++20 and -std=c++14. For example,

./src/build/Modules/Core/Common/src/CMakeFiles/ITKCommon.dir/flags.make:9:
CXX_FLAGS = -std=c++20  -Wall -Wcast-align -Wdisabled-optimization -Wextra -Wformat=2 -Winvalid-pch -Wno-format-nonliteral -Wpointer-arith -Wshadow -Wunused -Wwrite-strings -funit-at-a-time -Wno-strict-overflow -Wno-deprecated -Wno-invalid-offsetof -Wno-undefined-var-template -Woverloaded-virtual  -std=c++14 -fPIC

Then,

  1. I deleted the CMakeCache.txt from build_elastix;
  2. deleted both =libomp and -std=c++14 from build_elastix/Wrapping/Modules/Elastix/CMakeFiles/ElastixCastXML.dir/build.make;
  3. replaced
    set(INVALID_OPTIMIZATION_FLAGS "-fopenmp;-march=[a-zA-Z0-9\-]*;-mtune=[a-zA-Z0-9\-]*;-mfma")
    with
    set(INVALID_OPTIMIZATION_FLAGS "-fopenmp[a-zA-Z0-9\-=]*;-march=[a-zA-Z0-9\-]*;-mtune=[a-zA-Z0-9\-]*;-mfma;-std=c++14")
    in insight-toolkit/Wrapping/macro_files/itk_auto_load_submodules.cmake:31
  4. added this to insight-toolkit/Modules/ThirdParty/pygccxml/src/pygccxml/utils/utils.py::300
    '-std=c++20': 201703,
    '-std=gnu++20': 201703,
    '-std=c++23': 202002,
    '-std=gnu++23': 202002,
    
    (based on build/CMakeFiles/3.29.2/CompilerIdCXX/CMakeCXXCompilerId.cpp),
  5. and re-executed make inside build_elastix,

but it told me that

CMake Warning at CMakeLists.txt:109 (message):
  Python wrapping of ITKElastix is known not to work with RelWithDebInfo
  configuration.  Release is recommended.  Your CMAKE_BUILD_TYPE:


CMake Error at CMakeLists.txt:117 (include):
  include could not find requested file:

    ITKModuleExternal

Thus, I am going to retry again from the start (building ITK again) with those modifications, and see if it helps. I’ll report back later. Thanks.

[EDIT]
I am also adding this to utils.py:

    @property
    def is_cxx20(self):
        """Returns true if -std=c++14 is being used"""
        return self._cplusplus == cxx_standard.__STD_CXX['-std=c++20']

    @property
    def is_cxx20_or_greater(self):
        """Returns true if -std=c++14 or a newer standard is being used"""
        return self._cplusplus >= cxx_standard.__STD_CXX['-std=c++20']
1 Like

You might want to update the docstring to C++20.

Thanks. The perks of yanking (if you know what I mean).

Still no success. I also tried with

cmake "${_confopts[@]}"
find ./ -type f -exec grep -l '[-]std=c++14' \{\} + | parallel -q sed -i 's/ -std=c++14//g'
cmake --build build

To make sure that -std=c++14 was removed. The error now is

[  5%] Building C object Modules/ThirdParty/MINC/src/libminc/CMakeFiles/itkminc2.dir/libsrc2/dimension.c.o
In file included from /usr/src/googletest/src/gtest-all.cc:49:
In file included from /usr/src/googletest/src/gtest.cc:44:
/usr/lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/chrono:2360:48: error: call to consteval function 'std::chrono::hh_mm_ss::_S_fractional_width' is not a constant expression
        static constexpr unsigned fractional_width = {_S_fractional_width()};
                                                      ^
/usr/lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/chrono:2360:48: note: undefined function '_S_fractional_width' cannot be used in a constant expression
/usr/lib64/gcc/x86_64-pc-linux-gnu/13.2.1/../../../../include/c++/13.2.1/chrono:2315:2: note: declared here
        _S_fractional_width()
        ^

I will now replace the flag std=c++20 from "${_confopts[@]}" and let c++14 be

I only tried with ITKElastix, but setting it with ITK alone yields:

INFO: Running CMake...
-- The CXX compiler identification is Clang 14.0.6
-- The C compiler identification is Clang 14.0.6
-- Detecting CXX compiler ABI info
CMake Error in build/CMakeFiles/CMakeScratch/TryCompile-HiLhj7/CMakeLists.txt:
  Target "cmTC_687fb" requires the language dialect "CXX-std=c++20".  But
  the current compiler "Clang" does not support this, or CMake does not know
  the flags to enable it.


CMake Error at /usr/share/cmake/Modules/CMakeDetermineCompilerABI.cmake:64 (try_compile):
  Failed to generate test project build system.
Call Stack (most recent call first):
  /usr/share/cmake/Modules/CMakeTestCXXCompiler.cmake:26 (CMAKE_DETERMINE_COMPILER_ABI)
  CMakeLists.txt:46 (project)

The same thing happens with c++17. As a reminder, I am using clang14, because that is what ITK 5.3.0 needs. I will try to build again from scratch with c++14. What I did not try was to rebuild elastix (not ITKElastix) with that standard. I’ll check.

I’ll give up on this. I concluded that it is not possible to achieve 5.3.0 with ITKElastix, so I went for 5.4rc03 (the latest compatible with elastix). The compilation of ITK tried to download VXL (VNL) without internet. To go around it, I had to build DCMTK and tried to build vxl, but it is currently not working (Fails to build when dcmtk-3.6.5 is present: fatal error: 'dcistrma.h' file not found · Issue #768 · vxl/vxl · GitHub ; tested with mpicc and clang). I could check the building instructions of VXL inside of insight-toolkit, but I’ll just stop. Thanks.

1 Like