# Visual Studio安装多个工具链后CMake生成Nmake文件时报错问题分析 ## 提要 解决在下面情况下发生的的问题: 1. 由于编译版本需要,在正常安装了Visual Studio的某个版本(如VS 2017)以后,又通过其他方法安装了另一个版本(如VS 2015)的**工具链**。注意,不是安装了另一个完整的VS,而是仅安装了**工具链**(编译器和库)。编辑器、GUI等还是用第一次安装的; 2. 需要使用`nmake`配合`cmake`编译某个东西。 ## 问题表现 首先,直接开个`cmd`打`cmake`或者启动`cmake-gui`肯定是不行的,需要首先打开VS提供的命令行工具,如“VS2015 x64 本机工具命令提示符”(根据想要编译的类型选择),这个快捷方式包含了一系列设置各种环境变量的东西。从这里打开的命令行启动`cmake`或者启动`cmake-gui`,才可以准确地找到`cl`等VS家的编译器。 如果你是只装了一个VS,此时正常操作应该是没问题。但是假如你的VS 2015是只装了一个工具链(装工具链的时候是自动创建“VS2015 x64 本机工具命令提示符”等),那么此时`cmake`可能会报错: ``` The C compiler identification is MSVC 19.0.24231.0 The CXX compiler identification is MSVC 19.0.24231.0 Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe -- broken CMake Error at C:/APP/cmake-3.10.3-win64-x64/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message): The C compiler "C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe" is not able to compile a simple test program. It fails with the following output: Change Dir: C:/dev/libs/VTK-8.1.0/build/CMakeFiles/CMakeTmp Run Build Command:"nmake" "/NOLOGO" "cmTC_7e1d4\fast" "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\amd64\nmake.exe" -f CMakeFiles\cmTC_7e1d4.dir\build.make /nologo -L CMakeFiles\cmTC_7e1d4.dir\build Building C object CMakeFiles/cmTC_7e1d4.dir/testCCompiler.c.obj C:\PROGRA~2\MICROS~1.0\VC\bin\amd64\cl.exe @C:\Users\metor\AppData\Local\Temp\nm52E4.tmp testCCompiler.c Linking C executable cmTC_7e1d4.exe C:\APP\cmake-3.10.3-win64-x64\bin\cmake.exe -E vs_link_exe --intdir=CMakeFiles\cmTC_7e1d4.dir --manifests -- C:\PROGRA~2\MICROS~1.0\VC\bin\amd64\link.exe /nologo @CMakeFiles\cmTC_7e1d4.dir\objects1.rsp @C:\Users\metor\AppData\Local\Temp\nm53A0.tmp RC Pass 1: command "rc /foCMakeFiles\cmTC_7e1d4.dir/manifest.res CMakeFiles\cmTC_7e1d4.dir/manifest.rc" failed (exit code 0) with the following output: 绯荤粺鎵句笉鍒版寚瀹氱殑鏂囦欢銆侼MAKE : fatal error U1077: “C:\APP\cmake-3.10.3-win64-x64\bin\cmake.exe”: 返回代码“0xffffffff” Stop. NMAKE : fatal error U1077: “"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\BIN\amd64\nmake.exe"”: 返回代码“0x2” Stop. CMake will not be able to correctly generate this project. Call Stack (most recent call first): CMakeLists.txt:14 (project) Configuring incomplete, errors occurred! See also "C:/dev/libs/VTK-8.1.0/build/CMakeFiles/CMakeOutput.log". See also "C:/dev/libs/VTK-8.1.0/build/CMakeFiles/CMakeError.log". ``` ## 解决方法 搜索错误信息`NMAKE U1077 0x2`,得到的信息多是路径设置不对,需要从专用命令行工具进入或者手动执行`vcvarall.bat`云云。问题是我已经从专用命令行进入了。也尝试了手动运行`vcvarall.bat`,结果无效。 > 以下方法引用自[https://blog.csdn.net/sean4m/article/details/60143222]。 > 注意这些办法解决不了问题。只是举个例子。 ``` 1.NMAKE:fatal error U1077.“cl.exe” return code 0xc0000135 产生原因:在安装visual studio的时候没有勾选注册环境变量导致的。 解决办法:在系统环境变量中加入visual studio的安装路径:vs安装路径\VC\Bin,以及vs安装路径\Common7\IDE 2.NMAKE:fatal error U1077. return code 0x2 产生原因:找不到代码文件中包含的头文件 解决办法:cmd下进入到vs安装路径\VC\Bin下,执行vcvars32,此时会执行vcvas32.bat自动为vs设置环境变量 3.NMAKE:fatal error U1077. return code 0x460 产生原因:你的工程中连接了一个lib文件,链接的时候却出现不能解析的外部符号。可能问题是你包含的lib是错的,或者有不兼容问题。我的问题就是后者,我的系统的32位的,但是链接了一个64位的lib. 解决办法:链接正确的lib ``` 仔细分析上述错误信息,乱码旁边这一行,发现原始错误信息是关于`rc`命令的。尝试在命令行中运行`rc`,报错找不到命令。推测`0x2`错误意义是找不到某个东西,而非专指找不到头文件。 再一番搜索,发现了[这个帖子](https://blog.csdn.net/u012814856/article/details/78530596),这里的错误是`0x1`,但原因与这里相同。全盘搜索`rc.exe`,发现只有三个,都在`C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\*`目录下,分别对应于`x86`、`x64`、`arm64`架构。 这下就容易了,重新打开一个“VS2015 x64 本机工具命令提示符”,先执行(**注意不要乱加双引号**): ``` set path=C:\Program Files (x86)\Windows Kits\10\bin\10.0.16299.0\x64;%path% ``` 然后再执行`rc`命令,应该不报错。此时再正常执行`cmake`,应该就一切OK了。 ## 附加题 为什么不像上面帖子一样,直接把`rc.exe`所在路径加入`Path`呢? 三个架构,三个`rc.exe`,只加入一个显然不对,三个全加显然就乱套了。如果是正常安装的VS,估计这里会自动处理,但安装的工具链就没办法了。反正不常用,也懒得去手改VS的内部文件了。