Troubleshooting long CMake object paths (CMAKE_OBJECT_PATH_MAX)

This page explains how to troubleshoot build errors in CMake projects caused by too long object file paths. This error typically results in the following message when trying to build the project:

ninja: error: mkdir(CMakeFiles/<very long path>): No such file or directory

You can also confirm it by reloading the project via context menu in Solution Explorer and checking the VisualGDB Build window:If you see one or more of the following warnings in the configuration log, the problem is caused by long object file paths:

CMake Warning in CMakeLists.txt:
The object file directory
 
<long path here>
 
has ### characters. The maximum full path to an object file is ### characters (see CMAKE_OBJECT_PATH_MAX). Object file
 
<object file path>
 
cannot be safely placed under this directory. The build may not work correctly.

Cause

In order to build the proejct, each source file (.c or .cpp) included in it needs to be compiled into a corresponding object file (.o). CMake would normally place the object files under following path:

<build directory>\CMakeFiles\<target name>\<relative path to source file>\<source file name>.o

If the source file is located on a different logical drive (e.g. C:\users\… while the project is located in D:\projects), CMake will use C/users/… as the relative path.

If the resulting path is too long (exceeds the value of the CMAKE_OBJECT_PATH_MAX variable), CMake will try to shorten it to the following form:

<build directory>\CMakeFiles\<target name>\<unique hash>\<source file name>.o

If you are using the Sysprogs CMake fork with this patch, it can shorten the long file paths even further to the following syntax:

<build directory>\CMakeFiles\<target name>\<unique hash without extension>

If the length of the build directory and the target name are still too long to use this form, CMake will show a warning and proceed with the default unshortened path.

Workarounds

This section describes various workarounds to the problem.

Move the project under a shorter path

The easiest way to work around this limitation is to move the project under a shorter path. If the project is located under source control, consider creating a symbolic link:

mklink /d c:\prj\Name c:\long\path\under\source\control

You can then open the project using the shorter path (c:\prj\Name) while still keeping it under source control.

Shorten the build directory name

Another option would be to reduce the length of the build directory:

E.g. changing it from build/$(PlatformName)/$(ConfigurationName) to just build could reduce final path length by 15 characters (WARNING: this would cause clashes between debug and release builds).

Increase CMAKE_OBJECT_PATH_MAX

Another option would be to increase the value of Tools->Options->VisualGDB->Embedded->Other->Maximum CMake Object File Path as close as possible to the actual MAX_PATH limit (260). Note that you would need to fully rebuild the project after changing it.

Shorten target names

You can also reduce the length of the object file paths by using shorter names for targets (individual executables/libraries), since CMake uses them to derive the paths. If the target causing problems is generated from a VisualGDB BSP and has a long name (e.g. com.sysprogs.arm.stm32.<…>), you force VisualGDB to use a shorter name for it by editing the BSP.XML file as follows:

  1. Locate the <EmbeddedFramework> element matching the target. Note that mutually exclusive frameworks (e.g. HALs for different device families) will have the same ClassID. Make sure you are editing the correct one.
  2. Add a <ShortUniqueName> element inside the <EmbeddedFramework> element containing the desired name of the library.
  3. Delete the bsp.cmake and bsp.cmake.ver files in the BSP directory.
  4. Reload and rebuild the project.