Compiling ~MinimalPathExtraction~ with ITK 5.2.1


I am trying to build ITK with MinimalPathExtraction, because I want to try TubeTK. I am getting a compilation error.

I would appreciate if we can keep my compilation flags, so that the compilation does not restart from 0. Compiling really takes the whole day. (Using more than one process, i.e. make -jn... for n > 1, usually crashes my machine with segfault, and it becomes unusable during parts of the process). Of course, this is just a polite request to consider.


Desired outcome

I would like to have a Python interface to ITK without SimpleITK which allows me to use the TubeTK module.

Actual result

This is a sample of the compilation output

    -- MinimalPathExtraction: Creating module.
    -- MinimalPathExtraction: Creating itkArrivalFunctionToPathFilter submodule.
    -- MinimalPathExtraction: Creating itkIterateNeighborhoodOptimizer submodule.
    -- MinimalPathExtraction: Creating itkPhysicalCentralDifferenceImageFunction submodule.
    -- MinimalPathExtraction: Creating itkSingleImageCostFunction submodule.
    -- MinimalPathExtraction: Creating itkSpeedFunctionPathInformation submodule.
    -- MinimalPathExtraction: Creating itkSpeedFunctionToPathFilter submodule.

    Consolidate compiler generated dependencies of target MinimalPathExtraction
    [ 24%] Linking CXX shared library ../../../../Wrapping/Generators/Python/itk/
    [ 24%] Built target MinimalPathExtraction
    [ 24%] Built target MinimalPathExtraction-all

    [ 93%] Generating ../../itkIterateNeighborhoodOptimizer.xml
    In file included from insight-toolkit/src/insight-toolkit-5.2.1/build/Wrapping/itkIterateNeighborhoodOptimizer.cxx:16:
    insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:36: error: variable has incomplete type 'class MinimalPathExtraction_EXPORT'
    class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:7: note: forward declaration of 'itk::MinimalPathExtraction_EXPORT'
    class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:65: error: expected ';' after top level declarator
    class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:67: error: expected unqualified-id
    class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    insight-toolkit/src/insight-toolkit-5.2.1/build/Wrapping/itkIterateNeighborhoodOptimizer.cxx:26:18: error: no type named 'IterateNeighborhoodOptimizer' in namespace 'itk'
        typedef itk::IterateNeighborhoodOptimizer itkIterateNeighborhoodOptimizer;
    insight-toolkit/src/insight-toolkit-5.2.1/build/Wrapping/itkIterateNeighborhoodOptimizer.cxx:27:18: error: 'IterateNeighborhoodOptimizer' is not a class, namespace, or enumeration
        typedef itk::IterateNeighborhoodOptimizer::Pointer itkIterateNeighborhoodOptimizer_Pointer;
    insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:36: note: 'IterateNeighborhoodOptimizer' declared here
    class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    5 errors generated.
    make[2]: *** [Wrapping/Modules/MinimalPathExtraction/CMakeFiles/MinimalPathExtractionCastXML.dir/build.make:86: Wrapping/itkIterateNeighborhoodOptimizer.xml] Error 1
    make[1]: *** [CMakeFiles/Makefile2:31038: Wrapping/Modules/MinimalPathExtraction/CMakeFiles/MinimalPathExtractionCastXML.dir/all] Error 2
    make: *** [Makefile:156: all] Error 2

Compilation options (MWE)

If you use Parabola GNU/Linux, there is a PKGBUILD

safe_flags+=" -fcf-protection -fno-plt"
safe_flags+=" -fstack-clash-protection -Wformat"
safe_flags+=" -Werror=format-security"
generic_flags="-pipe -fno-plt -fPIC -fopenmp"
generic_flags+=" -march=native"
generic_flags+=" -mtune=native ${safe_flags}"
opt_flags="${generic_flags} -O3"
generic_flags="${generic_flags} -O2"

