在GYP中检测MSVC版本

Blo*_*Axe 4 c++ opencv node.js node-gyp

我正试图node-gyp configure在我的binding.gyp文件中检测msvc版本.基本上,我希望能够基于Visual C++版本链接特定的第三方库:

['OS=="win"' and 'toolset="vc12"' , {
    'libraries': [
        "opencv/lib/vc12/opencv_world300.lib"
    ],
}],

['OS=="win"' and 'toolset="vc11"' , {
    'libraries': [
        "opencv/lib/vc11/opencv_world300.lib"
    ],
}],

['OS=="win"' and 'toolset="vc10"' , {
    'libraries': [
        "opencv/lib/vc10/opencv_world300.lib"
    ],
}]
Run Code Online (Sandbox Code Playgroud)

不幸的是,toolset也不_toolset甚至$(TOOLSET)变量在GYP定义.我无法在GYP文档中找到这样的变量.有可能吗?

vul*_*ven 5

我无法从文档中找出如何检查工具集版本,但只找到顶级设置:https://chromium.googlesource.com/external/gyp/+/master/docs/UserDocumentation.md#典型的可执行文件的原型骷髅文件.

但是,在GitHub上@saper 想通了使用MSVS_VERSION,而不是:

['OS=="win"' and 'MSVS_VERSION=="2013"' , {
    'libraries': [
        "opencv/lib/vc12/opencv_world300.lib"
    ],
}],

['OS=="win"' and 'MSVS_VERSION=="2012"' , {
    'libraries': [
        "opencv/lib/vc11/opencv_world300.lib"
    ],
}],

['OS=="win"' and 'MSVS_VERSION=="2010"' , {
    'libraries': [
        "opencv/lib/vc10/opencv_world300.lib"
    ],
}]
Run Code Online (Sandbox Code Playgroud)

(在你的例子中,虽然toolset令牌不是由gyp识别的,但=应该替换为==)

示例:https://github.com/saper/node-sass/blob/c7e9cf0f0e0098e8316bd41722fc2edf4a835d9f/src/libsass.gyp#L91-L94.

限制1:

不幸的是,这些条件不会在.targets.vcxproj文件中发出(例如这个),但它会.vcxproj在后处理后发出给定版本的MSVS单独的条件,因此会使.vcxproj文件与较新/较旧版本的VCR不兼容.

但是,MSVS版本可以通过多种方式覆盖gyp,例如,使用环境变量:

在CMD中:

SET GYP_MSVS_VERSION=2012
Run Code Online (Sandbox Code Playgroud)

或者在PowerShell中:

$env:GYP_MSVS_VERSION=2015
Run Code Online (Sandbox Code Playgroud)

它也可以作为命令行参数传递:

node_modules/.bin/node-gyp build --msvs_version=2012
Run Code Online (Sandbox Code Playgroud)

如果同时存在env-var和命令行参数,则CLI arg将优先.

此CLI参数可以提供给npm任务,例如,为您的程序包的所有Windows使用者强制使用特定版本的MSVCR,否则会出错.

从那以后......

限制2:

从CLI arg,没有办法指定最小MSVS版本没有这样的标志:--min-msvs-version.

限制3:

如果安装了多个版本的MSBUILD,node-gyp的MSBUILD发现(目前)将忽略工具集的首选/必需版本.vcxproj,但优先于PATH中的版本.在这种情况下,您可能会收到错误,例如,如果您使用的是仅由VS2015提供的C99/C++ 1 [1/4/7]功能.为了解决这种情况:

  • 将PATH重置为所需的版本MSBuild bin目录.
  • 代替node-gyp buildrebuild,使用node-gyp configure随后"%ProgramFiles(x86)%\MSBuild\14.0\Bin\MSBuild" build/binding.sln /p:Configuration=Release(或从豪华,它会成为:&"${env:ProgramFiles(x86)}\MSBuild\14.0\Bin\MSBuild" build\binding.sln /p:Configuration=Release)
  • 通过发送节点gyp和pangyp的Pull请求来修复工具集版本感知的MSBUILD发现,如果你的Windows注册表技能不像我的那样生疏.:)