You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

VS2017下CMake编译C++项目报错:cl.exe无法编译测试程序

嘿,看起来你这问题是编译器架构不匹配加上NMake没拿到VS的完整编译环境导致的——毕竟昨天还正常,大概率是环境变量或者build目录里的旧配置搞的鬼。下面给你两种解决办法,优先推荐第一种,省心很多:

解决CMake + VS2017编译时NMAKE U1045错误(编译器识别失败)

方案1:改用VS专属的CMake生成器(强烈推荐)

NMake Makefiles特别容易因为VS环境变量没初始化全出问题,换成VS2017的专用生成器,CMake会自动帮你处理编译环境和架构匹配,不用手动折腾:

修改你的tasks.json里的任务配置:

{
  "version": "2.0.0",
  "tasks": [
    {
      "label": "CMake Debug",
      "type": "shell",
      "options": {
        "cwd": "${workspaceRoot}/build"
      },
      "command": "cmake",
      "args": [
        "-G", "Visual Studio 15 2017 Win64",
        "-DCMAKE_BUILD_TYPE=Debug",
        ".."
      ],
      "problemMatcher": [ "$msCompile" ]
    },
    {
      "label": "Build",
      "type": "shell",
      "options": {
        "cwd": "${workspaceRoot}/build"
      },
      "command": "msbuild",
      "args": [
        // 替换成你实际的解决方案名,或者用通配符自动匹配
        "${workspaceRoot}/build/*.sln",
        "/p:Configuration=Debug",
        "/m" // 启用多线程编译,加快速度
      ],
      "group": {
        "kind": "build",
        "isDefault": true
      }
    }
  ]
}

方案2:修复NMake的环境配置(如果必须用NMake)

要是你非得用NMake Makefiles,那得先确保VS的64位编译环境变量被正确加载:

  • 最直接的方式:打开VS2017 x64 Native Tools Command Prompt,在这个命令行里启动VS Code,这样所有环境变量都会自动继承。
  • 或者修改tasks.json,让CMake命令先加载VS的环境脚本:
{
  "label": "CMake Debug",
  "type": "shell",
  "options": {
    "cwd": "${workspaceRoot}/build"
  },
  "command": "cmd.exe",
  "args": [
    "/c",
    "\"C:/Program Files (x86)/Microsoft Visual Studio/2017/Community/VC/Auxiliary/Build/vcvars64.bat\" && cmake -G \"NMake Makefiles\" -DCMAKE_BUILD_TYPE=Debug .."
  ],
  "problemMatcher": [ "$gcc" ]
}

这个命令会先加载64位的VS编译环境,再执行CMake,避免架构不匹配的问题。

必做的前置操作

不管用哪个方案,先把build目录里的所有文件删掉,重新建个空的build目录——旧的错误配置残留很可能导致问题反复出现。另外也可以检查下VS2017的C++开发工具是不是装全了,比如MSVC编译器、NMake这些组件,在VS Installer里就能查看。

为啥会出这问题?

从你给的日志里能看出来:

你用的是Hostx64/x86/cl.exe(64位主机编译32位目标),但调用的NMake是64位的HostX64/x64/nmake.exe,架构不匹配导致NMake没法正确调用编译器,就出现了U1045: 动态生成失败: Invalid argument的错误。而且VS的编译环境变量没加载全的话,CMake也识别不了编译器的完整功能,直接就判定编译器“broken”了。

内容的提问来源于stack exchange,提问作者Jack Nonnen

火山引擎 最新活动