export COPTFLAGS="${opt_flags}"
export CPPFLAGS="$generic_flags"
export CFLAGS="$generic_flags"
export FFLAGS="$generic_flags"
export FCFLAGS="$generic_flags"
export F90FLAGS="$generic_flags"
export F77FLAGS="$generic_flags"

export LANG=C
export OMPI_MCA_opal_cuda_support=0
export OMPI_MCA_mpi_oversubscribe=0

_usepython=true  _confopts=(
  -S "${srcdir}"/"${pkgname}"-"${pkgver}"
  -B "${srcdir}"/"${pkgname}"-"${pkgver}"/build

  # TubeTK requires MinimalPathExtraction module enabled

  $( $_usepython && echo "-DITK_WRAP_PYTHON:BOOL=ON")
  $( $_usepython && echo "-DModule_ITKReview:BOOL=OFF")
  $( $_usepython && echo "-DITK_USE_SYSTEM_SWIG:BOOL=ON")
  $( $_usepython && echo "-DITK_USE_SYSTEM_CASTXML:BOOL=ON")
cmake "${_confopts[@]}"
make -j1 -s -C "${srcdir}/${pkgname}-${pkgver}"/build


Table 1: Python and ITK versions
Python 3.10.1
ITK 5.2.1
Numpy 1.21.5
Scipy 1.7.3
Parabola_(GNU/Linux) 5.15.12-gnu-1
gcc 11.1.0

A few notes: using ninja instead of make makes parallel builds easy and reliable. Python 3.10 is pretty new, I don’t know whether anyone tested it with ITK. GCC 11.1 is also fairly new, but it would probably give a different error message. Parabola is an uncommon distro.

The problem is, most likely, due to ITKMinimalPathExtraction's need for maintenance.

@Stephen_Aylward Is TubeTK supposed to build with this combination of parameters?

1 Like

Thank you. As general info, I have been able to build ITK with Python 3.10, GCC 11.1 and Parabola. Other remote modules seem to be compiling.

I will definitely try ninja.

This error is not in TubeTK, it is in MinimalPathExtraction.

For TubeTK from python, the easiest approach is to use

pip install --pre itk-tubetk

I just posted a new version of TubeTK (1.1rc01) last night (hence the -pre argument). TubeTKv1.1rc01 works with ITKv5.3rc03. It will automatically bring in MinimalPathExtraction wheels

Otherwise, for ITKv5.2.1, you will need the older version of TubeTK
pip install itk-tubetk # no -pre option

If you still want to compile from source, I am not certain why you are seeing those error in MinimalPathExtraction. You would need to contact the MinimalPathExtraction developers for confirmation. It should be easy to track down where MinimalPathExtraction_EXPORT is being defined and include that file in the appropriate source code. Those exports typically default to empty string except on windows (as I recall, but it has been years since I looked at that definition), if so, you could simply delete those references. It is regretful to have to modify code in that way, but I’m not certain how responsive the MinimalPathExtraction folks are.

1 Like

Thank you Stephen.

Yes, the idea is to build from source, but if there is a tar-ball on PyPi, that may become easier. Could you please confirm if

  1. I can install TubeTK with pip install after ITK has been compiled and installed?
  2. there is a tar-ball (not wheel) on PyPi?

Also, thank you for the advice on the _EXPORT tag. I am guessing that the developers of MinimalPathExtraction are not really around. I will see if I can get an e-mail address to send a message. Also, if you are the developer of TubeTK, are you sure that you want to keep using unmaintained code?

Ah - the joys of open source - today’s cool code is tomorrow’s unsupported code. Could spend a lifetime chasing such things…I think I have :slight_smile:

No need to store tarballs on PyPi - you can just checkout the source from github using the appropriate tag. v1.0 was the tag for the ITKv5.2 release. But that exact code is already in your ITK repo (ITK/Modules/Remote/TubeTK). So, I don’t think code-version is the issue.

In theory a pip install of tubetk using an installed-from-source version of ITK should work, assuming it is using the same version of ITK that was used to build the tubetk wheel, but it is always a gamble. We’ve spent quite a bit of time standardizing the build environments / github actions. Not certain, for example, of the impact of the various compiler options you’ve chosen.

Hope the MinimalPath folks respond!



That repository has 12 contributors, both you and me amongst them Stephen! :smiley: I wonder whether we will respond, or whether we are to busy with other stuff. :smiley: Maybe one of the other 10 past contributors has time to deal with it right now.

Another good thing about open source…anyone can contribute! Go for it!


I’m laughing my lungs out :stuck_out_tongue: !!! Thank you, both. I’ll check about the _EXPORT thing, and report back :slight_smile: .

The original issue is with a variable which is not properly defined and has the _EXPORT tag. By looking into the header files (build/Modules/Core/Common/MinimalPathExtractionExport.h), one finds this header:

#+caption: This header file has a conditional regarding ITK_STATIC which may change the definition

  #ifdef ITK_STATIC
  #  define MinimalPathExtraction_EXPORT
  #  define MinimalPathExtraction_HIDDEN
  #  ifndef MinimalPathExtraction_EXPORT
  #    ifdef MinimalPathExtraction_EXPORTS
  /* We are building this library */
  #      define MinimalPathExtraction_EXPORT __attribute__((visibility("default")))
  #    else
  /* We are using this library */
  #      define MinimalPathExtraction_EXPORT __attribute__((visibility("default")))
  #    endif
  #  endif

  #  ifndef MinimalPathExtraction_HIDDEN
  #    define MinimalPathExtraction_HIDDEN __attribute__((visibility("hidden")))
  #  endif

A similar header is found in ITKOptimizersExport.h, but this file produces no error (it is related to itkOptimizer.h in a similar way in which itkIterateNeighborhoodOptimizer is related to MinimalPathExtractionExport.h).

By grepping for ITK_STATIC in any directory which is not build

  find . \( -type f \( -regex '.*\(cxx\|hxx\|h\|cpp\|c\)$' \) -o -type d -name build -prune -false \) -exec grep --color -nH -e ITK_STATIC \{\} +

#+caption: I found these files with ITK_STATIC inside

./Modules/Filtering/FFT/src/itkFFTWGlobalConfiguration.cxx:513:#    if !defined(_WIN32) || defined(ITK_STATIC)
./Modules/Filtering/FFT/src/itkFFTWGlobalConfiguration.cxx:521:#    if !defined(_WIN32) || defined(ITK_STATIC)
./CMake/ITKModuleMacros.cmake:231:        STATIC_DEFINE ITK_STATIC )

