Hello,
we have hit once again the great wall of too long paths on Windows. This time, it is due to resource files. We use ninja as a generator. The command line to compile RC files looks like:
C:\Path\mingw64\bin\windres.exe -O coff -DSOME_DEFINE_1 -DSOME_DEFINE_2 -I ... -I ... -I ... c:/Path2/build/.../SomeLib.rc
The target has a long list of include directories (-I …), and they are passed as absolute paths, which leads quickly to a command line that is longer than 8192 characters, the upper limit.
The tool executed is windres.exe, from the MinGW toolchain. windres supports resource files:
Usage: C:\Path\mingw64\bin\windres.exe [option(s)] [input-file] [output-file]
The options are:
...
@<file> Read options from <file>
...
It appears to be some undocumented options to enable response files:
set(CMAKE_C_USE_RESPONSE_FILE_FOR_OBJECTS TRUE)
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS TRUE)
set(CMAKE_NINJA_FORCE_RESPONSE_FILE TRUE)
But it has no effect when building for resource files. Looking at the CMake source code, namely Source/cmNinjaTargetGenerator.cxx
, the behavior seems hard coded:
bool const lang_supports_response = lang != "RC";
if (lang_supports_response && this->ForceResponseFile()) {
...
Also hard coded is to use absolute paths:
std::string includeFlags = this->LocalGenerator->GetIncludeFlags(
includes, this->GeneratorTarget, language, config, false,
// full include paths for RC needed by cmcldeps
language == "RC" ? cmLocalGenerator::IncludePathStyle::Absolute
: cmLocalGenerator::IncludePathStyle::Default);
I found a workaround. Instead of adding the RC file as source to the target, I created a custom command that calls windres without the include paths, which are not necessary in our case.
Questions out of curiosity:
- what would it take to support response files for RC files as well? e.g. what needs to be done concretely?
- is there any reason why the CMAKE_RESPONSE_FILE files are not documented?
Thanks,
Olivier