mirror of
https://github.com/dart-lang/sdk
synced 2024-10-14 21:34:33 +00:00
152 lines
4.9 KiB
Python
152 lines
4.9 KiB
Python
|
#!/usr/bin/env python3
|
||
|
# Copyright 2014 The Chromium Authors. All rights reserved.
|
||
|
# Use of this source code is governed by a BSD-style license that can be
|
||
|
# found in the LICENSE file.
|
||
|
"""Helper script for GN to run `dart compile exe` and produce a depfile.
|
||
|
|
||
|
Run with:
|
||
|
python3 gn_dart_compile_exe.py \
|
||
|
--dart-binary <path to dart binary> \
|
||
|
--entry-point <path to dart entry point> \
|
||
|
--output <path to resulting executable> \
|
||
|
--sdk-hash <SDK hash> \
|
||
|
--packages <path to package config file> \
|
||
|
--depfile <path to depfile to write>
|
||
|
|
||
|
This is workaround for `dart compile exe` not supporting --depfile option
|
||
|
in the current version of prebuilt SDK. Once we roll in a new version
|
||
|
of checked in SDK we can remove this helper.
|
||
|
"""
|
||
|
|
||
|
import argparse
|
||
|
import os
|
||
|
import sys
|
||
|
import subprocess
|
||
|
from tempfile import TemporaryDirectory
|
||
|
|
||
|
|
||
|
def parse_args(argv):
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument("--dart-sdk",
|
||
|
required=True,
|
||
|
help="Path to the prebuilt Dart SDK")
|
||
|
parser.add_argument("--sdk-hash", required=True, help="SDK hash")
|
||
|
parser.add_argument("--entry-point",
|
||
|
required=True,
|
||
|
help="Dart entry point to precompile")
|
||
|
parser.add_argument("--output",
|
||
|
required=True,
|
||
|
help="Path to resulting executable ")
|
||
|
parser.add_argument("--packages",
|
||
|
required=True,
|
||
|
help="Path to package config file")
|
||
|
parser.add_argument("--depfile",
|
||
|
required=True,
|
||
|
help="Path to depfile to write")
|
||
|
return parser.parse_args(argv)
|
||
|
|
||
|
|
||
|
# Run a command, swallowing the output unless there is an error.
|
||
|
def run_command(command):
|
||
|
try:
|
||
|
subprocess.check_output(command, stderr=subprocess.STDOUT)
|
||
|
return True
|
||
|
except subprocess.CalledProcessError as e:
|
||
|
print("Command failed: " + " ".join(command) + "\n" + "output: " +
|
||
|
_decode(e.output))
|
||
|
return False
|
||
|
except OSError as e:
|
||
|
print("Command failed: " + " ".join(command) + "\n" + "output: " +
|
||
|
_decode(e.strerror))
|
||
|
return False
|
||
|
|
||
|
|
||
|
def _decode(bytes):
|
||
|
return bytes.decode("utf-8")
|
||
|
|
||
|
|
||
|
def main(argv):
|
||
|
args = parse_args(argv[1:])
|
||
|
|
||
|
# Unless the path is absolute, this script is designed to run binaries
|
||
|
# produced by the current build, which is the current working directory when
|
||
|
# this script is run.
|
||
|
prebuilt_sdk = os.path.abspath(args.dart_sdk)
|
||
|
|
||
|
dart_binary = os.path.join(prebuilt_sdk, "bin", "dart")
|
||
|
if not os.path.isfile(dart_binary):
|
||
|
print("Binary not found: " + dart_binary)
|
||
|
return 1
|
||
|
|
||
|
dartaotruntime_binary = os.path.join(prebuilt_sdk, "bin", "dartaotruntime")
|
||
|
if not os.path.isfile(dartaotruntime_binary):
|
||
|
print("Binary not found: " + dartaotruntime_binary)
|
||
|
return 1
|
||
|
|
||
|
gen_kernel_snapshot = os.path.join(prebuilt_sdk, "bin", "snapshots",
|
||
|
"gen_kernel_aot.dart.snapshot")
|
||
|
if not os.path.isfile(gen_kernel_snapshot):
|
||
|
print("Binary not found: " + gen_kernel_snapshot)
|
||
|
return 1
|
||
|
|
||
|
platform_dill = os.path.join(prebuilt_sdk, "lib", "_internal",
|
||
|
"vm_platform_strong.dill")
|
||
|
if not os.path.isfile(platform_dill):
|
||
|
print("Binary not found: " + platform_dill)
|
||
|
return 1
|
||
|
|
||
|
# Compile the executable.
|
||
|
ok = run_command([
|
||
|
dart_binary,
|
||
|
"compile",
|
||
|
"exe",
|
||
|
"--packages",
|
||
|
args.packages,
|
||
|
f"-Dsdk_hash={args.sdk_hash}",
|
||
|
"-o",
|
||
|
args.output,
|
||
|
args.entry_point,
|
||
|
])
|
||
|
if not ok:
|
||
|
return 1
|
||
|
|
||
|
# Collect dependencies by using gen_kernel.
|
||
|
with TemporaryDirectory() as tmpdir:
|
||
|
output_dill = os.path.join(tmpdir, "output.dill")
|
||
|
ok = run_command([
|
||
|
dartaotruntime_binary,
|
||
|
gen_kernel_snapshot,
|
||
|
"--platform",
|
||
|
platform_dill,
|
||
|
"--packages",
|
||
|
args.packages,
|
||
|
"--depfile",
|
||
|
args.depfile,
|
||
|
"-o",
|
||
|
output_dill,
|
||
|
args.entry_point,
|
||
|
])
|
||
|
if not ok:
|
||
|
return 1
|
||
|
|
||
|
# Fix generated depfile to refer to the output file name instead
|
||
|
# of referring to the temporary dill file we have generated.
|
||
|
with open(args.depfile, "r") as f:
|
||
|
content = f.read()
|
||
|
(target_name, deps) = content.split(": ", 1)
|
||
|
if target_name != output_dill:
|
||
|
print(
|
||
|
"ERROR: Something is wrong with generated depfile: expected {output_dill} as target, but got {target_name}"
|
||
|
)
|
||
|
return 1
|
||
|
with open(args.depfile, "w") as f:
|
||
|
f.write(args.output)
|
||
|
f.write(": ")
|
||
|
f.write(deps)
|
||
|
|
||
|
return 0
|
||
|
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
sys.exit(main(sys.argv))
|