There is a note about the relevance of that tag
#+caption: itkFFTWGlobalConfiguration.cxx has this

  #    if !defined(_WIN32) || defined(ITK_STATIC)
  // Cannot be called with shared libs on Windows because FFTW does not check
  // for signaled threads and it would cause a deadlock at the end of the main.

ITKModuleMacros.cmake seems to be the root of this piece of code

  # Generate the export macro header for symbol visibility/Windows DLL declspec
          EXPORT_FILE_NAME ${_export_header_file}
          EXPORT_MACRO_NAME ${itk-module}_EXPORT
          NO_EXPORT_MACRO_NAME ${itk-module}_HIDDEN

I think that this part is done:

And I would even say that it is being included

because it is mentioned in the error message:

  insight-toolkit/src/insight-toolkit-5.2.1/Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h:41:36: error: variable has incomplete type 'class MinimalPathExtraction_EXPORT'

I think that, somehow, there is a missing definition to that macro. I mean, both the optimizer’s files and the minimal path extraction’s files have the same structure, thus should be bening from the compiler’s perspective (both have the #define in the same way). Therefore, the question that I have is: if one does not fail why does the other?

If you are correct, and the header file is not being loaded, why does it show in the error log? I’m not arguing, it’s a question to figure out how to know that it is not being included.

Also, if you are compiling the software, what compilation instructions are you using? May be I can start playing with that.

By the way, I changed to Ninja (-G Ninja= for CMake), and the error is spotted much earlier (instead of taking hours to 93 %). Thank you for that!

Thank you for your help.


Great job digging in!

I think the value of MinimalPathExtraction_EXPORT isn’t being set by the #defines, because the compiler is reporting an error when it is trying to interpret MinimalPathExtraction_EXPORT as a class name in line 41 in itkIterateNeighborhoodOptimizer.h. If the #defines were working, then MinimalPathExtraction_EXPORT would either be mapped to blank or to __attribute__((visibility(“default”))) by the #defines, depending on the value of ITK_STATIC, as you noted.

The weird thing is that your compiler isn’t throwing an error that MinimalPathExtractionExport.h isn’t found by the #include in line 21 of itkIterateNeighborhoodOptimizer.h. So, if MinimalPathExtractionExport.h is being found and included in line 21, why isn’t MinimalPathExtraction_EXPORT being set and mapped to a valid value in line 41?

I’ll dig, but this is odd. I don’t see issues with the compiler flag you’re using.

Option 1) It is building static libs, correct? If so, MinimalPathExtraction_EXPORT should map to blank/nothing, so you could simply delete that variable from itkIterateNeighborhoodOptimizer.h, and you should be golden. Isn’t really a solution, but…I bet it works.
Option 2) See if there is another file called MinimalPathExtractionExport.h in your build directory. if so, delete it. If not, try option 3
Option 3) Delete everything in your build directory and start from scratch - because it really is odd behavior, and it could be an invalid .o file is lingering or such. I dunno - its like rebooting a windows machine, sometimes it just works…

