node-gyp的作用我已经不想赘述了,这里给一个我之前文章的链接:cnblogs看这里知乎看这里。本文主要从源码入手,介绍node-gyp查找VisualStudio的过程

为了方便我们研究node-gyp的源码,我们随意创建一个node项目,然后我们npm install node-gyp,安装node-gyp这个包来开始我们源码探索之路吧。

E:\Projects\node-gyp-demo> npm init
...
package name: (gyp-demo)
version: (1.0.0)
...
npm install node-gyp@latest // 安装最新的node-gyp

安装完成后,在项目/node_modules/node-gyp中,已经有了我们需要的node-gyp的js脚本代码:

那么,我们应该怎么入手呢?这里需要再次提到node-gyp的处理过程,主要分为两个步骤:

  1. configure

gyp首先根据C/C++源码目录下的binding.gyp文件+操作系统(Windows、macOS以及Linux)+编译构建工具(Windows下的VS,macOS以及Linux下的make)来决定生成什么样的项目结构(Windows下的sln以及vcxproj、macOS以及Linux下的make项目)这一步是configure配置过程,不会进行源码的编译,仅仅是生成能够作为对应平台下对应编译工具输入的项目结构。

  1. build

生成项目结构以后,执行build过程调用对应的编译工具完成编译任务。

所以,我们首先查看lib/configure.js文件,试着从源码中探索一下。进入configure.js,一下就可以看到我们期望的东西(图片顶部显示了js代码位置):

如果当前进程平台是win32(Windows操作系统标识),则会引入模块find-visualstudio。暂时停止阅读configure.js的代码,直接上我们的主角:find-visualstudio.js

find-visualstudio.js

在该文件中定义了一个名为VisualStudioFinder的类,查找的过程就是执行创建该类的一个实例,并调用实例的一个名为findVisualStudio的方法。该方法被定义在该类的原型里:

对于该函数来说,主要分为了三个步骤:

  1. 对于参数msvs_version的处理
  2. 对于环境变量VSINSTALLDIR的处理
  3. 查找各个版本的VS

对于步骤1和2,我们暂时不进行解析,主要解析步骤3。因为绝大多数开发者就卡在这个步骤,导致安装需要原生编译的node模块失败。对于步骤3来说,我们不难看出处理的过程是优先查找本地的vs2017以及更高的版本,然后是vs2015,最后是vs2013,所以开发者Windows机器上没有安装VS或者是不在源码中支持的范围都一定会报错,提示VS找不到。我们首先解析findVisualStudio2017OrNewer这个函数,然后解析findVisualStudio2015findVisualStudio2013,对于后两个,实际上最终都是相同的逻辑,后面会提到。

findVisualStudio2017OrNewer

该函数的签名表示,这个函数是通过调用PowerShell脚本来获取关于VS2017或是更高版本VS的安装信息。

那么这段代码的运行情况到底如何呢?我们将该段代码单独拿出来,并将Find-VisualStudio.cs拷贝到运行目录下来Debug它。

上图中,我模拟了node-gyp中查询VS2017以上版本的函数,通过Debug方式断点调试:

ps变量值为:C:\WINDOWS\System32\WindowsPowerShell\v1.0\powershell.exe,即为Windows下对应的最初版本的PowerShell。cs文件不再赘述,我们也不对CSharp代码解读了。代码的最后就是执行弄得的chile_process模块中的execFile函数,通过传入可执行程序的完整路径已经执行参数,完成外部程序调用。

而在这一步当中,如果执行出现了异常就会导致node-gyp的执行过程出现异常,进而导致需要原生编译的模块无法完成安装等。为了方便开发人员进行在Windows上查找VS2017以及以上版本,我把这段代码和CSharp代码提取出来,放在了github仓库(w4ngzhen/node-gyp-find-vs-check),读者如果出现了问题,可以直接下载脚本和CSharp代码进行环境的确认。

当然,有些读者的机器还是VS2015或者VS2013等版本,我们继续分析。

findVisualStudio2015/2013

通过源码可以知道,最终都调用了方法:findOldVS,并且还知道,nodejs的主版本大于等于9时,根本不会查找VS了。接下来我们查看方法findOldVs

对于该段代码,其实一点也不难理解,就是根据注册表上对应的键去查找的VS的安装路径(PS:好像又学习到了VS的安装路径可以从注册表里面查看呢!)对于该段代码,本人不提供demo代码帮助查询了。有兴趣的读者可以自己提取代码,模拟调用。

