forked from firka/flutter
Merge flutter/engine into framework
Adds files from flutter/flaux which contain modifications for the engine structure. The history for engine/ has been edited. Please see flutter/engine for the original PRs.
This commit is contained in:
13
.gitignore
vendored
13
.gitignore
vendored
@@ -1,6 +1,10 @@
|
||||
# Do not remove or rename entries in this file, only add new ones
|
||||
# See https://github.com/flutter/flutter/issues/128635 for more context.
|
||||
|
||||
# This is dynamic in a monorepo
|
||||
bin/internal/engine.version
|
||||
bin/internal/engine.realm
|
||||
|
||||
# Miscellaneous
|
||||
*.class
|
||||
*.lock
|
||||
@@ -74,7 +78,6 @@ unlinked_spec.ds
|
||||
**/android/**/GeneratedPluginRegistrant.java
|
||||
**/android/key.properties
|
||||
*.jks
|
||||
**/.cxx/
|
||||
|
||||
# iOS/XCode related
|
||||
**/ios/**/*.mode1v3
|
||||
@@ -139,3 +142,11 @@ app.*.symbols
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
!/dev/ci/**/Gemfile.lock
|
||||
!.vscode/settings.json
|
||||
|
||||
# Monorepo
|
||||
.cipd
|
||||
.gclient
|
||||
.gclient_entries
|
||||
.python-version
|
||||
.gclient_previous_custom_vars
|
||||
.gclient_previous_sync_commits
|
||||
|
||||
@@ -29,6 +29,7 @@ analyzer:
|
||||
- "bin/cache/**"
|
||||
# Ignore protoc generated files
|
||||
- "dev/conductor/lib/proto/*"
|
||||
- "engine/**"
|
||||
|
||||
formatter:
|
||||
page_width: 100
|
||||
|
||||
@@ -1881,6 +1881,7 @@ Future<List<File>> _gitFiles(String workingDirectory, {bool runSilently = true})
|
||||
assert(filenames.last.isEmpty); // git ls-files gives a trailing blank 0x00
|
||||
filenames.removeLast();
|
||||
return filenames
|
||||
.where((String filename) => !filename.startsWith('engine/'))
|
||||
.map<File>((String filename) => File(path.join(workingDirectory, filename)))
|
||||
.toList();
|
||||
}
|
||||
|
||||
10
engine/README.md
Normal file
10
engine/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# Flutter Engine
|
||||
|
||||
## `gclient` bootstrap
|
||||
|
||||
Flutter engine uses `gclient` to manage dependencies.
|
||||
|
||||
If you've already cloned the flutter repository:
|
||||
|
||||
1. Copy one of the `engine/scripts/*.gclient` to the root folder as `.gclient`
|
||||
2. run `gclient sync`
|
||||
14
engine/scripts/rbe.gclient
Normal file
14
engine/scripts/rbe.gclient
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copy this file to the root of your flutter checkout to bootstrap gclient
|
||||
# or just run gclient sync in an empty directory with this file.
|
||||
solutions = [
|
||||
{
|
||||
"custom_vars": {
|
||||
"use_rbe": True,
|
||||
},
|
||||
"deps_file": "DEPS",
|
||||
"managed": False,
|
||||
"name": ".",
|
||||
"safesync_url": "",
|
||||
"url": "https://github.com/flutter/flutter.git",
|
||||
},
|
||||
]
|
||||
12
engine/scripts/standard.gclient
Normal file
12
engine/scripts/standard.gclient
Normal file
@@ -0,0 +1,12 @@
|
||||
# Copy this file to the root of your flutter checkout to bootstrap gclient
|
||||
# or just run gclient sync in an empty directory with this file.
|
||||
solutions = [
|
||||
{
|
||||
"custom_deps": {},
|
||||
"deps_file": "DEPS",
|
||||
"managed": False,
|
||||
"name": ".",
|
||||
"safesync_url": "",
|
||||
"url": "https://github.com/flutter/flutter.git",
|
||||
},
|
||||
]
|
||||
7
engine/src/.gitattributes
vendored
Normal file
7
engine/src/.gitattributes
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
## This page intentionally left blank. ##
|
||||
#
|
||||
# Workaround for VS2013 automatically creating .gitattributes files with
|
||||
# default settings that we don't want.
|
||||
# See also:
|
||||
# http://connect.microsoft.com/VisualStudio/feedback/details/804948/inappropriately-creates-gitattributes-file
|
||||
# http://crbug.com/342064
|
||||
40
engine/src/.gitignore
vendored
Normal file
40
engine/src/.gitignore
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
# commonly generated files
|
||||
*.pyc
|
||||
*~
|
||||
.*.sw?
|
||||
.ccls-cache
|
||||
.checkstyle
|
||||
.clangd
|
||||
.classpath
|
||||
.cproject
|
||||
.DS_Store
|
||||
.gdb_history
|
||||
.gdbinit
|
||||
.idea
|
||||
.ignore
|
||||
.landmines
|
||||
.packages
|
||||
.project
|
||||
.pub
|
||||
.pydevproject
|
||||
.vscode
|
||||
.cache
|
||||
compile_commands.json
|
||||
cscope.*
|
||||
Session.vim
|
||||
tags
|
||||
Thumbs.db
|
||||
|
||||
# directories pulled in via deps or hooks
|
||||
/buildtools/
|
||||
/gradle/
|
||||
/ios_tools/
|
||||
/out/
|
||||
/third_party/
|
||||
/build/secondary/third_party/protobuf/
|
||||
|
||||
# This is where the gclient hook downloads the Fuchsia SDK and toolchain.
|
||||
/fuchsia/
|
||||
|
||||
# Override higher level build ignore
|
||||
!build/
|
||||
27
engine/src/.gn
Normal file
27
engine/src/.gn
Normal file
@@ -0,0 +1,27 @@
|
||||
# This file is used by the experimental meta-buildsystem in src/tools/gn to
|
||||
# find the root of the source tree and to set startup options.
|
||||
|
||||
# Use vpython3 from depot_tools for exec_script() calls.
|
||||
# See `gn help dotfile` for details.
|
||||
script_executable = "vpython3"
|
||||
|
||||
# The location of the build configuration file.
|
||||
buildconfig = "//build/config/BUILDCONFIG.gn"
|
||||
|
||||
# The secondary source root is a parallel directory tree where
|
||||
# GN build files are placed when they can not be placed directly
|
||||
# in the source tree, e.g. for third party source trees.
|
||||
secondary_source = "//flutter/build/secondary/"
|
||||
|
||||
# The set of targets known to pass 'gn check'. When all targets pass, remove
|
||||
# this.
|
||||
check_targets = [
|
||||
"//flutter/common/*",
|
||||
"//flutter/display_list/*",
|
||||
"//flutter/flow/*",
|
||||
"//flutter/fml/*",
|
||||
"//flutter/lib/*",
|
||||
"//flutter/impeller/*",
|
||||
"//flutter/runtime/*",
|
||||
"//flutter/shell/*",
|
||||
]
|
||||
20
engine/src/.vscode/settings.json
vendored
Normal file
20
engine/src/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"clangd.path": "${workspaceFolder}/buildtools/mac-arm64/clang/bin/clangd",
|
||||
"clangd.arguments": [
|
||||
"--compile-commands-dir=${workspaceFolder}/../out/host_debug_unopt_arm64"
|
||||
],
|
||||
"clang-format.executable": "${workspaceRoot}/buildtools/mac-arm64/clang/bin/clang-format",
|
||||
|
||||
// "clangd.path": "flutter/buildtools/mac-arm64/clang/bin/clangd",
|
||||
// "clangd.arguments": [
|
||||
// "--compile-commands-dir=out/host_debug_unopt_arm64"
|
||||
// ],
|
||||
// "clang-format.executable": "flutter/buildtools/mac-arm64/clang/bin/clang-format",
|
||||
|
||||
"search.followSymlinks": true,
|
||||
"search.quickOpen.includeHistory": true,
|
||||
"search.quickOpen.includeSymbols": false,
|
||||
"search.useIgnoreFiles": false,
|
||||
|
||||
"editor.tabSize": 2,
|
||||
}
|
||||
9
engine/src/AUTHORS
Normal file
9
engine/src/AUTHORS
Normal file
@@ -0,0 +1,9 @@
|
||||
# Below is a list of people and organizations that have contributed
|
||||
# to the Flutter project. Names should be added to the list like so:
|
||||
#
|
||||
# Name/Organization <email address>
|
||||
|
||||
Google Inc.
|
||||
Jim Simon <jim.j.simon@gmail.com>
|
||||
The Fuchsia Authors
|
||||
Hidenori Matsubayashi <Hidenori.Matsubayashi@sony.com>
|
||||
22
engine/src/BUILD.gn
Normal file
22
engine/src/BUILD.gn
Normal file
@@ -0,0 +1,22 @@
|
||||
# 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.
|
||||
|
||||
group("default") {
|
||||
testonly = true
|
||||
if (target_os == "wasm") {
|
||||
deps = [ "//flutter/wasm" ]
|
||||
} else {
|
||||
deps = [ "//flutter" ]
|
||||
}
|
||||
}
|
||||
|
||||
group("dist") {
|
||||
testonly = true
|
||||
|
||||
if (target_os == "wasm") {
|
||||
deps = [ "//flutter/wasm" ]
|
||||
} else {
|
||||
deps = [ "//flutter:dist" ]
|
||||
}
|
||||
}
|
||||
9
engine/src/CODEOWNERS
Normal file
9
engine/src/CODEOWNERS
Normal file
@@ -0,0 +1,9 @@
|
||||
# Below is a list of Flutter hackers GitHub handles who are
|
||||
# suggested reviewers for contributions to this repository.
|
||||
#
|
||||
# These names are just suggestions. It is fine to have your changes
|
||||
# reviewed by someone else.
|
||||
#
|
||||
# Use git ls-files '<pattern>' without a / prefix to see the list of matching files.
|
||||
|
||||
/build/config/ios/** @jmagman
|
||||
27
engine/src/LICENSE
Normal file
27
engine/src/LICENSE
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright 2014 The Chromium Authors. All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
14
engine/src/README.md
Normal file
14
engine/src/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
[](https://api.securityscorecards.dev/projects/github.com/flutter/buildroot)
|
||||
|
||||
# buildroot
|
||||
|
||||
Build environment for the Flutter engine
|
||||
|
||||
This repository is used by the [flutter/engine](https://github.com/flutter/engine) repository.
|
||||
For instructions on how to use it, see that repository's [CONTRIBUTING.md](https://github.com/flutter/engine/blob/main/CONTRIBUTING.md) file.
|
||||
|
||||
To update your checkout to use the latest buildroot, run `gclient sync`.
|
||||
|
||||
To submit patches to this buildroot repository, create a branch, push to that branch, then submit a PR on GitHub for that branch.
|
||||
|
||||
To point the engine to a new version of buildroot after your patch is merged, update the buildroot hash in the engine's [DEPS file](https://github.com/flutter/engine/blob/main/DEPS).
|
||||
4
engine/src/build/.gitignore
vendored
Normal file
4
engine/src/build/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Generated file containing information about the VS toolchain on Windows
|
||||
win_toolchain.json
|
||||
new_win_toolchain.json
|
||||
/linux/debian_*-sysroot/
|
||||
64
engine/src/build/android/gyp/create_flutter_jar.py
Normal file
64
engine/src/build/android/gyp/create_flutter_jar.py
Normal file
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2016 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.
|
||||
|
||||
"""Create a JAR incorporating all the components required to build a Flutter application"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
from util import build_utils
|
||||
|
||||
def main(args):
|
||||
args = build_utils.ExpandFileArgs(args)
|
||||
parser = optparse.OptionParser()
|
||||
build_utils.AddDepfileOption(parser)
|
||||
parser.add_option('--output', help='Path to output jar.')
|
||||
parser.add_option('--output_native_jar', help='Path to output native library jar.')
|
||||
parser.add_option('--dist_jar', help='Flutter shell Java code jar.')
|
||||
parser.add_option('--native_lib', action='append', help='Native code library.')
|
||||
parser.add_option('--android_abi', help='Native code ABI.')
|
||||
parser.add_option('--asset_dir', help='Path to assets.')
|
||||
options, _ = parser.parse_args(args)
|
||||
build_utils.CheckOptions(options, parser, [
|
||||
'output', 'dist_jar', 'native_lib', 'android_abi'
|
||||
])
|
||||
|
||||
input_deps = []
|
||||
|
||||
with zipfile.ZipFile(options.output, 'w', zipfile.ZIP_DEFLATED) as out_zip:
|
||||
input_deps.append(options.dist_jar)
|
||||
with zipfile.ZipFile(options.dist_jar, 'r') as dist_zip:
|
||||
for dist_file in dist_zip.infolist():
|
||||
if dist_file.filename.endswith('.class'):
|
||||
out_zip.writestr(dist_file.filename, dist_zip.read(dist_file.filename))
|
||||
|
||||
for native_lib in options.native_lib:
|
||||
input_deps.append(native_lib)
|
||||
out_zip.write(native_lib,
|
||||
'lib/%s/%s' % (options.android_abi, os.path.basename(native_lib)))
|
||||
|
||||
if options.asset_dir:
|
||||
for asset_file in os.listdir(options.asset_dir):
|
||||
input_deps.append(asset_file)
|
||||
out_zip.write(os.path.join(options.asset_dir, asset_file),
|
||||
'assets/flutter_shared/%s' % asset_file)
|
||||
|
||||
if options.output_native_jar:
|
||||
with zipfile.ZipFile(options.output_native_jar, 'w', zipfile.ZIP_DEFLATED) as out_zip:
|
||||
for native_lib in options.native_lib:
|
||||
out_zip.write(native_lib,
|
||||
'lib/%s/%s' % (options.android_abi, os.path.basename(native_lib)))
|
||||
|
||||
if options.depfile:
|
||||
build_utils.WriteDepfile(
|
||||
options.depfile,
|
||||
input_deps + build_utils.GetPythonDependencies())
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
87
engine/src/build/android/gyp/jar.py
Executable file
87
engine/src/build/android/gyp/jar.py
Executable file
@@ -0,0 +1,87 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2013 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.
|
||||
|
||||
import fnmatch
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
from util import build_utils
|
||||
from util import md5_check
|
||||
|
||||
|
||||
def Jar(class_files, classes_dir, jar_path, jar_bin, manifest_file=None, additional_jar_files=None):
|
||||
jar_path = os.path.abspath(jar_path)
|
||||
|
||||
# The paths of the files in the jar will be the same as they are passed in to
|
||||
# the command. Because of this, the command should be run in
|
||||
# options.classes_dir so the .class file paths in the jar are correct.
|
||||
jar_cwd = classes_dir
|
||||
class_files_rel = [os.path.relpath(f, jar_cwd) for f in class_files]
|
||||
jar_cmd = [jar_bin, 'cf0', jar_path]
|
||||
if manifest_file:
|
||||
jar_cmd[1] += 'm'
|
||||
jar_cmd.append(os.path.abspath(manifest_file))
|
||||
jar_cmd.extend(class_files_rel)
|
||||
if additional_jar_files:
|
||||
jar_cmd.extend(additional_jar_files)
|
||||
|
||||
with build_utils.TempDir() as temp_dir:
|
||||
empty_file = os.path.join(temp_dir, '.empty')
|
||||
build_utils.Touch(empty_file)
|
||||
jar_cmd.append(os.path.relpath(empty_file, jar_cwd))
|
||||
record_path = '%s.md5.stamp' % jar_path
|
||||
md5_check.CallAndRecordIfStale(
|
||||
lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
|
||||
record_path=record_path,
|
||||
input_paths=class_files,
|
||||
input_strings=jar_cmd,
|
||||
force=not os.path.exists(jar_path),
|
||||
)
|
||||
|
||||
build_utils.Touch(jar_path, fail_if_missing=True)
|
||||
|
||||
|
||||
def JarDirectory(classes_dir, excluded_classes, jar_path, jar_bin, manifest_file=None, additional_jar_files=None):
|
||||
class_files = build_utils.FindInDirectory(classes_dir, '*.class')
|
||||
for exclude in excluded_classes:
|
||||
class_files = [f for f in class_files if not fnmatch.fnmatch(f, exclude)]
|
||||
|
||||
Jar(class_files, classes_dir, jar_path, jar_bin, manifest_file=manifest_file,
|
||||
additional_jar_files=additional_jar_files)
|
||||
|
||||
|
||||
def main():
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('--classes-dir', help='Directory containing .class files.')
|
||||
parser.add_option('--jar-path', help='Jar output path.')
|
||||
parser.add_option('--excluded-classes',
|
||||
help='List of .class file patterns to exclude from the jar.')
|
||||
parser.add_option('--stamp', help='Path to touch on success.')
|
||||
|
||||
parser.add_option(
|
||||
'--jar-bin',
|
||||
default='jar',
|
||||
help='The jar binary. If empty, the jar binary is resolved from PATH.')
|
||||
|
||||
options, _ = parser.parse_args()
|
||||
|
||||
if options.excluded_classes:
|
||||
excluded_classes = build_utils.ParseGypList(options.excluded_classes)
|
||||
else:
|
||||
excluded_classes = []
|
||||
JarDirectory(options.classes_dir,
|
||||
excluded_classes,
|
||||
options.jar_path,
|
||||
options.jar_bin)
|
||||
|
||||
if options.stamp:
|
||||
build_utils.Touch(options.stamp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
|
||||
340
engine/src/build/android/gyp/javac.py
Executable file
340
engine/src/build/android/gyp/javac.py
Executable file
@@ -0,0 +1,340 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2013 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.
|
||||
|
||||
import fnmatch
|
||||
import optparse
|
||||
import os
|
||||
import shutil
|
||||
import re
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
from util import ansi_colors
|
||||
from util import build_utils
|
||||
from util import md5_check
|
||||
|
||||
import jar
|
||||
|
||||
def ColorJavacOutput(output):
|
||||
fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)'
|
||||
warning_re = re.compile(
|
||||
fileline_prefix + r'(?P<full_message> warning: (?P<message>.*))$')
|
||||
error_re = re.compile(
|
||||
fileline_prefix + r'(?P<full_message> (?P<message>.*))$')
|
||||
marker_re = re.compile(r'\s*(?P<marker>\^)\s*$')
|
||||
|
||||
warning_color = ['full_message', ansi_colors.FOREGROUND_YELLOW + ansi_colors.STYLE_DIM]
|
||||
error_color = ['full_message', ansi_colors.FOREGROUND_MAGENTA + ansi_colors.STYLE_BRIGHT]
|
||||
marker_color = ['marker', ansi_colors.FOREGROUND_BLUE + ansi_colors.STYLE_BRIGHT]
|
||||
|
||||
def Colorize(line, regex, color):
|
||||
match = regex.match(line)
|
||||
start = match.start(color[0])
|
||||
end = match.end(color[0])
|
||||
return (line[:start]
|
||||
+ color[1] + line[start:end]
|
||||
+ ansi_colors.FOREGROUND_RESET + ansi_colors.STYLE_RESET_ALL
|
||||
+ line[end:])
|
||||
|
||||
def ApplyColor(line):
|
||||
if warning_re.match(line):
|
||||
line = Colorize(line, warning_re, warning_color)
|
||||
elif error_re.match(line):
|
||||
line = Colorize(line, error_re, error_color)
|
||||
elif marker_re.match(line):
|
||||
line = Colorize(line, marker_re, marker_color)
|
||||
return line
|
||||
|
||||
return '\n'.join(map(ApplyColor, output.split('\n')))
|
||||
|
||||
def DoJavac(
|
||||
bootclasspath, classpath, classes_dir, chromium_code,
|
||||
javac_bin, java_version, java_files):
|
||||
"""Runs javac.
|
||||
|
||||
Builds |java_files| with the provided |classpath| and puts the generated
|
||||
.class files into |classes_dir|. If |chromium_code| is true, extra lint
|
||||
checking will be enabled.
|
||||
"""
|
||||
|
||||
jar_inputs = []
|
||||
for path in classpath:
|
||||
if os.path.exists(path + '.TOC'):
|
||||
jar_inputs.append(path + '.TOC')
|
||||
else:
|
||||
jar_inputs.append(path)
|
||||
|
||||
javac_args = [
|
||||
'-g',
|
||||
# Chromium only allows UTF8 source files. Being explicit avoids
|
||||
# javac pulling a default encoding from the user's environment.
|
||||
'-encoding', 'UTF-8',
|
||||
'-classpath', ':'.join(classpath),
|
||||
'-d', classes_dir,
|
||||
# TODO(camsim99): Fix deprecations:
|
||||
# https://github.com/flutter/flutter/issues/98602.
|
||||
'-Xlint:-deprecation']
|
||||
|
||||
if bootclasspath:
|
||||
javac_args.extend([
|
||||
'-bootclasspath', ':'.join(bootclasspath),
|
||||
'-source', java_version,
|
||||
'-target', java_version,
|
||||
])
|
||||
|
||||
if chromium_code:
|
||||
javac_args.extend(['-Xlint:unchecked'])
|
||||
else:
|
||||
# XDignore.symbol.file makes javac compile against rt.jar instead of
|
||||
# ct.sym. This means that using a java internal package/class will not
|
||||
# trigger a compile warning or error.
|
||||
javac_args.extend(['-XDignore.symbol.file'])
|
||||
|
||||
javac_cmd = [javac_bin] + javac_args + java_files
|
||||
|
||||
def Compile():
|
||||
build_utils.CheckOutput(
|
||||
javac_cmd,
|
||||
print_stdout=chromium_code,
|
||||
stderr_filter=ColorJavacOutput)
|
||||
|
||||
record_path = os.path.join(classes_dir, 'javac.md5.stamp')
|
||||
md5_check.CallAndRecordIfStale(
|
||||
Compile,
|
||||
record_path=record_path,
|
||||
input_paths=java_files + jar_inputs,
|
||||
input_strings=javac_cmd)
|
||||
|
||||
|
||||
_MAX_MANIFEST_LINE_LEN = 72
|
||||
|
||||
|
||||
def CreateManifest(manifest_path, classpath, main_class=None,
|
||||
manifest_entries=None):
|
||||
"""Creates a manifest file with the given parameters.
|
||||
|
||||
This generates a manifest file that compiles with the spec found at
|
||||
http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifest
|
||||
|
||||
Args:
|
||||
manifest_path: The path to the manifest file that should be created.
|
||||
classpath: The JAR files that should be listed on the manifest file's
|
||||
classpath.
|
||||
main_class: If present, the class containing the main() function.
|
||||
manifest_entries: If present, a list of (key, value) pairs to add to
|
||||
the manifest.
|
||||
|
||||
"""
|
||||
output = ['Manifest-Version: 1.0']
|
||||
if main_class:
|
||||
output.append('Main-Class: %s' % main_class)
|
||||
if manifest_entries:
|
||||
for k, v in manifest_entries:
|
||||
output.append('%s: %s' % (k, v))
|
||||
if classpath:
|
||||
sanitized_paths = []
|
||||
for path in classpath:
|
||||
sanitized_paths.append(os.path.basename(path.strip('"')))
|
||||
output.append('Class-Path: %s' % ' '.join(sanitized_paths))
|
||||
output.append('Created-By: ')
|
||||
output.append('')
|
||||
|
||||
wrapper = textwrap.TextWrapper(break_long_words=True,
|
||||
drop_whitespace=False,
|
||||
subsequent_indent=' ',
|
||||
width=_MAX_MANIFEST_LINE_LEN - 2)
|
||||
output = '\r\n'.join(w for l in output for w in wrapper.wrap(l))
|
||||
|
||||
with open(manifest_path, 'w') as f:
|
||||
f.write(output)
|
||||
|
||||
|
||||
def main(argv):
|
||||
argv = build_utils.ExpandFileArgs(argv)
|
||||
|
||||
parser = optparse.OptionParser()
|
||||
build_utils.AddDepfileOption(parser)
|
||||
|
||||
parser.add_option(
|
||||
'--src-gendirs',
|
||||
help='Directories containing generated java files.')
|
||||
parser.add_option(
|
||||
'--java-srcjars',
|
||||
action='append',
|
||||
default=[],
|
||||
help='List of srcjars to include in compilation.')
|
||||
parser.add_option(
|
||||
'--bootclasspath',
|
||||
action='append',
|
||||
default=[],
|
||||
help='Boot classpath for javac. If this is specified multiple times, '
|
||||
'they will all be appended to construct the classpath.')
|
||||
parser.add_option(
|
||||
'--classpath',
|
||||
action='append',
|
||||
help='Classpath for javac. If this is specified multiple times, they '
|
||||
'will all be appended to construct the classpath.')
|
||||
parser.add_option(
|
||||
'--javac-includes',
|
||||
help='A list of file patterns. If provided, only java files that match'
|
||||
'one of the patterns will be compiled.')
|
||||
parser.add_option(
|
||||
'--jar-excluded-classes',
|
||||
default='',
|
||||
help='List of .class file patterns to exclude from the jar.')
|
||||
|
||||
parser.add_option(
|
||||
'--chromium-code',
|
||||
type='int',
|
||||
help='Whether code being compiled should be built with stricter '
|
||||
'warnings for chromium code.')
|
||||
|
||||
parser.add_option(
|
||||
'--javac-bin',
|
||||
default='javac',
|
||||
help='The javac binary. If empty, the javac binary is resolved from PATH.')
|
||||
|
||||
parser.add_option(
|
||||
'--jar-bin',
|
||||
default='jar',
|
||||
help='The jar binary. If empty, the jar binary is resolved from PATH.')
|
||||
|
||||
parser.add_option(
|
||||
'--java-version',
|
||||
default='1.8',
|
||||
help='The source and target versions passed to javac.')
|
||||
|
||||
parser.add_option(
|
||||
'--classes-dir',
|
||||
help='Directory for compiled .class files.')
|
||||
parser.add_option('--jar-path', help='Jar output path.')
|
||||
parser.add_option('--jar-source-path', help='Source jar output path.')
|
||||
parser.add_option(
|
||||
'--jar-source-base-dir',
|
||||
help='Base directory for the source files included in the output source jar.')
|
||||
parser.add_option(
|
||||
'--main-class',
|
||||
help='The class containing the main method.')
|
||||
parser.add_option(
|
||||
'--manifest-entry',
|
||||
action='append',
|
||||
help='Key:value pairs to add to the .jar manifest.')
|
||||
parser.add_option(
|
||||
'--additional-jar-files',
|
||||
dest='additional_jar_files',
|
||||
action='append',
|
||||
help='Additional files to package into jar. By default, only Java .class '
|
||||
'files are packaged into the jar.')
|
||||
|
||||
parser.add_option('--stamp', help='Path to touch on success.')
|
||||
|
||||
options, args = parser.parse_args(argv)
|
||||
|
||||
if options.main_class and not options.jar_path:
|
||||
parser.error('--main-class requires --jar-path')
|
||||
|
||||
bootclasspath = []
|
||||
for arg in options.bootclasspath:
|
||||
bootclasspath += build_utils.ParseGypList(arg)
|
||||
|
||||
classpath = []
|
||||
for arg in options.classpath:
|
||||
classpath += build_utils.ParseGypList(arg)
|
||||
|
||||
java_srcjars = []
|
||||
for arg in options.java_srcjars:
|
||||
java_srcjars += build_utils.ParseGypList(arg)
|
||||
|
||||
java_files = args
|
||||
if options.src_gendirs:
|
||||
src_gendirs = build_utils.ParseGypList(options.src_gendirs)
|
||||
java_files += build_utils.FindInDirectories(src_gendirs, '*.java')
|
||||
|
||||
additional_jar_files = []
|
||||
for arg in options.additional_jar_files or []:
|
||||
additional_jar_files += build_utils.ParseGypList(arg)
|
||||
|
||||
input_files = bootclasspath + classpath + java_srcjars + java_files
|
||||
with build_utils.TempDir() as temp_dir:
|
||||
classes_dir = os.path.join(temp_dir, 'classes')
|
||||
os.makedirs(classes_dir)
|
||||
if java_srcjars:
|
||||
java_dir = os.path.join(temp_dir, 'java')
|
||||
os.makedirs(java_dir)
|
||||
for srcjar in java_srcjars:
|
||||
build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
|
||||
java_files += build_utils.FindInDirectory(java_dir, '*.java')
|
||||
|
||||
if options.javac_includes:
|
||||
javac_includes = build_utils.ParseGypList(options.javac_includes)
|
||||
filtered_java_files = []
|
||||
for f in java_files:
|
||||
for include in javac_includes:
|
||||
if fnmatch.fnmatch(f, include):
|
||||
filtered_java_files.append(f)
|
||||
break
|
||||
java_files = filtered_java_files
|
||||
|
||||
if len(java_files) != 0:
|
||||
DoJavac(
|
||||
bootclasspath,
|
||||
classpath,
|
||||
classes_dir,
|
||||
options.chromium_code,
|
||||
options.javac_bin,
|
||||
options.java_version,
|
||||
java_files)
|
||||
|
||||
if options.jar_path:
|
||||
if options.main_class or options.manifest_entry:
|
||||
if options.manifest_entry:
|
||||
entries = [e.split(":") for e in options.manifest_entry]
|
||||
else:
|
||||
entries = []
|
||||
manifest_file = os.path.join(temp_dir, 'manifest')
|
||||
CreateManifest(manifest_file, classpath, options.main_class, entries)
|
||||
else:
|
||||
manifest_file = None
|
||||
|
||||
if options.additional_jar_files:
|
||||
for f in additional_jar_files:
|
||||
# Also make the additional files available at the relative paths
|
||||
# matching their original locations.
|
||||
shutil.copyfile(f, os.path.join(
|
||||
classes_dir, os.path.relpath(f, options.jar_source_base_dir)))
|
||||
additional_jar_files = [os.path.relpath(
|
||||
f, options.jar_source_base_dir) for f in additional_jar_files]
|
||||
|
||||
jar.JarDirectory(classes_dir,
|
||||
build_utils.ParseGypList(options.jar_excluded_classes),
|
||||
options.jar_path,
|
||||
options.jar_bin,
|
||||
manifest_file=manifest_file,
|
||||
additional_jar_files=additional_jar_files)
|
||||
|
||||
if options.jar_source_path:
|
||||
jar.Jar(java_files, options.jar_source_base_dir, options.jar_source_path, options.jar_bin)
|
||||
|
||||
if options.classes_dir:
|
||||
# Delete the old classes directory. This ensures that all .class files in
|
||||
# the output are actually from the input .java files. For example, if a
|
||||
# .java file is deleted or an inner class is removed, the classes
|
||||
# directory should not contain the corresponding old .class file after
|
||||
# running this action.
|
||||
build_utils.DeleteDirectory(options.classes_dir)
|
||||
shutil.copytree(classes_dir, options.classes_dir)
|
||||
|
||||
if options.depfile:
|
||||
build_utils.WriteDepfile(
|
||||
options.depfile,
|
||||
input_files + build_utils.GetPythonDependencies())
|
||||
|
||||
if options.stamp:
|
||||
build_utils.Touch(options.stamp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
4
engine/src/build/android/gyp/util/__init__.py
Normal file
4
engine/src/build/android/gyp/util/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
14
engine/src/build/android/gyp/util/ansi_colors.py
Normal file
14
engine/src/build/android/gyp/util/ansi_colors.py
Normal file
@@ -0,0 +1,14 @@
|
||||
# Copyright 2013 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.
|
||||
|
||||
# The following are unicode (string) constants that were previously defined in
|
||||
# "colorama". They are inlined here to avoid a dependency, as this is the only
|
||||
# call site and it's unlikely we'll need to change them.
|
||||
FOREGROUND_YELLOW = '\x1b[33m'
|
||||
FOREGROUND_MAGENTA = '\x1b[35m'
|
||||
FOREGROUND_BLUE = '\x1b[34m'
|
||||
FOREGROUND_RESET = '\x1b[39m'
|
||||
STYLE_RESET_ALL = '\x1b[0m'
|
||||
STYLE_DIM = '\x1b[2m'
|
||||
STYLE_BRIGHT = '\x1b[1m'
|
||||
396
engine/src/build/android/gyp/util/build_utils.py
Normal file
396
engine/src/build/android/gyp/util/build_utils.py
Normal file
@@ -0,0 +1,396 @@
|
||||
# Copyright 2013 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.
|
||||
|
||||
import ast
|
||||
import contextlib
|
||||
import fnmatch
|
||||
import json
|
||||
import os
|
||||
import pipes
|
||||
import re
|
||||
import shlex
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
import zipfile
|
||||
|
||||
|
||||
# Definition copied from pylib/constants/__init__.py to avoid adding
|
||||
# a dependency on pylib.
|
||||
DIR_SOURCE_ROOT = os.environ.get('CHECKOUT_SOURCE_ROOT',
|
||||
os.path.abspath(os.path.join(os.path.dirname(__file__),
|
||||
os.pardir, os.pardir, os.pardir, os.pardir)))
|
||||
|
||||
# aapt should ignore OWNERS files in addition the default ignore pattern.
|
||||
AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' +
|
||||
'!CVS:!thumbs.db:!picasa.ini:!*~:!*.d.stamp')
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def TempDir():
|
||||
dirname = tempfile.mkdtemp()
|
||||
try:
|
||||
yield dirname
|
||||
finally:
|
||||
shutil.rmtree(dirname)
|
||||
|
||||
|
||||
def MakeDirectory(dir_path):
|
||||
try:
|
||||
os.makedirs(dir_path)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
def DeleteDirectory(dir_path):
|
||||
if os.path.exists(dir_path):
|
||||
shutil.rmtree(dir_path)
|
||||
|
||||
|
||||
def Touch(path, fail_if_missing=False):
|
||||
if fail_if_missing and not os.path.exists(path):
|
||||
raise Exception(path + ' doesn\'t exist.')
|
||||
|
||||
MakeDirectory(os.path.dirname(path))
|
||||
with open(path, 'a'):
|
||||
os.utime(path, None)
|
||||
|
||||
|
||||
def FindInDirectory(directory, filename_filter):
|
||||
files = []
|
||||
for root, _dirnames, filenames in os.walk(directory):
|
||||
matched_files = fnmatch.filter(filenames, filename_filter)
|
||||
files.extend((os.path.join(root, f) for f in matched_files))
|
||||
return files
|
||||
|
||||
|
||||
def FindInDirectories(directories, filename_filter):
|
||||
all_files = []
|
||||
for directory in directories:
|
||||
all_files.extend(FindInDirectory(directory, filename_filter))
|
||||
return all_files
|
||||
|
||||
|
||||
def ParseGnList(gn_string):
|
||||
return ast.literal_eval(gn_string)
|
||||
|
||||
|
||||
def ParseGypList(gyp_string):
|
||||
# The ninja generator doesn't support $ in strings, so use ## to
|
||||
# represent $.
|
||||
# TODO(cjhopman): Remove when
|
||||
# https://code.google.com/p/gyp/issues/detail?id=327
|
||||
# is addressed.
|
||||
gyp_string = gyp_string.replace('##', '$')
|
||||
|
||||
if gyp_string.startswith('['):
|
||||
return ParseGnList(gyp_string)
|
||||
return shlex.split(gyp_string)
|
||||
|
||||
|
||||
def CheckOptions(options, parser, required=None):
|
||||
if not required:
|
||||
return
|
||||
for option_name in required:
|
||||
if getattr(options, option_name) is None:
|
||||
parser.error('--%s is required' % option_name.replace('_', '-'))
|
||||
|
||||
|
||||
def WriteJson(obj, path, only_if_changed=False):
|
||||
old_dump = None
|
||||
if os.path.exists(path):
|
||||
with open(path, 'r') as oldfile:
|
||||
old_dump = oldfile.read()
|
||||
|
||||
new_dump = json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))
|
||||
|
||||
if not only_if_changed or old_dump != new_dump:
|
||||
with open(path, 'w') as outfile:
|
||||
outfile.write(new_dump)
|
||||
|
||||
|
||||
def ReadJson(path):
|
||||
with open(path, 'r') as jsonfile:
|
||||
return json.load(jsonfile)
|
||||
|
||||
|
||||
class CalledProcessError(Exception):
|
||||
"""This exception is raised when the process run by CheckOutput
|
||||
exits with a non-zero exit code."""
|
||||
|
||||
def __init__(self, cwd, args, output):
|
||||
super(CalledProcessError, self).__init__()
|
||||
self.cwd = cwd
|
||||
self.args = args
|
||||
self.output = output
|
||||
|
||||
def __str__(self):
|
||||
# A user should be able to simply copy and paste the command that failed
|
||||
# into their shell.
|
||||
copyable_command = '( cd {}; {} )'.format(os.path.abspath(self.cwd),
|
||||
' '.join(map(pipes.quote, self.args)))
|
||||
return 'Command failed: {}\n{}'.format(copyable_command, self.output)
|
||||
|
||||
|
||||
# This can be used in most cases like subprocess.check_output(). The output,
|
||||
# particularly when the command fails, better highlights the command's failure.
|
||||
# If the command fails, raises a build_utils.CalledProcessError.
|
||||
def CheckOutput(args, cwd=None,
|
||||
print_stdout=False, print_stderr=True,
|
||||
stdout_filter=None,
|
||||
stderr_filter=None,
|
||||
universal_newlines=True,
|
||||
fail_func=lambda returncode, stderr: returncode != 0):
|
||||
if not cwd:
|
||||
cwd = os.getcwd()
|
||||
|
||||
child = subprocess.Popen(args,
|
||||
universal_newlines=universal_newlines,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
|
||||
stdout, stderr = child.communicate()
|
||||
|
||||
if stdout_filter is not None:
|
||||
stdout = stdout_filter(stdout)
|
||||
|
||||
if stderr_filter is not None:
|
||||
stderr = stderr_filter(stderr)
|
||||
|
||||
if fail_func(child.returncode, stderr):
|
||||
raise CalledProcessError(cwd, args, stdout + stderr)
|
||||
|
||||
if print_stdout:
|
||||
sys.stdout.write(stdout)
|
||||
if print_stderr:
|
||||
sys.stderr.write(stderr)
|
||||
|
||||
return stdout
|
||||
|
||||
|
||||
def GetModifiedTime(path):
|
||||
# For a symlink, the modified time should be the greater of the link's
|
||||
# modified time and the modified time of the target.
|
||||
return max(os.lstat(path).st_mtime, os.stat(path).st_mtime)
|
||||
|
||||
|
||||
def IsTimeStale(output, inputs):
|
||||
if not os.path.exists(output):
|
||||
return True
|
||||
|
||||
output_time = GetModifiedTime(output)
|
||||
for i in inputs:
|
||||
if GetModifiedTime(i) > output_time:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def IsDeviceReady():
|
||||
device_state = CheckOutput(['adb', 'get-state'])
|
||||
return device_state.strip() == 'device'
|
||||
|
||||
|
||||
def CheckZipPath(name):
|
||||
if os.path.normpath(name) != name:
|
||||
raise Exception('Non-canonical zip path: %s' % name)
|
||||
if os.path.isabs(name):
|
||||
raise Exception('Absolute zip path: %s' % name)
|
||||
|
||||
|
||||
def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None):
|
||||
if path is None:
|
||||
path = os.getcwd()
|
||||
elif not os.path.exists(path):
|
||||
MakeDirectory(path)
|
||||
|
||||
with zipfile.ZipFile(zip_path) as z:
|
||||
for name in z.namelist():
|
||||
if name.endswith('/'):
|
||||
continue
|
||||
if pattern is not None:
|
||||
if not fnmatch.fnmatch(name, pattern):
|
||||
continue
|
||||
CheckZipPath(name)
|
||||
if no_clobber:
|
||||
output_path = os.path.join(path, name)
|
||||
if os.path.exists(output_path):
|
||||
raise Exception(
|
||||
'Path already exists from zip: %s %s %s'
|
||||
% (zip_path, name, output_path))
|
||||
|
||||
z.extractall(path=path)
|
||||
|
||||
|
||||
def DoZip(inputs, output, base_dir):
|
||||
with zipfile.ZipFile(output, 'w') as outfile:
|
||||
for f in inputs:
|
||||
CheckZipPath(os.path.relpath(f, base_dir))
|
||||
outfile.write(f, os.path.relpath(f, base_dir))
|
||||
|
||||
|
||||
def ZipDir(output, base_dir):
|
||||
with zipfile.ZipFile(output, 'w') as outfile:
|
||||
for root, _, files in os.walk(base_dir):
|
||||
for f in files:
|
||||
path = os.path.join(root, f)
|
||||
archive_path = os.path.relpath(path, base_dir)
|
||||
CheckZipPath(archive_path)
|
||||
outfile.write(path, archive_path)
|
||||
|
||||
|
||||
def MergeZips(output, inputs, exclude_patterns=None):
|
||||
added_names = set()
|
||||
def Allow(name):
|
||||
if exclude_patterns is not None:
|
||||
for p in exclude_patterns:
|
||||
if fnmatch.fnmatch(name, p):
|
||||
return False
|
||||
return True
|
||||
|
||||
with zipfile.ZipFile(output, 'w') as out_zip:
|
||||
for in_file in inputs:
|
||||
with zipfile.ZipFile(in_file, 'r') as in_zip:
|
||||
for name in in_zip.namelist():
|
||||
if name not in added_names and Allow(name):
|
||||
out_zip.writestr(name, in_zip.read(name))
|
||||
added_names.add(name)
|
||||
|
||||
|
||||
def PrintWarning(message):
|
||||
print('WARNING: %s' % message)
|
||||
|
||||
|
||||
def PrintBigWarning(message):
|
||||
print('***** ' * 8)
|
||||
PrintWarning(message)
|
||||
print('***** ' * 8)
|
||||
|
||||
|
||||
def GetSortedTransitiveDependencies(top, deps_func):
|
||||
"""Gets the list of all transitive dependencies in sorted order.
|
||||
|
||||
There should be no cycles in the dependency graph.
|
||||
|
||||
Args:
|
||||
top: a list of the top level nodes
|
||||
deps_func: A function that takes a node and returns its direct dependencies.
|
||||
Returns:
|
||||
A list of all transitive dependencies of nodes in top, in order (a node will
|
||||
appear in the list at a higher index than all of its dependencies).
|
||||
"""
|
||||
def Node(dep):
|
||||
return (dep, deps_func(dep))
|
||||
|
||||
# First: find all deps
|
||||
unchecked_deps = list(top)
|
||||
all_deps = set(top)
|
||||
while unchecked_deps:
|
||||
dep = unchecked_deps.pop()
|
||||
new_deps = deps_func(dep).difference(all_deps)
|
||||
unchecked_deps.extend(new_deps)
|
||||
all_deps = all_deps.union(new_deps)
|
||||
|
||||
# Then: simple, slow topological sort.
|
||||
sorted_deps = []
|
||||
unsorted_deps = dict(map(Node, all_deps))
|
||||
while unsorted_deps:
|
||||
for library, dependencies in unsorted_deps.items():
|
||||
if not dependencies.intersection(unsorted_deps.keys()):
|
||||
sorted_deps.append(library)
|
||||
del unsorted_deps[library]
|
||||
|
||||
return sorted_deps
|
||||
|
||||
|
||||
def GetPythonDependencies():
|
||||
"""Gets the paths of imported non-system python modules.
|
||||
|
||||
A path is assumed to be a "system" import if it is outside of chromium's
|
||||
src/. The paths will be relative to the current directory.
|
||||
"""
|
||||
_ForceLazyModulesToLoad()
|
||||
module_paths = (m.__file__ for m in sys.modules.values()
|
||||
if m is not None and hasattr(m, '__file__'))
|
||||
abs_module_paths = map(os.path.abspath, filter(lambda p: p is not None, module_paths))
|
||||
|
||||
assert os.path.isabs(DIR_SOURCE_ROOT)
|
||||
non_system_module_paths = [
|
||||
p for p in abs_module_paths if p.startswith(DIR_SOURCE_ROOT)]
|
||||
def ConvertPycToPy(s):
|
||||
if s.endswith('.pyc'):
|
||||
return s[:-1]
|
||||
return s
|
||||
|
||||
non_system_module_paths = map(ConvertPycToPy, non_system_module_paths)
|
||||
non_system_module_paths = map(os.path.relpath, non_system_module_paths)
|
||||
return sorted(set(non_system_module_paths))
|
||||
|
||||
|
||||
def _ForceLazyModulesToLoad():
|
||||
"""Forces any lazily imported modules to fully load themselves.
|
||||
|
||||
Inspecting the modules' __file__ attribute causes lazily imported modules
|
||||
(e.g. from email) to get fully imported and update sys.modules. Iterate
|
||||
over the values until sys.modules stabilizes so that no modules are missed.
|
||||
"""
|
||||
while True:
|
||||
num_modules_before = len(sys.modules.keys())
|
||||
for m in sys.modules.values():
|
||||
if m is not None and hasattr(m, '__file__'):
|
||||
_ = m.__file__
|
||||
num_modules_after = len(sys.modules.keys())
|
||||
if num_modules_before == num_modules_after:
|
||||
break
|
||||
|
||||
def AddDepfileOption(parser):
|
||||
parser.add_option('--depfile',
|
||||
help='Path to depfile. This must be specified as the '
|
||||
'action\'s first output.')
|
||||
|
||||
|
||||
def WriteDepfile(path, dependencies):
|
||||
with open(path, 'w') as depfile:
|
||||
depfile.write(path)
|
||||
depfile.write(': ')
|
||||
depfile.write(' '.join(dependencies))
|
||||
depfile.write('\n')
|
||||
|
||||
|
||||
def ExpandFileArgs(args):
|
||||
"""Replaces file-arg placeholders in args.
|
||||
|
||||
These placeholders have the form:
|
||||
@FileArg(filename:key1:key2:...:keyn)
|
||||
|
||||
The value of such a placeholder is calculated by reading 'filename' as json.
|
||||
And then extracting the value at [key1][key2]...[keyn].
|
||||
|
||||
Note: This intentionally does not return the list of files that appear in such
|
||||
placeholders. An action that uses file-args *must* know the paths of those
|
||||
files prior to the parsing of the arguments (typically by explicitly listing
|
||||
them in the action's inputs in build files).
|
||||
"""
|
||||
new_args = list(args)
|
||||
file_jsons = dict()
|
||||
r = re.compile('@FileArg\((.*?)\)')
|
||||
for i, arg in enumerate(args):
|
||||
match = r.search(arg)
|
||||
if not match:
|
||||
continue
|
||||
|
||||
if match.end() != len(arg):
|
||||
raise Exception('Unexpected characters after FileArg: ' + arg)
|
||||
|
||||
lookup_path = match.group(1).split(':')
|
||||
file_path = lookup_path[0]
|
||||
if not file_path in file_jsons:
|
||||
file_jsons[file_path] = ReadJson(file_path)
|
||||
|
||||
expansion = file_jsons[file_path]
|
||||
for k in lookup_path[1:]:
|
||||
expansion = expansion[k]
|
||||
|
||||
new_args[i] = arg[:match.start()] + str(expansion)
|
||||
|
||||
return new_args
|
||||
|
||||
86
engine/src/build/android/gyp/util/md5_check.py
Normal file
86
engine/src/build/android/gyp/util/md5_check.py
Normal file
@@ -0,0 +1,86 @@
|
||||
# Copyright 2013 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.
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
|
||||
def CallAndRecordIfStale(
|
||||
function, record_path=None, input_paths=None, input_strings=None,
|
||||
force=False):
|
||||
"""Calls function if the md5sum of the input paths/strings has changed.
|
||||
|
||||
The md5sum of the inputs is compared with the one stored in record_path. If
|
||||
this has changed (or the record doesn't exist), function will be called and
|
||||
the new md5sum will be recorded.
|
||||
|
||||
If force is True, the function will be called regardless of whether the
|
||||
md5sum is out of date.
|
||||
"""
|
||||
if not input_paths:
|
||||
input_paths = []
|
||||
if not input_strings:
|
||||
input_strings = []
|
||||
md5_checker = _Md5Checker(
|
||||
record_path=record_path,
|
||||
input_paths=input_paths,
|
||||
input_strings=input_strings)
|
||||
if force or md5_checker.IsStale():
|
||||
function()
|
||||
md5_checker.Write()
|
||||
|
||||
|
||||
def _UpdateMd5ForFile(md5, path, block_size=2**16):
|
||||
with open(path, 'rb') as infile:
|
||||
while True:
|
||||
data = infile.read(block_size)
|
||||
if not data:
|
||||
break
|
||||
md5.update(data)
|
||||
|
||||
|
||||
def _UpdateMd5ForDirectory(md5, dir_path):
|
||||
for root, _, files in os.walk(dir_path):
|
||||
for f in files:
|
||||
_UpdateMd5ForFile(md5, os.path.join(root, f))
|
||||
|
||||
|
||||
def _UpdateMd5ForPath(md5, path):
|
||||
if os.path.isdir(path):
|
||||
_UpdateMd5ForDirectory(md5, path)
|
||||
else:
|
||||
_UpdateMd5ForFile(md5, path)
|
||||
|
||||
|
||||
class _Md5Checker(object):
|
||||
def __init__(self, record_path=None, input_paths=None, input_strings=None):
|
||||
if not input_paths:
|
||||
input_paths = []
|
||||
if not input_strings:
|
||||
input_strings = []
|
||||
|
||||
assert record_path.endswith('.stamp'), (
|
||||
'record paths must end in \'.stamp\' so that they are easy to find '
|
||||
'and delete')
|
||||
|
||||
self.record_path = record_path
|
||||
|
||||
md5 = hashlib.md5()
|
||||
for i in sorted(input_paths):
|
||||
_UpdateMd5ForPath(md5, i)
|
||||
for s in input_strings:
|
||||
md5.update(s.encode('utf-8'))
|
||||
self.new_digest = md5.hexdigest()
|
||||
|
||||
self.old_digest = ''
|
||||
if os.path.exists(self.record_path):
|
||||
with open(self.record_path, 'r') as old_record:
|
||||
self.old_digest = old_record.read()
|
||||
|
||||
def IsStale(self):
|
||||
return self.old_digest != self.new_digest
|
||||
|
||||
def Write(self):
|
||||
with open(self.record_path, 'w') as new_record:
|
||||
new_record.write(self.new_digest)
|
||||
154
engine/src/build/build_config.h
Normal file
154
engine/src/build/build_config.h
Normal file
@@ -0,0 +1,154 @@
|
||||
// Copyright (c) 2012 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.
|
||||
|
||||
// This file adds defines about the platform we're currently building on.
|
||||
// Operating System:
|
||||
// OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX) /
|
||||
// OS_NACL (NACL_SFI or NACL_NONSFI) / OS_NACL_SFI / OS_NACL_NONSFI
|
||||
// Compiler:
|
||||
// COMPILER_MSVC / COMPILER_GCC
|
||||
// Processor:
|
||||
// ARCH_CPU_X86 / ARCH_CPU_X86_64 / ARCH_CPU_X86_FAMILY (X86 or X86_64)
|
||||
// ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
|
||||
|
||||
#ifndef BUILD_BUILD_CONFIG_H_
|
||||
#define BUILD_BUILD_CONFIG_H_
|
||||
|
||||
// A set of macros to use for platform detection.
|
||||
#if defined(__native_client__)
|
||||
// __native_client__ must be first, so that other OS_ defines are not set.
|
||||
#define OS_NACL 1
|
||||
// OS_NACL comes in two sandboxing technology flavors, SFI or Non-SFI.
|
||||
// PNaCl toolchain defines __native_client_nonsfi__ macro in Non-SFI build
|
||||
// mode, while it does not in SFI build mode.
|
||||
#if defined(__native_client_nonsfi__)
|
||||
#define OS_NACL_NONSFI
|
||||
#else
|
||||
#define OS_NACL_SFI
|
||||
#endif
|
||||
#elif defined(ANDROID)
|
||||
#define OS_ANDROID 1
|
||||
#elif defined(__APPLE__)
|
||||
// only include TargetConditions after testing ANDROID as some android builds
|
||||
// on mac don't have this header available and it's not needed unless the target
|
||||
// is really mac/ios.
|
||||
#include <TargetConditionals.h>
|
||||
#define OS_MACOSX 1
|
||||
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
#define OS_IOS 1
|
||||
#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
#elif defined(__linux__)
|
||||
#define OS_LINUX 1
|
||||
// include a system header to pull in features.h for glibc/uclibc macros.
|
||||
#include <unistd.h>
|
||||
#if defined(__GLIBC__) && !defined(__UCLIBC__)
|
||||
// we really are using glibc, not uClibc pretending to be glibc
|
||||
#define LIBC_GLIBC 1
|
||||
#endif
|
||||
#elif defined(_WIN32)
|
||||
#define OS_WIN 1
|
||||
#define TOOLKIT_VIEWS 1
|
||||
#elif defined(__FreeBSD__)
|
||||
#define OS_FREEBSD 1
|
||||
#elif defined(__OpenBSD__)
|
||||
#define OS_OPENBSD 1
|
||||
#elif defined(__sun)
|
||||
#define OS_SOLARIS 1
|
||||
#elif defined(__QNXNTO__)
|
||||
#define OS_QNX 1
|
||||
#else
|
||||
#error Please add support for your platform in build/build_config.h
|
||||
#endif
|
||||
|
||||
#if defined(USE_OPENSSL_CERTS) && defined(USE_NSS_CERTS)
|
||||
#error Cannot use both OpenSSL and NSS for certificates
|
||||
#endif
|
||||
|
||||
// For access to standard BSD features, use OS_BSD instead of a
|
||||
// more specific macro.
|
||||
#if defined(OS_FREEBSD) || defined(OS_OPENBSD)
|
||||
#define OS_BSD 1
|
||||
#endif
|
||||
|
||||
// For access to standard POSIXish features, use OS_POSIX instead of a
|
||||
// more specific macro.
|
||||
#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \
|
||||
defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \
|
||||
defined(OS_NACL) || defined(OS_QNX)
|
||||
#define OS_POSIX 1
|
||||
#endif
|
||||
|
||||
// Use tcmalloc
|
||||
#if (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_ANDROID)) && \
|
||||
!defined(NO_TCMALLOC)
|
||||
#define USE_TCMALLOC 1
|
||||
#endif
|
||||
|
||||
// Compiler detection.
|
||||
#if defined(__GNUC__)
|
||||
#define COMPILER_GCC 1
|
||||
#elif defined(_MSC_VER)
|
||||
#define COMPILER_MSVC 1
|
||||
#else
|
||||
#error Please add support for your compiler in build/build_config.h
|
||||
#endif
|
||||
|
||||
// Processor architecture detection. For more info on what's defined, see:
|
||||
// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
|
||||
// http://www.agner.org/optimize/calling_conventions.pdf
|
||||
// or with gcc, run: "echo | gcc -E -dM -"
|
||||
#if defined(_M_X64) || defined(__x86_64__)
|
||||
#define ARCH_CPU_X86_FAMILY 1
|
||||
#define ARCH_CPU_X86_64 1
|
||||
#define ARCH_CPU_64_BITS 1
|
||||
#define ARCH_CPU_LITTLE_ENDIAN 1
|
||||
#elif defined(_M_IX86) || defined(__i386__)
|
||||
#define ARCH_CPU_X86_FAMILY 1
|
||||
#define ARCH_CPU_X86 1
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#define ARCH_CPU_LITTLE_ENDIAN 1
|
||||
#elif defined(__ARMEL__)
|
||||
#define ARCH_CPU_ARM_FAMILY 1
|
||||
#define ARCH_CPU_ARMEL 1
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#define ARCH_CPU_LITTLE_ENDIAN 1
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define ARCH_CPU_ARM_FAMILY 1
|
||||
#define ARCH_CPU_ARM64 1
|
||||
#define ARCH_CPU_64_BITS 1
|
||||
#define ARCH_CPU_LITTLE_ENDIAN 1
|
||||
#elif defined(__pnacl__)
|
||||
#define ARCH_CPU_32_BITS 1
|
||||
#define ARCH_CPU_LITTLE_ENDIAN 1
|
||||
#else
|
||||
#error Please add support for your architecture in build/build_config.h
|
||||
#endif
|
||||
|
||||
// Type detection for wchar_t.
|
||||
#if defined(OS_WIN)
|
||||
#define WCHAR_T_IS_UTF16
|
||||
#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \
|
||||
(__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff)
|
||||
#define WCHAR_T_IS_UTF32
|
||||
#elif defined(OS_POSIX) && defined(COMPILER_GCC) && defined(__WCHAR_MAX__) && \
|
||||
(__WCHAR_MAX__ == 0x7fff || __WCHAR_MAX__ == 0xffff)
|
||||
// On Posix, we'll detect short wchar_t, but projects aren't guaranteed to
|
||||
// compile in this mode (in particular, Chrome doesn't). This is intended for
|
||||
// other projects using base who manage their own dependencies and make sure
|
||||
// short wchar works for them.
|
||||
#define WCHAR_T_IS_UTF16
|
||||
#else
|
||||
#error Please add support for your compiler in build/build_config.h
|
||||
#endif
|
||||
|
||||
#if defined(OS_ANDROID)
|
||||
// The compiler thinks std::string::const_iterator and "const char*" are
|
||||
// equivalent types.
|
||||
#define STD_STRING_ITERATOR_IS_CHAR_POINTER
|
||||
// The compiler thinks base::string16::const_iterator and "char16*" are
|
||||
// equivalent types.
|
||||
#define BASE_STRING16_ITERATOR_IS_CHAR16_POINTER
|
||||
#endif
|
||||
|
||||
#endif // BUILD_BUILD_CONFIG_H_
|
||||
111
engine/src/build/clobber.py
Executable file
111
engine/src/build/clobber.py
Executable file
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2015 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.
|
||||
|
||||
"""This script provides methods for clobbering build directories."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
|
||||
def extract_gn_build_commands(build_ninja_file):
|
||||
"""Extracts from a build.ninja the commands to run GN.
|
||||
|
||||
The commands to run GN are the gn rule and build.ninja build step at the
|
||||
top of the build.ninja file. We want to keep these when deleting GN builds
|
||||
since we want to preserve the command-line flags to GN.
|
||||
|
||||
On error, returns the empty string."""
|
||||
result = ""
|
||||
with open(build_ninja_file, 'r') as f:
|
||||
# Read until the second blank line. The first thing GN writes to the file
|
||||
# is the "rule gn" and the second is the section for "build build.ninja",
|
||||
# separated by blank lines.
|
||||
num_blank_lines = 0
|
||||
while num_blank_lines < 2:
|
||||
line = f.readline()
|
||||
if len(line) == 0:
|
||||
return '' # Unexpected EOF.
|
||||
result += line
|
||||
if line[0] == '\n':
|
||||
num_blank_lines = num_blank_lines + 1
|
||||
return result
|
||||
|
||||
|
||||
def delete_build_dir(build_dir):
|
||||
# GN writes a build.ninja.d file. Note that not all GN builds have args.gn.
|
||||
build_ninja_d_file = os.path.join(build_dir, 'build.ninja.d')
|
||||
if not os.path.exists(build_ninja_d_file):
|
||||
shutil.rmtree(build_dir)
|
||||
return
|
||||
|
||||
# GN builds aren't automatically regenerated when you sync. To avoid
|
||||
# messing with the GN workflow, erase everything but the args file, and
|
||||
# write a dummy build.ninja file that will automatically rerun GN the next
|
||||
# time Ninja is run.
|
||||
build_ninja_file = os.path.join(build_dir, 'build.ninja')
|
||||
build_commands = extract_gn_build_commands(build_ninja_file)
|
||||
|
||||
try:
|
||||
gn_args_file = os.path.join(build_dir, 'args.gn')
|
||||
with open(gn_args_file, 'r') as f:
|
||||
args_contents = f.read()
|
||||
except IOError:
|
||||
args_contents = ''
|
||||
|
||||
shutil.rmtree(build_dir)
|
||||
|
||||
# Put back the args file (if any).
|
||||
os.mkdir(build_dir)
|
||||
if args_contents != '':
|
||||
with open(gn_args_file, 'w') as f:
|
||||
f.write(args_contents)
|
||||
|
||||
# Write the build.ninja file sufficiently to regenerate itself.
|
||||
with open(os.path.join(build_dir, 'build.ninja'), 'w') as f:
|
||||
if build_commands != '':
|
||||
f.write(build_commands)
|
||||
else:
|
||||
# Couldn't parse the build.ninja file, write a default thing.
|
||||
f.write('''rule gn
|
||||
command = gn -q gen //out/%s/
|
||||
description = Regenerating ninja files
|
||||
|
||||
build build.ninja: gn
|
||||
generator = 1
|
||||
depfile = build.ninja.d
|
||||
''' % (os.path.split(build_dir)[1]))
|
||||
|
||||
# Write a .d file for the build which references a nonexistant file. This
|
||||
# will make Ninja always mark the build as dirty.
|
||||
with open(build_ninja_d_file, 'w') as f:
|
||||
f.write('build.ninja: nonexistant_file.gn\n')
|
||||
|
||||
|
||||
def clobber(out_dir):
|
||||
"""Clobber contents of build directory.
|
||||
|
||||
Don't delete the directory itself: some checkouts have the build directory
|
||||
mounted."""
|
||||
for f in os.listdir(out_dir):
|
||||
path = os.path.join(out_dir, f)
|
||||
if os.path.isfile(path):
|
||||
os.unlink(path)
|
||||
elif os.path.isdir(path):
|
||||
delete_build_dir(path)
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('out_dir', help='The output directory to clobber')
|
||||
args = parser.parse_args()
|
||||
clobber(args.out_dir)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
188
engine/src/build/compiled_action.gni
Normal file
188
engine/src/build/compiled_action.gni
Normal file
@@ -0,0 +1,188 @@
|
||||
# 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.
|
||||
|
||||
# This file introduces two related templates that act like action and
|
||||
# action_foreach but instead of running a Python script, it will compile a
|
||||
# given tool in the host toolchain and run that (either once or over the list
|
||||
# of inputs, depending on the variant).
|
||||
#
|
||||
# Parameters
|
||||
#
|
||||
# tool (required)
|
||||
# [label] Label of the tool to run. This should be an executable, and
|
||||
# this label should not include a toolchain (anything in parens). The
|
||||
# host compile of this tool will be used.
|
||||
#
|
||||
# outputs (required)
|
||||
# [list of files] Like the outputs of action (if using "compiled_action",
|
||||
# this would be just the list of outputs), or action_foreach (if using
|
||||
# "compiled_action_foreach", this would contain source expansions mapping
|
||||
# input to output files).
|
||||
#
|
||||
# args (required)
|
||||
# [list of strings] Same meaning as action/action_foreach.
|
||||
#
|
||||
# inputs (optional)
|
||||
# Files the binary takes as input. The step will be re-run whenever any
|
||||
# of these change. If inputs is empty, the step will run only when the
|
||||
# binary itself changes.
|
||||
#
|
||||
# visibility
|
||||
# deps
|
||||
# args (all optional)
|
||||
# Same meaning as action/action_foreach.
|
||||
#
|
||||
#
|
||||
# Example of usage:
|
||||
#
|
||||
# compiled_action("run_my_tool") {
|
||||
# tool = "//tools/something:mytool"
|
||||
# outputs = [
|
||||
# "$target_gen_dir/mysource.cc",
|
||||
# "$target_gen_dir/mysource.h",
|
||||
# ]
|
||||
#
|
||||
# # The tool takes this input.
|
||||
# inputs = [ "my_input_file.idl" ]
|
||||
#
|
||||
# # In this case, the tool takes as arguments the input file and the output
|
||||
# # build dir (both relative to the "cd" that the script will be run in)
|
||||
# # and will produce the output files listed above.
|
||||
# args = [
|
||||
# rebase_path("my_input_file.idl", root_build_dir),
|
||||
# "--output-dir", rebase_path(target_gen_dir, root_build_dir),
|
||||
# ]
|
||||
# }
|
||||
#
|
||||
# You would typically declare your tool like this:
|
||||
# if (host_toolchain == current_toolchain) {
|
||||
# executable("mytool") {
|
||||
# ...
|
||||
# }
|
||||
# }
|
||||
# The if statement around the executable is optional. That says "I only care
|
||||
# about this target in the host toolchain". Usually this is what you want, and
|
||||
# saves unnecessarily compiling your tool for the target platform. But if you
|
||||
# need a target build of your tool as well, just leave off the if statement.
|
||||
|
||||
if (host_os == "win") {
|
||||
_host_executable_suffix = ".exe"
|
||||
} else {
|
||||
_host_executable_suffix = ""
|
||||
}
|
||||
|
||||
template("compiled_action") {
|
||||
assert(defined(invoker.tool), "tool must be defined for $target_name")
|
||||
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
|
||||
assert(defined(invoker.args), "args must be defined for $target_name")
|
||||
|
||||
assert(!defined(invoker.sources),
|
||||
"compiled_action doesn't take a sources arg. Use inputs instead.")
|
||||
|
||||
action(target_name) {
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"visibility",
|
||||
"metadata",
|
||||
"testonly",
|
||||
"pool",
|
||||
"outputs",
|
||||
])
|
||||
|
||||
script = "//build/gn_run_binary.py"
|
||||
|
||||
if (defined(invoker.inputs)) {
|
||||
inputs = invoker.inputs
|
||||
} else {
|
||||
inputs = []
|
||||
}
|
||||
|
||||
if (defined(invoker.toolchain)) {
|
||||
toolchain = invoker.toolchain
|
||||
} else {
|
||||
toolchain = host_toolchain
|
||||
}
|
||||
|
||||
# Constuct the host toolchain version of the tool.
|
||||
host_tool = invoker.tool + "($toolchain)"
|
||||
|
||||
# Get the path to the executable. Currently, this assumes that the tool
|
||||
# does not specify output_name so that the target name is the name to use.
|
||||
# If that's not the case, we'll need another argument to the script to
|
||||
# specify this, since we can't know what the output name is (it might be in
|
||||
# another file not processed yet).
|
||||
host_executable =
|
||||
get_label_info(host_tool, "root_out_dir") + "/" +
|
||||
get_label_info(host_tool, "name") + _host_executable_suffix
|
||||
|
||||
# Add the executable itself as an input.
|
||||
inputs += [ host_executable ]
|
||||
|
||||
deps = [ host_tool ]
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
}
|
||||
if (defined(invoker.depfile)) {
|
||||
depfile = invoker.depfile
|
||||
}
|
||||
|
||||
# The script takes as arguments the binary to run, and then the arguments
|
||||
# to pass it.
|
||||
args = [ rebase_path(host_executable, root_build_dir) ] + invoker.args
|
||||
}
|
||||
}
|
||||
|
||||
template("compiled_action_foreach") {
|
||||
assert(defined(invoker.sources), "sources must be defined for $target_name")
|
||||
assert(defined(invoker.tool), "tool must be defined for $target_name")
|
||||
assert(defined(invoker.outputs), "outputs must be defined for $target_name")
|
||||
assert(defined(invoker.args), "args must be defined for $target_name")
|
||||
|
||||
action_foreach(target_name) {
|
||||
# Otherwise this is a standalone action, define visibility if requested.
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
}
|
||||
if (defined(invoker.pool)) {
|
||||
pool = invoker.pool
|
||||
}
|
||||
|
||||
script = "//build/gn_run_binary.py"
|
||||
sources = invoker.sources
|
||||
|
||||
if (defined(invoker.inputs)) {
|
||||
inputs = invoker.inputs
|
||||
} else {
|
||||
inputs = []
|
||||
}
|
||||
outputs = invoker.outputs
|
||||
|
||||
# Constuct the host toolchain version of the tool.
|
||||
host_tool = invoker.tool + "($host_toolchain)"
|
||||
|
||||
# Get the path to the executable. Currently, this assumes that the tool
|
||||
# does not specify output_name so that the target name is the name to use.
|
||||
# If that's not the case, we'll need another argument to the script to
|
||||
# specify this, since we can't know what the output name is (it might be in
|
||||
# another file not processed yet).
|
||||
host_executable =
|
||||
get_label_info(host_tool, "root_out_dir") + "/" +
|
||||
get_label_info(host_tool, "name") + _host_executable_suffix
|
||||
|
||||
# Add the executable itself as an input.
|
||||
inputs += [ host_executable ]
|
||||
|
||||
deps = [ host_tool ]
|
||||
if (defined(invoker.deps)) {
|
||||
deps += invoker.deps
|
||||
}
|
||||
if (defined(invoker.depfile)) {
|
||||
depfile = invoker.depfile
|
||||
}
|
||||
|
||||
# The script takes as arguments the binary to run, and then the arguments
|
||||
# to pass it.
|
||||
args = [ rebase_path(host_executable, root_build_dir) ] + invoker.args
|
||||
}
|
||||
}
|
||||
144
engine/src/build/compiler_version.py
Executable file
144
engine/src/build/compiler_version.py
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
"""Compiler version checking tool for gcc
|
||||
|
||||
Print gcc version as XY if you are running gcc X.Y.*.
|
||||
This is used to tweak build flags for gcc 4.4.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
compiler_version_cache = {} # Map from (compiler, tool) -> version.
|
||||
|
||||
|
||||
def Usage(program_name):
|
||||
print('%s MODE TOOL' % os.path.basename(program_name))
|
||||
print('MODE: host or target.')
|
||||
print('TOOL: assembler or compiler or linker.')
|
||||
return 1
|
||||
|
||||
|
||||
def ParseArgs(args):
|
||||
if len(args) != 2:
|
||||
raise Exception('Invalid number of arguments')
|
||||
mode = args[0]
|
||||
tool = args[1]
|
||||
if mode not in ('host', 'target'):
|
||||
raise Exception('Invalid mode: %s' % mode)
|
||||
if tool not in ('assembler', 'compiler', 'linker'):
|
||||
raise Exception('Invalid tool: %s' % tool)
|
||||
return mode, tool
|
||||
|
||||
|
||||
def GetEnvironFallback(var_list, default):
|
||||
"""Look up an environment variable from a possible list of variable names."""
|
||||
for var in var_list:
|
||||
if var in os.environ:
|
||||
return os.environ[var]
|
||||
return default
|
||||
|
||||
|
||||
def GetVersion(compiler, tool):
|
||||
tool_output = tool_error = None
|
||||
cache_key = (compiler, tool)
|
||||
cached_version = compiler_version_cache.get(cache_key)
|
||||
if cached_version:
|
||||
return cached_version
|
||||
try:
|
||||
# Note that compiler could be something tricky like "distcc g++".
|
||||
if tool == "compiler":
|
||||
compiler = compiler + " -dumpversion"
|
||||
# 4.6
|
||||
version_re = re.compile(r"(\d+)\.(\d+)")
|
||||
elif tool == "assembler":
|
||||
compiler = compiler + " -Xassembler --version -x assembler -c /dev/null"
|
||||
# Unmodified: GNU assembler (GNU Binutils) 2.24
|
||||
# Ubuntu: GNU assembler (GNU Binutils for Ubuntu) 2.22
|
||||
# Fedora: GNU assembler version 2.23.2
|
||||
version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
|
||||
elif tool == "linker":
|
||||
compiler = compiler + " -Xlinker --version"
|
||||
# Using BFD linker
|
||||
# Unmodified: GNU ld (GNU Binutils) 2.24
|
||||
# Ubuntu: GNU ld (GNU Binutils for Ubuntu) 2.22
|
||||
# Fedora: GNU ld version 2.23.2
|
||||
# Using Gold linker
|
||||
# Unmodified: GNU gold (GNU Binutils 2.24) 1.11
|
||||
# Ubuntu: GNU gold (GNU Binutils for Ubuntu 2.22) 1.11
|
||||
# Fedora: GNU gold (version 2.23.2) 1.11
|
||||
version_re = re.compile(r"^GNU [^ ]+ .* (\d+).(\d+).*?$", re.M)
|
||||
else:
|
||||
raise Exception("Unknown tool %s" % tool)
|
||||
|
||||
# Force the locale to C otherwise the version string could be localized
|
||||
# making regex matching fail.
|
||||
env = os.environ.copy()
|
||||
env["LC_ALL"] = "C"
|
||||
pipe = subprocess.Popen(compiler, shell=True, env=env,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
tool_output, tool_error = pipe.communicate()
|
||||
if pipe.returncode:
|
||||
raise subprocess.CalledProcessError(pipe.returncode, compiler)
|
||||
|
||||
parsed_output = version_re.match(tool_output)
|
||||
result = parsed_output.group(1) + parsed_output.group(2)
|
||||
compiler_version_cache[cache_key] = result
|
||||
return result
|
||||
except Exception as e:
|
||||
if tool_error:
|
||||
sys.stderr.write(tool_error)
|
||||
print("compiler_version.py failed to execute:", compiler, file=sys.stderr)
|
||||
print(e, file=sys.stderr)
|
||||
return ""
|
||||
|
||||
|
||||
def main(args):
|
||||
try:
|
||||
(mode, tool) = ParseArgs(args[1:])
|
||||
except Exception as e:
|
||||
sys.stderr.write(e.message + '\n\n')
|
||||
return Usage(args[0])
|
||||
|
||||
ret_code, result = ExtractVersion(mode, tool)
|
||||
if ret_code == 0:
|
||||
print(result)
|
||||
return ret_code
|
||||
|
||||
|
||||
def DoMain(args):
|
||||
"""Hook to be called from gyp without starting a separate python
|
||||
interpreter."""
|
||||
(mode, tool) = ParseArgs(args)
|
||||
ret_code, result = ExtractVersion(mode, tool)
|
||||
if ret_code == 0:
|
||||
return result
|
||||
raise Exception("Failed to extract compiler version for args: %s" % args)
|
||||
|
||||
|
||||
def ExtractVersion(mode, tool):
|
||||
# Check if various CXX environment variables exist and use them if they
|
||||
# exist. The preferences and fallback order is a close approximation of
|
||||
# GenerateOutputForConfig() in GYP's ninja generator.
|
||||
# The main difference being not supporting GYP's make_global_settings.
|
||||
environments = ['CXX_target', 'CXX']
|
||||
if mode == 'host':
|
||||
environments = ['CXX_host'] + environments;
|
||||
compiler = GetEnvironFallback(environments, 'c++')
|
||||
|
||||
if compiler:
|
||||
compiler_version = GetVersion(compiler, tool)
|
||||
if compiler_version != "":
|
||||
return (0, compiler_version)
|
||||
return (1, None)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
194
engine/src/build/config/BUILD.gn
Normal file
194
engine/src/build/config/BUILD.gn
Normal file
@@ -0,0 +1,194 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/config/allocator.gni")
|
||||
import("//build/config/crypto.gni")
|
||||
import("//build/config/dcheck_always_on.gni")
|
||||
import("//build/config/features.gni")
|
||||
import("//build/config/ui.gni")
|
||||
|
||||
declare_args() {
|
||||
# When set, turns off the (normally-on) iterator debugging and related stuff
|
||||
# that is normally turned on for Debug builds. These are generally useful for
|
||||
# catching bugs but in some cases may cause conflicts or excessive slowness.
|
||||
disable_iterator_debugging = false
|
||||
|
||||
# Set to true to compile with the OpenGL ES 2.0 conformance tests.
|
||||
internal_gles2_conform_tests = false
|
||||
}
|
||||
|
||||
# TODO(brettw) Most of these should be removed. Instead of global feature
|
||||
# flags, we should have more modular flags that apply only to a target and its
|
||||
# dependents. For example, depending on the "x11" meta-target should define
|
||||
# USE_X11 for all dependents so that everything that could use X11 gets the
|
||||
# define, but anything that doesn't depend on X11 doesn't see it.
|
||||
#
|
||||
# For now we define these globally to match the current GYP build.
|
||||
config("feature_flags") {
|
||||
defines = []
|
||||
|
||||
if (dcheck_always_on) {
|
||||
defines += [ "DCHECK_ALWAYS_ON=1" ]
|
||||
}
|
||||
if (use_glfw) {
|
||||
defines += [ "USE_GLFW=1" ]
|
||||
}
|
||||
if (use_openssl) {
|
||||
defines += [ "USE_OPENSSL=1" ]
|
||||
}
|
||||
if (use_openssl_certs) {
|
||||
defines += [ "USE_OPENSSL_CERTS=1" ]
|
||||
}
|
||||
if (use_nss_certs) {
|
||||
defines += [ "USE_NSS_CERTS=1" ]
|
||||
}
|
||||
if (is_asan) {
|
||||
defines += [ "ADDRESS_SANITIZER" ]
|
||||
}
|
||||
if (is_lsan) {
|
||||
defines += [ "LEAK_SANITIZER" ]
|
||||
}
|
||||
if (is_tsan) {
|
||||
defines += [
|
||||
"THREAD_SANITIZER",
|
||||
"DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
|
||||
"WTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1",
|
||||
]
|
||||
}
|
||||
if (is_msan) {
|
||||
defines += [ "MEMORY_SANITIZER" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Debug/release ----------------------------------------------------------------
|
||||
|
||||
config("debug") {
|
||||
defines = [ "_DEBUG" ]
|
||||
|
||||
if (is_win) {
|
||||
if (disable_iterator_debugging) {
|
||||
# Iterator debugging is enabled by the compiler on debug builds, and we
|
||||
# have to tell it to turn it off.
|
||||
defines += [ "_HAS_ITERATOR_DEBUGGING=0" ]
|
||||
}
|
||||
} else if (is_linux && !is_android && current_cpu == "x64" &&
|
||||
!disable_iterator_debugging) {
|
||||
# Enable libstdc++ debugging facilities to help catch problems early, see
|
||||
# http://crbug.com/65151 .
|
||||
# TODO(phajdan.jr): Should we enable this for all of POSIX?
|
||||
defines += [ "_GLIBCXX_DEBUG=1" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("release") {
|
||||
defines = [ "NDEBUG" ]
|
||||
|
||||
# Sanitizers.
|
||||
# TODO(GYP) The GYP build has "release_valgrind_build == 0" for this
|
||||
# condition. When Valgrind is set up, we need to do the same here.
|
||||
if (is_tsan) {
|
||||
defines += [
|
||||
"DYNAMIC_ANNOTATIONS_ENABLED=1",
|
||||
"WTF_USE_DYNAMIC_ANNOTATIONS=1",
|
||||
]
|
||||
} else {
|
||||
defines += [ "NVALGRIND" ]
|
||||
defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Default libraries ------------------------------------------------------------
|
||||
|
||||
# This config defines the default libraries applied to all targets.
|
||||
config("default_libs") {
|
||||
if (is_win) {
|
||||
# TODO(brettw) this list of defaults should probably be smaller, and
|
||||
# instead the targets that use the less common ones (e.g. wininet or
|
||||
# winspool) should include those explicitly.
|
||||
libs = [
|
||||
"advapi32.lib",
|
||||
"comdlg32.lib",
|
||||
"delayimp.lib",
|
||||
"dnsapi.lib",
|
||||
"iphlpapi.lib",
|
||||
"msimg32.lib",
|
||||
"odbc32.lib",
|
||||
"odbccp32.lib",
|
||||
"ole32.lib",
|
||||
"oleaut32.lib",
|
||||
"psapi.lib",
|
||||
"shell32.lib",
|
||||
"shlwapi.lib",
|
||||
"Rpcrt4.lib",
|
||||
"uuid.lib",
|
||||
"version.lib",
|
||||
"wininet.lib",
|
||||
"winmm.lib",
|
||||
"winspool.lib",
|
||||
"ws2_32.lib",
|
||||
|
||||
# Please don't add more stuff here. We should actually be making this
|
||||
# list smaller, since all common things should be covered. If you need
|
||||
# some extra libraries, please just add a libs = [ "foo.lib" ] to your
|
||||
# target that needs it.
|
||||
]
|
||||
} else if (is_android) {
|
||||
# Android uses -nostdlib so we need to add even libc here.
|
||||
libs = [
|
||||
# TODO(brettw) write a version of this, hopefully we can express this
|
||||
# without forking out to GCC just to get the library name. The android
|
||||
# toolchain directory should probably be extracted into a .gni file that
|
||||
# this file and the android toolchain .gn file can share.
|
||||
# # Manually link the libgcc.a that the cross compiler uses.
|
||||
# '<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
|
||||
"c",
|
||||
"dl",
|
||||
"m",
|
||||
]
|
||||
} else if (is_linux) {
|
||||
libs = [ "dl" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Add this config to your target to enable precompiled headers.
|
||||
#
|
||||
# On Windows, precompiled headers are done on a per-target basis. If you have
|
||||
# just a couple of files, the time it takes to precompile (~2 seconds) can
|
||||
# actually be longer than the time saved. On a Z620, a 100 file target compiles
|
||||
# about 2 seconds faster with precompiled headers, with greater savings for
|
||||
# larger targets.
|
||||
#
|
||||
# Recommend precompiled headers for targets with more than 50 .cc files.
|
||||
config("precompiled_headers") {
|
||||
# TODO(brettw) enable this when GN support in the binary has been rolled.
|
||||
#if (is_win) {
|
||||
if (false) {
|
||||
# This is a string rather than a file GN knows about. It has to match
|
||||
# exactly what's in the /FI flag below, and what might appear in the source
|
||||
# code in quotes for an #include directive.
|
||||
precompiled_header = "build/precompile.h"
|
||||
|
||||
# This is a file that GN will compile with the above header. It will be
|
||||
# implicitly added to the sources (potentially multiple times, with one
|
||||
# variant for each language used in the target).
|
||||
precompiled_source = "//build/precompile.cc"
|
||||
|
||||
# Force include the header.
|
||||
cflags = [ "/FI$precompiled_header" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("symbol_visibility_hidden") {
|
||||
# Empty but present because this is also present in other buildroots.
|
||||
# The same config from gcc/BUILD.gn is used instead.
|
||||
}
|
||||
|
||||
config("no_rtti") {
|
||||
if (is_win) {
|
||||
cflags_cc = [ "/GR-" ]
|
||||
} else {
|
||||
cflags_cc = [ "-fno-rtti" ]
|
||||
cflags_objcc = cflags_cc
|
||||
}
|
||||
}
|
||||
828
engine/src/build/config/BUILDCONFIG.gn
Normal file
828
engine/src/build/config/BUILDCONFIG.gn
Normal file
@@ -0,0 +1,828 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# =============================================================================
|
||||
# PLATFORM SELECTION
|
||||
# =============================================================================
|
||||
#
|
||||
# There are two main things to set: "os" and "cpu". The "toolchain" is the name
|
||||
# of the GN thing that encodes combinations of these things.
|
||||
#
|
||||
# Users typically only set the variables "target_os" and "target_cpu" in "gn
|
||||
# args", the rest are set up by our build and internal to GN.
|
||||
#
|
||||
# There are three different types of each of these things: The "host"
|
||||
# represents the computer doing the compile and never changes. The "target"
|
||||
# represents the main thing we're trying to build. The "current" represents
|
||||
# which configuration is currently being defined, which can be either the
|
||||
# host, the target, or something completely different (like nacl). GN will
|
||||
# run the same build file multiple times for the different required
|
||||
# configuration in the same build.
|
||||
#
|
||||
# This gives the following variables:
|
||||
# - host_os, host_cpu, host_toolchain
|
||||
# - target_os, target_cpu, default_toolchain
|
||||
# - current_os, current_cpu, current_toolchain.
|
||||
#
|
||||
# Note the default_toolchain isn't symmetrical (you would expect
|
||||
# target_toolchain). This is because the "default" toolchain is a GN built-in
|
||||
# concept, and "target" is something our build sets up that's symmetrical with
|
||||
# its GYP counterpart. Potentially the built-in default_toolchain variable
|
||||
# could be renamed in the future.
|
||||
#
|
||||
# When writing build files, to do something only for the host:
|
||||
# if (current_toolchain == host_toolchain) { ...
|
||||
|
||||
if (target_os == "") {
|
||||
target_os = host_os
|
||||
}
|
||||
|
||||
if (target_cpu == "") {
|
||||
if (target_os == "android") {
|
||||
# If we're building for Android, we should assume that we want to
|
||||
# build for ARM by default, not the host_cpu (which is likely x64).
|
||||
# This allows us to not have to specify both target_os and target_cpu
|
||||
# on the command line.
|
||||
target_cpu = "arm"
|
||||
} else {
|
||||
target_cpu = host_cpu
|
||||
}
|
||||
}
|
||||
|
||||
if (current_cpu == "") {
|
||||
current_cpu = target_cpu
|
||||
}
|
||||
if (current_os == "") {
|
||||
if (host_os == "win") {
|
||||
current_os = "win"
|
||||
} else {
|
||||
current_os = target_os
|
||||
}
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# BUILD FLAGS
|
||||
# =============================================================================
|
||||
#
|
||||
# This block lists input arguments to the build, along with their default
|
||||
# values.
|
||||
#
|
||||
# If a value is specified on the command line, it will overwrite the defaults
|
||||
# given in a declare_args block, otherwise the default will be used.
|
||||
#
|
||||
# YOU SHOULD ALMOST NEVER NEED TO ADD FLAGS TO THIS FILE. GN allows any file in
|
||||
# the build to declare build flags. If you need a flag for a single component,
|
||||
# you can just declare it in the corresponding BUILD.gn file. If you need a
|
||||
# flag in multiple components, there are a few options:
|
||||
#
|
||||
# - If your feature is a single target, say //components/foo, and the targets
|
||||
# depending on foo need to have some define set if foo is enabled: (1) Write
|
||||
# a declare_args block in foo's BUILD.gn file listing your enable_foo build
|
||||
# flag. (2) Write a config in that file listing the define, and list that
|
||||
# config in foo's public_configs. This will propagate that define to all the
|
||||
# targets depending on foo. (3) When foo is not enabled, just make it expand
|
||||
# to an empty group (or whatever's appropriate for the "off" state of your
|
||||
# feature.
|
||||
#
|
||||
# - If a semi-random set of targets need to know about a define: (1) In the
|
||||
# lowest level of the build that knows about this feature, add a declare_args
|
||||
# block in the build file for your enable flag. (2) Write a config that adds
|
||||
# a define conditionally based on that build flags. (3) Manually add that
|
||||
# config to the "configs" applying to the targets that need the define.
|
||||
#
|
||||
# - If a semi-random set of targets need to know about the build flag (to do
|
||||
# file inclusion or exclusion, more than just defines): (1) Write a .gni file
|
||||
# in the lowest-level directory that knows about the feature. (2) Put the
|
||||
# declare_args block with your build flag in that .gni file. (3) Import that
|
||||
# .gni file from the BUILD.gn files that need the flag.
|
||||
#
|
||||
# Other advice:
|
||||
#
|
||||
# - Use boolean values when possible. If you need a default value that expands
|
||||
# to some complex thing in the default case (like the location of the
|
||||
# compiler which would be computed by a script), use a default value of -1 or
|
||||
# the empty string. Outside of the declare_args block, conditionally expand
|
||||
# the default value as necessary.
|
||||
#
|
||||
# - Use a name like "use_foo" or "is_foo" (whatever is more appropriate for
|
||||
# your feature) rather than just "foo".
|
||||
#
|
||||
# - Write good comments directly above the declaration with no blank line.
|
||||
# These comments will appear as documentation in "gn args --list".
|
||||
#
|
||||
# - Don't call exec_script inside declare_args. This will execute the script
|
||||
# even if the value is overridden, which is wasteful. See first bullet.
|
||||
|
||||
declare_args() {
|
||||
# How many symbols to include in the build. This affects the performance of
|
||||
# the build since the symbols are large and dealing with them is slow.
|
||||
# 2 means regular build with symbols.
|
||||
# 1 means minimal symbols, usually enough for backtraces only.
|
||||
# 0 means no symbols.
|
||||
# -1 means auto-set (off in release, regular in debug).
|
||||
symbol_level = -1
|
||||
|
||||
# Component build.
|
||||
is_component_build = false
|
||||
|
||||
# Official build.
|
||||
is_official_build = false
|
||||
|
||||
# Debug build.
|
||||
is_debug = true
|
||||
|
||||
# Whether we're a traditional desktop unix.
|
||||
is_desktop_linux = current_os == "linux" && current_os != "chromeos"
|
||||
|
||||
# Set to true when compiling with the Clang compiler. Typically this is used
|
||||
# to configure warnings.
|
||||
is_clang = current_os == "mac" || current_os == "ios" ||
|
||||
current_os == "linux" || current_os == "chromeos"
|
||||
|
||||
# Compile for Address Sanitizer to find memory bugs.
|
||||
is_asan = false
|
||||
|
||||
# Compile for Leak Sanitizer to find leaks.
|
||||
is_lsan = false
|
||||
|
||||
# Compile for Memory Sanitizer to find uninitialized reads.
|
||||
is_msan = false
|
||||
|
||||
# Compile for Thread Sanitizer to find threading bugs.
|
||||
is_tsan = false
|
||||
|
||||
# Compile for Undefined Behavior Sanitizer.
|
||||
is_ubsan = false
|
||||
|
||||
# protobuf-gn fails to build if this argument isn't defined. This should never
|
||||
# be set to true, becuase we never build within the Fuchsia tree.
|
||||
is_fuchsia_tree = false
|
||||
|
||||
if (current_os == "chromeos") {
|
||||
# Allows the target toolchain to be injected as arguments. This is needed
|
||||
# to support the CrOS build system which supports per-build-configuration
|
||||
# toolchains.
|
||||
cros_use_custom_toolchain = false
|
||||
}
|
||||
|
||||
# DON'T ADD MORE FLAGS HERE. Read the comment above.
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# OS DEFINITIONS
|
||||
# =============================================================================
|
||||
#
|
||||
# We set these various is_FOO booleans for convenience in writing OS-based
|
||||
# conditions.
|
||||
#
|
||||
# - is_android, is_chromeos, is_ios, and is_win should be obvious.
|
||||
# - is_mac is set only for desktop Mac. It is not set on iOS.
|
||||
# - is_posix is true for mac and any Unix-like system (basically everything
|
||||
# except Windows).
|
||||
# - is_linux is true for desktop Linux and ChromeOS, but not Android (which is
|
||||
# generally too different despite being based on the Linux kernel).
|
||||
#
|
||||
# Do not add more is_* variants here for random lesser-used Unix systems like
|
||||
# aix or one of the BSDs. If you need to check these, just check the
|
||||
# current_os value directly.
|
||||
|
||||
if (current_os == "win") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = false
|
||||
is_win = true
|
||||
is_wasm = false
|
||||
} else if (current_os == "mac") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = true
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "android") {
|
||||
is_android = true
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "chromeos") {
|
||||
is_android = false
|
||||
is_chromeos = true
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = true
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "nacl") {
|
||||
# current_os == "nacl" will be passed by the nacl toolchain definition.
|
||||
# It is not set by default or on the command line. We treat is as a
|
||||
# Posix variant.
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "ios") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = true
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "linux") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = true
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "fuchsia" || target_os == "fuchsia") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = true
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = true
|
||||
is_win = false
|
||||
is_wasm = false
|
||||
} else if (current_os == "wasm") {
|
||||
is_android = false
|
||||
is_chromeos = false
|
||||
is_fuchsia = false
|
||||
is_fuchsia_host = false
|
||||
is_ios = false
|
||||
is_linux = false
|
||||
is_mac = false
|
||||
is_posix = false
|
||||
is_win = false
|
||||
is_wasm = true
|
||||
}
|
||||
|
||||
is_apple = is_ios || is_mac
|
||||
|
||||
# Needed for some third_party build files from Chromium.
|
||||
is_nacl = false
|
||||
|
||||
# Needed for //third_party/angle.
|
||||
is_castos = false
|
||||
is_chromecast = false
|
||||
is_chromeos_lacros = false
|
||||
ozone_platform_headless = false
|
||||
|
||||
# Needed for //flutter/third_party/swiftshader and //third_party/angle.
|
||||
if (is_linux) {
|
||||
ozone_platform_x11 = true
|
||||
ozone_platform_wayland = true
|
||||
} else {
|
||||
ozone_platform_x11 = false
|
||||
ozone_platform_wayland = false
|
||||
}
|
||||
|
||||
default_library_type = "static_library"
|
||||
|
||||
# =============================================================================
|
||||
# BUILD OPTIONS
|
||||
# =============================================================================
|
||||
|
||||
# These Sanitizers all imply using the Clang compiler. On Windows they either
|
||||
# don't work or work differently.
|
||||
using_sanitizer = !is_win && (is_asan || is_lsan || is_tsan || is_msan)
|
||||
if (!is_clang && using_sanitizer) {
|
||||
is_clang = true
|
||||
}
|
||||
|
||||
use_flutter_cxx = is_clang && (is_linux || is_android || is_mac || is_ios)
|
||||
|
||||
if (is_msan && !is_linux) {
|
||||
assert(false, "Memory sanitizer is only available on Linux.")
|
||||
}
|
||||
|
||||
# =============================================================================
|
||||
# TARGET DEFAULTS
|
||||
# =============================================================================
|
||||
#
|
||||
# Set up the default configuration for every build target of the given type.
|
||||
# The values configured here will be automatically set on the scope of the
|
||||
# corresponding target. Target definitions can add or remove to the settings
|
||||
# here as needed.
|
||||
|
||||
# Holds all configs used for making native executables and libraries, to avoid
|
||||
# duplication in each target below.
|
||||
_native_compiler_configs = [
|
||||
"//build/config:feature_flags",
|
||||
"//build/config/compiler:compiler",
|
||||
"//build/config/compiler:cxx_version_default",
|
||||
"//build/config/compiler:compiler_arm_fpu",
|
||||
"//build/config/compiler:chromium_code",
|
||||
"//build/config/compiler:default_include_dirs",
|
||||
"//build/config/compiler:no_rtti",
|
||||
"//build/config/compiler:runtime_library",
|
||||
]
|
||||
|
||||
if (use_flutter_cxx) {
|
||||
_native_compiler_configs += [
|
||||
"//flutter/third_party/libcxxabi:libcxxabi_config",
|
||||
"//flutter/third_party/libcxx:libcxx_config",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_win) {
|
||||
_native_compiler_configs += [
|
||||
"//build/config/win:lean_and_mean",
|
||||
"//build/config/win:nominmax",
|
||||
"//build/config/win:sdk",
|
||||
"//build/config/win:unicode",
|
||||
"//build/config/win:winver",
|
||||
]
|
||||
}
|
||||
if (is_posix) {
|
||||
_native_compiler_configs += [
|
||||
"//build/config/gcc:no_exceptions",
|
||||
"//build/config/gcc:relative_paths",
|
||||
"//build/config/gcc:symbol_visibility_hidden",
|
||||
"//build/config:symbol_visibility_hidden",
|
||||
]
|
||||
}
|
||||
|
||||
if (is_linux) {
|
||||
_native_compiler_configs += [ "//build/config/linux:sdk" ]
|
||||
} else if (is_mac) {
|
||||
_native_compiler_configs += [ "//build/config/mac:sdk" ]
|
||||
} else if (is_ios) {
|
||||
_native_compiler_configs += [ "//build/config/ios:sdk" ]
|
||||
} else if (is_android) {
|
||||
_native_compiler_configs += [ "//build/config/android:sdk" ]
|
||||
}
|
||||
|
||||
if (is_clang) {
|
||||
_native_compiler_configs += [ "//build/config/clang:extra_warnings" ]
|
||||
_native_compiler_configs += [ "//build/config/clang:find_bad_constructs" ]
|
||||
}
|
||||
|
||||
# Optimizations and debug checking.
|
||||
if (is_debug) {
|
||||
_native_compiler_configs += [ "//build/config:debug" ]
|
||||
_default_optimization_config = "//build/config/compiler:no_optimize"
|
||||
} else {
|
||||
_native_compiler_configs += [ "//build/config:release" ]
|
||||
_default_optimization_config = "//build/config/compiler:optimize"
|
||||
}
|
||||
_native_compiler_configs += [ _default_optimization_config ]
|
||||
|
||||
# zlib's BUILD.gn expects to have this config among default configs.
|
||||
_native_compiler_configs += [ "//build/config/compiler:default_optimization" ]
|
||||
|
||||
# If it wasn't manually set, set to an appropriate default.
|
||||
if (symbol_level == -1) {
|
||||
# Linux is slowed by having symbols as part of the target binary, whereas
|
||||
# Mac and Windows have them separate, so in Release Linux, default them off.
|
||||
# Wasm we definitely want to strip symbols in release mode because binary
|
||||
# size is paramount.
|
||||
if (is_debug || (!is_linux && !is_wasm)) {
|
||||
symbol_level = 2
|
||||
} else if (is_asan || is_lsan || is_tsan || is_msan) {
|
||||
# Sanitizers require symbols for filename suppressions to work.
|
||||
symbol_level = 1
|
||||
} else {
|
||||
symbol_level = 0
|
||||
}
|
||||
}
|
||||
|
||||
# Symbol setup.
|
||||
if (symbol_level == 2) {
|
||||
_default_symbols_config = "//build/config/compiler:symbols"
|
||||
} else if (symbol_level == 1) {
|
||||
_default_symbols_config = "//build/config/compiler:minimal_symbols"
|
||||
} else if (symbol_level == 0) {
|
||||
_default_symbols_config = "//build/config/compiler:no_symbols"
|
||||
} else {
|
||||
assert(false, "Bad value for symbol_level.")
|
||||
}
|
||||
_native_compiler_configs += [ _default_symbols_config ]
|
||||
|
||||
# Windows linker setup for EXEs and DLLs.
|
||||
if (is_win) {
|
||||
_windows_linker_configs = [
|
||||
"//build/config/win:default_incremental_linking",
|
||||
"//build/config/win:sdk_link",
|
||||
"//build/config/win:common_linker_setup",
|
||||
|
||||
# Default to console-mode apps. Most of our targets are tests and such
|
||||
# that shouldn't use the windows subsystem.
|
||||
"//build/config/win:console",
|
||||
]
|
||||
}
|
||||
|
||||
# Executable defaults.
|
||||
_executable_configs =
|
||||
_native_compiler_configs + [ "//build/config:default_libs" ]
|
||||
if (is_win) {
|
||||
_executable_configs += _windows_linker_configs
|
||||
} else if (is_mac) {
|
||||
_executable_configs += [
|
||||
"//build/config/mac:mac_dynamic_flags",
|
||||
"//build/config/mac:mac_executable_flags",
|
||||
]
|
||||
} else if (is_linux || is_android) {
|
||||
_executable_configs += [ "//build/config/gcc:executable_ldconfig" ]
|
||||
if (is_android) {
|
||||
_executable_configs += [ "//build/config/android:executable_config" ]
|
||||
}
|
||||
}
|
||||
set_defaults("executable") {
|
||||
configs = _executable_configs
|
||||
}
|
||||
|
||||
# Static library defaults.
|
||||
set_defaults("static_library") {
|
||||
configs = _native_compiler_configs
|
||||
}
|
||||
|
||||
# Shared library defaults (also for components in component mode).
|
||||
_shared_library_configs =
|
||||
_native_compiler_configs + [ "//build/config:default_libs" ]
|
||||
if (is_win) {
|
||||
_shared_library_configs += _windows_linker_configs
|
||||
} else if (is_mac) {
|
||||
_shared_library_configs += [ "//build/config/mac:mac_dynamic_flags" ]
|
||||
}
|
||||
set_defaults("shared_library") {
|
||||
configs = _shared_library_configs
|
||||
}
|
||||
if (is_component_build) {
|
||||
set_defaults("component") {
|
||||
configs = _shared_library_configs
|
||||
}
|
||||
}
|
||||
|
||||
# Source set defaults (also for components in non-component mode).
|
||||
set_defaults("source_set") {
|
||||
configs = _native_compiler_configs
|
||||
}
|
||||
if (!is_component_build) {
|
||||
set_defaults("component") {
|
||||
configs = _native_compiler_configs
|
||||
}
|
||||
}
|
||||
|
||||
# Test defaults.
|
||||
set_defaults("test") {
|
||||
if (is_android) {
|
||||
configs = _shared_library_configs
|
||||
} else {
|
||||
configs = _executable_configs
|
||||
}
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# TOOLCHAIN SETUP
|
||||
# ==============================================================================
|
||||
#
|
||||
# Here we set the default toolchain, as well as the variable host_toolchain
|
||||
# which will identify the toolchain corresponding to the local system when
|
||||
# doing cross-compiles. When not cross-compiling, this will be the same as the
|
||||
# default toolchain.
|
||||
import("//build/toolchain/custom/custom.gni")
|
||||
|
||||
# Define this to allow Fuchsia's fork of harfbuzz to build.
|
||||
# shlib_toolchain is a Fuchsia-specific symbol and not used by Flutter.
|
||||
shlib_toolchain = false
|
||||
|
||||
if (custom_toolchain != "") {
|
||||
assert(custom_sysroot != "")
|
||||
assert(custom_target_triple != "")
|
||||
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
|
||||
set_default_toolchain("//build/toolchain/custom")
|
||||
} else if (is_win) {
|
||||
assert(is_clang)
|
||||
host_toolchain = "//build/toolchain/win:clang_$host_cpu"
|
||||
set_default_toolchain("//build/toolchain/win:clang_$current_cpu")
|
||||
} else if (is_android) {
|
||||
if (host_os == "linux") {
|
||||
# Use clang for the x86/64 Linux host builds.
|
||||
if (host_cpu == "x86" || host_cpu == "x64") {
|
||||
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
|
||||
} else {
|
||||
host_toolchain = "//build/toolchain/linux:$host_cpu"
|
||||
}
|
||||
} else if (host_os == "mac") {
|
||||
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
|
||||
} else if (host_os == "win") {
|
||||
assert(is_clang)
|
||||
host_toolchain = "//build/toolchain/win:clang_$host_cpu"
|
||||
} else {
|
||||
assert(false, "Unknown host for android cross compile")
|
||||
}
|
||||
if (is_clang) {
|
||||
set_default_toolchain("//build/toolchain/android:clang_$current_cpu")
|
||||
} else {
|
||||
set_default_toolchain("//build/toolchain/android:$current_cpu")
|
||||
}
|
||||
} else if (is_linux) {
|
||||
if (is_clang) {
|
||||
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
|
||||
set_default_toolchain("//build/toolchain/linux:clang_$current_cpu")
|
||||
} else {
|
||||
host_toolchain = "//build/toolchain/linux:$host_cpu"
|
||||
set_default_toolchain("//build/toolchain/linux:$current_cpu")
|
||||
}
|
||||
if (is_chromeos && cros_use_custom_toolchain) {
|
||||
set_default_toolchain("//build/toolchain/cros:target")
|
||||
}
|
||||
} else if (is_mac) {
|
||||
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
|
||||
set_default_toolchain("//build/toolchain/mac:clang_$current_cpu")
|
||||
} else if (is_ios) {
|
||||
import("//build/config/ios/ios_sdk.gni") # For use_ios_simulator
|
||||
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
|
||||
if (use_ios_simulator) {
|
||||
if (target_cpu == "arm64") {
|
||||
set_default_toolchain("//build/toolchain/mac:ios_clang_arm_sim")
|
||||
} else {
|
||||
set_default_toolchain("//build/toolchain/mac:ios_clang_x64_sim")
|
||||
}
|
||||
} else {
|
||||
set_default_toolchain("//build/toolchain/mac:ios_clang_arm")
|
||||
}
|
||||
} else if (is_fuchsia) {
|
||||
if (host_os == "mac") {
|
||||
host_toolchain = "//build/toolchain/mac:clang_$host_cpu"
|
||||
} else {
|
||||
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
|
||||
}
|
||||
set_default_toolchain("//build/toolchain/fuchsia")
|
||||
} else if (is_wasm) {
|
||||
ar = "ar"
|
||||
cc = "cc"
|
||||
cxx = "c++"
|
||||
win_vc = ""
|
||||
win_toolchain_version = ""
|
||||
clang_win = ""
|
||||
clang_win_version = ""
|
||||
host_toolchain = "//build/toolchain/wasm"
|
||||
set_default_toolchain("//build/toolchain/wasm")
|
||||
} else {
|
||||
assert(false, "Toolchain not set because of unknown platform.")
|
||||
}
|
||||
|
||||
# Sets default dependencies for executable and shared_library targets.
|
||||
#
|
||||
# Variables
|
||||
# no_default_deps: If true, no standard dependencies will be added.
|
||||
if (use_flutter_cxx) {
|
||||
foreach(_target_type,
|
||||
[
|
||||
"executable",
|
||||
"loadable_module",
|
||||
"shared_library",
|
||||
]) {
|
||||
template(_target_type) {
|
||||
target(_target_type, target_name) {
|
||||
forward_variables_from(invoker, "*", [ "no_default_deps" ])
|
||||
if (!defined(deps)) {
|
||||
deps = []
|
||||
}
|
||||
if (!defined(invoker.no_default_deps) || !invoker.no_default_deps) {
|
||||
deps += [ "//flutter/third_party/libcxx" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# ==============================================================================
|
||||
# COMPONENT SETUP
|
||||
# ==============================================================================
|
||||
|
||||
# TODO(brettw) erase this once the built-in "component" function is removed.
|
||||
if (is_component_build) {
|
||||
component_mode = "shared_library"
|
||||
} else {
|
||||
component_mode = "source_set"
|
||||
}
|
||||
|
||||
template("component") {
|
||||
if (is_component_build) {
|
||||
shared_library(target_name) {
|
||||
# Configs will always be defined since we set_defaults for a component
|
||||
# above. We want to use those rather than whatever came with the nested
|
||||
# shared/static library inside the component.
|
||||
configs = [] # Prevent list overwriting warning.
|
||||
configs = invoker.configs
|
||||
|
||||
if (defined(invoker.all_dependent_configs)) {
|
||||
all_dependent_configs = invoker.all_dependent_configs
|
||||
}
|
||||
if (defined(invoker.allow_circular_includes_from)) {
|
||||
allow_circular_includes_from = invoker.allow_circular_includes_from
|
||||
}
|
||||
if (defined(invoker.cflags)) {
|
||||
cflags = invoker.cflags
|
||||
}
|
||||
if (defined(invoker.cflags_c)) {
|
||||
cflags_c = invoker.cflags_c
|
||||
}
|
||||
if (defined(invoker.cflags_cc)) {
|
||||
cflags_cc = invoker.cflags_cc
|
||||
}
|
||||
if (defined(invoker.cflags_objc)) {
|
||||
cflags_objc = invoker.cflags_objc
|
||||
}
|
||||
if (defined(invoker.cflags_objcc)) {
|
||||
cflags_objcc = invoker.cflags_objcc
|
||||
}
|
||||
if (defined(invoker.check_includes)) {
|
||||
check_includes = invoker.check_includes
|
||||
}
|
||||
if (defined(invoker.data)) {
|
||||
data = invoker.data
|
||||
}
|
||||
if (defined(invoker.data_deps)) {
|
||||
data_deps = invoker.data_deps
|
||||
}
|
||||
if (defined(invoker.datadeps)) {
|
||||
datadeps = invoker.datadeps
|
||||
}
|
||||
if (defined(invoker.defines)) {
|
||||
defines = invoker.defines
|
||||
}
|
||||
|
||||
# All shared libraries must have the sanitizer deps to properly link in
|
||||
# asan mode (this target will be empty in other cases).
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps + [ "//build/config/sanitizers:deps" ]
|
||||
} else {
|
||||
deps = [ "//build/config/sanitizers:deps" ]
|
||||
}
|
||||
if (defined(invoker.direct_dependent_configs)) {
|
||||
direct_dependent_configs = invoker.direct_dependent_configs
|
||||
}
|
||||
if (defined(invoker.forward_dependent_configs_from)) {
|
||||
forward_dependent_configs_from = invoker.forward_dependent_configs_from
|
||||
}
|
||||
if (defined(invoker.frameworks)) {
|
||||
frameworks = invoker.frameworks
|
||||
}
|
||||
if (defined(invoker.include_dirs)) {
|
||||
include_dirs = invoker.include_dirs
|
||||
}
|
||||
if (defined(invoker.ldflags)) {
|
||||
ldflags = invoker.ldflags
|
||||
}
|
||||
if (defined(invoker.lib_dirs)) {
|
||||
lib_dirs = invoker.lib_dirs
|
||||
}
|
||||
if (defined(invoker.libs)) {
|
||||
libs = invoker.libs
|
||||
}
|
||||
if (defined(invoker.output_extension)) {
|
||||
output_extension = invoker.output_extension
|
||||
}
|
||||
if (defined(invoker.output_name)) {
|
||||
output_name = invoker.output_name
|
||||
}
|
||||
if (defined(invoker.public)) {
|
||||
public = invoker.public
|
||||
}
|
||||
if (defined(invoker.public_configs)) {
|
||||
public_configs = invoker.public_configs
|
||||
}
|
||||
if (defined(invoker.public_deps)) {
|
||||
public_deps = invoker.public_deps
|
||||
}
|
||||
if (defined(invoker.sources)) {
|
||||
sources = invoker.sources
|
||||
}
|
||||
if (defined(invoker.testonly)) {
|
||||
testonly = invoker.testonly
|
||||
}
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
}
|
||||
}
|
||||
} else {
|
||||
source_set(target_name) {
|
||||
# See above.
|
||||
configs = [] # Prevent list overwriting warning.
|
||||
configs = invoker.configs
|
||||
|
||||
if (defined(invoker.all_dependent_configs)) {
|
||||
all_dependent_configs = invoker.all_dependent_configs
|
||||
}
|
||||
if (defined(invoker.allow_circular_includes_from)) {
|
||||
allow_circular_includes_from = invoker.allow_circular_includes_from
|
||||
}
|
||||
if (defined(invoker.cflags)) {
|
||||
cflags = invoker.cflags
|
||||
}
|
||||
if (defined(invoker.cflags_c)) {
|
||||
cflags_c = invoker.cflags_c
|
||||
}
|
||||
if (defined(invoker.cflags_cc)) {
|
||||
cflags_cc = invoker.cflags_cc
|
||||
}
|
||||
if (defined(invoker.cflags_objc)) {
|
||||
cflags_objc = invoker.cflags_objc
|
||||
}
|
||||
if (defined(invoker.cflags_objcc)) {
|
||||
cflags_objcc = invoker.cflags_objcc
|
||||
}
|
||||
if (defined(invoker.check_includes)) {
|
||||
check_includes = invoker.check_includes
|
||||
}
|
||||
if (defined(invoker.data)) {
|
||||
data = invoker.data
|
||||
}
|
||||
if (defined(invoker.data_deps)) {
|
||||
data_deps = invoker.data_deps
|
||||
}
|
||||
if (defined(invoker.datadeps)) {
|
||||
datadeps = invoker.datadeps
|
||||
}
|
||||
if (defined(invoker.defines)) {
|
||||
defines = invoker.defines
|
||||
}
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps
|
||||
}
|
||||
if (defined(invoker.direct_dependent_configs)) {
|
||||
direct_dependent_configs = invoker.direct_dependent_configs
|
||||
}
|
||||
if (defined(invoker.forward_dependent_configs_from)) {
|
||||
forward_dependent_configs_from = invoker.forward_dependent_configs_from
|
||||
}
|
||||
if (defined(invoker.frameworks)) {
|
||||
frameworks = invoker.frameworks
|
||||
}
|
||||
if (defined(invoker.include_dirs)) {
|
||||
include_dirs = invoker.include_dirs
|
||||
}
|
||||
if (defined(invoker.ldflags)) {
|
||||
ldflags = invoker.ldflags
|
||||
}
|
||||
if (defined(invoker.lib_dirs)) {
|
||||
lib_dirs = invoker.lib_dirs
|
||||
}
|
||||
if (defined(invoker.libs)) {
|
||||
libs = invoker.libs
|
||||
}
|
||||
if (defined(invoker.output_extension)) {
|
||||
output_extension = invoker.output_extension
|
||||
}
|
||||
if (defined(invoker.output_name)) {
|
||||
output_name = invoker.output_name
|
||||
}
|
||||
if (defined(invoker.public)) {
|
||||
public = invoker.public
|
||||
}
|
||||
if (defined(invoker.public_configs)) {
|
||||
public_configs = invoker.public_configs
|
||||
}
|
||||
if (defined(invoker.public_deps)) {
|
||||
public_deps = invoker.public_deps
|
||||
}
|
||||
if (defined(invoker.sources)) {
|
||||
sources = invoker.sources
|
||||
}
|
||||
if (defined(invoker.testonly)) {
|
||||
testonly = invoker.testonly
|
||||
}
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
8
engine/src/build/config/allocator.gni
Normal file
8
engine/src/build/config/allocator.gni
Normal file
@@ -0,0 +1,8 @@
|
||||
# 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.
|
||||
|
||||
declare_args() {
|
||||
# Memory allocator to use. Set to "none" to use default allocator.
|
||||
use_allocator = "none"
|
||||
}
|
||||
24
engine/src/build/config/android/BUILD.gn
Normal file
24
engine/src/build/config/android/BUILD.gn
Normal file
@@ -0,0 +1,24 @@
|
||||
# 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.
|
||||
|
||||
import("//build/config/android/config.gni")
|
||||
import("//build/config/sysroot.gni")
|
||||
|
||||
config("sdk") {
|
||||
if (sysroot != "") {
|
||||
cflags = [ "--sysroot=" + sysroot ]
|
||||
ldflags = [ "-L" + rebase_path("$android_lib", root_build_dir) ]
|
||||
}
|
||||
}
|
||||
|
||||
config("executable_config") {
|
||||
cflags = [ "-fPIE" ]
|
||||
ldflags = [ "-pie" ]
|
||||
}
|
||||
|
||||
config("hide_all_but_jni_onload") {
|
||||
ldflags = [ "-Wl,--version-script=" + rebase_path(
|
||||
"//build/android/android_only_explicit_jni_exports.lst",
|
||||
root_build_dir) ]
|
||||
}
|
||||
111
engine/src/build/config/android/config.gni
Normal file
111
engine/src/build/config/android/config.gni
Normal file
@@ -0,0 +1,111 @@
|
||||
# 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.
|
||||
|
||||
# This file contains common system config stuff for the Android build.
|
||||
|
||||
if (is_android) {
|
||||
if (!defined(default_android_sdk_root)) {
|
||||
default_android_sdk_root = "//flutter/third_party/android_tools/sdk"
|
||||
default_android_sdk_version = "35"
|
||||
default_android_sdk_build_tools_version = "35.0.0-rc4"
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
android_sdk_root = default_android_sdk_root
|
||||
android_sdk_version = default_android_sdk_version
|
||||
android_sdk_build_tools_version = default_android_sdk_build_tools_version
|
||||
|
||||
# Unused. Required for GN files maintained in other buildroots.
|
||||
enable_java_templates = false
|
||||
|
||||
android_api_level = 22
|
||||
}
|
||||
|
||||
# Host stuff -----------------------------------------------------------------
|
||||
|
||||
# Defines the name the Android build gives to the current host CPU
|
||||
# architecture, which is different than the names GN uses.
|
||||
if (host_cpu == "x64" || host_cpu == "x86" || host_cpu == "arm64") {
|
||||
android_host_arch = "x86_64"
|
||||
} else {
|
||||
assert(false, "Need Android toolchain support for your build CPU arch.")
|
||||
}
|
||||
|
||||
# Defines the name the Android build gives to the current host CPU
|
||||
# architecture, which is different than the names GN uses.
|
||||
if (host_os == "linux") {
|
||||
android_host_os = "linux"
|
||||
} else if (host_os == "mac") {
|
||||
android_host_os = "darwin"
|
||||
} else if (host_os == "win") {
|
||||
android_host_os = "win"
|
||||
} else {
|
||||
assert(false, "Need Android toolchain support for your build OS.")
|
||||
}
|
||||
|
||||
# Directories and files ------------------------------------------------------
|
||||
#
|
||||
# We define may of the dirs strings here for each output architecture (rather
|
||||
# than just the current one) since these are needed by the Android toolchain
|
||||
# file to define toolchains for all possible targets in one pass.
|
||||
|
||||
android_sdk = "${android_sdk_root}/platforms/android-${android_sdk_version}"
|
||||
|
||||
# Path to the Android NDK and SDK.
|
||||
android_ndk_root = "//flutter/third_party/android_tools/ndk"
|
||||
android_ndk_include_dir = "$android_ndk_root/usr/include"
|
||||
|
||||
android_sdk = "${android_sdk_root}/platforms/android-${android_sdk_version}"
|
||||
|
||||
android_sdk_tools = "${android_sdk_root}/tools"
|
||||
android_sdk_build_tools =
|
||||
"${android_sdk_root}/build-tools/$android_sdk_build_tools_version"
|
||||
|
||||
# Path to the SDK's android.jar
|
||||
android_sdk_jar = "$android_sdk/android.jar"
|
||||
|
||||
zipalign_path = "$android_sdk_build_tools/zipalign"
|
||||
|
||||
if (current_cpu != "x64" && current_cpu != "arm64") {
|
||||
android_api_level = 21
|
||||
}
|
||||
|
||||
# Toolchain root directory for each build. The actual binaries are inside
|
||||
# a "bin" directory inside of these.
|
||||
llvm_android_toolchain_root = "$android_ndk_root/toolchains/llvm/prebuilt/${android_host_os}-${android_host_arch}"
|
||||
android_toolchain_root = "$android_ndk_root/toolchains/llvm/prebuilt/${android_host_os}-${android_host_arch}"
|
||||
|
||||
# Toolchain stuff ------------------------------------------------------------
|
||||
_android_lib_prefix = "$android_toolchain_root/sysroot/usr/lib"
|
||||
|
||||
if (component_mode == "shared_library") {
|
||||
# By appending .cr, we prevent name collisions with libraries already
|
||||
# loaded by the Android zygote.
|
||||
android_product_extension = ".cr.so"
|
||||
} else {
|
||||
android_product_extension = ".so"
|
||||
}
|
||||
|
||||
# ABI ------------------------------------------------------------------------
|
||||
|
||||
if (current_cpu == "x86") {
|
||||
android_app_abi = "x86"
|
||||
_android_lib_dir = "i686-linux-android"
|
||||
} else if (current_cpu == "arm") {
|
||||
android_app_abi = "armeabi-v7a"
|
||||
_android_lib_dir = "arm-linux-androideabi"
|
||||
} else if (current_cpu == "x64") {
|
||||
android_app_abi = "x86_64"
|
||||
_android_lib_dir = "x86_64-linux-android"
|
||||
} else if (current_cpu == "arm64") {
|
||||
android_app_abi = "arm64-v8a"
|
||||
_android_lib_dir = "aarch64-linux-android"
|
||||
} else {
|
||||
assert(false, "Unknown Android ABI: " + current_cpu)
|
||||
}
|
||||
|
||||
android_lib = "$_android_lib_prefix/$_android_lib_dir/$android_api_level"
|
||||
|
||||
android_log_tag = "\"flutter\""
|
||||
}
|
||||
7
engine/src/build/config/android/rules.gni
Normal file
7
engine/src/build/config/android/rules.gni
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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.
|
||||
|
||||
# TODO(dnfield): Patch icu to not depend on this file
|
||||
import("//build/config/android/config.gni")
|
||||
assert(is_android)
|
||||
68
engine/src/build/config/arm.gni
Normal file
68
engine/src/build/config/arm.gni
Normal file
@@ -0,0 +1,68 @@
|
||||
# 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.
|
||||
|
||||
if (current_cpu == "arm" || current_cpu == "arm64") {
|
||||
declare_args() {
|
||||
# Version of the ARM processor when compiling on ARM. Ignored on non-ARM
|
||||
# platforms.
|
||||
if (current_cpu == "arm") {
|
||||
arm_version = 7
|
||||
} else if (current_cpu == "arm64") {
|
||||
arm_version = 8
|
||||
} else {
|
||||
assert(false, "Unconfigured arm version")
|
||||
}
|
||||
|
||||
# The ARM floating point mode. This is either the string "hard", "soft", or
|
||||
# "softfp". An empty string means to use the default one for the
|
||||
# arm_version.
|
||||
arm_float_abi = ""
|
||||
|
||||
# The ARM variant-specific tuning mode. This will be a string like "armv6"
|
||||
# or "cortex-a15". An empty string means to use the default for the
|
||||
# arm_version.
|
||||
arm_tune = ""
|
||||
|
||||
# Whether to use the neon FPU instruction set or not.
|
||||
arm_use_neon = true
|
||||
|
||||
# Whether to enable optional NEON code paths.
|
||||
arm_optionally_use_neon = false
|
||||
}
|
||||
|
||||
assert(arm_float_abi == "" || arm_float_abi == "hard" ||
|
||||
arm_float_abi == "soft" || arm_float_abi == "softfp")
|
||||
|
||||
if (arm_version == 6) {
|
||||
arm_arch = "armv6"
|
||||
if (arm_tune != "") {
|
||||
arm_tune = ""
|
||||
}
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "softfp"
|
||||
}
|
||||
arm_fpu = "vfp"
|
||||
|
||||
# Thumb is a reduced instruction set available on some ARM processors that
|
||||
# has increased code density.
|
||||
arm_use_thumb = false
|
||||
} else if (arm_version == 7) {
|
||||
arm_arch = "armv7-a"
|
||||
if (arm_tune == "") {
|
||||
arm_tune = "generic-armv7-a"
|
||||
}
|
||||
|
||||
if (arm_float_abi == "") {
|
||||
arm_float_abi = "softfp"
|
||||
}
|
||||
|
||||
arm_use_thumb = true
|
||||
|
||||
if (arm_use_neon) {
|
||||
arm_fpu = "neon"
|
||||
} else {
|
||||
arm_fpu = "vfpv3-d16"
|
||||
}
|
||||
}
|
||||
}
|
||||
9
engine/src/build/config/c++/c++.gni
Normal file
9
engine/src/build/config/c++/c++.gni
Normal file
@@ -0,0 +1,9 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
declare_args() {
|
||||
# Use libc++ (buildtools/third_party/libc++ and
|
||||
# buildtools/third_party/libc++abi) instead of stdlibc++ as standard library.
|
||||
use_custom_libcxx = false
|
||||
}
|
||||
36
engine/src/build/config/clang/BUILD.gn
Normal file
36
engine/src/build/config/clang/BUILD.gn
Normal file
@@ -0,0 +1,36 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/toolchain/clang.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
import("clang.gni")
|
||||
|
||||
# Empty entry to satisfy ANGLE build, which tries to remove this config.
|
||||
config("find_bad_constructs") {
|
||||
}
|
||||
|
||||
# Enables some extra Clang-specific warnings. Some third-party code won't
|
||||
# compile with these so may want to remove this config.
|
||||
config("extra_warnings") {
|
||||
cflags = [
|
||||
# Warns when a const char[] is converted to bool.
|
||||
"-Wstring-conversion",
|
||||
|
||||
# Warns when a source file doesn't have a newline at end-of-file.
|
||||
# This is to match Fuchsia, which enables this warning.
|
||||
"-Wnewline-eof",
|
||||
]
|
||||
|
||||
defines = [ "_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS" ]
|
||||
}
|
||||
|
||||
group("llvm-symbolizer_data") {
|
||||
if (is_win) {
|
||||
data = [ "$buildtools_path/windows-x64/bin/llvm-symbolizer.exe" ]
|
||||
} else if (is_mac) {
|
||||
data = [ "$buildtools_path/mac-${host_cpu}/clang/bin/llvm-symbolizer" ]
|
||||
} else if (is_linux) {
|
||||
data = [ "$buildtools_path/linux-${host_cpu}/clang/bin/llvm-symbolizer" ]
|
||||
}
|
||||
}
|
||||
6
engine/src/build/config/clang/clang.gni
Normal file
6
engine/src/build/config/clang/clang.gni
Normal file
@@ -0,0 +1,6 @@
|
||||
# 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.
|
||||
|
||||
declare_args() {
|
||||
}
|
||||
1031
engine/src/build/config/compiler/BUILD.gn
Normal file
1031
engine/src/build/config/compiler/BUILD.gn
Normal file
File diff suppressed because it is too large
Load Diff
16
engine/src/build/config/compiler/compiler.gni
Normal file
16
engine/src/build/config/compiler/compiler.gni
Normal file
@@ -0,0 +1,16 @@
|
||||
# Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
# This is a subset of Chromium's build/config/compiler/compiler.gni
|
||||
# required for compatibility with Chromium packages such as zlib.
|
||||
|
||||
declare_args() {
|
||||
build_with_chromium = false
|
||||
use_libfuzzer = false
|
||||
is_apple = is_ios || is_mac
|
||||
use_thin_lto = false
|
||||
|
||||
# zlib uses this identifier
|
||||
use_fuzzing_engine = false
|
||||
}
|
||||
29
engine/src/build/config/crypto.gni
Normal file
29
engine/src/build/config/crypto.gni
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# This file declares build flags for the SSL library configuration.
|
||||
#
|
||||
# TODO(brettw) this should probably be moved to src/crypto or somewhere, and
|
||||
# the global build dependency on it should be removed.
|
||||
#
|
||||
# PLEASE TRY TO AVOID ADDING FLAGS TO THIS FILE in cases where grit isn't
|
||||
# required. See the declare_args block of BUILDCONFIG.gn for advice on how
|
||||
# to set up feature flags.
|
||||
|
||||
declare_args() {
|
||||
# Use OpenSSL instead of NSS. This is used for all platforms but iOS. (See
|
||||
# http://crbug.com/338886).
|
||||
use_openssl = !is_ios
|
||||
}
|
||||
|
||||
# True when we're using OpenSSL for representing certificates. When targeting
|
||||
# Android, the platform certificate library is used for certificate
|
||||
# verification. On other targets, this flag also enables OpenSSL for certificate
|
||||
# verification, but this configuration is unsupported.
|
||||
use_openssl_certs = is_android
|
||||
|
||||
# True if NSS is used for certificate verification. Note that this is
|
||||
# independent from use_openssl. It is possible to use OpenSSL for the crypto
|
||||
# library, but NSS for the platform certificate library.
|
||||
use_nss_certs = false
|
||||
11
engine/src/build/config/dcheck_always_on.gni
Normal file
11
engine/src/build/config/dcheck_always_on.gni
Normal file
@@ -0,0 +1,11 @@
|
||||
# Copyright (c) 2016 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.
|
||||
|
||||
# Needed for ANGLE build.
|
||||
dcheck_is_configurable = false
|
||||
|
||||
declare_args() {
|
||||
# Set to true to enable dcheck in Release builds.
|
||||
dcheck_always_on = false
|
||||
}
|
||||
23
engine/src/build/config/features.gni
Normal file
23
engine/src/build/config/features.gni
Normal file
@@ -0,0 +1,23 @@
|
||||
# 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.
|
||||
|
||||
# This file contains Chrome-feature-related build flags (see ui.gni for
|
||||
# UI-related ones). These should theoretically be moved to the build files of
|
||||
# the features themselves.
|
||||
#
|
||||
# However, today we have many "bad" dependencies on some of these flags from,
|
||||
# e.g. base, so they need to be global to match the GYP configuration. Also,
|
||||
# anything that needs a grit define must be in either this file or ui.gni.
|
||||
#
|
||||
# PLEASE TRY TO AVOID ADDING FLAGS TO THIS FILE in cases where grit isn't
|
||||
# required. See the declare_args block of BUILDCONFIG.gn for advice on how
|
||||
# to set up feature flags.
|
||||
|
||||
if (is_android) {
|
||||
import("//build/config/android/config.gni")
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
use_blink = false
|
||||
}
|
||||
95
engine/src/build/config/gcc/BUILD.gn
Normal file
95
engine/src/build/config/gcc/BUILD.gn
Normal file
@@ -0,0 +1,95 @@
|
||||
# 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.
|
||||
|
||||
import("//build/config/profiler.gni")
|
||||
import("//build/toolchain/rbe.gni")
|
||||
|
||||
# This config causes functions not to be automatically exported from shared
|
||||
# libraries. By default, all symbols are exported but this means there are
|
||||
# lots of exports that slow everything down. In general we explicitly mark
|
||||
# which functiosn we want to export from components.
|
||||
#
|
||||
# Some third_party code assumes all functions are exported so this is separated
|
||||
# into its own config so such libraries can remove this config to make symbols
|
||||
# public again.
|
||||
#
|
||||
# See http://gcc.gnu.org/wiki/Visibility
|
||||
config("symbol_visibility_hidden") {
|
||||
# Note that -fvisibility-inlines-hidden is set globally in the compiler
|
||||
# config since that can almost always be applied.
|
||||
if (!enable_profiling && !disable_hidden_visibility) {
|
||||
defines = [ "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS" ]
|
||||
cflags = [ "-fvisibility=hidden" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Settings for executables and shared libraries.
|
||||
config("executable_ldconfig") {
|
||||
if (is_android) {
|
||||
ldflags = [
|
||||
"-Bdynamic",
|
||||
"-Wl,-z,nocopyreloc",
|
||||
]
|
||||
} else {
|
||||
# Android doesn't support rpath.
|
||||
ldflags = [
|
||||
# Want to pass "\$". GN will re-escape as required for ninja.
|
||||
"-Wl,-rpath=\$ORIGIN/",
|
||||
"-Wl,-rpath-link=",
|
||||
|
||||
# Newer binutils don't set DT_RPATH unless you disable "new" dtags
|
||||
# and the new DT_RUNPATH doesn't work without --no-as-needed flag.
|
||||
"-Wl,--disable-new-dtags",
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
config("no_exceptions") {
|
||||
no_exceptions_flags = [ "-fno-exceptions" ]
|
||||
cflags_cc = no_exceptions_flags
|
||||
cflags_objcc = no_exceptions_flags
|
||||
}
|
||||
|
||||
config("relative_paths") {
|
||||
# Make builds independent of absolute file path. The file names
|
||||
# embedded in debugging information will be expressed as relative to
|
||||
# the build directory, e.g. "../.." for an "out/subdir" under //.
|
||||
# This is consistent with the file names in __FILE__ expansions
|
||||
# (e.g. in assertion messages), which the compiler doesn't provide a
|
||||
# way to remap. That way source file names in logging and
|
||||
# symbolization can all be treated the same way. This won't go well
|
||||
# if root_build_dir is not a subdirectory //, but there isn't a better
|
||||
# option to keep all source file name references uniformly relative to
|
||||
# a single root.
|
||||
cflags = []
|
||||
cflags_objcc = []
|
||||
absolute_path = rebase_path("//")
|
||||
relative_path = ""
|
||||
if (use_rbe) {
|
||||
# objc builds are always local even when rbe is enabled.
|
||||
cflags_objcc += [
|
||||
# This makes sure that the DW_AT_comp_dir string (the current
|
||||
# directory while running the compiler, which is the basis for all
|
||||
# relative source file names in the DWARF info) is represented as
|
||||
# relative to //.
|
||||
"-fdebug-prefix-map=$absolute_path=$relative_path",
|
||||
]
|
||||
} else {
|
||||
cflags += [
|
||||
"-fdebug-prefix-map=$absolute_path=$relative_path",
|
||||
]
|
||||
}
|
||||
cflags += [
|
||||
# This makes sure that include directories in the toolchain are
|
||||
# represented as relative to the build directory (because that's how
|
||||
# we invoke the compiler), rather than absolute. This can affect
|
||||
# __FILE__ expansions (e.g. assertions in system headers). We
|
||||
# normally run a compiler that's someplace within the source tree
|
||||
# (//buildtools/...), so its absolute installation path will have a
|
||||
# prefix matching absolute_path and hence be mapped to relative_path
|
||||
# in the debugging information, so this should actually be
|
||||
# superfluous for purposes of the debugging information.
|
||||
"-no-canonical-prefixes",
|
||||
]
|
||||
}
|
||||
25
engine/src/build/config/gcc/gcc_version.gni
Normal file
25
engine/src/build/config/gcc/gcc_version.gni
Normal file
@@ -0,0 +1,25 @@
|
||||
# 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.
|
||||
|
||||
if (is_android) {
|
||||
gcc_version = 49
|
||||
} else if (current_toolchain == "//build/toolchain/cros:target") {
|
||||
gcc_version = exec_script("../../compiler_version.py",
|
||||
[
|
||||
"target",
|
||||
"compiler",
|
||||
],
|
||||
"value")
|
||||
} else if (current_toolchain == "//build/toolchain/linux:x64" ||
|
||||
current_toolchain == "//build/toolchain/linux:x86") {
|
||||
# These are both the same and just use the default gcc on the system.
|
||||
gcc_version = exec_script("../../compiler_version.py",
|
||||
[
|
||||
"host",
|
||||
"compiler",
|
||||
],
|
||||
"value")
|
||||
} else {
|
||||
gcc_version = 0
|
||||
}
|
||||
26
engine/src/build/config/host_byteorder.gni
Normal file
26
engine/src/build/config/host_byteorder.gni
Normal file
@@ -0,0 +1,26 @@
|
||||
# Copyright (c) 2017 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.
|
||||
|
||||
# This header file defines the "host_byteorder" variable.
|
||||
# Not that this is currently used only for building v8.
|
||||
# The chromium code generally assumes little-endianness.
|
||||
declare_args() {
|
||||
host_byteorder = "undefined"
|
||||
}
|
||||
|
||||
# Detect host byteorder
|
||||
# ppc64 can be either BE or LE
|
||||
if (host_cpu == "ppc64") {
|
||||
if (current_os == "aix") {
|
||||
host_byteorder = "big"
|
||||
} else {
|
||||
# Only use the script when absolutely necessary
|
||||
host_byteorder =
|
||||
exec_script("//build/config/get_host_byteorder.py", [], "trim string")
|
||||
}
|
||||
} else if (host_cpu == "ppc" || host_cpu == "s390" || host_cpu == "s390x") {
|
||||
host_byteorder = "big"
|
||||
} else {
|
||||
host_byteorder = "little"
|
||||
}
|
||||
7
engine/src/build/config/ios/BUILD.gn
Normal file
7
engine/src/build/config/ios/BUILD.gn
Normal file
@@ -0,0 +1,7 @@
|
||||
# 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.
|
||||
|
||||
config("sdk") {
|
||||
cflags_cc = [ "-stdlib=libc++" ]
|
||||
}
|
||||
68
engine/src/build/config/ios/ios_sdk.gni
Normal file
68
engine/src/build/config/ios/ios_sdk.gni
Normal file
@@ -0,0 +1,68 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
import("//build/toolchain/rbe.gni")
|
||||
|
||||
declare_args() {
|
||||
# SDK path to use. When empty this will use the default SDK based on the
|
||||
# value of use_ios_simulator.
|
||||
ios_sdk_path = ""
|
||||
|
||||
# Set to true when targeting a simulator build on iOS. False means that the
|
||||
# target is for running on the device. The default value is to use the
|
||||
# Simulator except when targeting GYP's Xcode builds (for compat with the
|
||||
# existing GYP build).
|
||||
use_ios_simulator = true
|
||||
|
||||
# Alias for use_ios_simulator used by Skia.
|
||||
ios_use_simulator = true
|
||||
|
||||
# Version of iOS that we're targeting.
|
||||
ios_deployment_target = "12.0"
|
||||
|
||||
# The path to the iOS device SDK.
|
||||
ios_device_sdk_path = ""
|
||||
|
||||
# The path to the iOS simulator SDK.
|
||||
ios_simulator_sdk_path = ""
|
||||
|
||||
# Version of iOS that we're targeting for tests.
|
||||
ios_testing_deployment_target = "13.0"
|
||||
}
|
||||
|
||||
if (ios_sdk_path == "") {
|
||||
ios_sdk_args = []
|
||||
if (use_rbe && create_xcode_symlinks) {
|
||||
ios_sdk_args += [
|
||||
"--symlink",
|
||||
rebase_path("//flutter/prebuilts"),
|
||||
]
|
||||
}
|
||||
if (!use_ios_simulator && ios_device_sdk_path == "") {
|
||||
ios_sdk_args += [
|
||||
"--sdk",
|
||||
"iphoneos",
|
||||
]
|
||||
_ios_device_sdk_result =
|
||||
exec_script("ios_sdk.py", ios_sdk_args, "list lines")
|
||||
ios_device_sdk_path = _ios_device_sdk_result[0]
|
||||
}
|
||||
|
||||
if (use_ios_simulator && ios_simulator_sdk_path == "") {
|
||||
ios_sdk_args += [
|
||||
"--sdk",
|
||||
"iphonesimulator",
|
||||
]
|
||||
_ios_sim_sdk_result = exec_script("ios_sdk.py", ios_sdk_args, "list lines")
|
||||
ios_simulator_sdk_path = _ios_sim_sdk_result[0]
|
||||
}
|
||||
|
||||
if (use_ios_simulator) {
|
||||
assert(ios_simulator_sdk_path != "")
|
||||
ios_sdk_path = ios_simulator_sdk_path
|
||||
} else {
|
||||
assert(ios_device_sdk_path != "")
|
||||
ios_sdk_path = ios_device_sdk_path
|
||||
}
|
||||
}
|
||||
117
engine/src/build/config/ios/ios_sdk.py
Normal file
117
engine/src/build/config/ios/ios_sdk.py
Normal file
@@ -0,0 +1,117 @@
|
||||
# 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.
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
sys.path.insert(1, os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
|
||||
from pyutil.file_util import symlink
|
||||
|
||||
# This script creates symlinks under flutter/prebuilts to the iphone and
|
||||
# iphone simulator SDKs.
|
||||
|
||||
SDKs = ['iphoneos', 'iphonesimulator']
|
||||
|
||||
PREBUILTS = os.path.realpath(os.path.join(
|
||||
os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, 'flutter', 'prebuilts',
|
||||
))
|
||||
|
||||
|
||||
def run_command_with_retry(command, timeout=10, retries=3):
|
||||
"""
|
||||
Runs a command using subprocess.check_output with timeout and retry logic.
|
||||
|
||||
Args:
|
||||
command: A list representing the command and its arguments.
|
||||
timeout: The maximum time (in seconds) to wait for each command execution.
|
||||
retries: The number of times to retry the command if it times out.
|
||||
|
||||
Returns:
|
||||
The output of the command as a bytes object if successful, otherwise
|
||||
raises a CalledProcessError.
|
||||
"""
|
||||
for attempt in range(1, retries + 1):
|
||||
try:
|
||||
result = subprocess.check_output(command, timeout=timeout)
|
||||
return result.decode('utf-8').strip()
|
||||
except subprocess.TimeoutExpired:
|
||||
if attempt >= retries:
|
||||
raise # Re-raise the TimeoutExpired error after all retries
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument(
|
||||
'--as-gclient-hook',
|
||||
default=False,
|
||||
action='store_true',
|
||||
help='Whether the script is running as a gclient hook.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--symlink',
|
||||
type=str,
|
||||
help='Whether to create a symlink in the buildroot to the SDK.',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sdk',
|
||||
choices=['iphoneos', 'iphonesimulator'],
|
||||
help='Which SDK to find.',
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
# On CI, Xcode is not yet installed when gclient hooks are being run.
|
||||
# This is because the version of Xcode that CI installs might depend on the
|
||||
# contents of the repo, so the repo must be set up first, which includes
|
||||
# running the gclient hooks. Instead, on CI, this script will be run during
|
||||
# GN.
|
||||
running_on_luci = os.environ.get('LUCI_CONTEXT') is not None
|
||||
if running_on_luci and args.as_gclient_hook:
|
||||
return 0
|
||||
|
||||
symlink_path = args.symlink
|
||||
if not running_on_luci and symlink_path is None:
|
||||
symlink_path = PREBUILTS
|
||||
|
||||
sdks = [args.sdk] if args.sdk is not None else SDKs
|
||||
|
||||
sdks_path = None
|
||||
libraries_path = None
|
||||
if symlink_path:
|
||||
sdks_path = os.path.join(symlink_path, 'SDKs')
|
||||
libraries_path = os.path.join(symlink_path, 'Library')
|
||||
# Remove any old files created by this script under PREBUILTS/SDKs.
|
||||
if args.as_gclient_hook:
|
||||
if os.path.isdir(sdks_path):
|
||||
shutil.rmtree(sdks_path)
|
||||
if os.path.isdir(libraries_path):
|
||||
shutil.rmtree(libraries_path)
|
||||
|
||||
for sdk in sdks:
|
||||
command = [
|
||||
'xcrun',
|
||||
'--sdk',
|
||||
sdk,
|
||||
'--show-sdk-path',
|
||||
]
|
||||
sdk_output = run_command_with_retry(command, timeout=300)
|
||||
if symlink_path:
|
||||
symlink_target = os.path.join(sdks_path, os.path.basename(sdk_output))
|
||||
symlink(sdk_output, symlink_target)
|
||||
frameworks_location = os.path.join(sdk_output, '..', '..', 'Library', 'Frameworks')
|
||||
frameworks_symlink = os.path.join(libraries_path, 'Frameworks')
|
||||
symlink(frameworks_location, frameworks_symlink)
|
||||
sdk_output = symlink_target
|
||||
if not args.as_gclient_hook:
|
||||
print(sdk_output)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.platform != 'darwin':
|
||||
raise Exception('This script only runs on Mac')
|
||||
sys.exit(main(sys.argv))
|
||||
62
engine/src/build/config/linux/BUILD.gn
Normal file
62
engine/src/build/config/linux/BUILD.gn
Normal file
@@ -0,0 +1,62 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/config/features.gni")
|
||||
import("//build/config/linux/pkg_config.gni")
|
||||
import("//build/config/sysroot.gni")
|
||||
import("//build/config/ui.gni")
|
||||
|
||||
config("sdk") {
|
||||
if (sysroot != "") {
|
||||
cflags = [ "--sysroot=" + sysroot ]
|
||||
ldflags = [ "--sysroot=" + sysroot ]
|
||||
|
||||
# Need to get some linker flags out of the sysroot.
|
||||
ldflags += [ exec_script("sysroot_ld_path.py",
|
||||
[
|
||||
rebase_path("//build/linux/sysroot_ld_path.sh",
|
||||
root_build_dir),
|
||||
sysroot,
|
||||
],
|
||||
"value") ]
|
||||
}
|
||||
}
|
||||
|
||||
config("fontconfig") {
|
||||
libs = [ "fontconfig" ]
|
||||
}
|
||||
|
||||
pkg_config("freetype2") {
|
||||
packages = [ "freetype2" ]
|
||||
}
|
||||
|
||||
config("x11") {
|
||||
libs = [
|
||||
"X11",
|
||||
"Xcomposite",
|
||||
"Xcursor",
|
||||
"Xdamage",
|
||||
"Xext",
|
||||
"Xfixes",
|
||||
"Xi",
|
||||
"Xrender",
|
||||
"Xtst",
|
||||
]
|
||||
}
|
||||
|
||||
config("xrandr") {
|
||||
libs = [ "Xrandr" ]
|
||||
}
|
||||
|
||||
config("xinerama") {
|
||||
libs = [ "Xinerama" ]
|
||||
}
|
||||
|
||||
config("xcomposite") {
|
||||
libs = [ "Xcomposite" ]
|
||||
}
|
||||
|
||||
config("xext") {
|
||||
libs = [ "Xext" ]
|
||||
}
|
||||
249
engine/src/build/config/linux/pkg-config.py
Normal file
249
engine/src/build/config/linux/pkg-config.py
Normal file
@@ -0,0 +1,249 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import re
|
||||
from optparse import OptionParser
|
||||
|
||||
# This script runs pkg-config, optionally filtering out some results, and
|
||||
# returns the result.
|
||||
#
|
||||
# The result will be [ <includes>, <cflags>, <libs>, <lib_dirs>, <ldflags> ]
|
||||
# where each member is itself a list of strings.
|
||||
#
|
||||
# You can filter out matches using "-v <regexp>" where all results from
|
||||
# pkgconfig matching the given regular expression will be ignored. You can
|
||||
# specify more than one regular expression my specifying "-v" more than once.
|
||||
#
|
||||
# You can specify a sysroot using "-s <sysroot>" where sysroot is the absolute
|
||||
# system path to the sysroot used for compiling. This script will attempt to
|
||||
# generate correct paths for the sysroot.
|
||||
#
|
||||
# When using a sysroot, you must also specify the architecture via
|
||||
# "-a <arch>" where arch is either "x86" or "x64".
|
||||
#
|
||||
# CrOS systemroots place pkgconfig files at <systemroot>/usr/share/pkgconfig
|
||||
# and one of <systemroot>/usr/lib/pkgconfig or <systemroot>/usr/lib64/pkgconfig
|
||||
# depending on whether the systemroot is for a 32 or 64 bit architecture. They
|
||||
# specify the 'lib' or 'lib64' of the pkgconfig path by defining the
|
||||
# 'system_libdir' variable in the args.gn file. pkg_config.gni communicates this
|
||||
# variable to this script with the "--system_libdir <system_libdir>" flag. If no
|
||||
# flag is provided, then pkgconfig files are assumed to come from
|
||||
# <systemroot>/usr/lib/pkgconfig.
|
||||
#
|
||||
# Additionally, you can specify the option --atleast-version. This will skip
|
||||
# the normal outputting of a dictionary and instead print true or false,
|
||||
# depending on the return value of pkg-config for the given package.
|
||||
|
||||
|
||||
def SetConfigPath(options):
|
||||
"""Set the PKG_CONFIG_LIBDIR environment variable.
|
||||
|
||||
This takes into account any sysroot and architecture specification from the
|
||||
options on the given command line.
|
||||
"""
|
||||
|
||||
sysroot = options.sysroot
|
||||
assert sysroot
|
||||
|
||||
# Compute the library path name based on the architecture.
|
||||
arch = options.arch
|
||||
if sysroot and not arch:
|
||||
print("You must specify an architecture via -a if using a sysroot.")
|
||||
sys.exit(1)
|
||||
|
||||
libdir = sysroot + '/usr/' + options.system_libdir + '/pkgconfig'
|
||||
libdir += ':' + sysroot + '/usr/share/pkgconfig'
|
||||
os.environ['PKG_CONFIG_LIBDIR'] = libdir
|
||||
return libdir
|
||||
|
||||
|
||||
def GetPkgConfigPrefixToStrip(options, args):
|
||||
"""Returns the prefix from pkg-config where packages are installed.
|
||||
|
||||
This returned prefix is the one that should be stripped from the beginning of
|
||||
directory names to take into account sysroots.
|
||||
"""
|
||||
# Some sysroots, like the Chromium OS ones, may generate paths that are not
|
||||
# relative to the sysroot. For example,
|
||||
# /path/to/chroot/build/x86-generic/usr/lib/pkgconfig/pkg.pc may have all
|
||||
# paths relative to /path/to/chroot (i.e. prefix=/build/x86-generic/usr)
|
||||
# instead of relative to /path/to/chroot/build/x86-generic (i.e prefix=/usr).
|
||||
# To support this correctly, it's necessary to extract the prefix to strip
|
||||
# from pkg-config's |prefix| variable.
|
||||
prefix = subprocess.check_output([options.pkg_config,
|
||||
"--variable=prefix"] + args, env=os.environ).decode('utf-8')
|
||||
if prefix[-4] == '/usr':
|
||||
return prefix[4:]
|
||||
return prefix
|
||||
|
||||
|
||||
def MatchesAnyRegexp(flag, list_of_regexps):
|
||||
"""Returns true if the first argument matches any regular expression in the
|
||||
given list."""
|
||||
for regexp in list_of_regexps:
|
||||
if regexp.search(flag) != None:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def RewritePath(path, strip_prefix, sysroot):
|
||||
"""Rewrites a path by stripping the prefix and prepending the sysroot."""
|
||||
if os.path.isabs(path) and not path.startswith(sysroot):
|
||||
if path.startswith(strip_prefix):
|
||||
path = path[len(strip_prefix):]
|
||||
path = path.lstrip('/')
|
||||
return os.path.join(sysroot, path)
|
||||
else:
|
||||
return path
|
||||
|
||||
|
||||
def main():
|
||||
# If this is run on non-Linux platforms, just return nothing and indicate
|
||||
# success. This allows us to "kind of emulate" a Linux build from other
|
||||
# platforms.
|
||||
if "linux" not in sys.platform:
|
||||
print("[[],[],[],[],[]]")
|
||||
return 0
|
||||
|
||||
parser = OptionParser()
|
||||
parser.add_option('-d', '--debug', action='store_true')
|
||||
parser.add_option('-p', action='store', dest='pkg_config', type='string',
|
||||
default='pkg-config')
|
||||
parser.add_option('-v', action='append', dest='strip_out', type='string')
|
||||
parser.add_option('-s', action='store', dest='sysroot', type='string')
|
||||
parser.add_option('-a', action='store', dest='arch', type='string')
|
||||
parser.add_option('--system_libdir', action='store', dest='system_libdir',
|
||||
type='string', default='lib')
|
||||
parser.add_option('--atleast-version', action='store',
|
||||
dest='atleast_version', type='string')
|
||||
parser.add_option('--libdir', action='store_true', dest='libdir')
|
||||
parser.add_option('--dridriverdir', action='store_true', dest='dridriverdir')
|
||||
parser.add_option('--version-as-components', action='store_true',
|
||||
dest='version_as_components')
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
# Make a list of regular expressions to strip out.
|
||||
strip_out = []
|
||||
if options.strip_out != None:
|
||||
for regexp in options.strip_out:
|
||||
strip_out.append(re.compile(regexp))
|
||||
|
||||
if options.sysroot:
|
||||
libdir = SetConfigPath(options)
|
||||
if options.debug:
|
||||
sys.stderr.write('PKG_CONFIG_LIBDIR=%s\n' % libdir)
|
||||
prefix = GetPkgConfigPrefixToStrip(options, args)
|
||||
else:
|
||||
prefix = ''
|
||||
|
||||
if options.atleast_version:
|
||||
# When asking for the return value, just run pkg-config and print the return
|
||||
# value, no need to do other work.
|
||||
if not subprocess.call([options.pkg_config,
|
||||
"--atleast-version=" + options.atleast_version] +
|
||||
args):
|
||||
print("true")
|
||||
else:
|
||||
print("false")
|
||||
return 0
|
||||
|
||||
if options.version_as_components:
|
||||
cmd = [options.pkg_config, "--modversion"] + args
|
||||
try:
|
||||
version_string = subprocess.check_output(cmd).decode('utf-8')
|
||||
except:
|
||||
sys.stderr.write('Error from pkg-config.\n')
|
||||
return 1
|
||||
print(json.dumps(list(map(int, version_string.strip().split(".")))))
|
||||
return 0
|
||||
|
||||
|
||||
if options.libdir:
|
||||
cmd = [options.pkg_config, "--variable=libdir"] + args
|
||||
if options.debug:
|
||||
sys.stderr.write('Running: %s\n' % cmd)
|
||||
try:
|
||||
libdir = subprocess.check_output(cmd).decode('utf-8')
|
||||
except:
|
||||
print("Error from pkg-config.")
|
||||
return 1
|
||||
sys.stdout.write(libdir.strip())
|
||||
return 0
|
||||
|
||||
if options.dridriverdir:
|
||||
cmd = [options.pkg_config, "--variable=dridriverdir"] + args
|
||||
if options.debug:
|
||||
sys.stderr.write('Running: %s\n' % cmd)
|
||||
try:
|
||||
dridriverdir = subprocess.check_output(cmd).decode('utf-8')
|
||||
except:
|
||||
print("Error from pkg-config.")
|
||||
return 1
|
||||
sys.stdout.write(dridriverdir.strip())
|
||||
return
|
||||
|
||||
cmd = [options.pkg_config, "--cflags", "--libs"] + args
|
||||
if options.debug:
|
||||
sys.stderr.write('Running: %s\n' % ' '.join(cmd))
|
||||
|
||||
try:
|
||||
flag_string = subprocess.check_output(cmd).decode('utf-8')
|
||||
except:
|
||||
sys.stderr.write('Could not run pkg-config.\n')
|
||||
return 1
|
||||
|
||||
# For now just split on spaces to get the args out. This will break if
|
||||
# pkgconfig returns quoted things with spaces in them, but that doesn't seem
|
||||
# to happen in practice.
|
||||
all_flags = flag_string.strip().split(' ')
|
||||
|
||||
|
||||
sysroot = options.sysroot
|
||||
if not sysroot:
|
||||
sysroot = ''
|
||||
|
||||
includes = []
|
||||
cflags = []
|
||||
libs = []
|
||||
lib_dirs = []
|
||||
|
||||
for flag in all_flags[:]:
|
||||
if len(flag) == 0 or MatchesAnyRegexp(flag, strip_out):
|
||||
continue;
|
||||
|
||||
if flag[:2] == '-l':
|
||||
libs.append(RewritePath(flag[2:], prefix, sysroot))
|
||||
elif flag[:2] == '-L':
|
||||
lib_dirs.append(RewritePath(flag[2:], prefix, sysroot))
|
||||
elif flag[:2] == '-I':
|
||||
includes.append(RewritePath(flag[2:], prefix, sysroot))
|
||||
elif flag[:3] == '-Wl':
|
||||
# Don't allow libraries to control ld flags. These should be specified
|
||||
# only in build files.
|
||||
pass
|
||||
elif flag == '-pthread':
|
||||
# Many libs specify "-pthread" which we don't need since we always include
|
||||
# this anyway. Removing it here prevents a bunch of duplicate inclusions
|
||||
# on the command line.
|
||||
pass
|
||||
else:
|
||||
cflags.append(flag)
|
||||
|
||||
# Output a GN array, the first one is the cflags, the second are the libs. The
|
||||
# JSON formatter prints GN compatible lists when everything is a list of
|
||||
# strings.
|
||||
print(json.dumps([includes, cflags, libs, lib_dirs]))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
128
engine/src/build/config/linux/pkg_config.gni
Normal file
128
engine/src/build/config/linux/pkg_config.gni
Normal file
@@ -0,0 +1,128 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/config/sysroot.gni")
|
||||
|
||||
# Defines a config specifying the result of running pkg-config for the given
|
||||
# packages. Put the package names you want to query in the "packages" variable
|
||||
# inside the template invocation.
|
||||
#
|
||||
# You can also add defines via the "defines" variable. This can be useful to
|
||||
# add this to the config to pass defines that the library expects to get by
|
||||
# users of its headers.
|
||||
#
|
||||
# Example:
|
||||
# pkg_config("mything") {
|
||||
# packages = [ "mything1", "mything2" ]
|
||||
# defines = [ "ENABLE_AWESOME" ]
|
||||
# }
|
||||
#
|
||||
# You can also use "extra args" to filter out results (see pkg-config.py):
|
||||
# extra_args = [ "-v, "foo" ]
|
||||
# To ignore libs and ldflags (only cflags/defines will be set, which is useful
|
||||
# when doing manual dynamic linking), set:
|
||||
# ignore_libs = true
|
||||
|
||||
declare_args() {
|
||||
# A pkg-config wrapper to call instead of trying to find and call the right
|
||||
# pkg-config directly. Wrappers like this are common in cross-compilation
|
||||
# environments.
|
||||
# Leaving it blank defaults to searching PATH for 'pkg-config' and relying on
|
||||
# the sysroot mechanism to find the right .pc files.
|
||||
pkg_config = ""
|
||||
|
||||
# A optional pkg-config wrapper to use for tools built on the host.
|
||||
host_pkg_config = ""
|
||||
|
||||
# CrOS systemroots place pkgconfig files at <systemroot>/usr/share/pkgconfig
|
||||
# and one of <systemroot>/usr/lib/pkgconfig or <systemroot>/usr/lib64/pkgconfig
|
||||
# depending on whether the systemroot is for a 32 or 64 bit architecture.
|
||||
#
|
||||
# When build under GYP, CrOS board builds specify the 'system_libdir' variable
|
||||
# as part of the GYP_DEFINES provided by the CrOS emerge build or simple
|
||||
# chrome build scheme. This variable permits controlling this for GN builds
|
||||
# in similar fashion by setting the `system_libdir` variable in the build's
|
||||
# args.gn file to 'lib' or 'lib64' as appropriate for the target architecture.
|
||||
system_libdir = "lib"
|
||||
}
|
||||
|
||||
pkg_config_script = "//build/config/linux/pkg-config.py"
|
||||
|
||||
# Define the args we pass to the pkg-config script for other build files that
|
||||
# need to invoke it manually.
|
||||
pkg_config_args = []
|
||||
|
||||
if (sysroot != "") {
|
||||
# Pass the sysroot if we're using one (it requires the CPU arch also).
|
||||
pkg_config_args += [
|
||||
"-s",
|
||||
rebase_path(sysroot, "", root_build_dir),
|
||||
"-a",
|
||||
current_cpu,
|
||||
]
|
||||
}
|
||||
|
||||
if (pkg_config != "") {
|
||||
pkg_config_args += [
|
||||
"-p",
|
||||
pkg_config,
|
||||
]
|
||||
}
|
||||
|
||||
# Only use the custom libdir when building with the target sysroot.
|
||||
if (target_sysroot != "" && sysroot == target_sysroot) {
|
||||
pkg_config_args += [
|
||||
"--system_libdir",
|
||||
system_libdir,
|
||||
]
|
||||
}
|
||||
|
||||
if (host_pkg_config != "") {
|
||||
host_pkg_config_args = [
|
||||
"-p",
|
||||
host_pkg_config,
|
||||
]
|
||||
} else {
|
||||
host_pkg_config_args = pkg_config_args
|
||||
}
|
||||
|
||||
template("pkg_config") {
|
||||
assert(defined(invoker.packages),
|
||||
"Variable |packages| must be defined to be a list in pkg_config.")
|
||||
config(target_name) {
|
||||
if (host_toolchain == current_toolchain) {
|
||||
args = host_pkg_config_args + invoker.packages
|
||||
} else {
|
||||
args = pkg_config_args + invoker.packages
|
||||
}
|
||||
if (defined(invoker.extra_args)) {
|
||||
args += invoker.extra_args
|
||||
}
|
||||
|
||||
pkgresult = exec_script(pkg_config_script, args, "value")
|
||||
cflags = pkgresult[1]
|
||||
|
||||
foreach(include, pkgresult[0]) {
|
||||
if (sysroot != "") {
|
||||
# We want the system include paths to use -isystem instead of -I to
|
||||
# suppress warnings in those headers.
|
||||
include_relativized = rebase_path(include, root_build_dir)
|
||||
cflags += [ "-isystem$include_relativized" ]
|
||||
} else {
|
||||
cflags += [ "-I$include" ]
|
||||
}
|
||||
}
|
||||
|
||||
if (!defined(invoker.ignore_libs) || !invoker.ignore_libs) {
|
||||
libs = pkgresult[2]
|
||||
lib_dirs = pkgresult[3]
|
||||
}
|
||||
|
||||
forward_variables_from(invoker,
|
||||
[
|
||||
"defines",
|
||||
"visibility",
|
||||
])
|
||||
}
|
||||
}
|
||||
21
engine/src/build/config/linux/sysroot_ld_path.py
Normal file
21
engine/src/build/config/linux/sysroot_ld_path.py
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# This file takes two arguments, the relative location of the shell script that
|
||||
# does the checking, and the name of the sysroot.
|
||||
|
||||
# TODO(brettw) the build/linux/sysroot_ld_path.sh script should be rewritten in
|
||||
# Python in this file.
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 3:
|
||||
print("Need two arguments")
|
||||
sys.exit(1)
|
||||
|
||||
result = subprocess.check_output([sys.argv[1], sys.argv[2]],
|
||||
universal_newlines=True).strip()
|
||||
|
||||
print('"%s"' % result)
|
||||
118
engine/src/build/config/locales.gni
Normal file
118
engine/src/build/config/locales.gni
Normal file
@@ -0,0 +1,118 @@
|
||||
# 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.
|
||||
|
||||
# Note: keep in sync with below.
|
||||
locales = [
|
||||
"am",
|
||||
"ar",
|
||||
"bg",
|
||||
"bn",
|
||||
"ca",
|
||||
"cs",
|
||||
"da",
|
||||
"de",
|
||||
"el",
|
||||
"en-GB",
|
||||
"en-US",
|
||||
"es-419",
|
||||
"es",
|
||||
"et",
|
||||
"fa",
|
||||
"fi",
|
||||
"fil",
|
||||
"fr",
|
||||
"gu",
|
||||
"he",
|
||||
"hi",
|
||||
"hr",
|
||||
"hu",
|
||||
"id",
|
||||
"it",
|
||||
"ja",
|
||||
"kn",
|
||||
"ko",
|
||||
"lt",
|
||||
"lv",
|
||||
"ml",
|
||||
"mr",
|
||||
"ms",
|
||||
"nb",
|
||||
"nl",
|
||||
"pl",
|
||||
"pt-BR",
|
||||
"pt-PT",
|
||||
"ro",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sr",
|
||||
"sv",
|
||||
"sw",
|
||||
"ta",
|
||||
"te",
|
||||
"th",
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"zh-CN",
|
||||
"zh-TW",
|
||||
]
|
||||
|
||||
# Same as the locales list but in the format Mac expects for output files:
|
||||
# it uses underscores instead of hyphens, and "en" instead of "en-US".
|
||||
locales_as_mac_outputs = [
|
||||
"am",
|
||||
"ar",
|
||||
"bg",
|
||||
"bn",
|
||||
"ca",
|
||||
"cs",
|
||||
"da",
|
||||
"de",
|
||||
"el",
|
||||
"en_GB",
|
||||
"en",
|
||||
"es_419",
|
||||
"es",
|
||||
"et",
|
||||
"fa",
|
||||
"fi",
|
||||
"fil",
|
||||
"fr",
|
||||
"gu",
|
||||
"he",
|
||||
"hi",
|
||||
"hr",
|
||||
"hu",
|
||||
"id",
|
||||
"it",
|
||||
"ja",
|
||||
"kn",
|
||||
"ko",
|
||||
"lt",
|
||||
"lv",
|
||||
"ml",
|
||||
"mr",
|
||||
"ms",
|
||||
"nb",
|
||||
"nl",
|
||||
"pl",
|
||||
"pt_BR",
|
||||
"pt_PT",
|
||||
"ro",
|
||||
"ru",
|
||||
"sk",
|
||||
"sl",
|
||||
"sr",
|
||||
"sv",
|
||||
"sw",
|
||||
"ta",
|
||||
"te",
|
||||
"th",
|
||||
"tr",
|
||||
"uk",
|
||||
"vi",
|
||||
"zh_CN",
|
||||
"zh_TW",
|
||||
]
|
||||
30
engine/src/build/config/mac/BUILD.gn
Normal file
30
engine/src/build/config/mac/BUILD.gn
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/config/sysroot.gni")
|
||||
|
||||
config("sdk") {
|
||||
cflags_cc = [ "-stdlib=libc++" ]
|
||||
}
|
||||
|
||||
# On Mac, this is used for everything except static libraries.
|
||||
config("mac_dynamic_flags") {
|
||||
ldflags = [
|
||||
"-Wl,-search_paths_first",
|
||||
"-L.",
|
||||
|
||||
# Path for loading shared libraries for unbundled binaries.
|
||||
"-Wl,-rpath,@loader_path/.",
|
||||
"-Wl,-rpath,/usr/local/lib/.",
|
||||
|
||||
# Path for loading shared libraries for bundled binaries. Get back from
|
||||
# Binary.app/Contents/MacOS.
|
||||
"-Wl,-rpath,@loader_path/../../..",
|
||||
]
|
||||
}
|
||||
|
||||
# On Mac, this is used only for executables.
|
||||
config("mac_executable_flags") {
|
||||
ldflags = [ "-Wl,-pie" ] # Position independent.
|
||||
}
|
||||
114
engine/src/build/config/mac/mac_app.py
Normal file
114
engine/src/build/config/mac/mac_app.py
Normal file
@@ -0,0 +1,114 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2015 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.
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import errno
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
PLUTIL = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'plutil'
|
||||
]
|
||||
|
||||
IBTOOL = [
|
||||
'/usr/bin/env',
|
||||
'xcrun',
|
||||
'ibtool',
|
||||
]
|
||||
|
||||
|
||||
def MakeDirectories(path):
|
||||
try:
|
||||
os.makedirs(path)
|
||||
except OSError as exc:
|
||||
if exc.errno == errno.EEXIST and os.path.isdir(path):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def ProcessInfoPlist(args):
|
||||
output_plist_file = os.path.abspath(os.path.join(args.output, 'Info.plist'))
|
||||
return subprocess.check_call( PLUTIL + [
|
||||
'-convert',
|
||||
'binary1',
|
||||
'-o',
|
||||
output_plist_file,
|
||||
'--',
|
||||
args.input,
|
||||
])
|
||||
|
||||
|
||||
def ProcessNIB(args):
|
||||
output_nib_file = os.path.join(os.path.abspath(args.output),
|
||||
"%s.nib" % os.path.splitext(os.path.basename(args.input))[0])
|
||||
|
||||
return subprocess.check_call(IBTOOL + [
|
||||
'--module',
|
||||
args.module,
|
||||
'--auto-activate-custom-fonts',
|
||||
'--target-device',
|
||||
'mac',
|
||||
'--compile',
|
||||
output_nib_file,
|
||||
os.path.abspath(args.input),
|
||||
])
|
||||
|
||||
|
||||
def GenerateProjectStructure(args):
|
||||
application_path = os.path.join( args.dir, args.name + ".app", "Contents" )
|
||||
return MakeDirectories( application_path )
|
||||
|
||||
|
||||
def Main():
|
||||
parser = argparse.ArgumentParser(description='A script that aids in '
|
||||
'the creation of an Mac application')
|
||||
|
||||
subparsers = parser.add_subparsers()
|
||||
|
||||
# Plist Parser
|
||||
|
||||
plist_parser = subparsers.add_parser('plist',
|
||||
help='Process the Info.plist')
|
||||
plist_parser.set_defaults(func=ProcessInfoPlist)
|
||||
|
||||
plist_parser.add_argument('-i', dest='input', help='The input plist path')
|
||||
plist_parser.add_argument('-o', dest='output', help='The output plist dir')
|
||||
|
||||
# NIB Parser
|
||||
|
||||
plist_parser = subparsers.add_parser('nib',
|
||||
help='Process a NIB file')
|
||||
plist_parser.set_defaults(func=ProcessNIB)
|
||||
|
||||
plist_parser.add_argument('-i', dest='input', help='The input nib path')
|
||||
plist_parser.add_argument('-o', dest='output', help='The output nib dir')
|
||||
plist_parser.add_argument('-m', dest='module', help='The module name')
|
||||
|
||||
# Directory Structure Parser
|
||||
|
||||
dir_struct_parser = subparsers.add_parser('structure',
|
||||
help='Creates the directory of an Mac application')
|
||||
|
||||
dir_struct_parser.set_defaults(func=GenerateProjectStructure)
|
||||
|
||||
dir_struct_parser.add_argument('-d', dest='dir', help='Out directory')
|
||||
dir_struct_parser.add_argument('-n', dest='name', help='App name')
|
||||
|
||||
# Engage!
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
return args.func(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
44
engine/src/build/config/mac/mac_sdk.gni
Normal file
44
engine/src/build/config/mac/mac_sdk.gni
Normal file
@@ -0,0 +1,44 @@
|
||||
# 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.
|
||||
|
||||
import("//build/toolchain/rbe.gni")
|
||||
|
||||
declare_args() {
|
||||
# Minimum supported version of the Mac SDK.
|
||||
mac_sdk_min = ""
|
||||
|
||||
# The MACOSX_DEPLOYMENT_TARGET variable used when compiling.
|
||||
# Must be of the form x.x.x for Info.plist files.
|
||||
mac_deployment_target = ""
|
||||
|
||||
# Path to a specific version of the Mac SDK, not including a backslash at
|
||||
# the end. If empty, the path to the lowest version greater than or equal to
|
||||
# mac_sdk_min is used.
|
||||
mac_sdk_path = ""
|
||||
}
|
||||
|
||||
assert(mac_sdk_min != "")
|
||||
assert(mac_deployment_target != "")
|
||||
|
||||
if (mac_sdk_path == "") {
|
||||
find_sdk_args = []
|
||||
if (use_rbe && create_xcode_symlinks) {
|
||||
# RBE has a restriction that paths cannot come from outside the build root.
|
||||
find_sdk_args += [
|
||||
"--symlink",
|
||||
rebase_path("//flutter/prebuilts"),
|
||||
]
|
||||
}
|
||||
find_sdk_args += [
|
||||
"--print_sdk_path",
|
||||
mac_sdk_min,
|
||||
]
|
||||
|
||||
# The tool will print the SDK path on the first line, and the version on the
|
||||
# second line.
|
||||
find_sdk_lines =
|
||||
exec_script("//build/mac/find_sdk.py", find_sdk_args, "list lines")
|
||||
|
||||
mac_sdk_path = find_sdk_lines[0]
|
||||
}
|
||||
60
engine/src/build/config/mac/package_framework.py
Normal file
60
engine/src/build/config/mac/package_framework.py
Normal file
@@ -0,0 +1,60 @@
|
||||
# Copyright 2016 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.
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
def Main():
|
||||
parser = argparse.ArgumentParser(description='Create Mac Framework symlinks')
|
||||
parser.add_argument('--framework', action='store', type=str, required=True)
|
||||
parser.add_argument('--version', action='store', type=str)
|
||||
parser.add_argument('--contents', action='store', type=str, nargs='+')
|
||||
parser.add_argument('--stamp', action='store', type=str, required=True)
|
||||
args = parser.parse_args()
|
||||
|
||||
VERSIONS = 'Versions'
|
||||
CURRENT = 'Current'
|
||||
|
||||
# Ensure the Foo.framework/Versions/A/ directory exists and create the
|
||||
# Foo.framework/Versions/Current symlink to it.
|
||||
if args.version:
|
||||
try:
|
||||
os.makedirs(os.path.join(args.framework, VERSIONS, args.version), 744)
|
||||
except OSError as e:
|
||||
if e.errno != errno.EEXIST:
|
||||
raise e
|
||||
_Relink(os.path.join(args.version),
|
||||
os.path.join(args.framework, VERSIONS, CURRENT))
|
||||
|
||||
# Establish the top-level symlinks in the framework bundle. The dest of
|
||||
# the symlinks may not exist yet.
|
||||
if args.contents:
|
||||
for item in args.contents:
|
||||
_Relink(os.path.join(VERSIONS, CURRENT, item),
|
||||
os.path.join(args.framework, item))
|
||||
|
||||
# Write out a stamp file.
|
||||
if args.stamp:
|
||||
with open(args.stamp, 'w') as f:
|
||||
f.write(str(args))
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def _Relink(dest, link):
|
||||
"""Creates a symlink to |dest| named |link|. If |link| already exists,
|
||||
it is overwritten."""
|
||||
try:
|
||||
os.remove(link)
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
shutil.rmtree(link)
|
||||
os.symlink(dest, link)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
||||
151
engine/src/build/config/mac/rules.gni
Normal file
151
engine/src/build/config/mac/rules.gni
Normal file
@@ -0,0 +1,151 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
mac_app_script = "//build/config/mac/mac_app.py"
|
||||
|
||||
template("code_sign_mac") {
|
||||
assert(defined(invoker.entitlements_path),
|
||||
"The path to the entitlements .xcent file")
|
||||
assert(defined(invoker.identity), "The code signing identity")
|
||||
assert(defined(invoker.application_path), "The application to code sign")
|
||||
assert(defined(invoker.deps))
|
||||
|
||||
action(target_name) {
|
||||
sources = [ invoker.entitlements_path ]
|
||||
|
||||
_application_path = invoker.application_path
|
||||
|
||||
script = mac_app_script
|
||||
|
||||
outputs = [ "$_application_path/_CodeSignature/CodeResources" ]
|
||||
|
||||
args = [
|
||||
"codesign",
|
||||
"-p",
|
||||
rebase_path(invoker.application_path, root_build_dir),
|
||||
"-i",
|
||||
invoker.identity,
|
||||
"-e",
|
||||
rebase_path(invoker.entitlements_path, root_build_dir),
|
||||
]
|
||||
|
||||
deps = invoker.deps
|
||||
}
|
||||
}
|
||||
|
||||
template("resource_copy_mac") {
|
||||
assert(defined(invoker.resources),
|
||||
"The source list of resources to copy over")
|
||||
assert(defined(invoker.bundle_directory),
|
||||
"The directory within the bundle to place the sources in")
|
||||
assert(defined(invoker.app_name), "The name of the application")
|
||||
|
||||
_bundle_directory = invoker.bundle_directory
|
||||
_app_name = invoker.app_name
|
||||
_resources = invoker.resources
|
||||
|
||||
copy(target_name) {
|
||||
sources = _resources
|
||||
outputs = [ "$root_build_dir/$_app_name.app/$_bundle_directory/Contents/Resources/{{source_file_part}}" ]
|
||||
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template("mac_app") {
|
||||
assert(defined(invoker.deps),
|
||||
"Dependencies must be specified for $target_name")
|
||||
assert(defined(invoker.info_plist),
|
||||
"The application plist file must be specified for $target_name")
|
||||
assert(defined(invoker.app_name),
|
||||
"The name of Mac application for $target_name")
|
||||
|
||||
# We just create a variable so we can use the same in interpolation
|
||||
app_name = invoker.app_name
|
||||
|
||||
# Generate the project structure
|
||||
|
||||
struct_gen_target_name = target_name + "_struct"
|
||||
|
||||
action(struct_gen_target_name) {
|
||||
script = mac_app_script
|
||||
|
||||
sources = []
|
||||
outputs = [ "$root_build_dir/$app_name.app" ]
|
||||
|
||||
args = [
|
||||
"structure",
|
||||
"-d",
|
||||
rebase_path(root_build_dir),
|
||||
"-n",
|
||||
app_name,
|
||||
]
|
||||
}
|
||||
|
||||
# Generate the executable
|
||||
|
||||
bin_gen_target_name = target_name + "_bin"
|
||||
|
||||
executable(bin_gen_target_name) {
|
||||
deps = invoker.deps
|
||||
output_name = app_name
|
||||
}
|
||||
|
||||
# Process the Info.plist
|
||||
|
||||
plist_gen_target_name = target_name + "_plist"
|
||||
|
||||
action(plist_gen_target_name) {
|
||||
script = mac_app_script
|
||||
|
||||
sources = [ invoker.info_plist ]
|
||||
outputs = [ "$root_build_dir/plist/$app_name/Info.plist" ]
|
||||
|
||||
args = [
|
||||
"plist",
|
||||
"-i",
|
||||
rebase_path(invoker.info_plist, root_build_dir),
|
||||
"-o",
|
||||
rebase_path("$root_build_dir/plist/$app_name"),
|
||||
]
|
||||
}
|
||||
|
||||
# Copy the generated binaries and assets to their appropriate locations
|
||||
|
||||
copy_plist_gen_target_name = target_name + "_plist_copy"
|
||||
copy(copy_plist_gen_target_name) {
|
||||
sources = [ "$root_build_dir/plist/$app_name/Info.plist" ]
|
||||
|
||||
outputs = [ "$root_build_dir/$app_name.app/Contents/{{source_file_part}}" ]
|
||||
|
||||
deps = [ ":$plist_gen_target_name" ]
|
||||
}
|
||||
|
||||
copy_bin_target_name = target_name + "_bin_copy"
|
||||
copy(copy_bin_target_name) {
|
||||
sources = [ "$root_build_dir/$app_name" ]
|
||||
|
||||
outputs =
|
||||
[ "$root_build_dir/$app_name.app/Contents/MacOS/{{source_file_part}}" ]
|
||||
|
||||
deps = [ ":$bin_gen_target_name" ]
|
||||
}
|
||||
|
||||
copy_all_target_name = target_name + "_all_copy"
|
||||
group(copy_all_target_name) {
|
||||
deps = [
|
||||
":$copy_bin_target_name",
|
||||
":$copy_plist_gen_target_name",
|
||||
":$struct_gen_target_name",
|
||||
]
|
||||
}
|
||||
|
||||
# Top level group
|
||||
|
||||
group(target_name) {
|
||||
deps = [ ":$copy_all_target_name" ]
|
||||
}
|
||||
}
|
||||
9
engine/src/build/config/ozone.gni
Normal file
9
engine/src/build/config/ozone.gni
Normal file
@@ -0,0 +1,9 @@
|
||||
# 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.
|
||||
|
||||
# This file is required by the ANGLE build.
|
||||
|
||||
import("//build/config/ui.gni")
|
||||
|
||||
ozone_platform_gbm = false
|
||||
21
engine/src/build/config/profiler.gni
Normal file
21
engine/src/build/config/profiler.gni
Normal file
@@ -0,0 +1,21 @@
|
||||
# Copyright (c) 2017 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.
|
||||
|
||||
declare_args() {
|
||||
# Compile in such a way as to enable profiling of the generated code. For
|
||||
# example, don't omit the frame pointer and leave in symbols.
|
||||
enable_profiling = false
|
||||
|
||||
# Use default visibility for all symbols.
|
||||
# Without this, any symbol that is not specifically exported will have
|
||||
# hidden visibility.
|
||||
disable_hidden_visibility = false
|
||||
|
||||
# Compile in such a way as to make it possible for the profiler to unwind full
|
||||
# stack frames. Setting this flag has a large effect on the performance of the
|
||||
# generated code than just setting profiling, but gives the profiler more
|
||||
# information to analyze.
|
||||
# Requires profiling to be set to true.
|
||||
enable_full_stack_frames_for_profiling = false
|
||||
}
|
||||
56
engine/src/build/config/sanitizers/BUILD.gn
Normal file
56
engine/src/build/config/sanitizers/BUILD.gn
Normal file
@@ -0,0 +1,56 @@
|
||||
# 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.
|
||||
|
||||
import("//build/config/c++/c++.gni")
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
# Contains the dependencies needed for sanitizers to link into executables and
|
||||
# shared_libraries. Unconditionally depend upon this target as it is empty if
|
||||
# |is_asan|, |is_lsan|, |is_tsan|, |is_msan| and |use_custom_libcxx| are false.
|
||||
group("deps") {
|
||||
if (is_asan || is_lsan || is_tsan || is_msan) {
|
||||
public_configs = [ ":sanitizer_options_link_helper" ]
|
||||
deps += [ ":options_sources" ]
|
||||
}
|
||||
if (use_custom_libcxx) {
|
||||
deps += [ "$buildtools_path/third_party/libc++:libcxx_proxy" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("sanitizer_options_link_helper") {
|
||||
ldflags = [ "-Wl,-u_sanitizer_options_link_helper" ]
|
||||
if (is_asan) {
|
||||
ldflags += [ "-fsanitize=address" ]
|
||||
}
|
||||
if (is_lsan) {
|
||||
ldflags += [ "-fsanitize=leak" ]
|
||||
}
|
||||
if (is_tsan) {
|
||||
ldflags += [ "-fsanitize=thread" ]
|
||||
}
|
||||
if (is_msan) {
|
||||
ldflags += [ "-fsanitize=memory" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set("options_sources") {
|
||||
visibility = [
|
||||
":deps",
|
||||
"//:gn_visibility",
|
||||
]
|
||||
sources = [ "//build/sanitizers/sanitizer_options.cc" ]
|
||||
|
||||
if (is_asan) {
|
||||
sources += [ "//build/sanitizers/asan_suppressions.cc" ]
|
||||
}
|
||||
|
||||
if (is_lsan) {
|
||||
sources += [ "//build/sanitizers/lsan_suppressions.cc" ]
|
||||
}
|
||||
|
||||
if (is_tsan) {
|
||||
sources += [ "//build/sanitizers/tsan_suppressions.cc" ]
|
||||
}
|
||||
}
|
||||
23
engine/src/build/config/sanitizers/sanitizers.gni
Normal file
23
engine/src/build/config/sanitizers/sanitizers.gni
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
declare_args() {
|
||||
# Track where uninitialized memory originates from. From fastest to slowest:
|
||||
# 0 - no tracking, 1 - track only the initial allocation site, 2 - track the
|
||||
# chain of stores leading from allocation site to use site.
|
||||
msan_track_origins = 2
|
||||
|
||||
# Use dynamic libraries instrumented by one of the sanitizers instead of the
|
||||
# standard system libraries. Set this flag to download prebuilt binaries from
|
||||
# GCS.
|
||||
use_prebuilt_instrumented_libraries = false
|
||||
|
||||
is_ubsan_vptr = false
|
||||
|
||||
# Perfetto targets fail to build if this argument isn't defined. When true,
|
||||
# the preprocessor macro ADDRESS_SANITIZER_WITHOUT_INSTRUMENTATION is defined.
|
||||
use_sanitizer_configs_without_instrumentation = false
|
||||
}
|
||||
|
||||
use_fuzzing_engine = false
|
||||
46
engine/src/build/config/sysroot.gni
Normal file
46
engine/src/build/config/sysroot.gni
Normal file
@@ -0,0 +1,46 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# This header file defines the "sysroot" variable which is the absolute path
|
||||
# of the sysroot. If no sysroot applies, the variable will be an empty string.
|
||||
|
||||
declare_args() {
|
||||
# The absolute path of the sysroot that is applied when compiling using
|
||||
# the target toolchain.
|
||||
target_sysroot = ""
|
||||
|
||||
# Whether to use the default sysroot when building for Linux, if an explicit
|
||||
# sysroot isn't set.
|
||||
use_default_linux_sysroot = true
|
||||
}
|
||||
|
||||
if (current_toolchain == default_toolchain && target_sysroot != "") {
|
||||
sysroot = target_sysroot
|
||||
} else if (is_android) {
|
||||
import("//build/config/android/config.gni")
|
||||
sysroot = rebase_path("$android_toolchain_root/sysroot", root_build_dir)
|
||||
} else if (is_linux && !is_chromeos) {
|
||||
if (use_default_linux_sysroot && !is_fuchsia) {
|
||||
if (current_cpu == "x64") {
|
||||
sysroot =
|
||||
rebase_path("//build/linux/debian_sid_amd64-sysroot", root_build_dir)
|
||||
} else {
|
||||
sysroot =
|
||||
rebase_path("//build/linux/debian_sid_arm64-sysroot", root_build_dir)
|
||||
}
|
||||
assert(
|
||||
exec_script("//build/dir_exists.py", [ sysroot ], "string") == "True",
|
||||
"Missing sysroot ($sysroot). To fix, run: build/linux/sysroot_scripts/install-sysroot.py --arch=$current_cpu")
|
||||
} else {
|
||||
sysroot = ""
|
||||
}
|
||||
} else if (is_mac) {
|
||||
import("//build/config/mac/mac_sdk.gni")
|
||||
sysroot = mac_sdk_path
|
||||
} else if (is_ios) {
|
||||
import("//build/config/ios/ios_sdk.gni")
|
||||
sysroot = ios_sdk_path
|
||||
} else {
|
||||
sysroot = ""
|
||||
}
|
||||
55
engine/src/build/config/templates/templates.gni
Normal file
55
engine/src/build/config/templates/templates.gni
Normal file
@@ -0,0 +1,55 @@
|
||||
# Copyright 2015 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.
|
||||
|
||||
# Declare a target for processing a template.
|
||||
#
|
||||
# Variables
|
||||
# input: The template file to be processed.
|
||||
# output: Where to save the result.
|
||||
# variables: A list of variables to make available to the template
|
||||
# processing environment, e.g. ["name=foo", "color=red"].
|
||||
#
|
||||
# Example
|
||||
# file_template("chrome_shell_manifest") {
|
||||
# input = "shell/java/AndroidManifest.xml"
|
||||
# output = "$target_gen_dir/AndroidManifest.xml"
|
||||
# variables = "app_name=chrome_shell app_version=1"
|
||||
# }
|
||||
template("file_template") {
|
||||
if (defined(invoker.testonly)) {
|
||||
testonly = invoker.testonly
|
||||
}
|
||||
|
||||
assert(defined(invoker.input), "The input file must be specified")
|
||||
assert(defined(invoker.output), "The output file must be specified")
|
||||
assert(defined(invoker.variables),
|
||||
"The variable used for substitution in templates must be specified")
|
||||
|
||||
variables = invoker.variables
|
||||
|
||||
action(target_name) {
|
||||
if (defined(invoker.visibility)) {
|
||||
visibility = invoker.visibility
|
||||
}
|
||||
|
||||
script = "//build/android/gyp/jinja_template.py"
|
||||
depfile = "$target_gen_dir/$target_name.d"
|
||||
|
||||
sources = [ invoker.input ]
|
||||
outputs = [
|
||||
invoker.output,
|
||||
depfile,
|
||||
]
|
||||
|
||||
args = [
|
||||
"--inputs",
|
||||
rebase_path(invoker.input, root_build_dir),
|
||||
"--output",
|
||||
rebase_path(invoker.output, root_build_dir),
|
||||
"--depfile",
|
||||
rebase_path(depfile, root_build_dir),
|
||||
"--variables=${variables}",
|
||||
]
|
||||
}
|
||||
}
|
||||
26
engine/src/build/config/ui.gni
Normal file
26
engine/src/build/config/ui.gni
Normal file
@@ -0,0 +1,26 @@
|
||||
# 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.
|
||||
|
||||
# This file contains UI-related build flags. It should theoretically be in the
|
||||
# src/ui directory and only things that depend on the ui module should get the
|
||||
# definitions.
|
||||
#
|
||||
# However, today we have many "bad" dependencies on some of these flags from,
|
||||
# e.g. base, so they need to be global.
|
||||
#
|
||||
# See also build/config/features.gni
|
||||
|
||||
declare_args() {
|
||||
# Indicates if GLFW is enabled. GLFW is an abstraction layer for the
|
||||
# windowing system and OpenGL rendering, providing cross-platform support
|
||||
# for creating windows and OpenGL surfaces and contexts, and handling
|
||||
# window system events and input.
|
||||
use_glfw = false
|
||||
}
|
||||
|
||||
# For ANGLE build. It's a build option there, but hard-coded here.
|
||||
use_x11 = false
|
||||
|
||||
# For ANGLE build. It's a build option there, but hard-coded here.
|
||||
use_ozone = false
|
||||
198
engine/src/build/config/win/BUILD.gn
Normal file
198
engine/src/build/config/win/BUILD.gn
Normal file
@@ -0,0 +1,198 @@
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
import("//build/config/win/visual_studio_version.gni")
|
||||
|
||||
# Compiler setup for the Windows SDK. Applied to all targets.
|
||||
config("sdk") {
|
||||
# The include path is the stuff returned by the script.
|
||||
#include_dirs = msvc_config[0] TODO(brettw) make this work.
|
||||
|
||||
defines = [
|
||||
"_ATL_NO_OPENGL",
|
||||
"_WINDOWS",
|
||||
"CERT_CHAIN_PARA_HAS_EXTRA_FIELDS",
|
||||
"NTDDI_VERSION=0x06030000",
|
||||
"PSAPI_VERSION=1",
|
||||
"WIN32",
|
||||
"_SECURE_ATL",
|
||||
|
||||
# This is required for ATL to use XP-safe versions of its functions.
|
||||
"_USING_V110_SDK71_",
|
||||
]
|
||||
|
||||
if (target_os == "winuwp") {
|
||||
defines += [ "WINUWP" ]
|
||||
}
|
||||
}
|
||||
|
||||
# Sets the default Windows build version. This is separated because some
|
||||
# targets need to manually override it for their compiles.
|
||||
config("winver") {
|
||||
defines = [
|
||||
"_WIN32_WINNT=0x0603",
|
||||
"WINVER=0x0603",
|
||||
]
|
||||
}
|
||||
|
||||
# Linker flags for Windows SDK setup, this is applied only to EXEs and DLLs.
|
||||
config("sdk_link") {
|
||||
if (current_cpu == "x64") {
|
||||
ldflags = [ "/MACHINE:X64" ]
|
||||
lib_dirs = [
|
||||
"$windows_sdk_path\Lib\winv6.3\um\x64",
|
||||
"$visual_studio_path\VC\lib\amd64",
|
||||
"$visual_studio_path\VC\atlmfc\lib\amd64",
|
||||
]
|
||||
} else if (current_cpu == "x86") {
|
||||
ldflags = [
|
||||
"/MACHINE:X86",
|
||||
"/SAFESEH", # Not compatible with x64 so use only for x86.
|
||||
]
|
||||
lib_dirs = [
|
||||
"$windows_sdk_path\Lib\winv6.3\um\x86",
|
||||
"$visual_studio_path\VC\lib",
|
||||
"$visual_studio_path\VC\atlmfc\lib",
|
||||
]
|
||||
if (!is_asan) {
|
||||
ldflags += [ "/largeaddressaware" ]
|
||||
}
|
||||
} else if (current_cpu == "arm64") {
|
||||
ldflags = [ "/MACHINE:ARM64" ]
|
||||
lib_dirs = [
|
||||
"$windows_sdk_path\Lib\winv6.3\um\arm64",
|
||||
"$visual_studio_path\VC\lib\arm64",
|
||||
"$visual_studio_path\VC\atlmfc\lib\arm64",
|
||||
]
|
||||
} else {
|
||||
assert(false, "Unsupported CPU type")
|
||||
}
|
||||
}
|
||||
|
||||
# This default linker setup is provided separately from the SDK setup so
|
||||
# targets who want different library configurations can remove this and specify
|
||||
# their own.
|
||||
config("common_linker_setup") {
|
||||
ldflags = [
|
||||
"/FIXED:NO",
|
||||
"/ignore:4199",
|
||||
"/ignore:4221",
|
||||
"/NXCOMPAT",
|
||||
|
||||
# Suggested by Microsoft Devrel to avoid
|
||||
# LINK : fatal error LNK1248: image size (80000000)
|
||||
# exceeds maximum allowable size (80000000)
|
||||
# which started happening more regularly after VS2013 Update 4.
|
||||
"/maxilksize:2147483647",
|
||||
]
|
||||
|
||||
# ASLR makes debugging with windbg difficult because Chrome.exe and
|
||||
# Chrome.dll share the same base name. As result, windbg will name the
|
||||
# Chrome.dll module like chrome_<base address>, where <base address>
|
||||
# typically changes with each launch. This in turn means that breakpoints in
|
||||
# Chrome.dll don't stick from one launch to the next. For this reason, we
|
||||
# turn ASLR off in debug builds.
|
||||
# /DYNAMICBASE:NO isn't compatible with arm64.
|
||||
if (is_debug && current_cpu != "arm64") {
|
||||
ldflags += [ "/DYNAMICBASE:NO" ]
|
||||
} else {
|
||||
ldflags += [ "/DYNAMICBASE" ]
|
||||
}
|
||||
|
||||
# Delay loaded DLLs.
|
||||
ldflags += [
|
||||
"/DELAYLOAD:dbghelp.dll",
|
||||
"/DELAYLOAD:dwmapi.dll",
|
||||
"/DELAYLOAD:shell32.dll",
|
||||
"/DELAYLOAD:uxtheme.dll",
|
||||
]
|
||||
}
|
||||
|
||||
# Subsystem --------------------------------------------------------------------
|
||||
|
||||
# This is appended to the subsystem to specify a minimum version.
|
||||
if (current_cpu == "x64") {
|
||||
# The number after the comma is the minimum required OS version.
|
||||
# 5.02 = Windows Server 2003.
|
||||
subsystem_version_suffix = ",5.02"
|
||||
} else if (current_cpu == "arm64") {
|
||||
# Windows ARM64 requires Windows 10.
|
||||
subsystem_version_suffix = ",10.0"
|
||||
} else {
|
||||
# 5.01 = Windows XP.
|
||||
subsystem_version_suffix = ",5.01"
|
||||
}
|
||||
|
||||
config("console") {
|
||||
ldflags = [ "/SUBSYSTEM:CONSOLE$subsystem_version_suffix" ]
|
||||
}
|
||||
config("windowed") {
|
||||
ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ]
|
||||
}
|
||||
|
||||
# Incremental linking ----------------------------------------------------------
|
||||
|
||||
incremental_linking_on_switch = [ "/INCREMENTAL" ]
|
||||
incremental_linking_off_switch = [ "/INCREMENTAL:NO" ]
|
||||
if (is_debug) {
|
||||
default_incremental_linking_switch = incremental_linking_on_switch
|
||||
} else {
|
||||
default_incremental_linking_switch = incremental_linking_off_switch
|
||||
}
|
||||
|
||||
# Applies incremental linking or not depending on the current configuration.
|
||||
config("default_incremental_linking") {
|
||||
ldflags = default_incremental_linking_switch
|
||||
}
|
||||
|
||||
# Explicitly on or off incremental linking
|
||||
config("incremental_linking") {
|
||||
ldflags = incremental_linking_on_switch
|
||||
}
|
||||
config("no_incremental_linking") {
|
||||
ldflags = incremental_linking_off_switch
|
||||
}
|
||||
|
||||
# Some large modules can't handle incremental linking in some situations. This
|
||||
# config should be applied to large modules to turn off incremental linking
|
||||
# when it won't work.
|
||||
config("default_large_module_incremental_linking") {
|
||||
if (symbol_level > 0 && (current_cpu == "x86" || !is_component_build)) {
|
||||
# When symbols are on, things get so large that the tools fail due to the
|
||||
# size of the .ilk files.
|
||||
ldflags = incremental_linking_off_switch
|
||||
} else {
|
||||
# Otherwise just do the default incremental linking for this build type.
|
||||
ldflags = default_incremental_linking_switch
|
||||
}
|
||||
}
|
||||
|
||||
# Character set ----------------------------------------------------------------
|
||||
|
||||
# Not including this config means "ansi" (8-bit system codepage).
|
||||
config("unicode") {
|
||||
defines = [
|
||||
"_UNICODE",
|
||||
"UNICODE",
|
||||
]
|
||||
}
|
||||
|
||||
# Lean and mean ----------------------------------------------------------------
|
||||
|
||||
# Some third party code might not compile with WIN32_LEAN_AND_MEAN so we have
|
||||
# to have a separate config for it. Remove this config from your target to
|
||||
# get the "bloaty and accomodating" version of windows.h.
|
||||
config("lean_and_mean") {
|
||||
defines = [ "WIN32_LEAN_AND_MEAN" ]
|
||||
}
|
||||
|
||||
# Nominmax --------------------------------------------------------------------
|
||||
|
||||
# Some third party code defines NOMINMAX before including windows.h, which
|
||||
# then causes warnings when it's been previously defined on the command line.
|
||||
# For such targets, this config can be removed.
|
||||
|
||||
config("nominmax") {
|
||||
defines = [ "NOMINMAX" ]
|
||||
}
|
||||
39
engine/src/build/config/win/visual_studio_version.gni
Normal file
39
engine/src/build/config/win/visual_studio_version.gni
Normal file
@@ -0,0 +1,39 @@
|
||||
# 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.
|
||||
|
||||
declare_args() {
|
||||
# Path to Visual Studio. If empty, the default is used which is to use the
|
||||
# automatic toolchain in depot_tools. If set, you must also set the
|
||||
# visual_studio_version and wdk_path.
|
||||
visual_studio_path = ""
|
||||
|
||||
# Version of Visual Studio pointed to by the visual_studio_path.
|
||||
# Use "2013" for Visual Studio 2013, or "2013e" for the Express version.
|
||||
visual_studio_version = ""
|
||||
|
||||
# Directory of the Windows driver kit. If visual_studio_path is empty, this
|
||||
# will be auto-filled.
|
||||
wdk_path = ""
|
||||
|
||||
# Full path to the Windows SDK, not including a backslash at the end.
|
||||
# This value is the default location, override if you have a different
|
||||
# installation location.
|
||||
windows_sdk_path = "C:\Program Files (x86)\Windows Kits\8.1"
|
||||
}
|
||||
|
||||
if (visual_studio_path == "") {
|
||||
_toolchain_data =
|
||||
exec_script("//build/vs_toolchain.py", [ "get_toolchain_dir" ], "scope")
|
||||
visual_studio_path = _toolchain_data.vs_path
|
||||
windows_sdk_path = _toolchain_data.sdk_path
|
||||
visual_studio_version = _toolchain_data.vs_version
|
||||
wdk_path = _toolchain_data.wdk_dir
|
||||
visual_studio_runtime_dirs = _toolchain_data.runtime_dirs
|
||||
} else {
|
||||
assert(visual_studio_version != "",
|
||||
"You must set the visual_studio_version if you set the path")
|
||||
assert(wdk_path != "",
|
||||
"You must set the wdk_path if you set the visual studio path")
|
||||
visual_studio_runtime_dirs = []
|
||||
}
|
||||
24
engine/src/build/dir_exists.py
Executable file
24
engine/src/build/dir_exists.py
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2011 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.
|
||||
"""Writes True if the argument is a directory."""
|
||||
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
def main():
|
||||
sys.stdout.write(_is_dir(sys.argv[1]))
|
||||
return 0
|
||||
|
||||
def _is_dir(dir_name):
|
||||
return str(os.path.isdir(dir_name))
|
||||
|
||||
def DoMain(args):
|
||||
"""Hook to be called from gyp without starting a separate python
|
||||
interpreter."""
|
||||
return _is_dir(args[0])
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
74
engine/src/build/find_depot_tools.py
Normal file
74
engine/src/build/find_depot_tools.py
Normal file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright 2011 The Chromium Authors
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
"""Small utility function to find depot_tools and add it to the python path.
|
||||
|
||||
Will throw an ImportError exception if depot_tools can't be found since it
|
||||
imports breakpad.
|
||||
|
||||
This can also be used as a standalone script to print out the depot_tools
|
||||
directory location.
|
||||
"""
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
# Path to //src
|
||||
SRC = os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir))
|
||||
|
||||
|
||||
def IsRealDepotTools(path):
|
||||
expanded_path = os.path.expanduser(path)
|
||||
return os.path.isfile(os.path.join(expanded_path, 'gclient.py'))
|
||||
|
||||
|
||||
def add_depot_tools_to_path():
|
||||
"""Search for depot_tools and add it to sys.path."""
|
||||
# First, check if we have a DEPS'd in "depot_tools".
|
||||
deps_depot_tools = os.path.join(SRC, 'flutter', 'third_party', 'depot_tools')
|
||||
if IsRealDepotTools(deps_depot_tools):
|
||||
# Put the pinned version at the start of the sys.path, in case there
|
||||
# are other non-pinned versions already on the sys.path.
|
||||
sys.path.insert(0, deps_depot_tools)
|
||||
return deps_depot_tools
|
||||
|
||||
# Then look if depot_tools is already in PYTHONPATH.
|
||||
for i in sys.path:
|
||||
if i.rstrip(os.sep).endswith('depot_tools') and IsRealDepotTools(i):
|
||||
return i
|
||||
# Then look if depot_tools is in PATH, common case.
|
||||
for i in os.environ['PATH'].split(os.pathsep):
|
||||
if IsRealDepotTools(i):
|
||||
sys.path.append(i.rstrip(os.sep))
|
||||
return i
|
||||
# Rare case, it's not even in PATH, look upward up to root.
|
||||
root_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
previous_dir = os.path.abspath(__file__)
|
||||
while root_dir and root_dir != previous_dir:
|
||||
i = os.path.join(root_dir, 'depot_tools')
|
||||
if IsRealDepotTools(i):
|
||||
sys.path.append(i)
|
||||
return i
|
||||
previous_dir = root_dir
|
||||
root_dir = os.path.dirname(root_dir)
|
||||
print('Failed to find depot_tools', file=sys.stderr)
|
||||
return None
|
||||
|
||||
DEPOT_TOOLS_PATH = add_depot_tools_to_path()
|
||||
|
||||
# pylint: disable=W0611
|
||||
import breakpad
|
||||
|
||||
|
||||
def main():
|
||||
if DEPOT_TOOLS_PATH is None:
|
||||
return 1
|
||||
print(DEPOT_TOOLS_PATH)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
364
engine/src/build/fuchsia/sdk.gni
Normal file
364
engine/src/build/fuchsia/sdk.gni
Normal file
@@ -0,0 +1,364 @@
|
||||
# Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/fuchsia/config.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
declare_args() {
|
||||
# The path to where GN targets derived from the Fuchsia SDK are instantiated.
|
||||
fuchsia_sdk_root = "//build/fuchsia"
|
||||
|
||||
# The Flutter buildroot is outside the Fuchsia root and can only use the SDK.
|
||||
using_fuchsia_sdk = true
|
||||
|
||||
# This is set by the dart sources. Once the engine repo switches to using the GN SDK,
|
||||
# this flag can be unified with `using_fuchsia_sdk`.
|
||||
using_fuchsia_gn_sdk = false
|
||||
|
||||
# The following variables are Flutter buildroot specific.
|
||||
fuchsia_sdk_path = "//fuchsia/sdk/$host_os"
|
||||
fuchsia_toolchain_path = "$buildtools_path/${host_os}-${host_cpu}/clang"
|
||||
}
|
||||
|
||||
declare_args() {
|
||||
# The Skia buildroot uses this flag to decide if it should be using the
|
||||
# Fuchsia SDK to build its translation units.
|
||||
skia_using_fuchsia_sdk = using_fuchsia_sdk
|
||||
}
|
||||
|
||||
_fuchsia_sdk_path = "//fuchsia/sdk/$host_os"
|
||||
_fuchsia_tools_path = "${_fuchsia_sdk_path}/tools/${host_cpu}"
|
||||
|
||||
template("_fuchsia_sysroot") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
assert(target_cpu == "x64" || target_cpu == "arm64",
|
||||
"We currently only support 'x64' and 'arm64' targets for fuchsia.")
|
||||
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
|
||||
assert(meta_json.type == "sysroot")
|
||||
|
||||
meta_json_versions = meta_json.versions
|
||||
if (target_cpu == "x64") {
|
||||
defs = meta_json_versions.x64
|
||||
} else {
|
||||
defs = meta_json_versions.arm64
|
||||
}
|
||||
|
||||
_libs = []
|
||||
_lib_dirs = []
|
||||
_include_dirs = []
|
||||
|
||||
foreach(link_lib, defs.link_libs) {
|
||||
if (link_lib != "arch/${target_cpu}/sysroot/lib/Scrt1.o") {
|
||||
_libs += [ "$_fuchsia_sdk_path/$link_lib" ]
|
||||
}
|
||||
}
|
||||
|
||||
defs_include_dir = defs.include_dir
|
||||
_include_dirs += [ "$_fuchsia_sdk_path/$defs_include_dir" ]
|
||||
|
||||
config_name = "config_$target_name"
|
||||
config(config_name) {
|
||||
lib_dirs = _lib_dirs
|
||||
libs = _libs
|
||||
include_dirs = _include_dirs
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
public_configs = [ ":$config_name" ]
|
||||
}
|
||||
}
|
||||
|
||||
template("fuchsia_fidl_library") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
assert(target_cpu == "x64" || target_cpu == "arm64",
|
||||
"We currently only support 'x64' and 'arm64' targets for fuchsia.")
|
||||
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
assert(meta_json.type == "fidl_library")
|
||||
|
||||
_deps = [
|
||||
"//build/fuchsia/pkg:fidl_cpp",
|
||||
"//build/fuchsia/pkg:fidl_cpp_hlcpp_conversion",
|
||||
"//build/fuchsia/pkg:fidl_cpp_natural_ostream",
|
||||
"//build/fuchsia/pkg:fidl_cpp_v2",
|
||||
"//build/fuchsia/pkg:fidl_cpp_wire",
|
||||
]
|
||||
|
||||
library_name = meta_json.name
|
||||
library_name_json = "${meta_json.name}.json"
|
||||
|
||||
foreach(dep, meta_json.deps) {
|
||||
# TODO(https://fxbug.dev/42172334): Make zx less special.
|
||||
if (dep != "zx") {
|
||||
_deps += [ ":$dep" ]
|
||||
}
|
||||
}
|
||||
|
||||
config_name = "config_$target_name"
|
||||
config(config_name) {
|
||||
include_dirs = [ target_gen_dir ]
|
||||
}
|
||||
|
||||
fidl_gen_target_name = "fidlgen_$target_name"
|
||||
action(fidl_gen_target_name) {
|
||||
script = "//build/fuchsia/fidl_gen_cpp.py"
|
||||
|
||||
library_name_slashes = string_replace(library_name, ".", "/")
|
||||
|
||||
inputs = [ invoker.meta ]
|
||||
|
||||
args = [
|
||||
"--fidlc-bin",
|
||||
rebase_path("${_fuchsia_tools_path}/fidlc"),
|
||||
"--sdk-base",
|
||||
rebase_path(_fuchsia_sdk_path),
|
||||
"--root",
|
||||
rebase_path(invoker.meta),
|
||||
"--json",
|
||||
rebase_path("$target_gen_dir/$library_name_json"),
|
||||
]
|
||||
|
||||
if (fuchsia_target_api_level != -1) {
|
||||
args += [
|
||||
"--target-api-level",
|
||||
"${fuchsia_target_api_level}",
|
||||
]
|
||||
}
|
||||
|
||||
outputs = [
|
||||
"$target_gen_dir/$library_name_slashes/cpp/fidl.cc",
|
||||
"$target_gen_dir/$library_name_slashes/cpp/fidl.h",
|
||||
"$target_gen_dir/$library_name_slashes/cpp/fidl_test_base.h",
|
||||
"$target_gen_dir/$library_name_slashes/cpp/tables.c",
|
||||
|
||||
"$target_gen_dir/fidl/$library_name/cpp/common_types.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/common_types.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/fidl.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/hlcpp_conversion.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/markers.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_messaging.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_messaging.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_ostream.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_ostream.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_types.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/natural_types.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/type_conversions.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/type_conversions.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire_messaging.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire_messaging.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire_test_base.h",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire_types.cc",
|
||||
"$target_gen_dir/fidl/$library_name/cpp/wire_types.h",
|
||||
]
|
||||
|
||||
args += [
|
||||
"--fidlgen-bin",
|
||||
rebase_path("${_fuchsia_tools_path}/fidlgen_cpp"),
|
||||
"--fidlgen-bin",
|
||||
rebase_path("${_fuchsia_tools_path}/fidlgen_hlcpp"),
|
||||
"--fidlgen-output-root",
|
||||
rebase_path("$target_gen_dir"),
|
||||
]
|
||||
}
|
||||
|
||||
source_set(target_name) {
|
||||
public_configs = [ ":$config_name" ]
|
||||
|
||||
sources = get_target_outputs(":$fidl_gen_target_name")
|
||||
|
||||
deps = [ ":$fidl_gen_target_name" ]
|
||||
|
||||
public_deps = _deps
|
||||
}
|
||||
}
|
||||
|
||||
template("_fuchsia_cc_source_library") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
|
||||
assert(meta_json.type == "cc_source_library")
|
||||
|
||||
_output_name = meta_json.name
|
||||
_include_dirs = []
|
||||
_public_headers = []
|
||||
_sources = []
|
||||
_deps = []
|
||||
|
||||
meta_json_include_dir = meta_json.include_dir
|
||||
_include_dirs += [ "$_fuchsia_sdk_path/$meta_json_include_dir" ]
|
||||
|
||||
foreach(header, meta_json.headers) {
|
||||
rebased_header = []
|
||||
rebased_header = [ "$_fuchsia_sdk_path/$header" ]
|
||||
_public_headers += rebased_header
|
||||
_sources += rebased_header
|
||||
}
|
||||
|
||||
foreach(source, meta_json.sources) {
|
||||
_sources += [ "$_fuchsia_sdk_path/$source" ]
|
||||
}
|
||||
|
||||
config_name = "config_$target_name"
|
||||
config(config_name) {
|
||||
include_dirs = _include_dirs
|
||||
}
|
||||
|
||||
foreach(dep, meta_json.deps) {
|
||||
_deps += [ "../pkg:$dep" ]
|
||||
}
|
||||
|
||||
foreach(dep, meta_json.fidl_deps) {
|
||||
_deps += [ "../fidl:$dep" ]
|
||||
}
|
||||
|
||||
foreach(binding_dep, meta_json.fidl_binding_deps) {
|
||||
# No need to check "binding_deps.binding_type" because we always
|
||||
# generate both hlcpp and natural bindings.
|
||||
foreach(dep, binding_dep.deps) {
|
||||
_deps += [ "../fidl:$dep" ]
|
||||
}
|
||||
}
|
||||
|
||||
source_set(target_name) {
|
||||
output_name = _output_name
|
||||
public = _public_headers
|
||||
sources = _sources
|
||||
public_configs = [ ":$config_name" ]
|
||||
public_deps = _deps
|
||||
}
|
||||
}
|
||||
|
||||
template("_fuchsia_cc_prebuilt_library") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
|
||||
_include_dirs = []
|
||||
_deps = []
|
||||
_libs = []
|
||||
|
||||
meta_json_include_dir = meta_json.include_dir
|
||||
_include_dirs += [ "$_fuchsia_sdk_path/$meta_json_include_dir" ]
|
||||
|
||||
foreach(dep, meta_json.deps) {
|
||||
_deps += [ ":$dep" ]
|
||||
}
|
||||
|
||||
meta_json_binaries = meta_json.binaries
|
||||
if (target_cpu == "x64") {
|
||||
meta_json_binaries_arch = meta_json_binaries.x64
|
||||
} else {
|
||||
meta_json_binaries_arch = meta_json_binaries.arm64
|
||||
}
|
||||
prebuilt_lib = meta_json_binaries_arch.link
|
||||
_libs = [ "$_fuchsia_sdk_path/$prebuilt_lib" ]
|
||||
|
||||
config_name = "config_$target_name"
|
||||
config(config_name) {
|
||||
include_dirs = _include_dirs
|
||||
libs = _libs
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
public_configs = [ ":$config_name" ]
|
||||
public_deps = _deps
|
||||
}
|
||||
}
|
||||
|
||||
template("fuchsia_sdk") {
|
||||
assert(defined(invoker.meta), "The meta.json file path must be specified.")
|
||||
assert(defined(invoker.enabled_parts),
|
||||
"A list containing the parts of the SDK to generate targets for.")
|
||||
|
||||
meta_json = read_file(invoker.meta, "json")
|
||||
|
||||
foreach(part, meta_json.parts) {
|
||||
part_meta_json = {
|
||||
}
|
||||
part_meta = part.meta
|
||||
part_meta_rebased = "$_fuchsia_sdk_path/$part_meta"
|
||||
|
||||
# Check if the part is using `part.element_type` or `part.type`.
|
||||
part_type = ""
|
||||
if (defined(part.element_type)) {
|
||||
part_type = part.element_type
|
||||
} else if (defined(part.type)) {
|
||||
part_type = part.type
|
||||
}
|
||||
|
||||
# Check if the part type is in `invoker.enabled_parts`.
|
||||
if (invoker.enabled_parts + [ part_type ] - [ part_type ] !=
|
||||
invoker.enabled_parts) {
|
||||
part_meta_json = read_file(part_meta_rebased, "json")
|
||||
subtarget_name = part_meta_json.name
|
||||
|
||||
if (part_type == "cc_source_library") {
|
||||
_fuchsia_cc_source_library(subtarget_name) {
|
||||
meta = part_meta_rebased
|
||||
}
|
||||
} else if (part_type == "sysroot") {
|
||||
_fuchsia_sysroot(subtarget_name) {
|
||||
meta = part_meta_rebased
|
||||
}
|
||||
} else if (part_type == "fidl_library") {
|
||||
# TODO(https://fxbug.dev/42172334): Make zx less special.
|
||||
if (subtarget_name != "zx") {
|
||||
fuchsia_fidl_library(subtarget_name) {
|
||||
meta = part_meta_rebased
|
||||
}
|
||||
}
|
||||
} else if (part_type == "cc_prebuilt_library") {
|
||||
_fuchsia_cc_prebuilt_library(subtarget_name) {
|
||||
meta = part_meta_rebased
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group(target_name) {
|
||||
}
|
||||
}
|
||||
|
||||
template("fuchsia_repo") {
|
||||
assert(defined(invoker.archives),
|
||||
"The list of archives to publish must be specified.")
|
||||
assert(defined(invoker.repo), "The location of the repo should be specified.")
|
||||
|
||||
action(target_name) {
|
||||
script = "//flutter/tools/fuchsia/gen_repo.py"
|
||||
|
||||
pm_binary = rebase_path("${_fuchsia_tools_path}/pm")
|
||||
repo_directory = invoker.repo
|
||||
|
||||
inputs = [ pm_binary ]
|
||||
|
||||
archive_flags = []
|
||||
|
||||
foreach(archive, invoker.archives) {
|
||||
assert(get_path_info(archive, "extension") == "far",
|
||||
"Archive '$archive' does not have the .far extension.")
|
||||
inputs += [ archive ]
|
||||
archive_flags += [
|
||||
"--archive",
|
||||
rebase_path(archive),
|
||||
]
|
||||
}
|
||||
|
||||
outputs = [ repo_directory ]
|
||||
|
||||
args = [
|
||||
"--pm-bin",
|
||||
pm_binary,
|
||||
"--repo-dir",
|
||||
rebase_path(repo_directory),
|
||||
] + archive_flags
|
||||
|
||||
if (defined(invoker.deps)) {
|
||||
deps = invoker.deps
|
||||
}
|
||||
}
|
||||
}
|
||||
60
engine/src/build/git-hooks/pre-commit
Executable file
60
engine/src/build/git-hooks/pre-commit
Executable file
@@ -0,0 +1,60 @@
|
||||
#!/bin/sh
|
||||
|
||||
submodule_diff() {
|
||||
if test -n "$2"; then
|
||||
git diff-tree -r --ignore-submodules=dirty "$1" "$2" | grep -e '^:160000' -e '^:...... 160000' | xargs
|
||||
else
|
||||
git diff-index --cached --ignore-submodules=dirty "$1" | grep -e '^:160000' -e '^:...... 160000' | xargs
|
||||
fi
|
||||
}
|
||||
|
||||
if git rev-parse --verify --quiet --no-revs MERGE_HEAD; then
|
||||
merge_base=$(git merge-base HEAD MERGE_HEAD)
|
||||
if test -z "$(submodule_diff $merge_base HEAD)"; then
|
||||
# Most up-to-date submodules are in MERGE_HEAD.
|
||||
head_ref=MERGE_HEAD
|
||||
else
|
||||
# Most up-to-date submodules are in HEAD.
|
||||
head_ref=HEAD
|
||||
fi
|
||||
else
|
||||
# No merge in progress. Submodules must match HEAD.
|
||||
head_ref=HEAD
|
||||
fi
|
||||
|
||||
submods=$(submodule_diff $head_ref)
|
||||
if test "$submods"; then
|
||||
echo "You are trying to commit changes to the following submodules:" 1>&2
|
||||
echo 1>&2
|
||||
echo $submods | cut -d ' ' -f 6 | sed 's/^/ /g' 1>&2
|
||||
cat <<EOF 1>&2
|
||||
|
||||
Submodule commits are not allowed. Please run:
|
||||
|
||||
git status --ignore-submodules=dirty
|
||||
|
||||
and/or:
|
||||
|
||||
git diff-index --cached --ignore-submodules=dirty HEAD
|
||||
|
||||
... to see what's in your index.
|
||||
|
||||
If you're really and truly trying to roll the version of a submodule, you should
|
||||
commit the new version to DEPS, instead.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
gitmodules_diff() {
|
||||
git diff-index --cached "$1" .gitmodules
|
||||
}
|
||||
|
||||
if [ "$(git ls-files .gitmodules)" ] && [ "$(gitmodules_diff $head_ref)" ]; then
|
||||
cat <<EOF 1>&2
|
||||
You are trying to commit a change to .gitmodules. That is not allowed.
|
||||
To make changes to submodule names/paths, edit DEPS.
|
||||
EOF
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
133
engine/src/build/gn_helpers.py
Normal file
133
engine/src/build/gn_helpers.py
Normal file
@@ -0,0 +1,133 @@
|
||||
# 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.
|
||||
|
||||
import sys
|
||||
|
||||
"""Helper functions useful when writing scripts that are run from GN's
|
||||
exec_script function."""
|
||||
|
||||
class GNError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
# Computes ASCII code of an element of encoded Python 2 str / Python 3 bytes.
|
||||
_Ord = ord if sys.version_info.major < 3 else lambda c: c
|
||||
|
||||
|
||||
def _TranslateToGnChars(s):
|
||||
for decoded_ch in s.encode('utf-8'): # str in Python 2, bytes in Python 3.
|
||||
code = _Ord(decoded_ch) # int
|
||||
if code in (34, 36, 92): # For '"', '$', or '\\'.
|
||||
yield '\\' + chr(code)
|
||||
elif 32 <= code < 127:
|
||||
yield chr(code)
|
||||
else:
|
||||
yield '$0x%02X' % code
|
||||
|
||||
|
||||
def ToGNString(value, pretty=False):
|
||||
"""Returns a stringified GN equivalent of a Python value.
|
||||
|
||||
Args:
|
||||
value: The Python value to convert.
|
||||
pretty: Whether to pretty print. If true, then non-empty lists are rendered
|
||||
recursively with one item per line, with indents. Otherwise lists are
|
||||
rendered without new line.
|
||||
Returns:
|
||||
The stringified GN equivalent to |value|.
|
||||
|
||||
Raises:
|
||||
GNError: |value| cannot be printed to GN.
|
||||
"""
|
||||
|
||||
if sys.version_info.major < 3:
|
||||
basestring_compat = basestring
|
||||
else:
|
||||
basestring_compat = str
|
||||
|
||||
# Emits all output tokens without intervening whitespaces.
|
||||
def GenerateTokens(v, level):
|
||||
if isinstance(v, basestring_compat):
|
||||
yield '"' + ''.join(_TranslateToGnChars(v)) + '"'
|
||||
|
||||
elif isinstance(v, bool):
|
||||
yield 'true' if v else 'false'
|
||||
|
||||
elif isinstance(v, int):
|
||||
yield str(v)
|
||||
|
||||
elif isinstance(v, list):
|
||||
yield '['
|
||||
for i, item in enumerate(v):
|
||||
if i > 0:
|
||||
yield ','
|
||||
for tok in GenerateTokens(item, level + 1):
|
||||
yield tok
|
||||
yield ']'
|
||||
|
||||
elif isinstance(v, dict):
|
||||
if level > 0:
|
||||
yield '{'
|
||||
for key in sorted(v):
|
||||
if not isinstance(key, basestring_compat):
|
||||
raise GNError('Dictionary key is not a string.')
|
||||
if not key or key[0].isdigit() or not key.replace('_', '').isalnum():
|
||||
raise GNError('Dictionary key is not a valid GN identifier.')
|
||||
yield key # No quotations.
|
||||
yield '='
|
||||
for tok in GenerateTokens(v[key], level + 1):
|
||||
yield tok
|
||||
if level > 0:
|
||||
yield '}'
|
||||
|
||||
else: # Not supporting float: Add only when needed.
|
||||
raise GNError('Unsupported type when printing to GN.')
|
||||
|
||||
can_start = lambda tok: tok and tok not in ',}]='
|
||||
can_end = lambda tok: tok and tok not in ',{[='
|
||||
|
||||
# Adds whitespaces, trying to keep everything (except dicts) in 1 line.
|
||||
def PlainGlue(gen):
|
||||
prev_tok = None
|
||||
for i, tok in enumerate(gen):
|
||||
if i > 0:
|
||||
if can_end(prev_tok) and can_start(tok):
|
||||
yield '\n' # New dict item.
|
||||
elif prev_tok == '[' and tok == ']':
|
||||
yield ' ' # Special case for [].
|
||||
elif tok != ',':
|
||||
yield ' '
|
||||
yield tok
|
||||
prev_tok = tok
|
||||
|
||||
# Adds whitespaces so non-empty lists can span multiple lines, with indent.
|
||||
def PrettyGlue(gen):
|
||||
prev_tok = None
|
||||
level = 0
|
||||
for i, tok in enumerate(gen):
|
||||
if i > 0:
|
||||
if can_end(prev_tok) and can_start(tok):
|
||||
yield '\n' + ' ' * level # New dict item.
|
||||
elif tok == '=' or prev_tok in '=':
|
||||
yield ' ' # Separator before and after '=', on same line.
|
||||
if tok in ']}':
|
||||
level -= 1
|
||||
# Exclude '[]' and '{}' cases.
|
||||
if int(prev_tok == '[') + int(tok == ']') == 1 or \
|
||||
int(prev_tok == '{') + int(tok == '}') == 1:
|
||||
yield '\n' + ' ' * level
|
||||
yield tok
|
||||
if tok in '[{':
|
||||
level += 1
|
||||
if tok == ',':
|
||||
yield '\n' + ' ' * level
|
||||
prev_tok = tok
|
||||
|
||||
token_gen = GenerateTokens(value, 0)
|
||||
ret = ''.join((PrettyGlue if pretty else PlainGlue)(token_gen))
|
||||
# Add terminating '\n' for dict |value| or multi-line output.
|
||||
if isinstance(value, dict) or '\n' in ret:
|
||||
return ret + '\n'
|
||||
return ret
|
||||
|
||||
28
engine/src/build/gn_run_binary.py
Normal file
28
engine/src/build/gn_run_binary.py
Normal file
@@ -0,0 +1,28 @@
|
||||
# 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 an arbitrary binary. See compiled_action.gni.
|
||||
|
||||
Run with:
|
||||
python gn_run_binary.py <binary_name> [args ...]
|
||||
"""
|
||||
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# This script is designed to run binaries produced by the current build. We
|
||||
# always prefix it with "./" to avoid picking up system versions that might
|
||||
# also be on the path.
|
||||
path = './' + sys.argv[1]
|
||||
|
||||
# The rest of the arguements are passed directly to the executable.
|
||||
args = [path] + sys.argv[2:]
|
||||
|
||||
try:
|
||||
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
print("Command failed: " + ' '.join(args))
|
||||
print("exitCode: " + str(ex.returncode))
|
||||
print(ex.output.decode('utf-8', errors='replace'))
|
||||
sys.exit(ex.returncode)
|
||||
54
engine/src/build/gn_run_malioc.py
Normal file
54
engine/src/build/gn_run_malioc.py
Normal file
@@ -0,0 +1,54 @@
|
||||
# Copyright 2013 The Flutter 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 malioc.
|
||||
|
||||
This is the same as `gn_run_binary.py`, except an extra parameter is included
|
||||
for the malioc output file. When the malioc run fails, errors are placed in the
|
||||
json output file. This script attempts to read the output file and dump it to
|
||||
stdout upon failure.
|
||||
|
||||
Run with:
|
||||
python gn_run_malioc.py <binary_name> <output_path> [args ...]
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import subprocess
|
||||
|
||||
# This script is designed to run binaries produced by the current build. We
|
||||
# always prefix it with "./" to avoid picking up system versions that might
|
||||
# also be on the path.
|
||||
path = './' + sys.argv[1]
|
||||
|
||||
malioc_output = sys.argv[2]
|
||||
|
||||
# The rest of the arguements are passed directly to the executable.
|
||||
args = [path, '--output', malioc_output] + sys.argv[3:]
|
||||
|
||||
try:
|
||||
subprocess.check_output(args, stderr=subprocess.STDOUT)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
print(ex.output.decode('utf-8', errors='replace'))
|
||||
if os.path.exists(malioc_output):
|
||||
with open(malioc_output, 'r') as malioc_file:
|
||||
malioc_json = malioc_file.read()
|
||||
|
||||
print('malioc output:')
|
||||
# Attempt to pretty print the json output, but fall back to printing the
|
||||
# raw output if doing so fails.
|
||||
try:
|
||||
parsed = json.loads(malioc_json)
|
||||
print(json.dumps(parsed, indent=2))
|
||||
except:
|
||||
print(malioc_json)
|
||||
|
||||
else:
|
||||
print(
|
||||
'Unable to find the malioc output file in order to print contained'
|
||||
'errors:',
|
||||
malioc_output,
|
||||
)
|
||||
sys.exit(ex.returncode)
|
||||
24
engine/src/build/internal/README.chromium
Normal file
24
engine/src/build/internal/README.chromium
Normal file
@@ -0,0 +1,24 @@
|
||||
Internal property sheets:
|
||||
essential.vsprops
|
||||
Contains the common settings used throughout the projects. Is included by either ..\debug.vsprops or ..\release.vsprops, so in general, it is not included directly.
|
||||
|
||||
release_defaults.vsprops
|
||||
Included by ..\release.vsprops. Its settings are overriden by release_impl$(CHROME_BUILD_TYPE).vsprops. Uses the default VS setting which is "Maximize Speed". Results in relatively fast build with reasonable optimization level but without whole program optimization to reduce build time.
|
||||
|
||||
release_impl.vsprops
|
||||
Included by ..\release.vsprops by default when CHROME_BUILD_TYPE is undefined. Includes release_defaults.vsprops.
|
||||
|
||||
release_impl_checksenabled.vsprops
|
||||
Included by ..\release.vsprops when CHROME_BUILD_TYPE=_checksenabled. Matches what release_defaults.vsprops does, but doesn't actually inherit from it as we couldn't quite get that working. The only difference is that _DEBUG is set instead of NDEBUG. Used for keeping debug checks enabled with a build that is fast enough to dogfood with.
|
||||
|
||||
release_impl_official.vsprops
|
||||
Included by ..\release.vsprops when CHROME_BUILD_TYPE=_official. Includes release_defaults.vsprops. Enables Whole Program Optimizations (WPO), which doubles the build time. Results in much more optimized build. Uses "Full Optimization" and "Flavor small code".
|
||||
|
||||
release_impl_pgo_instrument.vsprops
|
||||
Included by ..\release.vsprops when CHROME_BUILD_TYPE=_pgo_instrument. Includes release_defaults.vsprops. Enables Profile Guided Optimization (PGO) instrumentation (first pass). Uses "Full Optimization" and "Flavor small code".
|
||||
|
||||
release_impl_pgo_optimize.vsprops
|
||||
Included by ..\release.vsprops when CHROME_BUILD_TYPE=_pgo_optimize. Includes release_defaults.vsprops. Enables Profile Guided Optimization (PGO) optimization (second pass). Uses "Full Optimization" and "Flavor small code".
|
||||
|
||||
release_impl_purify.vsprops
|
||||
Included by ..\release.vsprops when CHROME_BUILD_TYPE=_purify. Includes release_defaults.vsprops. Disables optimizations. Used with Purify to test without debug tools and without optimization; i.e. NDEBUG is defined but the compiler doesn't optimize the binary.
|
||||
1
engine/src/build/linux/bin/eu-strip.sha1
Normal file
1
engine/src/build/linux/bin/eu-strip.sha1
Normal file
@@ -0,0 +1 @@
|
||||
0a9b8f68615ce388b65201e6d22da7a9cf2e729c
|
||||
29
engine/src/build/linux/chrome_linux.croc
Normal file
29
engine/src/build/linux/chrome_linux.croc
Normal file
@@ -0,0 +1,29 @@
|
||||
# -*- python -*-
|
||||
# Crocodile config file for Chromium linux
|
||||
|
||||
# TODO(jhawkins): We'll need to add a chromeos.croc once we get a coverage bot
|
||||
# for that platform.
|
||||
|
||||
{
|
||||
# List of rules, applied in order
|
||||
'rules' : [
|
||||
# Specify inclusions before exclusions, since rules are in order.
|
||||
|
||||
# Don't include non-Linux platform dirs
|
||||
{
|
||||
'regexp' : '.*/(chromeos|views)/',
|
||||
'include' : 0,
|
||||
},
|
||||
# Don't include chromeos, windows, or mac specific files
|
||||
{
|
||||
'regexp' : '.*(_|/)(chromeos|mac|win|views)(\\.|_)',
|
||||
'include' : 0,
|
||||
},
|
||||
|
||||
# Groups
|
||||
{
|
||||
'regexp' : '.*_test_linux\\.',
|
||||
'group' : 'test',
|
||||
},
|
||||
],
|
||||
}
|
||||
29
engine/src/build/linux/dump_app_syms.py
Normal file
29
engine/src/build/linux/dump_app_syms.py
Normal file
@@ -0,0 +1,29 @@
|
||||
# Copyright 2015 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 to run dump_syms on Chrome Linux executables and strip
|
||||
# them if needed.
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 5:
|
||||
print("dump_app_syms.py <dump_syms_exe> <strip_binary>")
|
||||
print(" <binary_with_symbols> <symbols_output>")
|
||||
sys.exit(1)
|
||||
|
||||
dumpsyms = sys.argv[1]
|
||||
strip_binary = sys.argv[2]
|
||||
infile = sys.argv[3]
|
||||
outfile = sys.argv[4]
|
||||
|
||||
# Dump only when the output file is out-of-date.
|
||||
if not os.path.isfile(outfile) or \
|
||||
os.stat(outfile).st_mtime > os.stat(infile).st_mtime:
|
||||
with open(outfile, 'w') as outfileobj:
|
||||
subprocess.check_call([dumpsyms, '-r', infile], stdout=outfileobj)
|
||||
|
||||
if strip_binary != '0':
|
||||
subprocess.check_call(['strip', infile])
|
||||
74
engine/src/build/linux/install-chromeos-fonts.py
Executable file
74
engine/src/build/linux/install-chromeos-fonts.py
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2013 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.
|
||||
|
||||
# Script to install the Chrome OS fonts on Linux.
|
||||
# This script can be run manually (as root), but is also run as part
|
||||
# install-build-deps.sh.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
# Taken from the media-fonts/notofonts ebuild in chromiumos-overlay.
|
||||
VERSION = '20140815'
|
||||
URL = ('https://commondatastorage.googleapis.com/chromeos-localmirror/'
|
||||
'distfiles/notofonts-%s.tar.bz2') % (VERSION)
|
||||
FONTS_DIR = '/usr/local/share/fonts'
|
||||
|
||||
def main(args):
|
||||
if not sys.platform.startswith('linux'):
|
||||
print("Error: %s must be run on Linux." % __file__)
|
||||
return 1
|
||||
|
||||
if os.getuid() != 0:
|
||||
print("Error: %s must be run as root." % __file__)
|
||||
return 1
|
||||
|
||||
if not os.path.isdir(FONTS_DIR):
|
||||
print("Error: Destination directory does not exist: %s" % FONTS_DIR)
|
||||
return 1
|
||||
|
||||
dest_dir = os.path.join(FONTS_DIR, 'chromeos')
|
||||
|
||||
stamp = os.path.join(dest_dir, ".stamp02")
|
||||
if os.path.exists(stamp):
|
||||
with open(stamp) as s:
|
||||
if s.read() == URL:
|
||||
print("Chrome OS fonts already up-to-date in %s." % dest_dir)
|
||||
return 0
|
||||
|
||||
if os.path.isdir(dest_dir):
|
||||
shutil.rmtree(dest_dir)
|
||||
os.mkdir(dest_dir)
|
||||
os.chmod(dest_dir, 0o755)
|
||||
|
||||
print("Installing Chrome OS fonts to %s." % dest_dir)
|
||||
tarball = os.path.join(dest_dir, os.path.basename(URL))
|
||||
subprocess.check_call(['curl', '-L', URL, '-o', tarball])
|
||||
subprocess.check_call(['tar', '--no-same-owner', '--no-same-permissions',
|
||||
'-xf', tarball, '-C', dest_dir])
|
||||
os.remove(tarball)
|
||||
|
||||
readme = os.path.join(dest_dir, "README")
|
||||
with open(readme, 'w') as s:
|
||||
s.write("This directory and its contents are auto-generated.\n")
|
||||
s.write("It may be deleted and recreated. Do not modify.\n")
|
||||
s.write("Script: %s\n" % __file__)
|
||||
|
||||
with open(stamp, 'w') as s:
|
||||
s.write(URL)
|
||||
|
||||
for base, dirs, files in os.walk(dest_dir):
|
||||
for dir in dirs:
|
||||
os.chmod(os.path.join(base, dir), 0o755)
|
||||
for file in files:
|
||||
os.chmod(os.path.join(base, file), 0o644)
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
59
engine/src/build/linux/pkg-config-wrapper
Executable file
59
engine/src/build/linux/pkg-config-wrapper
Executable file
@@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
# This program wraps around pkg-config to generate the correct include and
|
||||
# library paths when cross-compiling using a sysroot.
|
||||
# The assumption is that the sysroot contains the .pc files in usr/lib/pkgconfig
|
||||
# and usr/share/pkgconfig (relative to the sysroot) and that they output paths
|
||||
# relative to some parent path of the sysroot.
|
||||
# This assumption is valid for a range of sysroots, in particular: a
|
||||
# LSB-compliant root filesystem mounted at the sysroot, and a board build
|
||||
# directory of a Chromium OS chroot.
|
||||
# Additional directories containing .pc files may be specified by setting
|
||||
# the PKG_CONFIG_PATH environment variable- these will be prepended to the
|
||||
# generated paths.
|
||||
|
||||
root="$1"
|
||||
shift
|
||||
target_arch="$1"
|
||||
shift
|
||||
libpath="$1"
|
||||
shift
|
||||
|
||||
if [ -z "$root" -o -z "$target_arch" ]
|
||||
then
|
||||
echo "usage: $0 /path/to/sysroot target_arch libdir [pkg-config-arguments] package" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$target_arch" = "x64" ]
|
||||
then
|
||||
: ${libpath:="lib64"}
|
||||
else
|
||||
: ${libpath:="lib"}
|
||||
fi
|
||||
|
||||
rewrite=`dirname $0`/rewrite_dirs.py
|
||||
package=${!#}
|
||||
|
||||
config_path=$root/usr/$libpath/pkgconfig:$root/usr/share/pkgconfig
|
||||
|
||||
# prepend any paths specified by the environment
|
||||
if [ -n "$PKG_CONFIG_PATH" ]
|
||||
then
|
||||
config_path="$PKG_CONFIG_PATH:$config_path"
|
||||
fi
|
||||
|
||||
set -e
|
||||
# Some sysroots, like the Chromium OS ones, may generate paths that are not
|
||||
# relative to the sysroot. For example,
|
||||
# /path/to/chroot/build/x86-generic/usr/lib/pkgconfig/pkg.pc may have all paths
|
||||
# relative to /path/to/chroot (i.e. prefix=/build/x86-generic/usr) instead of
|
||||
# relative to /path/to/chroot/build/x86-generic (i.e prefix=/usr).
|
||||
# To support this correctly, it's necessary to extract the prefix to strip from
|
||||
# pkg-config's |prefix| variable.
|
||||
prefix=`PKG_CONFIG_PATH=$config_path pkg-config --variable=prefix "$package" | sed -e 's|/usr$||'`
|
||||
result=`PKG_CONFIG_PATH=$config_path pkg-config "$@"`
|
||||
echo "$result"| $rewrite --sysroot "$root" --strip-prefix "$prefix"
|
||||
72
engine/src/build/linux/rewrite_dirs.py
Executable file
72
engine/src/build/linux/rewrite_dirs.py
Executable file
@@ -0,0 +1,72 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2011 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.
|
||||
|
||||
"""Rewrites paths in -I, -L and other option to be relative to a sysroot."""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import optparse
|
||||
|
||||
REWRITE_PREFIX = ['-I',
|
||||
'-idirafter',
|
||||
'-imacros',
|
||||
'-imultilib',
|
||||
'-include',
|
||||
'-iprefix',
|
||||
'-iquote',
|
||||
'-isystem',
|
||||
'-L']
|
||||
|
||||
def RewritePath(path, opts):
|
||||
"""Rewrites a path by stripping the prefix and prepending the sysroot."""
|
||||
sysroot = opts.sysroot
|
||||
prefix = opts.strip_prefix
|
||||
if os.path.isabs(path) and not path.startswith(sysroot):
|
||||
if path.startswith(prefix):
|
||||
path = path[len(prefix):]
|
||||
path = path.lstrip('/')
|
||||
return os.path.join(sysroot, path)
|
||||
else:
|
||||
return path
|
||||
|
||||
|
||||
def RewriteLine(line, opts):
|
||||
"""Rewrites all the paths in recognized options."""
|
||||
args = line.split()
|
||||
count = len(args)
|
||||
i = 0
|
||||
while i < count:
|
||||
for prefix in REWRITE_PREFIX:
|
||||
# The option can be either in the form "-I /path/to/dir" or
|
||||
# "-I/path/to/dir" so handle both.
|
||||
if args[i] == prefix:
|
||||
i += 1
|
||||
try:
|
||||
args[i] = RewritePath(args[i], opts)
|
||||
except IndexError:
|
||||
sys.stderr.write('Missing argument following %s\n' % prefix)
|
||||
break
|
||||
elif args[i].startswith(prefix):
|
||||
args[i] = prefix + RewritePath(args[i][len(prefix):], opts)
|
||||
i += 1
|
||||
|
||||
return ' '.join(args)
|
||||
|
||||
|
||||
def main(argv):
|
||||
parser = optparse.OptionParser()
|
||||
parser.add_option('-s', '--sysroot', default='/', help='sysroot to prepend')
|
||||
parser.add_option('-p', '--strip-prefix', default='', help='prefix to strip')
|
||||
opts, args = parser.parse_args(argv[1:])
|
||||
|
||||
for line in sys.stdin.readlines():
|
||||
line = RewriteLine(line.strip(), opts)
|
||||
print(line)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv))
|
||||
100
engine/src/build/linux/sysroot_ld_path.sh
Executable file
100
engine/src/build/linux/sysroot_ld_path.sh
Executable file
@@ -0,0 +1,100 @@
|
||||
#!/bin/sh
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# Reads etc/ld.so.conf and/or etc/ld.so.conf.d/*.conf and returns the
|
||||
# appropriate linker flags.
|
||||
#
|
||||
# sysroot_ld_path.sh /abspath/to/sysroot
|
||||
#
|
||||
|
||||
log_error_and_exit() {
|
||||
echo $0: $@
|
||||
exit 1
|
||||
}
|
||||
|
||||
process_entry() {
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
log_error_and_exit "bad arguments to process_entry()"
|
||||
fi
|
||||
local root="$1"
|
||||
local localpath="$2"
|
||||
|
||||
echo $localpath | grep -qs '^/'
|
||||
if [ $? -ne 0 ]; then
|
||||
log_error_and_exit $localpath does not start with /
|
||||
fi
|
||||
local entry="$root$localpath"
|
||||
echo -L$entry
|
||||
echo -Wl,-rpath-link=$entry
|
||||
}
|
||||
|
||||
process_ld_so_conf() {
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
log_error_and_exit "bad arguments to process_ld_so_conf()"
|
||||
fi
|
||||
local root="$1"
|
||||
local ld_so_conf="$2"
|
||||
|
||||
# ld.so.conf may include relative include paths. pushd is a bashism.
|
||||
local saved_pwd=$(pwd)
|
||||
cd $(dirname "$ld_so_conf")
|
||||
|
||||
cat "$ld_so_conf" | \
|
||||
while read ENTRY; do
|
||||
echo "$ENTRY" | grep -qs ^include
|
||||
if [ $? -eq 0 ]; then
|
||||
local included_files=$(echo "$ENTRY" | sed 's/^include //')
|
||||
echo "$included_files" | grep -qs ^/
|
||||
if [ $? -eq 0 ]; then
|
||||
if ls $root$included_files >/dev/null 2>&1 ; then
|
||||
for inc_file in $root$included_files; do
|
||||
process_ld_so_conf "$root" "$inc_file"
|
||||
done
|
||||
fi
|
||||
else
|
||||
if ls $(pwd)/$included_files >/dev/null 2>&1 ; then
|
||||
for inc_file in $(pwd)/$included_files; do
|
||||
process_ld_so_conf "$root" "$inc_file"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
echo "$ENTRY" | grep -qs ^/
|
||||
if [ $? -eq 0 ]; then
|
||||
process_entry "$root" "$ENTRY"
|
||||
fi
|
||||
done
|
||||
|
||||
# popd is a bashism
|
||||
cd "$saved_pwd"
|
||||
}
|
||||
|
||||
# Main
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo Usage $0 /abspath/to/sysroot
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo $1 | grep -qs ' '
|
||||
if [ $? -eq 0 ]; then
|
||||
log_error_and_exit $1 contains whitespace.
|
||||
fi
|
||||
|
||||
LD_SO_CONF="$1/etc/ld.so.conf"
|
||||
LD_SO_CONF_D="$1/etc/ld.so.conf.d"
|
||||
|
||||
if [ -e "$LD_SO_CONF" ]; then
|
||||
process_ld_so_conf "$1" "$LD_SO_CONF" | xargs echo
|
||||
elif [ -e "$LD_SO_CONF_D" ]; then
|
||||
find "$LD_SO_CONF_D" -maxdepth 1 -name '*.conf' -print -quit > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
for entry in $LD_SO_CONF_D/*.conf; do
|
||||
process_ld_so_conf "$1" "$entry"
|
||||
done | xargs echo
|
||||
fi
|
||||
fi
|
||||
166
engine/src/build/linux/sysroot_scripts/install-sysroot.py
Executable file
166
engine/src/build/linux/sysroot_scripts/install-sysroot.py
Executable file
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
"""Install Debian sysroots for building chromium.
|
||||
"""
|
||||
|
||||
# The sysroot is needed to ensure that binaries that get built will run on
|
||||
# the oldest stable version of Debian that we currently support.
|
||||
# This script can be run manually but is more often run as part of gclient
|
||||
# hooks. When run from hooks this script is a no-op on non-linux platforms.
|
||||
|
||||
# The sysroot image could be constructed from scratch based on the current state
|
||||
# of the Debian archive but for consistency we use a pre-built root image (we
|
||||
# don't want upstream changes to Debian to effect the chromium build until we
|
||||
# choose to pull them in). The images will normally need to be rebuilt every
|
||||
# time chrome's build dependencies are changed but should also be updated
|
||||
# periodically to include upstream security fixes from Debian.
|
||||
|
||||
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import platform
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
try:
|
||||
# For Python 3.0 and later
|
||||
from urllib.request import urlopen
|
||||
except ImportError:
|
||||
# Fall back to Python 2's urllib2
|
||||
from urllib.request import urlopen
|
||||
|
||||
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
URL_PREFIX = 'https://commondatastorage.googleapis.com'
|
||||
URL_PATH = 'chrome-linux-sysroot/toolchain'
|
||||
|
||||
VALID_ARCHS = ('arm', 'arm64', 'i386', 'amd64')
|
||||
|
||||
ARCH_TRANSLATIONS = {
|
||||
'x64': 'amd64',
|
||||
'x86': 'i386',
|
||||
}
|
||||
|
||||
DEFAULT_TARGET_PLATFORM = 'sid'
|
||||
|
||||
class Error(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def GetSha1(filename):
|
||||
sha1 = hashlib.sha1()
|
||||
with open(filename, 'rb') as f:
|
||||
while True:
|
||||
# Read in 1mb chunks, so it doesn't all have to be loaded into memory.
|
||||
chunk = f.read(1024*1024)
|
||||
if not chunk:
|
||||
break
|
||||
sha1.update(chunk)
|
||||
return sha1.hexdigest()
|
||||
|
||||
|
||||
def main(args):
|
||||
parser = optparse.OptionParser('usage: %prog [OPTIONS]', description=__doc__)
|
||||
parser.add_option('--arch',
|
||||
help='Sysroot architecture: %s' % ', '.join(VALID_ARCHS))
|
||||
parser.add_option('--all', action='store_true',
|
||||
help='Install all sysroot images (useful when updating the'
|
||||
' images)')
|
||||
parser.add_option('--print-hash',
|
||||
help='Print the hash of the sysroot for the given arch.')
|
||||
options, _ = parser.parse_args(args)
|
||||
if not sys.platform.startswith('linux'):
|
||||
return 0
|
||||
|
||||
if options.print_hash:
|
||||
arch = options.print_hash
|
||||
print(GetSysrootDict(DEFAULT_TARGET_PLATFORM,
|
||||
ARCH_TRANSLATIONS.get(arch, arch))['Sha1Sum'])
|
||||
return 0
|
||||
if options.arch:
|
||||
InstallSysroot(DEFAULT_TARGET_PLATFORM,
|
||||
ARCH_TRANSLATIONS.get(options.arch, options.arch))
|
||||
elif options.all:
|
||||
for arch in VALID_ARCHS:
|
||||
InstallSysroot(DEFAULT_TARGET_PLATFORM, arch)
|
||||
else:
|
||||
print('You much specify one of the options.')
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
def GetSysrootDict(target_platform, target_arch):
|
||||
if target_arch not in VALID_ARCHS:
|
||||
raise Error('Unknown architecture: %s' % target_arch)
|
||||
|
||||
sysroots_file = os.path.join(SCRIPT_DIR, 'sysroots.json')
|
||||
sysroots = json.load(open(sysroots_file))
|
||||
sysroot_key = '%s_%s' % (target_platform, target_arch)
|
||||
if sysroot_key not in sysroots:
|
||||
raise Error('No sysroot for: %s %s' % (target_platform, target_arch))
|
||||
return sysroots[sysroot_key]
|
||||
|
||||
|
||||
def InstallSysroot(target_platform, target_arch):
|
||||
sysroot_dict = GetSysrootDict(target_platform, target_arch)
|
||||
tarball_filename = sysroot_dict['Tarball']
|
||||
tarball_sha1sum = sysroot_dict['Sha1Sum']
|
||||
# TODO(thestig) Consider putting this elsewhere to avoid having to recreate
|
||||
# it on every build.
|
||||
linux_dir = os.path.dirname(SCRIPT_DIR)
|
||||
sysroot = os.path.join(linux_dir, sysroot_dict['SysrootDir'])
|
||||
|
||||
url = '%s/%s/%s/%s' % (URL_PREFIX, URL_PATH, tarball_sha1sum,
|
||||
tarball_filename)
|
||||
|
||||
stamp = os.path.join(sysroot, '.stamp')
|
||||
if os.path.exists(stamp):
|
||||
with open(stamp) as s:
|
||||
if s.read() == url:
|
||||
return
|
||||
|
||||
print('Installing Debian %s %s root image: %s' % \
|
||||
(target_platform, target_arch, sysroot))
|
||||
if os.path.isdir(sysroot):
|
||||
shutil.rmtree(sysroot)
|
||||
os.mkdir(sysroot)
|
||||
tarball = os.path.join(sysroot, tarball_filename)
|
||||
print('Downloading %s' % url)
|
||||
sys.stdout.flush()
|
||||
sys.stderr.flush()
|
||||
for _ in range(3):
|
||||
try:
|
||||
response = urlopen(url)
|
||||
with open(tarball, "wb") as f:
|
||||
f.write(response.read())
|
||||
break
|
||||
except Exception: # Ignore exceptions.
|
||||
pass
|
||||
else:
|
||||
raise Error('Failed to download %s' % url)
|
||||
sha1sum = GetSha1(tarball)
|
||||
if sha1sum != tarball_sha1sum:
|
||||
raise Error('Tarball sha1sum is wrong.'
|
||||
'Expected %s, actual: %s' % (tarball_sha1sum, sha1sum))
|
||||
subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot])
|
||||
os.remove(tarball)
|
||||
|
||||
with open(stamp, 'w') as s:
|
||||
s.write(url)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
sys.exit(main(sys.argv[1:]))
|
||||
except Error as e:
|
||||
sys.stderr.write(str(e) + '\n')
|
||||
sys.exit(1)
|
||||
27
engine/src/build/linux/sysroot_scripts/sysroots.json
Normal file
27
engine/src/build/linux/sysroot_scripts/sysroots.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"sid_amd64": {
|
||||
"Sha1Sum": "79a7783607a69b6f439add567eb6fcb48877085c",
|
||||
"SysrootDir": "debian_sid_amd64-sysroot",
|
||||
"Tarball": "debian_sid_amd64_sysroot.tar.xz"
|
||||
},
|
||||
"sid_arm": {
|
||||
"Sha1Sum": "3fcc1d4e44127006318371002a0f421a4fde2ab4",
|
||||
"SysrootDir": "debian_sid_arm-sysroot",
|
||||
"Tarball": "debian_sid_arm_sysroot.tar.xz"
|
||||
},
|
||||
"sid_arm64": {
|
||||
"Sha1Sum": "2cade9ee1ca9186b28ac768c19e1ab7c45ee0600",
|
||||
"SysrootDir": "debian_sid_arm64-sysroot",
|
||||
"Tarball": "debian_sid_arm64_sysroot.tar.xz"
|
||||
},
|
||||
"sid_armel": {
|
||||
"Sha1Sum": "72aecf0a5603919b41cfb0766fe511c34933e915",
|
||||
"SysrootDir": "debian_sid_armel-sysroot",
|
||||
"Tarball": "debian_sid_armel_sysroot.tar.xz"
|
||||
},
|
||||
"sid_i386": {
|
||||
"Sha1Sum": "e954fb79fcddf64bc39d721c9a5b652b6da549fa",
|
||||
"SysrootDir": "debian_sid_i386-sysroot",
|
||||
"Tarball": "debian_sid_i386_sysroot.tar.xz"
|
||||
}
|
||||
}
|
||||
39
engine/src/build/ls.py
Executable file
39
engine/src/build/ls.py
Executable file
@@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2015 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.
|
||||
|
||||
"""Recursively list files of the target directory. Ignores dot files."""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
def main(target_directory, file_extension):
|
||||
for root, dirs, files in os.walk(target_directory):
|
||||
files = [f for f in files if not f[0] == '.']
|
||||
dirs[:] = [d for d in dirs if not d[0] == '.']
|
||||
for f in files:
|
||||
if file_extension is None or os.path.splitext(f)[-1] == file_extension:
|
||||
path = os.path.join(root, f)
|
||||
print(path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Recursively list files of the target directory")
|
||||
parser.add_argument("--target-directory",
|
||||
dest="target_directory",
|
||||
metavar="<target-directory>",
|
||||
type=str,
|
||||
required=True,
|
||||
help="The target directory")
|
||||
parser.add_argument("--file-extension",
|
||||
dest="file_extension",
|
||||
metavar="<file-extension>",
|
||||
type=str,
|
||||
required=False,
|
||||
help="File extension to filter")
|
||||
|
||||
args = parser.parse_args()
|
||||
sys.exit(main(args.target_directory, args.file_extension))
|
||||
270
engine/src/build/mac/change_mach_o_flags.py
Executable file
270
engine/src/build/mac/change_mach_o_flags.py
Executable file
@@ -0,0 +1,270 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2011 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.
|
||||
|
||||
"""Usage: change_mach_o_flags.py [--executable-heap] [--no-pie] <executablepath>
|
||||
|
||||
Arranges for the executable at |executable_path| to have its data (heap)
|
||||
pages protected to prevent execution on Mac OS X 10.7 ("Lion"), and to have
|
||||
the PIE (position independent executable) bit set to enable ASLR (address
|
||||
space layout randomization). With --executable-heap or --no-pie, the
|
||||
respective bits are cleared instead of set, making the heap executable or
|
||||
disabling PIE/ASLR.
|
||||
|
||||
This script is able to operate on thin (single-architecture) Mach-O files
|
||||
and fat (universal, multi-architecture) files. When operating on fat files,
|
||||
it will set or clear the bits for each architecture contained therein.
|
||||
|
||||
NON-EXECUTABLE HEAP
|
||||
|
||||
Traditionally in Mac OS X, 32-bit processes did not have data pages set to
|
||||
prohibit execution. Although user programs could call mprotect and
|
||||
mach_vm_protect to deny execution of code in data pages, the kernel would
|
||||
silently ignore such requests without updating the page tables, and the
|
||||
hardware would happily execute code on such pages. 64-bit processes were
|
||||
always given proper hardware protection of data pages. This behavior was
|
||||
controllable on a system-wide level via the vm.allow_data_exec sysctl, which
|
||||
is set by default to 1. The bit with value 1 (set by default) allows code
|
||||
execution on data pages for 32-bit processes, and the bit with value 2
|
||||
(clear by default) does the same for 64-bit processes.
|
||||
|
||||
In Mac OS X 10.7, executables can "opt in" to having hardware protection
|
||||
against code execution on data pages applied. This is done by setting a new
|
||||
bit in the |flags| field of an executable's |mach_header|. When
|
||||
MH_NO_HEAP_EXECUTION is set, proper protections will be applied, regardless
|
||||
of the setting of vm.allow_data_exec. See xnu-1699.22.73/osfmk/vm/vm_map.c
|
||||
override_nx and xnu-1699.22.73/bsd/kern/mach_loader.c load_machfile.
|
||||
|
||||
The Apple toolchain has been revised to set the MH_NO_HEAP_EXECUTION when
|
||||
producing executables, provided that -allow_heap_execute is not specified
|
||||
at link time. Only linkers shipping with Xcode 4.0 and later (ld64-123.2 and
|
||||
later) have this ability. See ld64-123.2.1/src/ld/Options.cpp
|
||||
Options::reconfigureDefaults() and
|
||||
ld64-123.2.1/src/ld/HeaderAndLoadCommands.hpp
|
||||
HeaderAndLoadCommandsAtom<A>::flags().
|
||||
|
||||
This script sets the MH_NO_HEAP_EXECUTION bit on Mach-O executables. It is
|
||||
intended for use with executables produced by a linker that predates Apple's
|
||||
modifications to set this bit itself. It is also useful for setting this bit
|
||||
for non-i386 executables, including x86_64 executables. Apple's linker only
|
||||
sets it for 32-bit i386 executables, presumably under the assumption that
|
||||
the value of vm.allow_data_exec is set in stone. However, if someone were to
|
||||
change vm.allow_data_exec to 2 or 3, 64-bit x86_64 executables would run
|
||||
without hardware protection against code execution on data pages. This
|
||||
script can set the bit for x86_64 executables, guaranteeing that they run
|
||||
with appropriate protection even when vm.allow_data_exec has been tampered
|
||||
with.
|
||||
|
||||
POSITION-INDEPENDENT EXECUTABLES/ADDRESS SPACE LAYOUT RANDOMIZATION
|
||||
|
||||
This script sets or clears the MH_PIE bit in an executable's Mach-O header,
|
||||
enabling or disabling position independence on Mac OS X 10.5 and later.
|
||||
Processes running position-independent executables have varying levels of
|
||||
ASLR protection depending on the OS release. The main executable's load
|
||||
address, shared library load addresess, and the heap and stack base
|
||||
addresses may be randomized. Position-independent executables are produced
|
||||
by supplying the -pie flag to the linker (or defeated by supplying -no_pie).
|
||||
Executables linked with a deployment target of 10.7 or higher have PIE on
|
||||
by default.
|
||||
|
||||
This script is never strictly needed during the build to enable PIE, as all
|
||||
linkers used are recent enough to support -pie. However, it's used to
|
||||
disable the PIE bit as needed on already-linked executables.
|
||||
"""
|
||||
|
||||
import optparse
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
|
||||
|
||||
# <mach-o/fat.h>
|
||||
FAT_MAGIC = 0xcafebabe
|
||||
FAT_CIGAM = 0xbebafeca
|
||||
|
||||
# <mach-o/loader.h>
|
||||
MH_MAGIC = 0xfeedface
|
||||
MH_CIGAM = 0xcefaedfe
|
||||
MH_MAGIC_64 = 0xfeedfacf
|
||||
MH_CIGAM_64 = 0xcffaedfe
|
||||
MH_EXECUTE = 0x2
|
||||
MH_PIE = 0x00200000
|
||||
MH_NO_HEAP_EXECUTION = 0x01000000
|
||||
|
||||
|
||||
class MachOError(Exception):
|
||||
"""A class for exceptions thrown by this module."""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def CheckedSeek(file, offset):
|
||||
"""Seeks the file-like object at |file| to offset |offset| and raises a
|
||||
MachOError if anything funny happens."""
|
||||
|
||||
file.seek(offset, os.SEEK_SET)
|
||||
new_offset = file.tell()
|
||||
if new_offset != offset:
|
||||
raise MachOError('seek: expected offset %d, observed %d' % (offset, new_offset))
|
||||
|
||||
|
||||
def CheckedRead(file, count):
|
||||
"""Reads |count| bytes from the file-like |file| object, raising a
|
||||
MachOError if any other number of bytes is read."""
|
||||
|
||||
bytes = file.read(count)
|
||||
if len(bytes) != count:
|
||||
raise MachOError('read: expected length %d, observed %d' % (count, len(bytes)))
|
||||
|
||||
return bytes
|
||||
|
||||
|
||||
def ReadUInt32(file, endian):
|
||||
"""Reads an unsinged 32-bit integer from the file-like |file| object,
|
||||
treating it as having endianness specified by |endian| (per the |struct|
|
||||
module), and returns it as a number. Raises a MachOError if the proper
|
||||
length of data can't be read from |file|."""
|
||||
|
||||
bytes = CheckedRead(file, 4)
|
||||
|
||||
(uint32,) = struct.unpack(endian + 'I', bytes)
|
||||
return uint32
|
||||
|
||||
|
||||
def ReadMachHeader(file, endian):
|
||||
"""Reads an entire |mach_header| structure (<mach-o/loader.h>) from the
|
||||
file-like |file| object, treating it as having endianness specified by
|
||||
|endian| (per the |struct| module), and returns a 7-tuple of its members
|
||||
as numbers. Raises a MachOError if the proper length of data can't be read
|
||||
from |file|."""
|
||||
|
||||
bytes = CheckedRead(file, 28)
|
||||
|
||||
magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = \
|
||||
struct.unpack(endian + '7I', bytes)
|
||||
return magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags
|
||||
|
||||
|
||||
def ReadFatArch(file):
|
||||
"""Reads an entire |fat_arch| structure (<mach-o/fat.h>) from the file-like
|
||||
|file| object, treating it as having endianness specified by |endian|
|
||||
(per the |struct| module), and returns a 5-tuple of its members as numbers.
|
||||
Raises a MachOError if the proper length of data can't be read from
|
||||
|file|."""
|
||||
|
||||
bytes = CheckedRead(file, 20)
|
||||
|
||||
cputype, cpusubtype, offset, size, align = struct.unpack('>5I', bytes)
|
||||
return cputype, cpusubtype, offset, size, align
|
||||
|
||||
|
||||
def WriteUInt32(file, uint32, endian):
|
||||
"""Writes |uint32| as an unsinged 32-bit integer to the file-like |file|
|
||||
object, treating it as having endianness specified by |endian| (per the
|
||||
|struct| module)."""
|
||||
|
||||
bytes = struct.pack(endian + 'I', uint32)
|
||||
assert len(bytes) == 4
|
||||
|
||||
file.write(bytes)
|
||||
|
||||
|
||||
def HandleMachOFile(file, options, offset=0):
|
||||
"""Seeks the file-like |file| object to |offset|, reads its |mach_header|,
|
||||
and rewrites the header's |flags| field if appropriate. The header's
|
||||
endianness is detected. Both 32-bit and 64-bit Mach-O headers are supported
|
||||
(mach_header and mach_header_64). Raises MachOError if used on a header that
|
||||
does not have a known magic number or is not of type MH_EXECUTE. The
|
||||
MH_PIE and MH_NO_HEAP_EXECUTION bits are set or cleared in the |flags| field
|
||||
according to |options| and written to |file| if any changes need to be made.
|
||||
If already set or clear as specified by |options|, nothing is written."""
|
||||
|
||||
CheckedSeek(file, offset)
|
||||
magic = ReadUInt32(file, '<')
|
||||
if magic == MH_MAGIC or magic == MH_MAGIC_64:
|
||||
endian = '<'
|
||||
elif magic == MH_CIGAM or magic == MH_CIGAM_64:
|
||||
endian = '>'
|
||||
else:
|
||||
raise MachOError('Mach-O file at offset %d has illusion of magic' % offset)
|
||||
|
||||
CheckedSeek(file, offset)
|
||||
magic, cputype, cpusubtype, filetype, ncmds, sizeofcmds, flags = \
|
||||
ReadMachHeader(file, endian)
|
||||
assert magic == MH_MAGIC or magic == MH_MAGIC_64
|
||||
if filetype != MH_EXECUTE:
|
||||
raise MachOError('Mach-O file at offset %d is type 0x%x, expected MH_EXECUTE' % \
|
||||
(offset, filetype))
|
||||
|
||||
original_flags = flags
|
||||
|
||||
if options.no_heap_execution:
|
||||
flags |= MH_NO_HEAP_EXECUTION
|
||||
else:
|
||||
flags &= ~MH_NO_HEAP_EXECUTION
|
||||
|
||||
if options.pie:
|
||||
flags |= MH_PIE
|
||||
else:
|
||||
flags &= ~MH_PIE
|
||||
|
||||
if flags != original_flags:
|
||||
CheckedSeek(file, offset + 24)
|
||||
WriteUInt32(file, flags, endian)
|
||||
|
||||
|
||||
def HandleFatFile(file, options, fat_offset=0):
|
||||
"""Seeks the file-like |file| object to |offset| and loops over its
|
||||
|fat_header| entries, calling HandleMachOFile for each."""
|
||||
|
||||
CheckedSeek(file, fat_offset)
|
||||
magic = ReadUInt32(file, '>')
|
||||
assert magic == FAT_MAGIC
|
||||
|
||||
nfat_arch = ReadUInt32(file, '>')
|
||||
|
||||
for index in range(0, nfat_arch):
|
||||
cputype, cpusubtype, offset, size, align = ReadFatArch(file)
|
||||
assert size >= 28
|
||||
|
||||
# HandleMachOFile will seek around. Come back here after calling it, in
|
||||
# case it sought.
|
||||
fat_arch_offset = file.tell()
|
||||
HandleMachOFile(file, options, offset)
|
||||
CheckedSeek(file, fat_arch_offset)
|
||||
|
||||
|
||||
def main(me, args):
|
||||
parser = optparse.OptionParser('%prog [options] <executable_path>')
|
||||
parser.add_option('--executable-heap', action='store_false',
|
||||
dest='no_heap_execution', default=True,
|
||||
help='Clear the MH_NO_HEAP_EXECUTION bit')
|
||||
parser.add_option('--no-pie', action='store_false',
|
||||
dest='pie', default=True,
|
||||
help='Clear the MH_PIE bit')
|
||||
(options, loose_args) = parser.parse_args(args)
|
||||
if len(loose_args) != 1:
|
||||
parser.print_usage()
|
||||
return 1
|
||||
|
||||
executable_path = loose_args[0]
|
||||
executable_file = open(executable_path, 'rb+')
|
||||
|
||||
magic = ReadUInt32(executable_file, '<')
|
||||
if magic == FAT_CIGAM:
|
||||
# Check FAT_CIGAM and not FAT_MAGIC because the read was little-endian.
|
||||
HandleFatFile(executable_file, options)
|
||||
elif magic == MH_MAGIC or magic == MH_CIGAM or \
|
||||
magic == MH_MAGIC_64 or magic == MH_CIGAM_64:
|
||||
HandleMachOFile(executable_file, options)
|
||||
else:
|
||||
raise MachOError('%s is not a Mach-O or fat file' % executable_file)
|
||||
|
||||
executable_file.close()
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main(sys.argv[0], sys.argv[1:]))
|
||||
15
engine/src/build/mac/change_mach_o_flags_from_xcode.sh
Executable file
15
engine/src/build/mac/change_mach_o_flags_from_xcode.sh
Executable file
@@ -0,0 +1,15 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2011 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.
|
||||
|
||||
# This is a small wrapper script around change_mach_o_flags.py allowing it to
|
||||
# be invoked easily from Xcode. change_mach_o_flags.py expects its arguments
|
||||
# on the command line, but Xcode puts its parameters in the environment.
|
||||
|
||||
set -e
|
||||
|
||||
exec "$(dirname "${0}")/change_mach_o_flags.py" \
|
||||
"${@}" \
|
||||
"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"
|
||||
36
engine/src/build/mac/chrome_mac.croc
Normal file
36
engine/src/build/mac/chrome_mac.croc
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- python -*-
|
||||
# Crocodile config file for Chromium mac
|
||||
|
||||
{
|
||||
# List of rules, applied in order
|
||||
'rules' : [
|
||||
# Specify inclusions before exclusions, since rules are in order.
|
||||
|
||||
# Don't include chromeos, linux, or windows specific files
|
||||
{
|
||||
'regexp' : '.*(_|/)(chromeos|linux|win|views)(\\.|_)',
|
||||
'include' : 0,
|
||||
},
|
||||
# Don't include ChromeOS dirs
|
||||
{
|
||||
'regexp' : '.*/chromeos/',
|
||||
'include' : 0,
|
||||
},
|
||||
|
||||
# Groups
|
||||
{
|
||||
'regexp' : '.*_test_mac\\.',
|
||||
'group' : 'test',
|
||||
},
|
||||
|
||||
# Languages
|
||||
{
|
||||
'regexp' : '.*\\.m$',
|
||||
'language' : 'ObjC',
|
||||
},
|
||||
{
|
||||
'regexp' : '.*\\.mm$',
|
||||
'language' : 'ObjC++',
|
||||
},
|
||||
],
|
||||
}
|
||||
76
engine/src/build/mac/copy_asan_runtime_dylib.sh
Executable file
76
engine/src/build/mac/copy_asan_runtime_dylib.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2013 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.
|
||||
|
||||
# For app bundles built with ASan, copies the runtime lib
|
||||
# (libclang_rt.asan_osx_dynamic.dylib), on which their executables depend, from
|
||||
# the compiler installation path into the bundle and fixes the dylib's install
|
||||
# name in the binary to be relative to @executable_path.
|
||||
|
||||
set -e
|
||||
|
||||
BINARY="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"
|
||||
|
||||
if [[ ! -f "$BINARY" ]]; then
|
||||
# This is neither an .app bundle nor a standalone executable.
|
||||
# Most certainly the script has been called for a data bundle.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
BINARY_DIR="$(dirname "${BINARY}")"
|
||||
|
||||
# Find the link to the ASan runtime encoded in the binary.
|
||||
BUILTIN_DYLIB_PATH=$(otool -L "${BINARY}" | \
|
||||
sed -Ene 's/^[[:blank:]]+(.*libclang_rt\.asan_.*_dynamic\.dylib).*$/\1/p')
|
||||
|
||||
if [[ "${BUILTIN_DYLIB_PATH}" == *asan_iossim_dynamic* ]]; then
|
||||
ASAN_DYLIB_NAME=libclang_rt.asan_iossim_dynamic.dylib
|
||||
elif [[ "${BUILTIN_DYLIB_PATH}" == *asan_osx_dynamic* ]]; then
|
||||
ASAN_DYLIB_NAME=libclang_rt.asan_osx_dynamic.dylib
|
||||
fi
|
||||
|
||||
if [[ -z "${BUILTIN_DYLIB_PATH}" ]]; then
|
||||
echo "${BINARY} does not depend on the ASan runtime library!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO(glider): this doesn't work if we set CC and CXX to override the default
|
||||
# Clang.
|
||||
ASAN_DYLIB=$(find \
|
||||
"${BUILT_PRODUCTS_DIR}/../../third_party/llvm-build/Release+Asserts/lib/clang/" \
|
||||
-type f -path "*${ASAN_DYLIB_NAME}")
|
||||
|
||||
DYLIB_BASENAME=$(basename "${ASAN_DYLIB}")
|
||||
if [[ "${DYLIB_BASENAME}" != "${ASAN_DYLIB_NAME}" ]]; then
|
||||
echo "basename(${ASAN_DYLIB}) != ${ASAN_DYLIB_NAME}" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check whether the directory containing the executable binary is named
|
||||
# "MacOS". In this case we're building a full-fledged OSX app and will put
|
||||
# the runtime into appname.app/Contents/Libraries/. Otherwise this is probably
|
||||
# an iOS gtest app, and the ASan runtime is put next to the executable.
|
||||
UPPER_DIR=$(dirname "${BINARY_DIR}")
|
||||
if [ "${UPPER_DIR}" == "MacOS" ]; then
|
||||
LIBRARIES_DIR="${UPPER_DIR}/Libraries"
|
||||
mkdir -p "${LIBRARIES_DIR}"
|
||||
NEW_LC_ID_DYLIB="@executable_path/../Libraries/${ASAN_DYLIB_NAME}"
|
||||
else
|
||||
LIBRARIES_DIR="${BINARY_DIR}"
|
||||
NEW_LC_ID_DYLIB="@executable_path/${ASAN_DYLIB_NAME}"
|
||||
fi
|
||||
|
||||
cp "${ASAN_DYLIB}" "${LIBRARIES_DIR}"
|
||||
|
||||
# Make LC_ID_DYLIB of the runtime copy point to its location.
|
||||
install_name_tool \
|
||||
-id "${NEW_LC_ID_DYLIB}" \
|
||||
"${LIBRARIES_DIR}/${ASAN_DYLIB_NAME}"
|
||||
|
||||
# Fix the rpath to the runtime library recorded in the binary.
|
||||
install_name_tool \
|
||||
-change "${BUILTIN_DYLIB_PATH}" \
|
||||
"${NEW_LC_ID_DYLIB}" \
|
||||
"${BINARY}"
|
||||
118
engine/src/build/mac/copy_framework_unversioned.sh
Executable file
118
engine/src/build/mac/copy_framework_unversioned.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
# Copies a framework to its new home, "unversioning" it.
|
||||
#
|
||||
# Normally, frameworks are versioned bundles. The contents of a framework are
|
||||
# stored in a versioned directory within the bundle, and symbolic links
|
||||
# provide access to the actual code and resources. See
|
||||
# http://developer.apple.com/mac/library/documentation/MacOSX/Conceptual/BPFrameworks/Concepts/FrameworkAnatomy.html
|
||||
#
|
||||
# The symbolic links usually found in frameworks create problems. Symbolic
|
||||
# links are excluded from code signatures. That means that it's possible to
|
||||
# remove or retarget a symbolic link within a framework without affecting the
|
||||
# seal. In Chrome's case, the outer .app bundle contains a framework where
|
||||
# all application code and resources live. In order for the signature on the
|
||||
# .app to be meaningful, it encompasses the framework. Because framework
|
||||
# resources are accessed through the framework's symbolic links, this
|
||||
# arrangement results in a case where the resources can be altered without
|
||||
# affecting the .app signature's validity.
|
||||
#
|
||||
# Indirection through symbolic links also carries a runtime performance
|
||||
# penalty on open() operations, although open() typically completes so quickly
|
||||
# that this is not considered a major performance problem.
|
||||
#
|
||||
# To resolve these problems, the frameworks that ship within Chrome's .app
|
||||
# bundle are unversioned. Unversioning is simple: instead of using the
|
||||
# original outer .framework directory as the framework that ships within the
|
||||
# .app, the inner versioned directory is used. Instead of accessing bundled
|
||||
# resources through symbolic links, they are accessed directly. In normal
|
||||
# situations, the only hard-coded use of the versioned directory is by dyld,
|
||||
# when loading the framework's code, but this is handled through a normal
|
||||
# Mach-O load command, and it is easy to adjust the load command to point to
|
||||
# the unversioned framework code rather than the versioned counterpart.
|
||||
#
|
||||
# The resulting framework bundles aren't strictly conforming, but they work
|
||||
# as well as normal versioned framework bundles.
|
||||
#
|
||||
# An option to skip running install_name_tool is available. By passing -I as
|
||||
# the first argument to this script, install_name_tool will be skipped. This
|
||||
# is only suitable for copied frameworks that will not be linked against, or
|
||||
# when install_name_tool will be run on any linker output when something is
|
||||
# linked against the copied framework. This option exists to allow signed
|
||||
# frameworks to pass through without subjecting them to any modifications that
|
||||
# would break their signatures.
|
||||
|
||||
set -e
|
||||
|
||||
RUN_INSTALL_NAME_TOOL=1
|
||||
if [ $# -eq 3 ] && [ "${1}" = "-I" ] ; then
|
||||
shift
|
||||
RUN_INSTALL_NAME_TOOL=
|
||||
fi
|
||||
|
||||
if [ $# -ne 2 ] ; then
|
||||
echo "usage: ${0} [-I] FRAMEWORK DESTINATION_DIR" >& 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# FRAMEWORK should be a path to a versioned framework bundle, ending in
|
||||
# .framework. DESTINATION_DIR is the directory that the unversioned framework
|
||||
# bundle will be copied to.
|
||||
|
||||
FRAMEWORK="${1}"
|
||||
DESTINATION_DIR="${2}"
|
||||
|
||||
FRAMEWORK_NAME="$(basename "${FRAMEWORK}")"
|
||||
if [ "${FRAMEWORK_NAME: -10}" != ".framework" ] ; then
|
||||
echo "${0}: ${FRAMEWORK_NAME} does not end in .framework" >& 2
|
||||
exit 1
|
||||
fi
|
||||
FRAMEWORK_NAME_NOEXT="${FRAMEWORK_NAME:0:$((${#FRAMEWORK_NAME} - 10))}"
|
||||
|
||||
# Find the current version.
|
||||
VERSIONS="${FRAMEWORK}/Versions"
|
||||
CURRENT_VERSION_LINK="${VERSIONS}/Current"
|
||||
CURRENT_VERSION_ID="$(readlink "${VERSIONS}/Current")"
|
||||
CURRENT_VERSION="${VERSIONS}/${CURRENT_VERSION_ID}"
|
||||
|
||||
# Make sure that the framework's structure makes sense as a versioned bundle.
|
||||
if [ ! -e "${CURRENT_VERSION}/${FRAMEWORK_NAME_NOEXT}" ] ; then
|
||||
echo "${0}: ${FRAMEWORK_NAME} does not contain a dylib" >& 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DESTINATION="${DESTINATION_DIR}/${FRAMEWORK_NAME}"
|
||||
|
||||
# Copy the versioned directory within the versioned framework to its
|
||||
# destination location.
|
||||
mkdir -p "${DESTINATION_DIR}"
|
||||
rsync -acC --delete --exclude Headers --exclude PrivateHeaders \
|
||||
--include '*.so' "${CURRENT_VERSION}/" "${DESTINATION}"
|
||||
|
||||
if [[ -n "${RUN_INSTALL_NAME_TOOL}" ]]; then
|
||||
# Adjust the Mach-O LC_ID_DYLIB load command in the framework. This does not
|
||||
# change the LC_LOAD_DYLIB load commands in anything that may have already
|
||||
# linked against the framework. Not all frameworks will actually need this
|
||||
# to be changed. Some frameworks may already be built with the proper
|
||||
# LC_ID_DYLIB for use as an unversioned framework. Xcode users can do this
|
||||
# by setting LD_DYLIB_INSTALL_NAME to
|
||||
# $(DYLIB_INSTALL_NAME_BASE:standardizepath)/$(WRAPPER_NAME)/$(PRODUCT_NAME)
|
||||
# If invoking ld via gcc or g++, pass the desired path to -Wl,-install_name
|
||||
# at link time.
|
||||
FRAMEWORK_DYLIB="${DESTINATION}/${FRAMEWORK_NAME_NOEXT}"
|
||||
LC_ID_DYLIB_OLD="$(otool -l "${FRAMEWORK_DYLIB}" |
|
||||
grep -A10 "^ *cmd LC_ID_DYLIB$" |
|
||||
grep -m1 "^ *name" |
|
||||
sed -Ee 's/^ *name (.*) \(offset [0-9]+\)$/\1/')"
|
||||
VERSION_PATH="/Versions/${CURRENT_VERSION_ID}/${FRAMEWORK_NAME_NOEXT}"
|
||||
LC_ID_DYLIB_NEW="$(echo "${LC_ID_DYLIB_OLD}" |
|
||||
sed -Ee "s%${VERSION_PATH}$%/${FRAMEWORK_NAME_NOEXT}%")"
|
||||
|
||||
if [ "${LC_ID_DYLIB_NEW}" != "${LC_ID_DYLIB_OLD}" ] ; then
|
||||
install_name_tool -id "${LC_ID_DYLIB_NEW}" "${FRAMEWORK_DYLIB}"
|
||||
fi
|
||||
fi
|
||||
19
engine/src/build/mac/edit_xibs.sh
Executable file
19
engine/src/build/mac/edit_xibs.sh
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
# This script is a convenience to run GYP for /src/chrome/chrome_nibs.gyp
|
||||
# with the Xcode generator (as you likely use ninja). Documentation:
|
||||
# http://dev.chromium.org/developers/design-documents/mac-xib-files
|
||||
|
||||
set -e
|
||||
|
||||
RELSRC=$(dirname "$0")/../..
|
||||
SRC=$(cd "$RELSRC" && pwd)
|
||||
export PYTHONPATH="$PYTHONPATH:$SRC/build"
|
||||
export GYP_GENERATORS=xcode
|
||||
"$SRC/tools/gyp/gyp" -I"$SRC/build/common.gypi" "$SRC/chrome/chrome_nibs.gyp"
|
||||
echo "You can now edit XIB files in Xcode using:"
|
||||
echo " $SRC/chrome/chrome_nibs.xcodeproj"
|
||||
116
engine/src/build/mac/find_sdk.py
Executable file
116
engine/src/build/mac/find_sdk.py
Executable file
@@ -0,0 +1,116 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
"""Prints the lowest locally available SDK version greater than or equal to a
|
||||
given minimum sdk version to standard output.
|
||||
|
||||
Usage:
|
||||
python find_sdk.py 10.6 # Ignores SDKs < 10.6
|
||||
"""
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
sys.path.append(os.path.dirname(os.path.dirname(__file__)))
|
||||
from pyutil.file_util import symlink
|
||||
|
||||
PREBUILTS = os.path.realpath(os.path.join(
|
||||
os.path.dirname(__file__), os.pardir, os.pardir, 'flutter', 'prebuilts',
|
||||
))
|
||||
|
||||
def parse_version(version_str):
|
||||
"""'10.6' => [10, 6]"""
|
||||
return [int(x) for x in re.findall(r'(\d+)', version_str)]
|
||||
|
||||
|
||||
def run_command_with_retry(command, timeout=10, retries=3):
|
||||
"""
|
||||
Runs a command using subprocess.check_output with timeout and retry logic.
|
||||
|
||||
Args:
|
||||
command: A list representing the command and its arguments.
|
||||
timeout: The maximum time (in seconds) to wait for each command execution.
|
||||
retries: The number of times to retry the command if it times out.
|
||||
|
||||
Returns:
|
||||
The output of the command as a bytes object if successful, otherwise
|
||||
raises a CalledProcessError.
|
||||
"""
|
||||
for attempt in range(1, retries + 1):
|
||||
try:
|
||||
result = subprocess.check_output(command, timeout=timeout)
|
||||
return result.decode('utf-8').strip()
|
||||
except subprocess.TimeoutExpired:
|
||||
if attempt >= retries:
|
||||
raise # Re-raise the TimeoutExpired error after all retries
|
||||
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
parser.add_option("--print_sdk_path",
|
||||
action="store_true", dest="print_sdk_path", default=False,
|
||||
help="Additionaly print the path the SDK (appears first).")
|
||||
parser.add_option("--as-gclient-hook",
|
||||
action="store_true", dest="as_gclient_hook", default=False,
|
||||
help="Whether the script is running as a gclient hook.")
|
||||
parser.add_option("--symlink",
|
||||
action="store", type="string", dest="symlink",
|
||||
help="Whether to create a symlink in the buildroot to the SDK.")
|
||||
(options, args) = parser.parse_args()
|
||||
min_sdk_version = args[0]
|
||||
|
||||
# On CI, Xcode is not yet installed when gclient hooks are being run.
|
||||
# This is because the version of Xcode that CI installs might depend on the
|
||||
# contents of the repo, so the repo must be set up first, which includes
|
||||
# running the gclient hooks. Instead, on CI, this script will be run during
|
||||
# GN.
|
||||
running_on_luci = os.environ.get('LUCI_CONTEXT') is not None
|
||||
if running_on_luci and options.as_gclient_hook:
|
||||
return 0
|
||||
|
||||
symlink_path = options.symlink
|
||||
if not running_on_luci and symlink_path is None:
|
||||
symlink_path = PREBUILTS
|
||||
|
||||
job = subprocess.Popen(['xcode-select', '-print-path'],
|
||||
universal_newlines=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
out, err = job.communicate()
|
||||
if job.returncode != 0:
|
||||
sys.stderr.writelines([out, err])
|
||||
raise Exception(('Error %d running xcode-select, you might have to run '
|
||||
'|sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer| '
|
||||
'if you are using Xcode 4.') % job.returncode)
|
||||
|
||||
# xcrun --sdk macosx --show-sdk-path
|
||||
sdk_command = [
|
||||
'xcrun',
|
||||
'--sdk',
|
||||
'macosx',
|
||||
'--show-sdk-path',
|
||||
]
|
||||
sdk_output = run_command_with_retry(sdk_command, timeout=300)
|
||||
if symlink_path:
|
||||
sdks_path = os.path.join(symlink_path, 'SDKs')
|
||||
symlink_target = os.path.join(sdks_path, os.path.basename(sdk_output))
|
||||
symlink(sdk_output, symlink_target)
|
||||
sdk_output = symlink_target
|
||||
|
||||
if not options.as_gclient_hook:
|
||||
print(sdk_output)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if sys.platform != 'darwin':
|
||||
raise Exception("This script only runs on Mac")
|
||||
sys.exit((main()))
|
||||
91
engine/src/build/mac/make_more_helpers.sh
Executable file
91
engine/src/build/mac/make_more_helpers.sh
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
# Usage: make_more_helpers.sh <directory_within_contents> <app_name>
|
||||
#
|
||||
# This script creates additional helper .app bundles for Chromium, based on
|
||||
# the existing helper .app bundle, changing their Mach-O header's flags to
|
||||
# enable and disable various features. Based on Chromium Helper.app, it will
|
||||
# create Chromium Helper EH.app, which has the MH_NO_HEAP_EXECUTION bit
|
||||
# cleared to support Chromium child processes that require an executable heap,
|
||||
# and Chromium Helper NP.app, which has the MH_PIE bit cleared to support
|
||||
# Chromium child processes that cannot tolerate ASLR.
|
||||
#
|
||||
# This script expects to be called from the chrome_exe target as a postbuild,
|
||||
# and operates directly within the built-up browser app's versioned directory.
|
||||
#
|
||||
# Each helper is adjusted by giving it the proper bundle name, renaming the
|
||||
# executable, adjusting several Info.plist keys, and changing the executable's
|
||||
# Mach-O flags.
|
||||
|
||||
set -eu
|
||||
|
||||
make_helper() {
|
||||
local containing_dir="${1}"
|
||||
local app_name="${2}"
|
||||
local feature="${3}"
|
||||
local flags="${4}"
|
||||
|
||||
local helper_name="${app_name} Helper"
|
||||
local helper_stem="${containing_dir}/${helper_name}"
|
||||
local original_helper="${helper_stem}.app"
|
||||
if [[ ! -d "${original_helper}" ]]; then
|
||||
echo "${0}: error: ${original_helper} is a required directory" >& 2
|
||||
exit 1
|
||||
fi
|
||||
local original_helper_exe="${original_helper}/Contents/MacOS/${helper_name}"
|
||||
if [[ ! -f "${original_helper_exe}" ]]; then
|
||||
echo "${0}: error: ${original_helper_exe} is a required file" >& 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local feature_helper="${helper_stem} ${feature}.app"
|
||||
|
||||
rsync -acC --delete --include '*.so' "${original_helper}/" "${feature_helper}"
|
||||
|
||||
local helper_feature="${helper_name} ${feature}"
|
||||
local helper_feature_exe="${feature_helper}/Contents/MacOS/${helper_feature}"
|
||||
mv "${feature_helper}/Contents/MacOS/${helper_name}" "${helper_feature_exe}"
|
||||
|
||||
local change_flags="$(dirname "${0}")/change_mach_o_flags.py"
|
||||
"${change_flags}" ${flags} "${helper_feature_exe}"
|
||||
|
||||
local feature_info="${feature_helper}/Contents/Info"
|
||||
local feature_info_plist="${feature_info}.plist"
|
||||
|
||||
defaults write "${feature_info}" "CFBundleDisplayName" "${helper_feature}"
|
||||
defaults write "${feature_info}" "CFBundleExecutable" "${helper_feature}"
|
||||
|
||||
cfbundleid="$(defaults read "${feature_info}" "CFBundleIdentifier")"
|
||||
feature_cfbundleid="${cfbundleid}.${feature}"
|
||||
defaults write "${feature_info}" "CFBundleIdentifier" "${feature_cfbundleid}"
|
||||
|
||||
cfbundlename="$(defaults read "${feature_info}" "CFBundleName")"
|
||||
feature_cfbundlename="${cfbundlename} ${feature}"
|
||||
defaults write "${feature_info}" "CFBundleName" "${feature_cfbundlename}"
|
||||
|
||||
# As usual, defaults might have put the plist into whatever format excites
|
||||
# it, but Info.plists get converted back to the expected XML format.
|
||||
plutil -convert xml1 "${feature_info_plist}"
|
||||
|
||||
# `defaults` also changes the file permissions, so make the file
|
||||
# world-readable again.
|
||||
chmod a+r "${feature_info_plist}"
|
||||
}
|
||||
|
||||
if [[ ${#} -ne 2 ]]; then
|
||||
echo "usage: ${0} <directory_within_contents> <app_name>" >& 2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DIRECTORY_WITHIN_CONTENTS="${1}"
|
||||
APP_NAME="${2}"
|
||||
|
||||
CONTENTS_DIR="${BUILT_PRODUCTS_DIR}/${CONTENTS_FOLDER_PATH}"
|
||||
CONTAINING_DIR="${CONTENTS_DIR}/${DIRECTORY_WITHIN_CONTENTS}"
|
||||
|
||||
make_helper "${CONTAINING_DIR}" "${APP_NAME}" "EH" "--executable-heap"
|
||||
make_helper "${CONTAINING_DIR}" "${APP_NAME}" "NP" "--no-pie"
|
||||
62
engine/src/build/mac/strip_from_xcode
Executable file
62
engine/src/build/mac/strip_from_xcode
Executable file
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2008 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.
|
||||
|
||||
# This is a handy wrapper script that figures out how to call the strip
|
||||
# utility (strip_save_dsym in this case), if it even needs to be called at all,
|
||||
# and then does it. This script should be called by a post-link phase in
|
||||
# targets that might generate Mach-O executables, dynamic libraries, or
|
||||
# loadable bundles.
|
||||
#
|
||||
# An example "Strip If Needed" build phase placed after "Link Binary With
|
||||
# Libraries" would do:
|
||||
# exec "${XCODEPROJ_DEPTH}/build/mac/strip_from_xcode"
|
||||
|
||||
if [ "${CONFIGURATION}" != "Release" ] ; then
|
||||
# Only strip in release mode.
|
||||
exit 0
|
||||
fi
|
||||
|
||||
declare -a FLAGS
|
||||
|
||||
# MACH_O_TYPE is not set for a command-line tool, so check PRODUCT_TYPE too.
|
||||
# Weird.
|
||||
if [ "${MACH_O_TYPE}" = "mh_execute" ] || \
|
||||
[ "${PRODUCT_TYPE}" = "com.apple.product-type.tool" ] ; then
|
||||
# Strip everything (no special flags). No-op.
|
||||
true
|
||||
elif [ "${MACH_O_TYPE}" = "mh_dylib" ] || \
|
||||
[ "${MACH_O_TYPE}" = "mh_bundle" ]; then
|
||||
# Strip debugging symbols and local symbols
|
||||
FLAGS[${#FLAGS[@]}]=-S
|
||||
FLAGS[${#FLAGS[@]}]=-x
|
||||
elif [ "${MACH_O_TYPE}" = "staticlib" ] ; then
|
||||
# Don't strip static libraries.
|
||||
exit 0
|
||||
else
|
||||
# Warn, but don't treat this as an error.
|
||||
echo $0: warning: unrecognized MACH_O_TYPE ${MACH_O_TYPE}
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ -n "${STRIPFLAGS}" ] ; then
|
||||
# Pick up the standard STRIPFLAGS Xcode setting, used for "Additional Strip
|
||||
# Flags".
|
||||
for stripflag in "${STRIPFLAGS}" ; do
|
||||
FLAGS[${#FLAGS[@]}]="${stripflag}"
|
||||
done
|
||||
fi
|
||||
|
||||
if [ -n "${CHROMIUM_STRIP_SAVE_FILE}" ] ; then
|
||||
# An Xcode project can communicate a file listing symbols to saved in this
|
||||
# environment variable by setting it as a build setting. This isn't a
|
||||
# standard Xcode setting. It's used in preference to STRIPFLAGS to
|
||||
# eliminate quoting ambiguity concerns.
|
||||
FLAGS[${#FLAGS[@]}]=-s
|
||||
FLAGS[${#FLAGS[@]}]="${CHROMIUM_STRIP_SAVE_FILE}"
|
||||
fi
|
||||
|
||||
exec "$(dirname ${0})/strip_save_dsym" "${FLAGS[@]}" \
|
||||
"${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"
|
||||
337
engine/src/build/mac/strip_save_dsym
Executable file
337
engine/src/build/mac/strip_save_dsym
Executable file
@@ -0,0 +1,337 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (c) 2011 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.
|
||||
|
||||
# Usage: strip_save_dsym <whatever-arguments-you-would-pass-to-strip>
|
||||
#
|
||||
# strip_save_dsym is a wrapper around the standard strip utility. Given an
|
||||
# input Mach-O file, strip_save_dsym will save a copy of the file in a "fake"
|
||||
# .dSYM bundle for debugging, and then call strip to strip the Mach-O file.
|
||||
# Note that the .dSYM file is a "fake" in that it's not a self-contained
|
||||
# .dSYM bundle, it just contains a copy of the original (unstripped) Mach-O
|
||||
# file, and therefore contains references to object files on the filesystem.
|
||||
# The generated .dSYM bundle is therefore unsuitable for debugging in the
|
||||
# absence of these .o files.
|
||||
#
|
||||
# If a .dSYM already exists and has a newer timestamp than the Mach-O file,
|
||||
# this utility does nothing. That allows strip_save_dsym to be run on a file
|
||||
# that has already been stripped without trashing the .dSYM.
|
||||
#
|
||||
# Rationale: the "right" way to generate dSYM bundles, dsymutil, is incredibly
|
||||
# slow. On the other hand, doing a file copy (which is really all that
|
||||
# dsymutil does) is comparatively fast. Since we usually just want to strip
|
||||
# a release-mode executable but still be able to debug it, and we don't care
|
||||
# so much about generating a hermetic dSYM bundle, we'll prefer the file copy.
|
||||
# If a real dSYM is ever needed, it's still possible to create one by running
|
||||
# dsymutil and pointing it at the original Mach-O file inside the "fake"
|
||||
# bundle, provided that the object files are available.
|
||||
|
||||
import errno
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import time
|
||||
|
||||
# Returns a list of architectures contained in a Mach-O file. The file can be
|
||||
# a universal (fat) file, in which case there will be one list element for
|
||||
# each contained architecture, or it can be a thin single-architecture Mach-O
|
||||
# file, in which case the list will contain a single element identifying the
|
||||
# architecture. On error, returns an empty list. Determines the architecture
|
||||
# list by calling file.
|
||||
def macho_archs(macho):
|
||||
macho_types = ["executable",
|
||||
"dynamically linked shared library",
|
||||
"bundle"]
|
||||
macho_types_re = "Mach-O (?:64-bit )?(?:" + "|".join(macho_types) + ")"
|
||||
|
||||
file_cmd = subprocess.Popen(["/usr/bin/file", "-b", "--", macho],
|
||||
stdout=subprocess.PIPE)
|
||||
|
||||
archs = []
|
||||
|
||||
type_line = file_cmd.stdout.readline()
|
||||
type_match = re.match("^%s (.*)$" % macho_types_re, type_line)
|
||||
if type_match:
|
||||
archs.append(type_match.group(1))
|
||||
return [type_match.group(1)]
|
||||
else:
|
||||
type_match = re.match("^Mach-O universal binary with (.*) architectures$",
|
||||
type_line)
|
||||
if type_match:
|
||||
for i in range(0, int(type_match.group(1))):
|
||||
arch_line = file_cmd.stdout.readline()
|
||||
arch_match = re.match(
|
||||
"^.* \(for architecture (.*)\):\t%s .*$" % macho_types_re,
|
||||
arch_line)
|
||||
if arch_match:
|
||||
archs.append(arch_match.group(1))
|
||||
|
||||
if file_cmd.wait() != 0:
|
||||
archs = []
|
||||
|
||||
if len(archs) == 0:
|
||||
print("No architectures in %s" % macho, file=sys.stderr)
|
||||
|
||||
return archs
|
||||
|
||||
# Returns a dictionary mapping architectures contained in the file as returned
|
||||
# by macho_archs to the LC_UUID load command for that architecture.
|
||||
# Architectures with no LC_UUID load command are omitted from the dictionary.
|
||||
# Determines the UUID value by calling otool.
|
||||
def macho_uuids(macho):
|
||||
uuids = {}
|
||||
|
||||
archs = macho_archs(macho)
|
||||
if len(archs) == 0:
|
||||
return uuids
|
||||
|
||||
for arch in archs:
|
||||
if arch == "":
|
||||
continue
|
||||
|
||||
otool_cmd = subprocess.Popen(["/usr/bin/otool", "-arch", arch, "-l", "-",
|
||||
macho],
|
||||
stdout=subprocess.PIPE)
|
||||
# state 0 is when nothing UUID-related has been seen yet. State 1 is
|
||||
# entered after a load command begins, but it may not be an LC_UUID load
|
||||
# command. States 2, 3, and 4 are intermediate states while reading an
|
||||
# LC_UUID command. State 5 is the terminal state for a successful LC_UUID
|
||||
# read. State 6 is the error state.
|
||||
state = 0
|
||||
uuid = ""
|
||||
for otool_line in otool_cmd.stdout:
|
||||
if state == 0:
|
||||
if re.match("^Load command .*$", otool_line):
|
||||
state = 1
|
||||
elif state == 1:
|
||||
if re.match("^ cmd LC_UUID$", otool_line):
|
||||
state = 2
|
||||
else:
|
||||
state = 0
|
||||
elif state == 2:
|
||||
if re.match("^ cmdsize 24$", otool_line):
|
||||
state = 3
|
||||
else:
|
||||
state = 6
|
||||
elif state == 3:
|
||||
# The UUID display format changed in the version of otool shipping
|
||||
# with the Xcode 3.2.2 prerelease. The new format is traditional:
|
||||
# uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
|
||||
# and with Xcode 3.2.6, then line is indented one more space:
|
||||
# uuid 4D7135B2-9C56-C5F5-5F49-A994258E0955
|
||||
# The old format, from cctools-750 and older's otool, breaks the UUID
|
||||
# up into a sequence of bytes:
|
||||
# uuid 0x4d 0x71 0x35 0xb2 0x9c 0x56 0xc5 0xf5
|
||||
# 0x5f 0x49 0xa9 0x94 0x25 0x8e 0x09 0x55
|
||||
new_uuid_match = re.match("^ {3,4}uuid (.{8}-.{4}-.{4}-.{4}-.{12})$",
|
||||
otool_line)
|
||||
if new_uuid_match:
|
||||
uuid = new_uuid_match.group(1)
|
||||
|
||||
# Skip state 4, there is no second line to read.
|
||||
state = 5
|
||||
else:
|
||||
old_uuid_match = re.match("^ uuid 0x(..) 0x(..) 0x(..) 0x(..) "
|
||||
"0x(..) 0x(..) 0x(..) 0x(..)$",
|
||||
otool_line)
|
||||
if old_uuid_match:
|
||||
state = 4
|
||||
uuid = old_uuid_match.group(1) + old_uuid_match.group(2) + \
|
||||
old_uuid_match.group(3) + old_uuid_match.group(4) + "-" + \
|
||||
old_uuid_match.group(5) + old_uuid_match.group(6) + "-" + \
|
||||
old_uuid_match.group(7) + old_uuid_match.group(8) + "-"
|
||||
else:
|
||||
state = 6
|
||||
elif state == 4:
|
||||
old_uuid_match = re.match("^ 0x(..) 0x(..) 0x(..) 0x(..) "
|
||||
"0x(..) 0x(..) 0x(..) 0x(..)$",
|
||||
otool_line)
|
||||
if old_uuid_match:
|
||||
state = 5
|
||||
uuid += old_uuid_match.group(1) + old_uuid_match.group(2) + "-" + \
|
||||
old_uuid_match.group(3) + old_uuid_match.group(4) + \
|
||||
old_uuid_match.group(5) + old_uuid_match.group(6) + \
|
||||
old_uuid_match.group(7) + old_uuid_match.group(8)
|
||||
else:
|
||||
state = 6
|
||||
|
||||
if otool_cmd.wait() != 0:
|
||||
state = 6
|
||||
|
||||
if state == 5:
|
||||
uuids[arch] = uuid.upper()
|
||||
|
||||
if len(uuids) == 0:
|
||||
print("No UUIDs in %s" % macho, file=sys.stderr)
|
||||
|
||||
return uuids
|
||||
|
||||
# Given a path to a Mach-O file and possible information from the environment,
|
||||
# determines the desired path to the .dSYM.
|
||||
def dsym_path(macho):
|
||||
# If building a bundle, the .dSYM should be placed next to the bundle. Use
|
||||
# WRAPPER_NAME to make this determination. If called from xcodebuild,
|
||||
# WRAPPER_NAME will be set to the name of the bundle.
|
||||
dsym = ""
|
||||
if "WRAPPER_NAME" in os.environ:
|
||||
if "BUILT_PRODUCTS_DIR" in os.environ:
|
||||
dsym = os.path.join(os.environ["BUILT_PRODUCTS_DIR"],
|
||||
os.environ["WRAPPER_NAME"])
|
||||
else:
|
||||
dsym = os.environ["WRAPPER_NAME"]
|
||||
else:
|
||||
dsym = macho
|
||||
|
||||
dsym += ".dSYM"
|
||||
|
||||
return dsym
|
||||
|
||||
# Creates a fake .dSYM bundle at dsym for macho, a Mach-O image with the
|
||||
# architectures and UUIDs specified by the uuids map.
|
||||
def make_fake_dsym(macho, dsym):
|
||||
uuids = macho_uuids(macho)
|
||||
if len(uuids) == 0:
|
||||
return False
|
||||
|
||||
dwarf_dir = os.path.join(dsym, "Contents", "Resources", "DWARF")
|
||||
dwarf_file = os.path.join(dwarf_dir, os.path.basename(macho))
|
||||
try:
|
||||
os.makedirs(dwarf_dir)
|
||||
except OSError as xxx_todo_changeme:
|
||||
(err, error_string) = xxx_todo_changeme.args
|
||||
if err != errno.EEXIST:
|
||||
raise
|
||||
shutil.copyfile(macho, dwarf_file)
|
||||
|
||||
# info_template is the same as what dsymutil would have written, with the
|
||||
# addition of the fake_dsym key.
|
||||
info_template = \
|
||||
'''<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.%(root_name)s</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>dSYM_UUID</key>
|
||||
<dict>
|
||||
%(uuid_dict)s </dict>
|
||||
<key>fake_dsym</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
'''
|
||||
|
||||
root_name = os.path.basename(dsym)[:-5] # whatever.dSYM without .dSYM
|
||||
uuid_dict = ""
|
||||
for arch in sorted(uuids):
|
||||
uuid_dict += "\t\t\t<key>" + arch + "</key>\n"\
|
||||
"\t\t\t<string>" + uuids[arch] + "</string>\n"
|
||||
info_dict = {
|
||||
"root_name": root_name,
|
||||
"uuid_dict": uuid_dict,
|
||||
}
|
||||
info_contents = info_template % info_dict
|
||||
info_file = os.path.join(dsym, "Contents", "Info.plist")
|
||||
info_fd = open(info_file, "w")
|
||||
info_fd.write(info_contents)
|
||||
info_fd.close()
|
||||
|
||||
return True
|
||||
|
||||
# For a Mach-O file, determines where the .dSYM bundle should be located. If
|
||||
# the bundle does not exist or has a modification time older than the Mach-O
|
||||
# file, calls make_fake_dsym to create a fake .dSYM bundle there, then strips
|
||||
# the Mach-O file and sets the modification time on the .dSYM bundle and Mach-O
|
||||
# file to be identical.
|
||||
def strip_and_make_fake_dsym(macho):
|
||||
dsym = dsym_path(macho)
|
||||
macho_stat = os.stat(macho)
|
||||
dsym_stat = None
|
||||
try:
|
||||
dsym_stat = os.stat(dsym)
|
||||
except OSError as xxx_todo_changeme1:
|
||||
(err, error_string) = xxx_todo_changeme1.args
|
||||
if err != errno.ENOENT:
|
||||
raise
|
||||
|
||||
if dsym_stat is None or dsym_stat.st_mtime < macho_stat.st_mtime:
|
||||
# Make a .dSYM bundle
|
||||
if not make_fake_dsym(macho, dsym):
|
||||
return False
|
||||
|
||||
# Strip the Mach-O file
|
||||
remove_dsym = True
|
||||
try:
|
||||
strip_cmdline = ['xcrun', 'strip'] + sys.argv[1:]
|
||||
strip_cmd = subprocess.Popen(strip_cmdline)
|
||||
if strip_cmd.wait() == 0:
|
||||
remove_dsym = False
|
||||
finally:
|
||||
if remove_dsym:
|
||||
shutil.rmtree(dsym)
|
||||
|
||||
# Update modification time on the Mach-O file and .dSYM bundle
|
||||
now = time.time()
|
||||
os.utime(macho, (now, now))
|
||||
os.utime(dsym, (now, now))
|
||||
|
||||
return True
|
||||
|
||||
def main(argv=None):
|
||||
if argv is None:
|
||||
argv = sys.argv
|
||||
|
||||
# This only supports operating on one file at a time. Look at the arguments
|
||||
# to strip to figure out what the source to be stripped is. Arguments are
|
||||
# processed in the same way that strip does, although to reduce complexity,
|
||||
# this doesn't do all of the same checking as strip. For example, strip
|
||||
# has no -Z switch and would treat -Z on the command line as an error. For
|
||||
# the purposes this is needed for, that's fine.
|
||||
macho = None
|
||||
process_switches = True
|
||||
ignore_argument = False
|
||||
for arg in argv[1:]:
|
||||
if ignore_argument:
|
||||
ignore_argument = False
|
||||
continue
|
||||
if process_switches:
|
||||
if arg == "-":
|
||||
process_switches = False
|
||||
# strip has these switches accept an argument:
|
||||
if arg in ["-s", "-R", "-d", "-o", "-arch"]:
|
||||
ignore_argument = True
|
||||
if arg[0] == "-":
|
||||
continue
|
||||
if macho is None:
|
||||
macho = arg
|
||||
else:
|
||||
print("Too many things to strip", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if macho is None:
|
||||
print("Nothing to strip", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not strip_and_make_fake_dsym(macho):
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main(sys.argv))
|
||||
280
engine/src/build/mac/tweak_info_plist.py
Executable file
280
engine/src/build/mac/tweak_info_plist.py
Executable file
@@ -0,0 +1,280 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Copyright (c) 2012 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.
|
||||
|
||||
#
|
||||
# Xcode supports build variable substitutions and CPP; sadly, that doesn't work
|
||||
# because:
|
||||
#
|
||||
# 1. Xcode wants to do the Info.plist work before it runs any build phases,
|
||||
# this means if we were to generate a .h file for INFOPLIST_PREFIX_HEADER
|
||||
# we'd have to put it in another target so it runs in time.
|
||||
# 2. Xcode also doesn't check to see if the header being used as a prefix for
|
||||
# the Info.plist has changed. So even if we updated it, it's only looking
|
||||
# at the modtime of the info.plist to see if that's changed.
|
||||
#
|
||||
# So, we work around all of this by making a script build phase that will run
|
||||
# during the app build, and simply update the info.plist in place. This way
|
||||
# by the time the app target is done, the info.plist is correct.
|
||||
#
|
||||
|
||||
import optparse
|
||||
import os
|
||||
from os import environ as env
|
||||
import plistlib
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
TOP = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
|
||||
|
||||
|
||||
def _GetOutput(args):
|
||||
"""Runs a subprocess and waits for termination. Returns (stdout, returncode)
|
||||
of the process. stderr is attached to the parent."""
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
(stdout, stderr) = proc.communicate()
|
||||
return (stdout, proc.returncode)
|
||||
|
||||
|
||||
def _GetOutputNoError(args):
|
||||
"""Similar to _GetOutput() but ignores stderr. If there's an error launching
|
||||
the child (like file not found), the exception will be caught and (None, 1)
|
||||
will be returned to mimic quiet failure."""
|
||||
try:
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
except OSError:
|
||||
return (None, 1)
|
||||
(stdout, stderr) = proc.communicate()
|
||||
return (stdout, proc.returncode)
|
||||
|
||||
|
||||
def _RemoveKeys(plist, *keys):
|
||||
"""Removes a varargs of keys from the plist."""
|
||||
for key in keys:
|
||||
try:
|
||||
del plist[key]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
def _AddVersionKeys(plist, version=None):
|
||||
"""Adds the product version number into the plist. Returns True on success and
|
||||
False on error. The error will be printed to stderr."""
|
||||
if version:
|
||||
match = re.match('\d+\.\d+\.(\d+\.\d+)$', version)
|
||||
if not match:
|
||||
print('Invalid version string specified: "%s"' % version, file=sys.stderr)
|
||||
return False
|
||||
|
||||
full_version = match.group(0)
|
||||
bundle_version = match.group(1)
|
||||
|
||||
else:
|
||||
# Pull in the Chrome version number.
|
||||
VERSION_TOOL = os.path.join(TOP, 'build/util/version.py')
|
||||
VERSION_FILE = os.path.join(TOP, 'chrome/VERSION')
|
||||
|
||||
(stdout, retval1) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
|
||||
'@MAJOR@.@MINOR@.@BUILD@.@PATCH@'])
|
||||
full_version = stdout.rstrip()
|
||||
|
||||
(stdout, retval2) = _GetOutput([VERSION_TOOL, '-f', VERSION_FILE, '-t',
|
||||
'@BUILD@.@PATCH@'])
|
||||
bundle_version = stdout.rstrip()
|
||||
|
||||
# If either of the two version commands finished with non-zero returncode,
|
||||
# report the error up.
|
||||
if retval1 or retval2:
|
||||
return False
|
||||
|
||||
# Add public version info so "Get Info" works.
|
||||
plist['CFBundleShortVersionString'] = full_version
|
||||
|
||||
# Honor the 429496.72.95 limit. The maximum comes from splitting 2^32 - 1
|
||||
# into 6, 2, 2 digits. The limitation was present in Tiger, but it could
|
||||
# have been fixed in later OS release, but hasn't been tested (it's easy
|
||||
# enough to find out with "lsregister -dump).
|
||||
# http://lists.apple.com/archives/carbon-dev/2006/Jun/msg00139.html
|
||||
# BUILD will always be an increasing value, so BUILD_PATH gives us something
|
||||
# unique that meetings what LS wants.
|
||||
plist['CFBundleVersion'] = bundle_version
|
||||
|
||||
# Return with no error.
|
||||
return True
|
||||
|
||||
|
||||
def _DoSCMKeys(plist, add_keys):
|
||||
"""Adds the SCM information, visible in about:version, to property list. If
|
||||
|add_keys| is True, it will insert the keys, otherwise it will remove them."""
|
||||
scm_revision = None
|
||||
if add_keys:
|
||||
# Pull in the Chrome revision number.
|
||||
VERSION_TOOL = os.path.join(TOP, 'build/util/version.py')
|
||||
LASTCHANGE_FILE = os.path.join(TOP, 'build/util/LASTCHANGE')
|
||||
(stdout, retval) = _GetOutput([VERSION_TOOL, '-f', LASTCHANGE_FILE, '-t',
|
||||
'@LASTCHANGE@'])
|
||||
if retval:
|
||||
return False
|
||||
scm_revision = stdout.rstrip()
|
||||
|
||||
# See if the operation failed.
|
||||
_RemoveKeys(plist, 'SCMRevision')
|
||||
if scm_revision != None:
|
||||
plist['SCMRevision'] = scm_revision
|
||||
elif add_keys:
|
||||
print('Could not determine SCM revision. This may be OK.', file=sys.stderr)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def _AddBreakpadKeys(plist, branding):
|
||||
"""Adds the Breakpad keys. This must be called AFTER _AddVersionKeys() and
|
||||
also requires the |branding| argument."""
|
||||
plist['BreakpadReportInterval'] = '3600' # Deliberately a string.
|
||||
plist['BreakpadProduct'] = '%s_Mac' % branding
|
||||
plist['BreakpadProductDisplay'] = branding
|
||||
plist['BreakpadVersion'] = plist['CFBundleShortVersionString']
|
||||
# These are both deliberately strings and not boolean.
|
||||
plist['BreakpadSendAndExit'] = 'YES'
|
||||
plist['BreakpadSkipConfirm'] = 'YES'
|
||||
|
||||
|
||||
def _RemoveBreakpadKeys(plist):
|
||||
"""Removes any set Breakpad keys."""
|
||||
_RemoveKeys(plist,
|
||||
'BreakpadURL',
|
||||
'BreakpadReportInterval',
|
||||
'BreakpadProduct',
|
||||
'BreakpadProductDisplay',
|
||||
'BreakpadVersion',
|
||||
'BreakpadSendAndExit',
|
||||
'BreakpadSkipConfirm')
|
||||
|
||||
|
||||
def _TagSuffixes():
|
||||
# Keep this list sorted in the order that tag suffix components are to
|
||||
# appear in a tag value. That is to say, it should be sorted per ASCII.
|
||||
components = ('32bit', 'full')
|
||||
assert tuple(sorted(components)) == components
|
||||
|
||||
components_len = len(components)
|
||||
combinations = 1 << components_len
|
||||
tag_suffixes = []
|
||||
for combination in range(0, combinations):
|
||||
tag_suffix = ''
|
||||
for component_index in range(0, components_len):
|
||||
if combination & (1 << component_index):
|
||||
tag_suffix += '-' + components[component_index]
|
||||
tag_suffixes.append(tag_suffix)
|
||||
return tag_suffixes
|
||||
|
||||
|
||||
def _AddKeystoneKeys(plist, bundle_identifier):
|
||||
"""Adds the Keystone keys. This must be called AFTER _AddVersionKeys() and
|
||||
also requires the |bundle_identifier| argument (com.example.product)."""
|
||||
plist['KSVersion'] = plist['CFBundleShortVersionString']
|
||||
plist['KSProductID'] = bundle_identifier
|
||||
plist['KSUpdateURL'] = 'https://tools.google.com/service/update2'
|
||||
|
||||
_RemoveKeys(plist, 'KSChannelID')
|
||||
for tag_suffix in _TagSuffixes():
|
||||
if tag_suffix:
|
||||
plist['KSChannelID' + tag_suffix] = tag_suffix
|
||||
|
||||
|
||||
def _RemoveKeystoneKeys(plist):
|
||||
"""Removes any set Keystone keys."""
|
||||
_RemoveKeys(plist,
|
||||
'KSVersion',
|
||||
'KSProductID',
|
||||
'KSUpdateURL')
|
||||
|
||||
tag_keys = []
|
||||
for tag_suffix in _TagSuffixes():
|
||||
tag_keys.append('KSChannelID' + tag_suffix)
|
||||
_RemoveKeys(plist, *tag_keys)
|
||||
|
||||
|
||||
def Main(argv):
|
||||
parser = optparse.OptionParser('%prog [options]')
|
||||
parser.add_option('--breakpad', dest='use_breakpad', action='store',
|
||||
type='int', default=False, help='Enable Breakpad [1 or 0]')
|
||||
parser.add_option('--breakpad_uploads', dest='breakpad_uploads',
|
||||
action='store', type='int', default=False,
|
||||
help='Enable Breakpad\'s uploading of crash dumps [1 or 0]')
|
||||
parser.add_option('--keystone', dest='use_keystone', action='store',
|
||||
type='int', default=False, help='Enable Keystone [1 or 0]')
|
||||
parser.add_option('--scm', dest='add_scm_info', action='store', type='int',
|
||||
default=True, help='Add SCM metadata [1 or 0]')
|
||||
parser.add_option('--branding', dest='branding', action='store',
|
||||
type='string', default=None, help='The branding of the binary')
|
||||
parser.add_option('--bundle_id', dest='bundle_identifier',
|
||||
action='store', type='string', default=None,
|
||||
help='The bundle id of the binary')
|
||||
parser.add_option('--version', dest='version', action='store', type='string',
|
||||
default=None, help='The version string [major.minor.build.patch]')
|
||||
(options, args) = parser.parse_args(argv)
|
||||
|
||||
if len(args) > 0:
|
||||
print(parser.get_usage(), file=sys.stderr)
|
||||
return 1
|
||||
|
||||
# Read the plist into its parsed format.
|
||||
DEST_INFO_PLIST = os.path.join(env['TARGET_BUILD_DIR'], env['INFOPLIST_PATH'])
|
||||
plist = plistlib.readPlist(DEST_INFO_PLIST)
|
||||
|
||||
# Insert the product version.
|
||||
if not _AddVersionKeys(plist, version=options.version):
|
||||
return 2
|
||||
|
||||
# Add Breakpad if configured to do so.
|
||||
if options.use_breakpad:
|
||||
if options.branding is None:
|
||||
print('Use of Breakpad requires branding.', file=sys.stderr)
|
||||
return 1
|
||||
_AddBreakpadKeys(plist, options.branding)
|
||||
if options.breakpad_uploads:
|
||||
plist['BreakpadURL'] = 'https://clients2.google.com/cr/report'
|
||||
else:
|
||||
# This allows crash dumping to a file without uploading the
|
||||
# dump, for testing purposes. Breakpad does not recognise
|
||||
# "none" as a special value, but this does stop crash dump
|
||||
# uploading from happening. We need to specify something
|
||||
# because if "BreakpadURL" is not present, Breakpad will not
|
||||
# register its crash handler and no crash dumping will occur.
|
||||
plist['BreakpadURL'] = 'none'
|
||||
else:
|
||||
_RemoveBreakpadKeys(plist)
|
||||
|
||||
# Only add Keystone in Release builds.
|
||||
if options.use_keystone and env['CONFIGURATION'] == 'Release':
|
||||
if options.bundle_identifier is None:
|
||||
print('Use of Keystone requires the bundle id.', file=sys.stderr)
|
||||
return 1
|
||||
_AddKeystoneKeys(plist, options.bundle_identifier)
|
||||
else:
|
||||
_RemoveKeystoneKeys(plist)
|
||||
|
||||
# Adds or removes any SCM keys.
|
||||
if not _DoSCMKeys(plist, options.add_scm_info):
|
||||
return 3
|
||||
|
||||
# Now that all keys have been mutated, rewrite the file.
|
||||
temp_info_plist = tempfile.NamedTemporaryFile()
|
||||
plistlib.writePlist(plist, temp_info_plist.name)
|
||||
|
||||
# Info.plist will work perfectly well in any plist format, but traditionally
|
||||
# applications use xml1 for this, so convert it to ensure that it's valid.
|
||||
proc = subprocess.Popen(['plutil', '-convert', 'xml1', '-o', DEST_INFO_PLIST,
|
||||
temp_info_plist.name])
|
||||
proc.wait()
|
||||
return proc.returncode
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main(sys.argv[1:]))
|
||||
42
engine/src/build/mac/verify_no_objc.sh
Executable file
42
engine/src/build/mac/verify_no_objc.sh
Executable file
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) 2011 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.
|
||||
|
||||
# This script makes sure that no __OBJC,__image_info section appears in the
|
||||
# executable file built by the Xcode target that runs the script. If such a
|
||||
# section appears, the script prints an error message and exits nonzero.
|
||||
#
|
||||
# Why is this important?
|
||||
#
|
||||
# On 10.5, there's a bug in CFBundlePreflightExecutable that causes it to
|
||||
# crash when operating in an executable that has not loaded at its default
|
||||
# address (that is, when it's a position-independent executable with the
|
||||
# MH_PIE bit set in its mach_header) and the executable has an
|
||||
# __OBJC,__image_info section. See http://crbug.com/88697.
|
||||
#
|
||||
# Chrome's main executables don't use any Objective-C at all, and don't need
|
||||
# to carry this section around. Not linking them as Objective-C when they
|
||||
# don't need it anyway saves about 4kB in the linked executable, although most
|
||||
# of that 4kB is just filled with zeroes.
|
||||
#
|
||||
# This script makes sure that nobody goofs and accidentally introduces these
|
||||
# sections into the main executables.
|
||||
|
||||
set -eu
|
||||
|
||||
executable="${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}"
|
||||
|
||||
if xcrun otool -arch i386 -o "${executable}" | grep -q '^Contents.*section$'; \
|
||||
then
|
||||
echo "${0}: ${executable} has an __OBJC,__image_info section" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ${PIPESTATUS[0]} -ne 0 ]]; then
|
||||
echo "${0}: otool failed" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
||||
7
engine/src/build/precompile.cc
Normal file
7
engine/src/build/precompile.cc
Normal file
@@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2011 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.
|
||||
|
||||
// Precompiled header generator for Windows builds. No include is needed
|
||||
// in this file as the PCH include is forced via the "Forced Include File"
|
||||
// flag in the projects generated by GYP.
|
||||
109
engine/src/build/precompile.h
Normal file
109
engine/src/build/precompile.h
Normal file
@@ -0,0 +1,109 @@
|
||||
// Copyright (c) 2012 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.
|
||||
|
||||
// Precompiled header for Chromium project on Windows, not used by
|
||||
// other build configurations. Using precompiled headers speeds the
|
||||
// build up significantly, around 1/4th on VS 2010 on an HP Z600 with 12
|
||||
// GB of memory.
|
||||
//
|
||||
// Numeric comments beside includes are the number of times they were
|
||||
// included under src/chrome/browser on 2011/8/20, which was used as a
|
||||
// baseline for deciding what to include in the PCH. Includes without
|
||||
// a numeric comment are generally included at least 5 times. It may
|
||||
// be possible to tweak the speed of the build by commenting out or
|
||||
// removing some of the less frequently used headers.
|
||||
|
||||
#if defined(BUILD_PRECOMPILE_H_)
|
||||
#error You shouldn't include the precompiled header file more than once.
|
||||
#endif
|
||||
|
||||
#define BUILD_PRECOMPILE_H_
|
||||
|
||||
#define _USE_MATH_DEFINES
|
||||
|
||||
// The Windows header needs to come before almost all the other
|
||||
// Windows-specific headers.
|
||||
#include <Windows.h>
|
||||
#include <dwmapi.h>
|
||||
#include <shellapi.h>
|
||||
#include <wtypes.h> // 2
|
||||
|
||||
// Defines in atlbase.h cause conflicts; if we could figure out how
|
||||
// this family of headers can be included in the PCH, it might speed
|
||||
// up the build as several of them are used frequently.
|
||||
/*
|
||||
#include <atlbase.h>
|
||||
#include <atlapp.h>
|
||||
#include <atlcom.h>
|
||||
#include <atlcrack.h> // 2
|
||||
#include <atlctrls.h> // 2
|
||||
#include <atlmisc.h> // 2
|
||||
#include <atlsafe.h> // 1
|
||||
#include <atltheme.h> // 1
|
||||
#include <atlwin.h> // 2
|
||||
*/
|
||||
|
||||
// Objbase.h and other files that rely on it bring in [ #define
|
||||
// interface struct ] which can cause problems in a multi-platform
|
||||
// build like Chrome's. #undef-ing it does not work as there are
|
||||
// currently 118 targets that break if we do this, so leaving out of
|
||||
// the precompiled header for now.
|
||||
//#include <commctrl.h> // 2
|
||||
//#include <commdlg.h> // 3
|
||||
//#include <cryptuiapi.h> // 2
|
||||
//#include <Objbase.h> // 2
|
||||
//#include <objidl.h> // 1
|
||||
//#include <ole2.h> // 1
|
||||
//#include <oleacc.h> // 2
|
||||
//#include <oleauto.h> // 1
|
||||
//#include <oleidl.h> // 1
|
||||
//#include <propkey.h> // 2
|
||||
//#include <propvarutil.h> // 2
|
||||
//#include <pstore.h> // 2
|
||||
//#include <shlguid.h> // 1
|
||||
//#include <shlwapi.h> // 1
|
||||
//#include <shobjidl.h> // 4
|
||||
//#include <urlhist.h> // 2
|
||||
|
||||
// Caused other conflicts in addition to the 'interface' issue above.
|
||||
// #include <shlobj.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h> // 4
|
||||
#include <math.h>
|
||||
#include <memory.h> // 1
|
||||
#include <signal.h>
|
||||
#include <stdarg.h> // 1
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h> // 4
|
||||
|
||||
#include <algorithm>
|
||||
#include <bitset> // 3
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
#include <cstdio> // 3
|
||||
#include <cstdlib> // 2
|
||||
#include <cstring>
|
||||
#include <deque>
|
||||
#include <fstream> // 3
|
||||
#include <functional>
|
||||
#include <iomanip> // 2
|
||||
#include <iosfwd> // 2
|
||||
#include <iterator>
|
||||
#include <limits>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <numeric> // 2
|
||||
#include <ostream>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#include <stack>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user