dart-sdk/tools/create_sdk.py
Zachary Anderson 3355532f01 Fuchsia: Copy libraries to SDK bin directory
Dart in Fuchsia-land is dynamically linked. For the SDK for the host,
that is used during the Fuchsia build for running the analyzer, etc.,
we have to put the .so's next to the binary so the dynamic linker
can find them.

R=asiva@google.com

Review-Url: https://codereview.chromium.org/2646853005 .
2017-01-20 13:06:34 -08:00

358 lines
11 KiB
Python
Executable file

#!/usr/bin/env python
#
# Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.
#
# A script which will be invoked from gyp to create an SDK.
#
# Usage: create_sdk.py sdk_directory
#
# The SDK will be used either from the command-line or from the editor.
# Top structure is
#
# ..dart-sdk/
# ....bin/
# ......dart or dart.exe (executable)
# ......dart.lib (import library for VM native extensions on Windows)
# ......dartdoc
# ......dartfmt
# ......dart2js
# ......dartanalyzer
# ......dartdevc
# ......pub
# ......snapshots/
# ........analysis_server.dart.snapshot
# ........dart2js.dart.snapshot
# ........dartanalyzer.dart.snapshot
# ........dartdoc.dart.snapshot
# ........dartfmt.dart.snapshot
# ........dartdevc.dart.snapshot
# ........pub.dart.snapshot
# ........utils_wrapper.dart.snapshot
#.........resources/
#...........dartdoc/
#..............packages
#.............resources/
#.............templates/
# ....include/
# ......dart_api.h
# ......dart_mirrors_api.h
# ......dart_native_api.h
# ......dart_tools_api.h
# ....lib/
# ......dart_client.platform
# ......dart_server.platform
# ......dart_shared.platform
# ......_internal/
#.........spec.sum
#.........strong.sum
#.........dev_compiler/
# ......analysis_server/
# ......analyzer/
# ......async/
# ......collection/
# ......convert/
# ......core/
# ......front_end/
# ......html/
# ......internal/
# ......io/
# ......isolate/
# ......js/
# ......js_util/
# ......math/
# ......mirrors/
# ......typed_data/
# ......api_readme.md
# ....util/
# ......(more will come here)
import optparse
import os
import re
import sys
import subprocess
import utils
HOST_OS = utils.GuessOS()
# TODO(dgrove): Only import modules following Google style guide.
from os.path import basename, dirname, join, realpath, exists
# TODO(dgrove): Only import modules following Google style guide.
from shutil import copyfile, copymode, copytree, ignore_patterns, rmtree, move
def GetOptions():
options = optparse.OptionParser(usage='usage: %prog [options]')
options.add_option("--sdk_output_dir",
help='Where to output the sdk')
options.add_option("--snapshot_location",
help='Location of the snapshots.')
options.add_option("--copy_libs",
action="store_true", default=False,
help='Copy dynamically linked libraries to the SDK bin directory.')
return options.parse_args()
def ReplaceInFiles(paths, subs):
"""Reads a series of files, applies a series of substitutions to each, and
saves them back out. subs should by a list of (pattern, replace) tuples."""
for path in paths:
contents = open(path).read()
for pattern, replace in subs:
contents = re.sub(pattern, replace, contents)
dest = open(path, 'w')
dest.write(contents)
dest.close()
def Copy(src, dest):
copyfile(src, dest)
copymode(src, dest)
def CopyShellScript(src_file, dest_dir):
"""Copies a shell/batch script to the given destination directory. Handles
using the appropriate platform-specific file extension."""
file_extension = ''
if HOST_OS == 'win32':
file_extension = '.bat'
# If we're copying an SDK-specific shell script, strip off the suffix.
dest_file = basename(src_file)
if dest_file.endswith('_sdk'):
dest_file = dest_file.replace('_sdk', '')
src = src_file + file_extension
dest = join(dest_dir, dest_file + file_extension)
Copy(src, dest)
def CopyLibs(out_dir, bin_dir):
for library in ['libcrypto', 'libssl']:
ext = '.so'
if HOST_OS == 'macos':
ext = '.dylib'
elif HOST_OS == 'win32':
ext = '.dll'
src = os.path.join(out_dir, library + ext)
dst = os.path.join(bin_dir, library + ext)
if os.path.isfile(src):
copyfile(src, dst)
copymode(src, dst)
def CopyDartScripts(home, sdk_root):
for executable in ['dart2js_sdk', 'dartanalyzer_sdk', 'dartfmt_sdk',
'pub_sdk', 'dartdoc', 'dartdevc_sdk']:
CopyShellScript(os.path.join(home, 'sdk', 'bin', executable),
os.path.join(sdk_root, 'bin'))
def CopySnapshots(snapshots, sdk_root):
for snapshot in ['analysis_server', 'dart2js', 'dartanalyzer', 'dartfmt',
'utils_wrapper', 'pub', 'dartdoc', 'dartdevc']:
snapshot += '.dart.snapshot'
copyfile(join(snapshots, snapshot),
join(sdk_root, 'bin', 'snapshots', snapshot))
def CopyAnalyzerSources(home, lib_dir):
for library in ['analyzer', 'analysis_server', 'front_end']:
copytree(join(home, 'pkg', library), join(lib_dir, library),
ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
'.gitignore', 'packages'))
def CopyDartdocResources(home, sdk_root):
RESOURCE_DIR = join(sdk_root, 'bin', 'snapshots', 'resources')
DARTDOC = join(RESOURCE_DIR, 'dartdoc')
copytree(join(home, 'third_party', 'pkg', 'dartdoc', 'lib', 'templates'),
join(DARTDOC, 'templates'))
copytree(join(home, 'third_party', 'pkg', 'dartdoc', 'lib', 'resources'),
join(DARTDOC, 'resources'))
# write the .packages file
PACKAGES_FILE = join(DARTDOC, '.packages')
packages_file = open(PACKAGES_FILE, 'w')
packages_file.write('dartdoc:.')
packages_file.close()
def CopyAnalysisSummaries(snapshots, lib):
copyfile(join(snapshots, 'spec.sum'),
join(lib, '_internal', 'spec.sum'))
copyfile(join(snapshots, 'strong.sum'),
join(lib, '_internal', 'strong.sum'))
def CopyDevCompilerSdk(home, lib):
copyfile(join(home, 'pkg', 'dev_compiler', 'lib', 'sdk', 'ddc_sdk.sum'),
join(lib, '_internal', 'ddc_sdk.sum'))
copytree(join(home, 'pkg', 'dev_compiler', 'lib', 'js'),
join(lib, 'dev_compiler'))
def Main():
# Pull in all of the gypi files which will be munged into the sdk.
HOME = dirname(dirname(realpath(__file__)))
(options, args) = GetOptions()
SDK = options.sdk_output_dir
SDK_tmp = '%s.tmp' % SDK
SNAPSHOT = options.snapshot_location
# TODO(dgrove) - deal with architectures that are not ia32.
if exists(SDK):
rmtree(SDK)
if exists(SDK_tmp):
rmtree(SDK_tmp)
os.makedirs(SDK_tmp)
# Create and populate sdk/bin.
BIN = join(SDK_tmp, 'bin')
os.makedirs(BIN)
os.makedirs(join(BIN, 'snapshots'))
# Copy the Dart VM binary and the Windows Dart VM link library
# into sdk/bin.
#
# TODO(dgrove) - deal with architectures that are not ia32.
build_dir = os.path.dirname(SDK)
dart_file_extension = ''
if HOST_OS == 'win32':
dart_file_extension = '.exe'
dart_import_lib_src = join(HOME, build_dir, 'dart.lib')
dart_import_lib_dest = join(BIN, 'dart.lib')
copyfile(dart_import_lib_src, dart_import_lib_dest)
dart_src_binary = join(HOME, build_dir, 'dart' + dart_file_extension)
dart_dest_binary = join(BIN, 'dart' + dart_file_extension)
copyfile(dart_src_binary, dart_dest_binary)
copymode(dart_src_binary, dart_dest_binary)
# Strip the binaries on platforms where that is supported.
if HOST_OS == 'linux':
subprocess.call(['strip', dart_dest_binary])
elif HOST_OS == 'macos':
subprocess.call(['strip', '-x', dart_dest_binary])
#
# Create and populate sdk/include.
#
INCLUDE = join(SDK_tmp, 'include')
os.makedirs(INCLUDE)
copyfile(join(HOME, 'runtime', 'include', 'dart_api.h'),
join(INCLUDE, 'dart_api.h'))
copyfile(join(HOME, 'runtime', 'include', 'dart_mirrors_api.h'),
join(INCLUDE, 'dart_mirrors_api.h'))
copyfile(join(HOME, 'runtime', 'include', 'dart_native_api.h'),
join(INCLUDE, 'dart_native_api.h'))
copyfile(join(HOME, 'runtime', 'include', 'dart_tools_api.h'),
join(INCLUDE, 'dart_tools_api.h'))
#
# Create and populate sdk/lib.
#
LIB = join(SDK_tmp, 'lib')
os.makedirs(LIB)
#
# Create and populate lib/{async, core, isolate, ...}.
#
os.makedirs(join(LIB, 'html'))
for library in [join('_blink', 'dartium'),
join('_chrome', 'dart2js'), join('_chrome', 'dartium'),
join('_internal', 'js_runtime'),
join('_internal', 'sdk_library_metadata'),
'async', 'collection', 'convert', 'core', 'developer',
'internal', 'io', 'isolate',
join('html', 'dart2js'), join('html', 'dartium'),
join('html', 'html_common'),
join('indexed_db', 'dart2js'), join('indexed_db', 'dartium'),
'js', 'js_util', 'math', 'mirrors', 'profiler', 'typed_data',
join('svg', 'dart2js'), join('svg', 'dartium'),
join('web_audio', 'dart2js'), join('web_audio', 'dartium'),
join('web_gl', 'dart2js'), join('web_gl', 'dartium'),
join('web_sql', 'dart2js'), join('web_sql', 'dartium')]:
copytree(join(HOME, 'sdk', 'lib', library), join(LIB, library),
ignore=ignore_patterns('*.svn', 'doc', '*.py', '*.gypi', '*.sh',
'.gitignore'))
# Copy the platform descriptors.
for file_name in ["dart_client.platform",
"dart_server.platform",
"dart_shared.platform"]:
copyfile(join(HOME, 'sdk', 'lib', file_name), join(LIB, file_name));
# Copy libraries.dart to lib/_internal/libraries.dart for backwards
# compatibility.
#
# TODO(sigmund): stop copying libraries.dart. Old versions (<=0.25.1-alpha.4)
# of the analyzer package do not support the new location of this file. We
# should be able to remove the old file once we release a newer version of
# analyzer and popular frameworks have migrated to use it.
copyfile(join(HOME, 'sdk', 'lib', '_internal',
'sdk_library_metadata', 'lib', 'libraries.dart'),
join(LIB, '_internal', 'libraries.dart'))
# Create and copy tools.
UTIL = join(SDK_tmp, 'util')
os.makedirs(UTIL)
RESOURCE = join(SDK_tmp, 'lib', '_internal', 'pub', 'asset')
os.makedirs(os.path.dirname(RESOURCE))
copytree(join(HOME, 'third_party', 'pkg', 'pub', 'lib', 'src',
'asset'),
join(RESOURCE),
ignore=ignore_patterns('.svn'))
# Copy in 7zip for Windows.
if HOST_OS == 'win32':
copytree(join(HOME, 'third_party', '7zip'),
join(RESOURCE, '7zip'),
ignore=ignore_patterns('.svn'))
# Copy dart2js/pub.
CopyDartScripts(HOME, SDK_tmp)
CopySnapshots(SNAPSHOT, SDK_tmp)
CopyDartdocResources(HOME, SDK_tmp)
CopyAnalyzerSources(HOME, LIB)
CopyAnalysisSummaries(SNAPSHOT, LIB)
CopyDevCompilerSdk(HOME, LIB)
if options.copy_libs:
CopyLibs(build_dir, BIN)
# Write the 'version' file
version = utils.GetVersion()
versionFile = open(os.path.join(SDK_tmp, 'version'), 'w')
versionFile.write(version + '\n')
versionFile.close()
# Write the 'revision' file
revision = utils.GetGitRevision()
if revision is not None:
with open(os.path.join(SDK_tmp, 'revision'), 'w') as f:
f.write('%s\n' % revision)
f.close()
Copy(join(HOME, 'README.dart-sdk'), join(SDK_tmp, 'README'))
Copy(join(HOME, 'LICENSE'), join(SDK_tmp, 'LICENSE'))
Copy(join(HOME, 'sdk', 'api_readme.md'), join(SDK_tmp, 'lib', 'api_readme.md'))
move(SDK_tmp, SDK)
if __name__ == '__main__':
sys.exit(Main())