def build_v8(arch: str, config: str, runtime: str, spec: PackageSpec,
             extra_options: List[str]):
    depot_dir = DEPS_DIR / "depot_tools"
    gn = depot_dir / "gn.bat"
    env = make_v8_env(depot_dir)

    source_dir = DEPS_DIR / "v8-checkout" / "v8"

    build_dir = get_tmp_path(arch, config, runtime) / "v8"
    if not (build_dir / "build.ninja").exists():
        if build_dir.exists():
            shutil.rmtree(build_dir)

        if config == 'Release':
            configuration_args = [
                "is_official_build=true",
                "is_debug=false",
                "v8_enable_v8_checks=false",
            ]
        else:
            configuration_args = [
                "is_debug=true",
                "v8_enable_v8_checks=true",
            ]

        (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk()

        args = " ".join([
            "target_cpu=\"{}\"".format(msvc_platform_from_arch(arch)),
        ] + configuration_args + [
            "use_crt=\"{}\"".format(runtime),
            "is_clang=false",
            "visual_studio_path=\"{}\"".format(
                winenv.get_msvs_installation_dir()),
            "visual_studio_version=\"{}\"".format(winenv.get_msvs_version()),
            "wdk_path=\"{}\"".format(win10_sdk_dir),
            "windows_sdk_path=\"{}\"".format(win10_sdk_dir),
            "symbol_level=0",
            "strip_absolute_paths_from_debug_symbols=true",
        ] + spec.options + extra_options)

        perform(gn,
                "gen",
                PurePath("..", "..", "..") / build_dir.relative_to(ROOT_DIR),
                "--args=" + args,
                cwd=source_dir,
                env=env)

    monolith_path = build_dir / "obj" / "v8_monolith.lib"
    perform(NINJA, "v8_monolith", cwd=build_dir, env=env)

    version, api_version = v8.detect_version(source_dir)

    prefix = get_prefix_path(arch, config, runtime)

    include_dir = prefix / "include" / ("v8-" + api_version) / "v8"
    header_dirs = [
        source_dir / "include",
        build_dir / "gen" / "include",
    ]
    for header_dir in header_dirs:
        header_files = [
            PurePath(path.relative_to(header_dir))
            for path in header_dir.glob("**/*.h")
        ]
        copy_files(header_dir, header_files, include_dir)

    v8.patch_config_header(include_dir / "v8config.h", source_dir, build_dir,
                           gn, env)

    lib_dir = prefix / "lib"

    pkgconfig_dir = lib_dir / "pkgconfig"
    pkgconfig_dir.mkdir(parents=True, exist_ok=True)

    libv8_path = lib_dir / "libv8-{}.a".format(api_version)
    shutil.copyfile(monolith_path, libv8_path)

    (pkgconfig_dir / "v8-{}.pc".format(api_version)).write_text("""\
prefix={prefix}
libdir=${{prefix}}/lib
includedir=${{prefix}}/include/v8-{api_version}

Name: V8
Description: V8 JavaScript Engine
Version: {version}
Libs: -L${{libdir}} -lv8-{api_version}
Libs.private: {libs_private}
Cflags: -I${{includedir}} -I${{includedir}}/v8""" \
        .format(
            prefix=prefix.as_posix(),
            version=version,
            api_version=api_version,
            libs_private="-lshlwapi -lwinmm"
        ),
        encoding='utf-8')

    manifest_lines = [
        line.format(api_version=api_version) for line in [
            "lib/libv8-{api_version}.a",
            "lib/pkgconfig/v8-{api_version}.pc",
        ]
    ]
    for header in include_dir.glob("**/*"):
        manifest_lines.append(str(header.relative_to(prefix).as_posix()))
    manifest_lines.sort()
    manifest_path = get_manifest_path("v8", arch, config, runtime)
    manifest_path.parent.mkdir(parents=True, exist_ok=True)
    manifest_path.write_text("\n".join(manifest_lines), encoding='utf-8')
Exemple #2
0
def build_v8(platform, configuration, runtime):
    prefix = get_prefix_path(platform, configuration, runtime)

    lib_dir = os.path.join(prefix, "lib")
    pkgconfig_dir = os.path.join(lib_dir, "pkgconfig")
    if len(glob.glob(os.path.join(pkgconfig_dir, "v8-*.pc"))) > 0:
        return

    checkout_dir = os.path.join(ROOT_DIR, "v8-checkout")

    depot_dir = os.path.join(checkout_dir, "depot_tools")
    if not os.path.exists(depot_dir):
        perform(
            "git",
            "clone",
            "--recurse-submodules",
            "https://chromium.googlesource.com/chromium/tools/depot_tools.git",
            r"v8-checkout\depot_tools",
            cwd=ROOT_DIR)

    gclient = os.path.join(depot_dir, "gclient.bat")
    gn = os.path.join(depot_dir, "gn.bat")

    env = {}
    env.update(os.environ)
    env["PATH"] = depot_dir + ";" + env["PATH"]
    env["DEPOT_TOOLS_WIN_TOOLCHAIN"] = "0"

    config_path = os.path.join(checkout_dir, ".gclient")
    if not os.path.exists(config_path):
        spec = """solutions = [ {{ "url": "{url}", "managed": False, "name": "v8", "deps_file": "DEPS", "custom_deps": {{}}, }}, ]""" \
            .format(url=make_frida_repo_url("v8"))
        perform(gclient, "config", "--spec", spec, cwd=checkout_dir, env=env)

    source_dir = os.path.join(checkout_dir, "v8")
    if not os.path.exists(source_dir):
        perform(gclient, "sync", cwd=checkout_dir, env=env)

    build_dir = os.path.join(get_tmp_path(platform, configuration, runtime),
                             "v8")
    if not os.path.exists(os.path.join(build_dir, "build.ninja")):
        if os.path.exists(build_dir):
            shutil.rmtree(build_dir)

        if configuration == 'Release':
            configuration_args = [
                "is_official_build=true",
                "is_debug=false",
                "v8_enable_v8_checks=false",
            ]
        else:
            configuration_args = [
                "is_debug=true",
                "v8_enable_v8_checks=true",
            ]

        (win10_sdk_dir, win10_sdk_version) = winenv.get_win10_sdk()

        args = " ".join([
            "target_cpu=\"{}\"".format(platform_to_msvc(platform)),
        ] + configuration_args + [
            "use_crt=\"{}\"".format(runtime),
            "is_clang=false",
            "visual_studio_path=\"{}\"".format(
                winenv.get_msvs_installation_dir()),
            "visual_studio_version=\"{}\"".format(winenv.get_msvs_version()),
            "wdk_path=\"{}\"".format(win10_sdk_dir),
            "windows_sdk_path=\"{}\"".format(win10_sdk_dir),
            "symbol_level=0",
            "use_thin_lto=false",
            "v8_monolithic=true",
            "v8_use_external_startup_data=false",
            "is_component_build=false",
            "v8_enable_debugging_features=false",
            "v8_enable_disassembler=false",
            "v8_enable_gdbjit=false",
            "v8_enable_i18n_support=false",
            "v8_untrusted_code_mitigations=false",
            "treat_warnings_as_errors=false",
            "strip_absolute_paths_from_debug_symbols=true",
            "use_goma=false",
            "v8_embedder_string=\"-frida\"",
        ])

        perform(gn,
                "gen",
                os.path.relpath(build_dir, start=source_dir),
                "--args=" + args,
                cwd=source_dir,
                env=env)

    monolith_path = os.path.join(build_dir, "obj", "v8_monolith.lib")
    perform(NINJA, "v8_monolith", cwd=build_dir, env=env)

    version, api_version = v8.detect_version(source_dir)

    include_dir = os.path.join(prefix, "include", "v8-" + api_version, "v8")
    for header_dir in [
            os.path.join(source_dir, "include"),
            os.path.join(build_dir, "gen", "include")
    ]:
        header_files = [
            os.path.relpath(path, header_dir)
            for path in glob.glob(os.path.join(header_dir, "**", "*.h"),
                                  recursive=True)
        ]
        copy_files(header_dir, header_files, include_dir)

    v8.patch_config_header(os.path.join(include_dir, "v8config.h"), source_dir,
                           build_dir, gn, env)

    if not os.path.exists(pkgconfig_dir):
        os.makedirs(pkgconfig_dir)

    libv8_path = os.path.join(lib_dir, "libv8-{}.a".format(api_version))
    shutil.copyfile(monolith_path, libv8_path)

    with open(os.path.join(pkgconfig_dir, "v8-{}.pc".format(api_version)),
              "w",
              encoding='utf-8') as f:
        f.write("""\
prefix={prefix}
libdir=${{prefix}}/lib
includedir=${{prefix}}/include/v8-{api_version}

Name: V8
Description: V8 JavaScript Engine
Version: {version}
Libs: -L${{libdir}} -lv8-{api_version}
Libs.private: {libs_private}
Cflags: -I${{includedir}} -I${{includedir}}/v8""".format(
            prefix=prefix.replace("\\", "/"),
            version=version,
            api_version=api_version,
            libs_private="-lshlwapi -lwinmm"))