PS> @dzenanz - I checked, in 7 years of MinimalPathExtraction’s existence, I made 1 commit that changed 2 lines :slight_smile:. I have contributed the least of anyone :slight_smile: But this error actually seems like an ITK config error or a corrupt build directory or ???



The good news is that it compiles now. I just:

    --- /tmp/ediffwAYxBY	2022-02-08
    +++ Modules/Remote/MinimalPathExtraction/include/itkIterateNeighborhoodOptimizer.h	2022-02-08 14:13:03.030561789 -0600
    @@ -38,7 +38,7 @@
      * \ingroup MinimalPathExtraction
    -class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
    +class IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer

and it stopped complaining. As to how to really solve this… I don’t know. The macro, as you mentioned, should be blank, and other parts of ITK have a similar structure, as has already been established in this thread.

Regarding the static situation, I do have -DBUILD_SHARED_LIBS:BOOL=ON in my (command-line) compilation options, but–again–other parts are working as expected. Also, I tried by changing build/Modules/Core/Common/MinimalPathExtractionExport.h from #ifdef ITK_STATIC to #if !defined(_WIN32) || defined(ITK_STATIC), and that didn’t work. What may be useful could be that this does compile (it’s an excerpt, the rest of the code, which is also shown above, should remain):

    #ifdef ITK_STATIC
    #  define MinimalPathExtraction_EXPORT
    #  define MinimalPathExtraction_HIDDEN
    #  ifndef MinimalPathExtraction_EXPORT
    #  define MinimalPathExtraction_EXPORT
    #  define MinimalPathExtraction_HIDDEN
    #  endif

but I think that this file is automatically generated. Thus, may be the next thing would be to look at ITKModuleMacros.cmake. Could it be that MinimalPathExtraction_EXPORT is being defined twice during the compilation? To be honest, the compilation is still running with the last change, but it’s already past this:

    [3/109] Building CXX object Modules/Remote/MinimalPathExtraction/src/CMakeFiles/MinimalPathExtraction.dir/itkIterateNeighborhoodOptimizer.cxx.o
    [4/109] Linking CXX shared library Wrapping/Generators/Python/itk/
    [5/109] Creating library symlink Wrapping/Generators/Python/itk/
    [6/109] Linking CXX shared library Wrapping/Generators/Python/itk/
    [7/109] Creating library symlink Wrapping/Generators/Python/itk/
    [8/109] Linking CXX shared module Wrapping/Generators/Python/itk/
    [9/109] Linking CXX shared module Wrapping/Generators/Python/itk/
    [10/109] Linking CXX shared module Wrapping/Generators/Python/itk/
    [11/109] Linking CXX shared module Wrapping/Generators/Python/itk/
    [48/109] Linking CXX shared module Wrapping/Generators/Python/itk/

