Skip to content

Latest commit

 

History

History
230 lines (173 loc) · 6.76 KB

setup.py.md

File metadata and controls

230 lines (173 loc) · 6.76 KB

setup.py

import

#!/usr/bin/env python
import third_party
from util import run, root_path, build_path, build_mode
import os
import re
import sys
from distutils.spawn import find_executable

main

def main():
    os.chdir(root_path) # 1. 改变到当前目录 `cd ../..`

    third_party.fix_symlinks() # 2. 建立起 第三方项目与根项目相关的软连接
    third_party.download_gn()
    third_party.download_clang_format()
    third_party.download_clang()
    third_party.maybe_download_sysroot()

    write_lastchange()

    mode = build_mode(default=None) # 确认 deno脚本的等级模式
    if mode is not None: # 这里主要就是 mode == default == Node
        gn_gen(mode)
    else:
        gn_gen("release")
        gn_gen("debug")

write_if_not_exists

如果filename不存在, 就写入contents

def write_if_not_exists(filename, contents):
    if not os.path.exists(filename):
        with open(filename, "w+") as f:
            f.write(contents)

write_lastchange

如有需要,标上变化Change的标签

def write_lastchange():
    write_if_not_exists(
        "build/util/LASTCHANGE",
        "LASTCHANGE=c42e4ddbb7973bfb0c57a49ab6bf6dc432baad7e-\n")
    write_if_not_exists("build/util/LASTCHANGE.committime", "1535518087")
    # TODO 我们应该调用以下脚本,但它似乎会导致
    # 每次提交都要重建。
    # run([
    #    sys.executable, "build/util/lastchange.py", "-o",
    #    "build/util/LASTCHANGE", "--source-dir", root_path, "--filter="
    # ])

gn_args_are_generated

是否在字符串中, 匹配到下面文本.

# 如果在 args.gn 中找到此文本,我们假设它未经过手工编辑。
gn_args_header = [
    "# This file is automatically generated by tools/setup.py.",
    "# REMOVE THIS LINE to preserve any changes you make.", ""
]

def gn_args_are_generated(lines):
    for line in lines:
        if re.match("^\s*#.*REMOVE THIS LINE", line):
            return True
    return False

read_gn_args

  1. 不存在文件, 自然都是 否定的
  2. 存在, 返回 参数+是否手工
def read_gn_args(args_filename):
    if not os.path.exists(args_filename):
        return (None, False)  # 没有内容, 不是手工修改的

    with open(args_filename) as f:
        lines = f.read().splitlines()
        args = [l.strip() for l in lines if not re.match("^\s*(#|$)", l)]
        hand_edited = not gn_args_are_generated(lines)
        return (args, hand_edited)

write_gn_args

写入, gn 参数-argsargs_filename

def write_gn_args(args_filename, args):
    assert not gn_args_are_generated(args)  # 没有标题 -> 手工制作。
    lines = gn_args_header + args
    assert gn_args_are_generated(lines)  # 用标题 ->  生成。

    # 确保 args.gn 存在的目录。
    dir = os.path.dirname(args_filename)
    if not os.path.isdir(dir):
        os.makedirs(dir)

    with open(args_filename, "w") as f:
        f.write("\n".join(lines) + "\n")

generate_gn_args

获取 gn 需要的参数

TODO 详解 ?

def generate_gn_args(mode):
    out = []
    if mode == "release":
        out += ["is_official_build=true"]
    elif mode == "debug":
        pass
    else:
        print "Bad mode {}. Use 'release' or 'debug' (default)" % mode
        sys.exit(1)

    if "DENO_BUILD_ARGS" in os.environ:
        out += os.environ["DENO_BUILD_ARGS"].split()

    # 检查 ccache 或 sccache 是否在路径中,如果是,我们设置 cc_wrapper。
    cc_wrapper = find_executable("ccache") or find_executable("sccache")
    if cc_wrapper:
        out += ['cc_wrapper="%s"' % cc_wrapper]
        # 要使 cc_wrapper 在Windows上运行,我们需要选择自己的工具链                                                                                                                                                             
        # 通过覆盖'custom_toolchain'和'host_toolchain'。
        # TODO:有没有办法在没有 args.gn 的情况下使用它?
        if os.name == "nt":
            tc = "//build_extra/toolchain/win:win_clang_x64"
            out += ['custom_toolchain="%s"' % tc, 'host_toolchain="%s"' % tc]

    return out
  • find_executable 返回是否能在shell使用

gn_gen

GN 生成

deno第三方包-V8-使用的构建系统是Ninja,而 GN 是用来生成.ninja文件的工具。

GN 被包含在 depot_tools

def gn_gen(mode):
    os.environ["DENO_BUILD_MODE"] = mode

    # 我们不是直接使用 gn gen --args 而是写入 args.gn 文件。
    # 这是为了避免在传递命令行参数时,会覆盖, 引起 quoting/escaping 并发症

    args_filename = os.path.join(build_path(), "args.gn") # 根据构建模式,返回参数文件路径

    # 检查 args.gn 是否存在,以及它是自动生成还是手工制作。
    existing_gn_args, hand_edited = read_gn_args(args_filename)

    # 如果 args.gn 不是手工制作的,那就重新生成它。
    if hand_edited:
        print "%s: Using gn options from hand edited '%s'." % (mode,
                                                               args_filename)
        gn_args = existing_gn_args
    else:
        print "%s: Writing gn options to '%s'." % (mode, args_filename)
        gn_args = generate_gn_args(mode) # 生成的参数
        if gn_args != existing_gn_args:
            write_gn_args(args_filename, gn_args) # 写入

    for line in gn_args:
        print "  " + line # 调试展示

    # 运行 gn
    run([third_party.gn_path, "gen", build_path()],
        env=third_party.google_env()) # 整合环境变量

main

if __name__ == '__main__':
    sys.exit(main())