NB: TL;DR在底部。
我已经取得了一些进展,但不幸的是,乍一看应该影响所述行为的变量却没有任何作用(或者与评论中所期望的方式不同),即使强制将空值缓存给它们。摘录自Modules\Platform\Windows.cmake
:
if(CMAKE_GENERATOR MATCHES "NMake")
set(CMAKE_START_TEMP_FILE "@<<\n")
set(CMAKE_END_TEMP_FILE "\n<<")
endif()
include(Platform/WindowsPaths)
我在评论中找不到所引用的Windows-bcc32.cmake
,但可以推断这是指Borland C编译器可执行文件的旧名称。因此,Windows-Borland-C.cmake
和Windows-Borland-CXX.cmake
很可能是它们的继任者,它们又分别包含Windows-Embarcadero-C.cmake
和Windows-Embarcadero-CXX.cmake
。但是一旦我追踪了这个线索,我发现第二次提到Windows-bcc32.cmake
的引用(实际上在评论中提到了"Borland")似乎与此无关。
然而,重要的是两个变量CMAKE_START_TEMP_FILE
和MAKE_END_TEMP_FILE
。在调用project()
之后设置它们(即使强制写入缓存)也无法产生期望的效果。
这些变量在Windows.cmake
中定义(上面摘录)并在以下位置使用:
Modules\Platform\Windows-df.cmake
Modules\Platform\Windows-Embarcadero.cmake
Modules\Platform\Windows-MSVC.cmake
Modules\Platform\Windows-NVIDIA-CUDA.cmake
Modules\Platform\Windows-OpenWatcom.cmake
Modules\Platform\Windows-PGI.cmake
Tests\RunCMake\add_link_options\LINKER_expansion-list.cmake
Tests\RunCMake\Make\VerboseBuild.cmake
Tests\RunCMake\target_link_options\LINKER_expansion.cmake
Source\cmMakefileTargetGenerator.cxx
看起来 CMAKE_START_TEMP_FILE
和 CMAKE_END_TEMP_FILE
在使用它们的地方已经被展开,这是在 project()
完成之前。这意味着改变 Windows.cmake
将是唯一(丑陋的)可行选项... 除非...
简而言之
在调用 project()
之后添加以下内容,但请注意,如果/每当您处理大量文件/命令行参数时,这可能会达到 Windows 命令行长度限制的“上限”。但这是如何使 NMake 执行的命令再次可见。
set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 0 FORCE)
foreach(lang IN ITEMS C CXX)
foreach(cmd IN ITEMS COMPILE_OBJECT CREATE_SHARED_LIBRARY CREATE_PREPROCESSED_SOURCE CREATE_ASSEMBLY_SOURCE LINK_EXECUTABLE)
string(REPLACE "${CMAKE_START_TEMP_FILE}" "" CMAKE_${lang}_${cmd} "${CMAKE_${lang}_${cmd}}")
string(REPLACE "${CMAKE_END_TEMP_FILE}" "" CMAKE_${lang}_${cmd} "${CMAKE_${lang}_${cmd}}")
endforeach()
endforeach()
顺便说一下:替换语法是从Tests\RunCMake\Make\VerboseBuild.cmake
中获取的。我只是将其转化为循环,以更简洁地处理多个变量。
这样做的目的是将NMake文件中使用的各种命令中的CMAKE_START_TEMP_FILE
/CMAKE_END_TEMP_FILE
实例替换为空字符串,从而禁用内联文件的特殊NMake语法。因为事实证明,导致无法看到命令的罪魁祸首并不是CMake,而是NMake。
参考资料:Makefile中的内联文件
现在这打开了其他各种可尝试的替代方案。一些想法:
将以下内容翻译成中文:
- 在
CMAKE_END_TEMP_FILE
后追加KEEP
,以保留响应文件...
- 在
CMAKE_START_TEMP_FILE
后添加要使用的文件名(请参阅"重复使用内联文件"和此答案)。