Therefore, I guess that it’s safe to assume that it’s now compiling. I will now try to use it.

Once more, thank you Stephen @Stephen_Aylward and @dzenanz. I hope that this helps ITK and its community.

I found a solution:

  diff --git a/include/itkIterateNeighborhoodOptimizer.h b/include/itkIterateNeighborhoodOptimizer.h
  index dd11be1..9ec7b21 100644
  --- a/include/itkIterateNeighborhoodOptimizer.h
  +++ b/include/itkIterateNeighborhoodOptimizer.h
  @@ -18,7 +18,7 @@
   #ifndef itkIterateNeighborhoodOptimizer_h
   #define itkIterateNeighborhoodOptimizer_h

  -#include "MinimalPathExtractionExport.h"
  +#include "itkMacro.h"

   #include "itkArray.h"
   #include "itkSingleValuedNonLinearOptimizer.h"
  @@ -38,7 +38,7 @@ namespace itk
    ,* \ingroup MinimalPathExtraction
  -class MinimalPathExtraction_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer
  +class ITK_TEMPLATE_EXPORT IterateNeighborhoodOptimizer : public SingleValuedNonLinearOptimizer

Ah - the joys of {free software} :slight_smile:

Using this cannot be the right solution, as IterateNeighborhoodOptimizer is not a templated class. But if it is a working workaround for you, you can keep it. Probably removing the export specification is less wrong than this.

Glad we got it fixed, but too bad it required a hack. It is good to record this for others!

I think we should close this for now, and see if it occurs in the newer versions of ITK. The illogical nature of what you experienced suggests a corrupt build that you could get it to move past. Once it is compiled, it would be interesting to see if restoring the original file would cause the problem to re-appear or not. However - that would require quite a bit of re-compiling for you, so we won’t ask that of you at this time. However, if you ever encounter this again, we will definitely re-open and dig some more.


Just saw your follow up, and I agree with Dzenan, it is better to delete the original rather than replace it with an incorrect compiler directive that just happens to also be mapped to blank/nop. But regardless, it is a hack to address an error that cannot be easily explained, so…fingers cross it doesn’t return!

:laughing: It never occured to me that _TEMPLATE_ meant C++ template :stuck_out_tongue: I just saw that it provided the structure which was needed.

Thanks for the advice

[EDIT]: I have second thoughts about this (see next comment)

I’m unsure if I understand correctly, but are you saying

  1. remove the *_EXPORT macro from the class definition (leave everything else unchanged),
  2. compile,
  3. reenable the *_EXPORT macro, and
  4. compile again ?

I think I did it, and both make and samu (samurai is similar to ninja) detect the change. They do not go about compiling the whole of ITK again (compilation flags are the same; the compilation instructions are not reset by cmake). Step (4) fails again.

Now that I am reading your comment (and obviously you have much more experience than me on this and other matters), I am not so sure: Given the structure of ITK_TEMPLATE_EXPORT, I actually assumed that it was a template of a tag, as in "cookie-cutter for anything which needs _EXPORT" (not: this is for C++ templates). What would be interesting is to check if other header files which are generated automatically would work with ITK_TEMPLATE_EXPORT.

By the looks of it, the value of ITK_TEMPLATE_EXPORT depends on ITK_TEMPLATE_VISIBILITY_DEFAULT, and Modules/Core/Common/CMakeLists.txt states that:

“Set symbol visibility to default for template class declarations.

Granted, the class is not a template, but it seems to have the same type of use for the _EXPORT thing, that is: visibility.

Long story short, with this:

cmake ...
    -DModule_MinimalPathExtraction:BOOL=ON \

I have the issues of the _EXPORT tag, and like this:

cmake ...

the issues disappear. In other words, there may be something that TubeTK changes which affects the compilation of MinimalPathExtraction.

This might be of particular interest to @Stephen_Aylward.