Enable long path compilation

Hi,

First time here.
I was facing the fact that you have deactivated the compilation for long path on windows 10 even if we enabled long path in GPO.
See this commit:

In your discussion about that issue, I have noticed that fbudin succeed to compile ITK:

Moreover, things evolved one year ago:

So, if I am using ITK v5.0, I get this error:

ITK build directory path length is too long (55 > 50).Please set the ITK build directory to a directory with a shorter path.

However, modifying the ITK CMakeList with the following lines makes the compilation working fine:

if( CMAKE_HOST_WIN32 )
  if(${CMAKE_SYSTEM_VERSION} VERSION_GREATER "10.0.14392") # Win10 version 1607
    set(_LongPathKey LongPathsEnabled)
    execute_process(COMMAND reg query HKLM\\SYSTEM\\CurrentControlSet\\Control\\FileSystem /v ${_LongPathKey} OUTPUT_VARIABLE _output)
    string(REGEX MATCH "${_LongPathKey}.*REG_DWORD.*[0-9]x([0-9])" _regex ${_output})
    if (${CMAKE_MATCH_1})
      set(ITK_SKIP_PATH_LENGTH_CHECKS 1 "Skips max path length checks. These checks can be disabled for Windows version 10.0.14393 and later if registry key HKLM\\SYSTEM\\CurrentControlSet\\Control\\FileSystem\\LongPathsEnabled is set to 1 and all tools support long paths. As of January 2018, MSBuild and Visual Studio do not support it yet.")
    endif()
  endif()
endif()

I didn’t know if it would have been better to create an Issue on your GitHub or to directly propose a Merge Request on your release branch. Let me know.

By the way, I am using Visual Studio 2017:

– Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.18362.
– The C compiler identification is MSVC 19.16.27035.0
– The CXX compiler identification is MSVC 19.16.27035.0

– Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
– Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe – works

– Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe
– Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Tools/MSVC/14.16.27023/bin/Hostx86/x64/cl.exe – works

Microsoft ® Build Engine version 15.9.21+g9802d43bc3 for .NET Framework

Regards,

Thibault

1 Like

Welcome to the community Thibault.

Proposing a pull request on master branch is the preferred way to get contributions. Just be careful to remove long path error only on VS versions where it works.

1 Like

Thanks,

Why isn’t it acceptable to allow it for all Visual Studio since long paths are not supported by default: the developers have to manage GPO? And in the worst case, they will run into the compilation issue with the explicit error from the compiler.

That code is there as a convenience, to prevent a developer for waiting a long time for build to fail. More importantly, with older compiler versions there is no user-friendly error about long path, just a mysterious failure. And this frustration was the reason for adding the CMake code to prevent building.

1 Like

There may be a misunderstanding here. Maximum path length of the file system was never a problem.

Too long paths cause problems in the build system of large projects, as they make intermediate build files or data structures too large. Such limitations exist on all platforms: on MacOSX you get “malformed mach-o” error if you use too long paths.

1 Like

I am sorry but I don’t connect your point with this issue since you are talking about a MacOSX limitation on another project. The limitation I am pointing out is only applied on Windows toolchain according to the ITK CMakeLists.

if( CMAKE_HOST_WIN32 AND NOT ITK_SKIP_PATH_LENGTH_CHECKS )

  string( LENGTH "${CMAKE_CURRENT_SOURCE_DIR}" n )
  if( n GREATER 50 )
    message(
      FATAL_ERROR
      "ITK source code directory path length is too long (${n} > 50)."
      "Please move the ITK source code directory to a directory with a shorter path."
      )
  endif()

  string( LENGTH "${CMAKE_CURRENT_BINARY_DIR}" n )
  if( n GREATER 50 )
    message(
      WARNING
      "ITK_SKIP_PATH_LENGTH_CHECKS "
      "${ITK_SKIP_PATH_LENGTH_CHECKS}"
      )
    message(
      WARNING
      "CMAKE_MATCH_1 "
      "${CMAKE_MATCH_1}"
      )
    message(
      FATAL_ERROR
      "ITK build directory path length is too long (${n} > 50)."
      "Please set the ITK build directory to a directory with a shorter path."
      )
  endif()

