[CMake] Problems with cmake in Windows related to maximum path length

Hauke Krüger krueger at ind.rwth-aachen.de
Thu Nov 5 16:16:44 EST 2015


Hi everybody,

I am a new user of cmake and a new member of this mailing list.
Apologies in case the reason for my problem is the fact that I am not
experienced with using cmake.

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
1) "XX"
2) "XX_variant1_with_modification_a"

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 "<path-to-XX>/CMakeFiles/XX.dir" and
"<path-to-XX>/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 "<path-to-XX>/CMakeFiles/XX.dir".
This is not the maximum directory length as would be expected: In my
opinion, the value of "dir_max" should be
"<path-to-XX>/CMakeFiles/XX_variant1_with_modification_a.dir"!

If an object filename meets the constraints given the directory
"<path-to-XX>/CMakeFiles/XX.dir" to not cause the filename shortening,
it may happen that the path is too long for the directory
"<path-to-XX>/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., 

set(CMAKE_OBJECT_PATH_MAX 240)

in order to take into account that the maximum target path directory
length is by maximum 10 larger than the project directory path.

Does anyone else have an opinion on this? Or am I doing something in a
forbidden way?

Thank you for any comment and best regards

Hauke



More information about the CMake mailing list