Makefiles: Problems in Windows related to maximum path length
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
I use cmake to generate "nmake Makefiles" in Windows (Visual Studio compiler). The project is rather large, hence, I tend to run into max path limitation problems. I have understood that I should not run into these problems since the hashing of the paths is intended to cope with most of these problems.
I have then downloaded the latest version of the cmake source code and found the reason for this problem:
Let us assume we have defined a project XX which defines two targets
which, e.g., are shared libraries.
I use very long path names and run into the system maximum path limitations. I understood that the maximum path length is 250 on Windows and leads to the shortened version of the object paths in case the path turns out to be too large. The shortening is based on the MD5 hashing mechanism.
I found that the object filename shortening happens in file "cmLocalGenerator.cxx". In that function, all object file lengths are checked against the maximum path length given. The function declaration is "bool cmLocalGeneratorCheckObjectName(std::string& objName, std::string::size_type dir_len, std::string::size_type max_total_len)", the object file path is characterized by the "dir_len" and the "objName", the path limitation is specified by "max_total_len".
In the path length comparison, the "dir_len" value comes from an evaluation of the variable "dir_max" which originates from a function called void "cmLocalUnixMakefileGenerator3::ComputeObjectFilenames(std::map<cmSourceFile const*, std::string>& mapping,cmGeneratorTarget const* gt) in "cmLocalUnixMakefileGenerator3.cpp" (involving functions "CreateSafeUniqueObjectFileName" and "GetObjectFileNameWithoutTarget").
As far as I understood, the variable "dir_max" and with it value of "dir_len" are incorrect: Coming back to our situation with the two targets which are derived from the project name, cmake generates object files in subfolders of "/CMakeFiles/XX.dir" and "/CMakeFiles/XX_variant1_with_modification_a.dir". In the function "cmLocalGeneratorCheckObjectName", however, the variable "dir_len" is related to a value of "dir_max" which corresponds to the "/CMakeFiles/XX.dir". This is not the maximum directory length as would be expected: In my opinion, the value of "dir_max" should be "/CMakeFiles/XX_variant1_with_modification_a.dir"!
If an object filename meets the constraints given the directory "/CMakeFiles/XX.dir" to not cause the filename shortening, it may happen that the path is too long for the directory "/CMakeFiles/XX_variant1_with_modification_a.dir". In the current implementation, the hashing/shortening mechanism is not triggered, the resulting object file name path is longer than 250 and I see a hard-to-understand build error.
The conclusion: the variable "dir_max" does not really contain the maximum length directory name given all targets but only the directory name of the first target or the project name - i did not follow this in detail. My solution to overcome this problem currently: I set the CMAKE_OBJECT_PATH_MAX value to a value lower than 250, e.g.,
in order to take into account that the maximum target path directory length is by maximum 10 larger than the project directory path.