endif()

What did I misunderstand?
What is your definition of a large project?
Otherwise, why is the path limitation set at 50?

It seems that your assumption is that path length limitation is imposed because of file system limitations. File system limitations rarely the bottleneck. The problem is that build systems on all platforms have limitations on the maximum length of file names, path lengths, etc. regardless of what is the maximum allowed path length on the file system.

ITK is already a large project by itself, so if you enable building all of its components then you may run into issues that would not occur if you only worked with a few hundred files.

The formula to compute the maximum allowed length from project name (yes, this affects the length of the allowed file name that you can use), folder name, and other parameters depends on the build toolchain version. 50 was a number that seemed to work well for most projects. If you are confident that you won’t have problems due to long paths then disable the check and see if you succeed. If the build is successful then you can use that build tree. Of course it does not mean that the same thing will work on a different computer.

See Microsoft build systems engineers’ take on this issue here: https://github.com/Microsoft/msbuild/issues/53

1 Like

You are saying that all platforms have limitations.
Could you explain why is this limitation in place only for Windows?

Could you be more specific? I would like to know what is the root cause of the limitation.
What is the maximum number of files supported without limitations?

It seems that you have no formula and that you accidentally make the toolchain work with a random number without having investigated this issue…

I have tried and I succeed: see my first message.

As I have said in my first message, since you have deactivated the compilation for path length > 50 for Windows ( 2018 Jan) changes have happened -> https://github.com/Microsoft/msbuild/issues/53#issuecomment-459062618

Enabling building of tests is more likely to produce problems. Enabling additional modules (which are OFF by default) can cause problems.

Does that mean things work?

No, for all the reasons detailed in comments above: just because MSBuild works, doesn’t mean your build will, because many other tools are involved.

devenv.exe , the main Visual Studio process, does not yet opt into support. That means only command-line builds will be affected by the MSBuild changes.

This is not too encouraging. It works on your computer, but might not on someone else’s computer.

The code singles out the Windows platform, because it is the most restrictive, and the most people use it. The limit of 50 characters was arrived at experimentally. It depends on which modules are enabled, and whether tests are enabled. The length of file names matters, not just the depth of directory hierarchy.

2 Likes

Ok, so if someone is succeeding in building all ITK with all additional modules and tests, then this solution should be proposed.

Why is this limitation not related to the activation of these additional modules and tests?

So, currently, with this path length limitation, all additional modules and tests are correctly built on all platforms?

“malformed mach-o” error started to show up not too long ago on MacOSX (due to operating system, build toolchain, or ITK changes) and there has not been enough time to understand and address this issue well enough. Probably path length warning or limitation would be useful for MacOSX, too.

I don’t have the answer for this - it depends on number of compilation units, libraries, etc. For example, lots of new issues came in with ITK modularization, even though total number of files did not change.

In recent years, I probably spent tens of hours with debugging issues related to long paths. At some point I ran tens of builds in parallel with different path lengths to collect more data so that I can understand what’s happening. Still, I have no formula. Microsoft published formulae for some older Visual Studio versions but they are not available for more recent versions.

Also, some randomness may be involved in the process, too. Just an example: long paths may cause your environment (where environment variables stored) reach the maximum allowed size. On certain Windows versions, the environment was allowed to grow up to 4x the allowed size, but a single character was removed at each n x 8192th position. Each of these removed characters corrupted a single path. This corruption caused build errors in some cases, while it did not matter in other cases. So, it happened that some build error could be resolved by making the path one character longer, or changing values of some unrelated environment variables. None of these issues happened if path lengths were kept short.

Some issues only come up if you link further libraries into your application. So, if you build a small test application with only ITK, it does not mean that the same thing will work if you link VTK to it as well.

It would be great if you could do your own investigation, with current operating system and build toolchain versions and share the results with us. As a testbed, you can use existing open-source applications that use ITK, such as 3D Slicer or MITK.

3 Likes

Ok! Thanks a lot for the clarification!

It makes the issue a way more understandable. I now see how to test the toolchain.

I will try to test all that when I will have more time, because it would be very appreciated for CI purpose.
However I will only test on Windows 10, but with different version of VS.