Windows下node-gyp查找VS安装路径简单解析的更多相关文章

  1. Windows下Node.js+Express+WebSocket 安装配置

    Linux参考: Linux安装Node.js 使用Express搭建Web服务器 Node.js是一个Javascript运行环境(runtime).实际上它是对Google V8引擎进行了封装.V ...

  2. windows下node.js+sublime中安装coffeescript

    node.js中安装Coffeescript 1.我的node.js安装目录 2.node.js 全局模块所在目录   3.node.js安装coffeescript npm install -g c ...

  3. 安装选择msi格式还是zip(windows下Nodejs zip版下载安装及环境变量配置)

    安装选择msi格式还是zip((windows下Nodejs zip版下载安装及环境变量配置)) -----以node.js 安装为例: 1,外观对比: ✿ 简单介绍一下node的作用: • node ...

  4. Windows下当地RabbitMQ服务的安装

    Windows下本地RabbitMQ服务的安装 本文参考:刘若泽相关技术文档 当然这些内容页可以通过RabbitMQ官方网站获得. RabbitMQ配置说明手册 一.RaibbitMQ服务器配置 1. ...

  5. windows下使用cpanm进行模块安装

    windows下使用cpanm进行模块安装 要放假了,突然想整理一下手头上的软件,突然发现perl的安装模块这个功能不能用. 弄了一下,使得windows 下 perl 的 cpanm能用,避免成天为 ...

  6. windows下配置lamp环境(1)---安装Apache服务器2.2.25

    window下lamp成为wamp; 安装wamp环境的第一步是安装Apache服务器.下面开始安装步骤图文并茂. 一.双击安装包点“next”进行下一步,然后同意协议(这张图没有截):

  7. Windows下的lua-5.3.4安装过程

    Windows下的lua-5.3.4安装过程 Mingw平台下的编译过程: $ make echo$ make mingw$ make local $ make echo PLAT= none CC= ...

  8. <亲测>CentOS 7.3下Node.js 8.6安装配置(含NPM以及PM2)

    CentOS 7.3下Node.js 8.6安装配置 2017年09月30日 14:12:02 阅读数:2245更多 个人分类: Nodejs   版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  9. Windows 下 MySql 5.7.20安装及data和my.ini文件的配置(转)

    Windows 下 MySql 5.7.20安装及data和my.ini文件的配置     本文通过图文并茂的形式给大家介绍了MySql 5.7.20安装及data和my.ini文件的配置方法. my ...

随机推荐

  1. 关于oracle样例数据库emp、dept、salgrade的mysql脚本复杂查询分析

    大家可以自行网上找资源(网上资源比较多,不建议下载我的),也可以在我这里下载: 1.取得每个部门最高薪水的人员名称:正确   一共有4个单位,要进行左外连接 其中一个单位没得员工 SELECT dep ...

  2. 并发编程之:ThreadLocal

    大家好,我是小黑,一个在互联网苟且偷生的农民工. 从前上一期[并发编程之:synchronized] 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁. 但是,加锁通常情况下会让运行效率 ...

  3. Android中TextView和EditView常用属性设置

    Android中TextView和EditView常用属性设置 点击跳转

  4. MPI集群搭建

    高性能计算     ubantu下集群搭建 参考博客:https://blog.csdn.net/u012304016/article/details/52423738(尊重别人的知识产权),一些细节 ...

  5. NOIP模拟38:b

      这是T2.   一个容斥(其实也可以欧拉反演做,但是我不会).   首先开一个桶,记录第i行的j有多少个.   然后枚举1-\(maxn\),枚举他的值域内的倍数,记录倍数在第i行有多少个,将个数 ...

  6. Jenkins持续集成接口压测

    步骤 自动化压测- jmeter + shell Jenkins与jmeter压测,环境要求 自动压测运行逻辑 Jmeter输出压力测试报告 压测报告与Jenkins集成 Jenkins任务:源码同步 ...

  7. 开源自己编写的半人工标注平台PaddleOCRLabel(.NET Winform版本)

    大家好, 我是博客园的老用户了,许久不做.NET技术了,从2013年起,开始从事App技术,写过书,在Linux上搭建区块链,用GO写智能合约,使用nodejs搭建过微服务,用python写过爬虫,写 ...

  8. jsPlumb开发流程设计器

    前言 jsPlumb是一款开源软件,但jsPlumb toolkit是收费的. 本文主要使用jsPlumb实现一些简单的流程设计功能. 基础学习 首先引入jsplumb.min.js. <scr ...

  9. Linux之crontab命令

    简介 通过crontab 命令,我们可以在固定的间隔时间执行指定的系统指令或 shell 脚本.时间间隔的单位可以 是分钟.小时.日.月.周及以上的任意组合.这个命令非常适合周期性的日志分析或数据备份 ...

  10. python语言介绍及安装

    Python语言简介 Python是什么语言 Python是一种解释型的.可移植的.开源的脚本. 什么是计算机编程 计算机程序:为了让计算机执行某些操作或解决某个问题而编写的一系列有序指令的集合 如何 ...