Skip to content

Node.js是如何启动的? #5

@yorkie

Description

@yorkie

在每次安装node,我指的是install from source的时候,我们都是通过./configure来执行joyent/node下的configure文件作为开始的,下面简单地说一说node究竟在configure下了多大功夫吧。

查看这个文件可以从第637行开始看起:

通过output来声明一个默认的配置属性,然后通过调用:

configure_node(output)
configure_libz(output)
configure_http_parser(output)
configure_cares(output)
configure_libuv(output)
configure_v8(output)
configure_openssl(output)
configure_winsdk(output)

给output初始化,在每一个配置函数中给相应的依赖软件添加配置项,方便后面将这些软件集成到Node程序中。

  • configure_node: 定义了一些关于操作系统的相关的参数配置
  • configure_libz: 定义了与zlib相关的参数配置,zlib是提供数据压缩用的函式库,代码在deps/zlib中。
  • configure_http_parser: 用于解析HTTP报文的一个C函数库,代码同样在node的deps目录下可以找到,以下类似。
  • ...

下面我们将注意力转到代码的第663行,pprint.pprint(output, indent=2),这段代码打印了我们当前的所有配置信息,本人clone了node v0.10.12的源文件,并在其目录下运行./configure,得到如下输出:

{ 'target_defaults': { 
                       'cflags': [],
                       'default_configuration': 'Release',
                       'defines': ['OPENSSL_NO_SSL2=1'],
                       'include_dirs': [],
                       'libraries': [] },
  'variables': { 'clang': 1,
                 'host_arch': 'x64',
                 'node_install_npm': 'true',
                 'node_prefix': '',
                 'node_shared_cares': 'false',
                 'node_shared_http_parser': 'false',
                 'node_shared_libuv': 'false',
                 'node_shared_openssl': 'false',
                 'node_shared_v8': 'false',
                 'node_shared_zlib': 'false',
                 'node_tag': '',
                 'node_use_dtrace': 'true',
                 'node_use_etw': 'false',
                 'node_use_mdb': 'false',
                 'node_use_openssl': 'true',
                 'node_use_perfctr': 'false',
                 'python': '/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python',
                 'target_arch': 'x64',
                 'uv_parent_path': '/deps/uv/',
                 'uv_use_dtrace': 'true',
                 'v8_enable_gdbjit': 0,
                 'v8_no_strict_aliasing': 1,
                 'v8_use_snapshot': 'true'}}
creating  ./config.gypi
creating  ./config.mk

在输出的最后两行,可以看到这个脚本生成了两个文件:./config.gypiconfig.mk,它们将会在makefile中有所用途。

在脚本的最后一行:
subprocess.call([sys.executable, 'tools/gyp_node'] + gyp_args)会执行命令python tools/gyp_node,因此我们需要继续阅读tools/gyp_node中的代码。

代码:tools/gyp_node
分析:这个脚本仍然是一个python脚本,我们可以先从第23行代码入手,从23到倒数第二行的过程中,程序通过判断操作系统类型来生成运行gyp的相关参数,最后通过函数run_gyp来生成。

Node如何启动只是开了个头,不过偶是一个懒惰的人,如果你无意间看到,只希望你一扫而过就行,别太认真。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions