Add missing sentry-native file

gitignore gone wrong
This commit is contained in:
Marek Roszko 2022-04-03 21:19:19 -04:00
parent aee5ff8935
commit 9a0fa460d1
69 changed files with 11417 additions and 0 deletions

View File

@ -0,0 +1,73 @@
# GitHub actions workflow.
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
name: Build+Test CI
on:
push:
branches: [main]
schedule:
# The GH mirroring from Google GoB does not trigger push actions.
# Fire it every other day to provide some coverage. This will run ~8 AM PT.
- cron: '39 3 */2 * *'
# Allow for manual triggers from the web.
workflow_dispatch:
jobs:
autotools:
strategy:
fail-fast: false
matrix:
include:
- os: ubuntu-latest
cc: gcc
cxx: g++
- os: ubuntu-latest
cc: clang
cxx: clang++
- os: macos-latest
cc: clang
cxx: clang++
runs-on: ${{ matrix.os }}
env:
CC: ${{ matrix.cc }}
CXX: ${{ matrix.cxx }}
steps:
- name: System settings
run: |
set -x
$CC --version
$CXX --version
getconf _NPROCESSORS_ONLN
getconf _NPROCESSORS_CONF
true
- name: Checkout depot_tools
run: git clone --depth=1 https://chromium.googlesource.com/chromium/tools/depot_tools.git ../depot_tools
- name: Checkout breakpad
run: |
set -xe
PATH+=:$PWD/../depot_tools
gclient config --unmanaged --name=src https://github.com/${{ github.repository }}
gclient sync --no-history --nohooks
# First build & test in-tree.
- run: ./configure --disable-silent-rules
working-directory: src
- run: make -j$(getconf _NPROCESSORS_CONF)
working-directory: src
- run: make -j$(getconf _NPROCESSORS_CONF) check VERBOSE=1
working-directory: src
- run: make -j$(getconf _NPROCESSORS_CONF) distclean
working-directory: src
# Then build & test out-of-tree.
- run: mkdir -p src/build/native
- run: ../../configure --disable-silent-rules
working-directory: src/build/native
- run: make -j$(getconf _NPROCESSORS_CONF) distcheck VERBOSE=1
working-directory: src/build/native

View File

@ -0,0 +1,41 @@
# Copyright 2014 Google Inc. 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.
{
'targets': [
{
'target_name': 'All',
'type': 'none',
'dependencies': [
'../common/common.gyp:*',
'../processor/processor.gyp:*',
'../tools/tools.gyp:*',
],
},
],
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
# Copyright 2014 Google Inc. 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.
{
'target_conditions': [
['OS!="win"', {
'sources/': [
['exclude', '(^|/)windows/'],
],
}],
['OS!="linux"', {
'sources/': [
['exclude', '(^|/)linux/'],
],
}],
['OS!="mac"', {
'sources/': [
['exclude', '(^|/)mac/'],
],
}],
['OS!="android"', {
'sources/': [
['exclude', '(^|/)android/'],
],
}],
['OS!="solaris"', {
'sources/': [
['exclude', '(^|/)solaris/'],
],
}],
],
}

View File

@ -0,0 +1,67 @@
#!/usr/bin/env python
# Copyright 2014 Google Inc. 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.
import os
import platform
import sys
script_dir = os.path.dirname(os.path.realpath(__file__))
breakpad_root = os.path.abspath(os.path.join(script_dir, os.pardir))
sys.path.insert(0, os.path.join(breakpad_root, 'tools', 'gyp', 'pylib'))
import gyp
def run_gyp(args):
rc = gyp.main(args)
if rc != 0:
print 'Error running GYP'
sys.exit(rc)
def main():
args = sys.argv[1:]
args.append(os.path.join(script_dir, 'all.gyp'))
args.append('-I')
args.append(os.path.join(breakpad_root, 'build', 'common.gypi'))
args.extend(['-D', 'gyp_output_dir=out'])
# Set the GYP DEPTH variable to the root of the project.
args.append('--depth=' + os.path.relpath(breakpad_root))
print 'Updating projects from gyp files...'
sys.stdout.flush()
run_gyp(args)
if __name__ == '__main__':
sys.exit(main())

View File

@ -0,0 +1,90 @@
# Copyright 2014 Google Inc. 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.
{
'targets': [
{
'target_name': 'gtest',
'type': 'static_library',
'sources': [
'../testing/googletest/src/gtest-all.cc',
],
'include_dirs': [
'../testing/googletest',
'../testing/googletest/include',
],
'direct_dependent_settings': {
'include_dirs': [
'../testing/googletest/include',
],
},
},
{
'target_name': 'gtest_main',
'type': 'static_library',
'dependencies': [
'gtest',
],
'sources': [
'../testing/googletest/src/gtest_main.cc',
],
},
{
'target_name': 'gmock',
'type': 'static_library',
'dependencies': [
'gtest',
],
'sources': [
'../testing/googlemock/src/gmock-all.cc',
],
'include_dirs': [
'../testing/googlemock',
'../testing/googlemock/include',
],
'direct_dependent_settings': {
'include_dirs': [
'../testing/googlemock/include',
],
},
'export_dependent_settings': [
'gtest',
],
},
{
'target_name': 'gmock_main',
'type': 'static_library',
'dependencies': [
'gmock',
],
'sources': [
'../testing/googlemock/src/gmock_main.cc',
],
},
],
}

View File

@ -0,0 +1,45 @@
name: Build
on:
push:
branches:
- getsentry
pull_request:
jobs:
build:
strategy:
fail-fast: false
matrix:
platform: [ubuntu-latest, windows-latest, macos-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- name: Installing Linux Dependencies
if: ${{ runner.os == 'Linux' }}
run: |
sudo apt update
sudo apt install zlib1g-dev libcurl4-openssl-dev libssl-dev libunwind-dev pkg-config
- name: Build crashpad
run: |
cmake -B cmake-build
cmake --build cmake-build --parallel
- name: Build crashpad with client-side stack traces
run: |
cmake -B cmake-build-stacks -D CRASHPAD_ENABLE_STACKTRACE=ON
cmake --build cmake-build-stacks --parallel
build-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- run: |
cmake -B crashpad-xcode -GXcode -DCMAKE_SYSTEM_NAME=iOS
xcodebuild build -project crashpad-xcode/crashpad.xcodeproj

View File

@ -0,0 +1,184 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("build/crashpad_buildconfig.gni")
import("build/test.gni")
import("util/net/tls.gni")
config("crashpad_config") {
include_dirs = [ "." ]
}
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
test("crashpad_tests") {
deps = [
"client:client_test",
"minidump:minidump_test",
"snapshot:snapshot_test",
"test:googlemock_main",
"test:test_test",
"util:util_test",
]
if (!crashpad_is_ios && !crashpad_is_fuchsia) {
deps += [ "handler:handler_test" ]
}
if (crashpad_is_in_fuchsia) {
# TODO(fuchsia:46559): Fix the leaks and remove this.
deps += [ "//build/config/sanitizers:suppress-lsan.DO-NOT-USE-THIS" ]
}
if (crashpad_is_android) {
use_raw_android_executable = true
copy("crashpad_test_data") {
testonly = true
sources = [
"test/test_paths_test_data_root.txt",
"util/net/testdata/ascii_http_body.txt",
"util/net/testdata/binary_http_body.dat",
]
outputs = [ "$root_out_dir/crashpad_test_data/{{source}}" ]
}
deps += [ ":crashpad_test_data" ]
extra_dist_files = [
"$root_out_dir/crashpad_handler",
"$root_out_dir/crashpad_test_test_multiprocess_exec_test_child",
"$root_out_dir/crashpad_test_data",
]
}
}
if (crashpad_is_in_fuchsia) {
import("//build/components.gni")
fuchsia_test_component("crashpad-test-component") {
manifest = "test/fuchsia_crashpad_tests.cmx"
deps = [
":crashpad-test-resources",
":crashpad_tests",
"snapshot:crashpad_snapshot_test_both_dt_hash_styles",
"snapshot:crashpad_snapshot_test_module",
"snapshot:crashpad_snapshot_test_module_large",
"snapshot:crashpad_snapshot_test_module_small",
"test:crashpad_test_test_multiprocess_exec_test_child",
"util:http_transport_test_server",
]
}
fuchsia_test_package("crashpad-test") {
test_components = [ ":crashpad-test-component" ]
deps = [
"//src/connectivity/network/dns:component-legacy",
"//src/connectivity/network/netstack:component-legacy",
]
test_specs = {
log_settings = {
max_severity = "FATAL"
}
}
}
_resource_files = [
"test/test_paths_test_data_root.txt",
"util/net/testdata/ascii_http_body.txt",
"util/net/testdata/binary_http_body.dat",
]
if (crashpad_use_boringssl_for_http_transport_socket) {
_resource_files += [
"util/net/testdata/crashpad_util_test_cert.pem",
"util/net/testdata/crashpad_util_test_key.pem",
]
}
_resources = []
foreach(resource_file, _resource_files) {
_resource_file_target = string_replace(resource_file, "/", "_")
resource("${_resource_file_target}") {
sources = [ "${resource_file}" ]
outputs = [ "data/${resource_file}" ]
}
_resources += [ ":${_resource_file_target}" ]
}
group("crashpad-test-resources") {
deps = _resources
}
fuchsia_shell_package("crashpad-database-util") {
package_name = "crashpad_database_util"
deps = [ "tools:crashpad_database_util" ]
}
group("tests") {
testonly = true
deps = [ ":crashpad-test" ]
}
}
} else if (crashpad_is_standalone || crashpad_is_external) {
test("crashpad_client_test") {
deps = [
"client:client_test",
"test:googlemock_main",
]
}
test("crashpad_handler_test") {
deps = [
"handler:handler_test",
"test:googletest_main",
]
if (crashpad_is_ios || crashpad_is_fuchsia) {
deps -= [ "handler:handler_test" ]
}
}
test("crashpad_minidump_test") {
deps = [
"minidump:minidump_test",
"test:googletest_main",
]
}
test("crashpad_snapshot_test") {
deps = [
"snapshot:snapshot_test",
"test:googlemock_main",
]
}
test("crashpad_test_test") {
deps = [
"test:googlemock_main",
"test:test_test",
]
}
test("crashpad_util_test") {
deps = [
"test:googlemock_main",
"util:util_test",
]
}
}
if (crashpad_is_ios) {
group("ios_xcuitests") {
testonly = true
deps = [ "test/ios:all_tests" ]
}
}

View File

@ -0,0 +1,68 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# When building in Chromium, these configs is used to set #defines that indicate
# whether code is being built standalone, or in Chromium, or potentially in some
# other configutation.
import("crashpad_buildconfig.gni")
config("crashpad_is_in_chromium") {
if (crashpad_is_in_chromium) {
defines = [ "CRASHPAD_IS_IN_CHROMIUM" ]
}
}
config("crashpad_is_in_fuchsia") {
if (crashpad_is_in_fuchsia) {
defines = [ "CRASHPAD_IS_IN_FUCHSIA" ]
}
}
group("default_exe_manifest_win") {
if (crashpad_is_in_chromium) {
deps = [ "//build/win:default_exe_manifest" ]
}
}
config("crashpad_fuzzer_flags") {
cflags = [
"-fsanitize=address",
"-fsanitize-address-use-after-scope",
"-fsanitize=fuzzer",
]
ldflags = [ "-fsanitize=address" ]
}
if (crashpad_is_ios) {
group("ios_enable_arc") {
if (crashpad_is_in_chromium) {
public_configs = [ "//build/config/compiler:enable_arc" ]
} else if (crashpad_is_standalone) {
public_configs =
[ "//third_party/mini_chromium/mini_chromium/build/config:ios_enable_arc" ]
}
}
group("ios_xctest") {
if (crashpad_is_in_chromium) {
public_configs = [ "//build/config/ios:xctest_config" ]
} else if (crashpad_is_standalone) {
public_configs = [
"//third_party/mini_chromium/mini_chromium/build/ios:xctest_config",
]
}
}
}

View File

@ -0,0 +1,99 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Intentionally very minimal, so that Crashpad can build in-tree in a variety of
# other projects, unrelated to the variables that are set in those projects'
# BUILDCONFIG.gn. Do not add more variables here. Instead, make them available
# in build/crashpad_buildconfig.gni if they must be globally available.
if (target_os == "") {
target_os = host_os
}
if (current_os == "") {
current_os = target_os
}
if (target_cpu == "") {
target_cpu = host_cpu
}
if (current_cpu == "") {
current_cpu = target_cpu
}
import("//build/crashpad_buildconfig.gni")
if (crashpad_is_standalone) {
_mini_chromium_dir = "//third_party/mini_chromium/mini_chromium"
} else if (crashpad_is_external) {
_mini_chromium_dir = "//../../mini_chromium/mini_chromium"
}
if (current_os == "win") {
set_default_toolchain(
"$_mini_chromium_dir/build/config:msvc_toolchain_$current_cpu")
} else {
set_default_toolchain("$_mini_chromium_dir/build/config:gcc_like_toolchain")
}
declare_args() {
# When true, enables the debug configuration, with additional run-time checks
# and logging. When false, enables the release configuration, with additional
# optimizations.
is_debug = false
# When true, build all code with -fsanitize=fuzzer, and enable various
# *_fuzzer targets.
crashpad_use_libfuzzer = false
}
_default_configs = [
"$_mini_chromium_dir/build/config:default",
"$_mini_chromium_dir/build/config:Wexit_time_destructors",
"$_mini_chromium_dir/build/config:Wimplicit_fallthrough",
]
if (crashpad_use_libfuzzer) {
_default_configs += [ "//build/config:crashpad_fuzzer_flags" ]
}
_default_executable_configs = _default_configs + [
"$_mini_chromium_dir/build/config:executable",
"$_mini_chromium_dir/build/config:win_console",
]
set_defaults("source_set") {
configs = _default_configs
}
set_defaults("static_library") {
configs = _default_configs
}
set_defaults("executable") {
configs = _default_executable_configs
}
set_defaults("loadable_module") {
configs = _default_configs
}
set_defaults("shared_library") {
configs = _default_configs
}
set_defaults("test") {
configs = _default_executable_configs
}

View File

@ -0,0 +1,160 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
declare_args() {
# Determines various flavors of build configuration, and which concrete
# targets to use for dependencies. Valid values are "standalone", "chromium",
# "fuchsia", "dart" or "external".
crashpad_dependencies = "standalone"
if (defined(is_fuchsia_tree) && is_fuchsia_tree) {
crashpad_dependencies = "fuchsia"
}
}
assert(
crashpad_dependencies == "chromium" || crashpad_dependencies == "fuchsia" ||
crashpad_dependencies == "standalone" ||
crashpad_dependencies == "external" || crashpad_dependencies == "dart")
crashpad_is_in_chromium = crashpad_dependencies == "chromium"
crashpad_is_in_fuchsia = crashpad_dependencies == "fuchsia"
crashpad_is_in_dart = crashpad_dependencies == "dart"
crashpad_is_external = crashpad_dependencies == "external"
crashpad_is_standalone = crashpad_dependencies == "standalone"
# This is the parent directory that contains the mini_chromium source dir.
# This variable is not used when crashpad_is_in_chromium.
if (crashpad_is_in_fuchsia) {
mini_chromium_source_parent = "//third_party/crashpad/third_party/mini_chromium"
} else {
mini_chromium_source_parent = "../third_party/mini_chromium"
}
# This is the source directory of mini_chromium (what is checked out).
_mini_chromium_source_root = "$mini_chromium_source_parent/mini_chromium"
# This references the mini_chromium location for importing GN files.
if (crashpad_is_external || crashpad_is_in_dart) {
mini_chromium_import_root = "../../../$_mini_chromium_source_root"
} else if (crashpad_is_in_fuchsia) {
mini_chromium_import_root = "//third_party/mini_chromium"
} else {
mini_chromium_import_root = _mini_chromium_source_root
}
if (crashpad_is_in_chromium) {
crashpad_is_mac = is_mac
crashpad_is_ios = is_ios
crashpad_is_win = is_win
crashpad_is_linux = is_linux || is_chromeos
crashpad_is_android = is_android
crashpad_is_fuchsia = is_fuchsia
crashpad_is_posix = is_posix
crashpad_is_clang = is_clang
} else {
import("$mini_chromium_import_root/build/compiler.gni")
import("$mini_chromium_import_root/build/platform.gni")
crashpad_is_mac = mini_chromium_is_mac
crashpad_is_ios = mini_chromium_is_ios
crashpad_is_win = mini_chromium_is_win
crashpad_is_linux = mini_chromium_is_linux
crashpad_is_android = mini_chromium_is_android
crashpad_is_fuchsia = mini_chromium_is_fuchsia
crashpad_is_posix = mini_chromium_is_posix
crashpad_is_clang = mini_chromium_is_clang
}
template("crashpad_executable") {
executable(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
if (crashpad_is_in_fuchsia) {
conversion_config = [ "//build/config:Wno-conversion" ]
if (configs + conversion_config - conversion_config == configs) {
# TODO(https://fxbug.dev/58162): Decide if these are worth enabling.
configs += conversion_config
}
}
}
}
template("crashpad_loadable_module") {
loadable_module(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
if (crashpad_is_in_fuchsia) {
conversion_config = [ "//build/config:Wno-conversion" ]
if (configs + conversion_config - conversion_config == configs) {
# TODO(https://fxbug.dev/58162): Decide if these are worth enabling.
configs += conversion_config
}
}
}
}
template("crashpad_static_library") {
static_library(target_name) {
forward_variables_from(invoker,
"*",
[
"configs",
"remove_configs",
])
if (defined(invoker.remove_configs)) {
configs -= invoker.remove_configs
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
if (crashpad_is_in_fuchsia) {
conversion_config = [ "//build/config:Wno-conversion" ]
if (configs + conversion_config - conversion_config == configs) {
# TODO(https://fxbug.dev/58162): Decide if these are worth enabling.
configs += conversion_config
}
}
}
}

View File

@ -0,0 +1,58 @@
# Copyright 2018 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("crashpad_buildconfig.gni")
import("test.gni")
if (crashpad_is_in_chromium) {
import("//testing/libfuzzer/fuzzer_test.gni")
}
template("crashpad_fuzzer_test") {
if (crashpad_is_standalone && crashpad_use_libfuzzer) {
test(target_name) {
forward_variables_from(invoker,
[
"cflags",
"cflags_cc",
"check_includes",
"defines",
"include_dirs",
"sources",
])
configs += [ "..:crashpad_config" ]
if (defined(invoker.deps)) {
deps = invoker.deps
}
deps += [ "../third_party/libfuzzer" ]
if (!defined(invoker.cflags)) {
cflags = []
}
cflags += [ "-fsanitize=fuzzer" ]
}
if (defined(invoker.seed_corpus)) {
not_needed(invoker, [ "seed_corpus" ])
}
} else if (crashpad_is_in_chromium && use_fuzzing_engine) {
# Append "crashpad_" to the beginning of the fuzzer's name to make it easier
# in Chromium to recognize where fuzzer came from.
forward_variables_from(invoker, "*")
fuzzer_test("crashpad_" + target_name) {
}
} else {
not_needed(invoker, "*")
group(target_name) {
}
}
}

View File

@ -0,0 +1,74 @@
#!/usr/bin/env python3
# Copyright 2018 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Various code adapted from:
# https://cs.chromium.org/chromium/src/build/linux/sysroot_scripts/install-sysroot.py
import os
import shutil
import subprocess
import sys
import urllib.request
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
# Sysroot revision from:
# https://cs.chromium.org/chromium/src/build/linux/sysroot_scripts/sysroots.json
SERVER = 'https://commondatastorage.googleapis.com'
PATH = 'chrome-linux-sysroot/toolchain'
REVISION = '43a87bbebccad99325fdcf34166295b121ee15c7'
FILENAME = 'debian_sid_amd64_sysroot.tar.xz'
def main():
url = '%s/%s/%s/%s' % (SERVER, PATH, REVISION, FILENAME)
sysroot = os.path.join(SCRIPT_DIR, os.pardir, 'third_party', 'linux',
'sysroot')
stamp = os.path.join(sysroot, '.stamp')
if os.path.exists(stamp):
with open(stamp) as s:
if s.read() == url:
return
print('Installing Debian root image from %s' % url)
if os.path.isdir(sysroot):
shutil.rmtree(sysroot)
os.mkdir(sysroot)
tarball = os.path.join(sysroot, FILENAME)
print('Downloading %s' % url)
for _ in range(3):
response = urllib.request.urlopen(url)
with open(tarball, 'wb') as f:
f.write(response.read())
break
else:
raise Exception('Failed to download %s' % url)
subprocess.check_call(['tar', 'xf', tarball, '-C', sysroot])
os.remove(tarball)
with open(stamp, 'w') as s:
s.write(url)
if __name__ == '__main__':
main()
sys.exit(0)

View File

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleIdentifier</key>
<string>${IOS_BUNDLE_ID_PREFIX}.googletest.${GTEST_BUNDLE_ID_SUFFIX:rfc1034identifier}</string>
<key>UIApplicationDelegate</key>
<string>CrashpadUnitTestDelegate</string>
</dict>
</plist>

View File

@ -0,0 +1,361 @@
#!/usr/bin/env python
# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Convert GN Xcode projects to platform and configuration independent targets.
GN generates Xcode projects that build one configuration only. However, typical
iOS development involves using the Xcode IDE to toggle the platform and
configuration. This script replaces the 'gn' configuration with 'Debug',
'Release' and 'Profile', and changes the ninja invocation to honor these
configurations.
"""
import argparse
import collections
import copy
import filecmp
import json
import hashlib
import os
import re
import shutil
import subprocess
import sys
import tempfile
class XcodeProject(object):
def __init__(self, objects, counter = 0):
self.objects = objects
self.counter = 0
def AddObject(self, parent_name, obj):
while True:
self.counter += 1
str_id = "%s %s %d" % (parent_name, obj['isa'], self.counter)
new_id = hashlib.sha1(str_id.encode("utf-8")).hexdigest()[:24].upper()
# Make sure ID is unique. It's possible there could be an id conflict
# since this is run after GN runs.
if new_id not in self.objects:
self.objects[new_id] = obj
return new_id
def check_output(command):
"""Wrapper around subprocess.check_output that decode output as utf-8."""
return subprocess.check_output(command).decode('utf-8')
def CopyFileIfChanged(source_path, target_path):
"""Copy |source_path| to |target_path| if different."""
target_dir = os.path.dirname(target_path)
if not os.path.isdir(target_dir):
os.makedirs(target_dir)
if not os.path.exists(target_path) or \
not filecmp.cmp(source_path, target_path):
shutil.copyfile(source_path, target_path)
def CopyTreeIfChanged(source, target):
"""Copy |source| to |target| recursively; files are copied iff changed."""
if os.path.isfile(source):
return CopyFileIfChanged(source, target)
if not os.path.isdir(target):
os.makedirs(target)
for name in os.listdir(source):
CopyTreeIfChanged(
os.path.join(source, name),
os.path.join(target, name))
def LoadXcodeProjectAsJSON(project_dir):
"""Return Xcode project at |path| as a JSON string."""
return check_output([
'plutil', '-convert', 'json', '-o', '-',
os.path.join(project_dir, 'project.pbxproj')])
def WriteXcodeProject(output_path, json_string):
"""Save Xcode project to |output_path| as XML."""
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(json_string.encode("utf-8"))
temp_file.flush()
subprocess.check_call(['plutil', '-convert', 'xml1', temp_file.name])
CopyFileIfChanged(
temp_file.name,
os.path.join(output_path, 'project.pbxproj'))
def UpdateXcodeProject(project_dir, configurations, root_dir):
"""Update inplace Xcode project to support multiple configurations.
Args:
project_dir: path to the input Xcode project
configurations: list of string corresponding to the configurations that
need to be supported by the tweaked Xcode projects, must contains at
least one value.
root_dir: path to the root directory used to find markdown files
"""
json_data = json.loads(LoadXcodeProjectAsJSON(project_dir))
project = XcodeProject(json_data['objects'])
objects_to_remove = []
for value in list(project.objects.values()):
isa = value['isa']
# Teach build shell script to look for the configuration and platform.
if isa == 'PBXShellScriptBuildPhase':
shell_path = value['shellPath']
if shell_path.endswith('/sh'):
value['shellScript'] = value['shellScript'].replace(
'ninja -C .',
'ninja -C "../${CONFIGURATION}${EFFECTIVE_PLATFORM_NAME}"')
elif re.search('[ /]python[23]?$', shell_path):
value['shellScript'] = value['shellScript'].replace(
'ninja_params = [ \'-C\', \'.\' ]',
'ninja_params = [ \'-C\', \'../\' + os.environ[\'CONFIGURATION\']'
' + os.environ[\'EFFECTIVE_PLATFORM_NAME\'] ]')
# Add new configuration, using the first one as default.
if isa == 'XCConfigurationList':
value['defaultConfigurationName'] = configurations[0]
objects_to_remove.extend(value['buildConfigurations'])
build_config_template = project.objects[value['buildConfigurations'][0]]
build_config_template['buildSettings']['CONFIGURATION_BUILD_DIR'] = \
'$(PROJECT_DIR)/../$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)'
value['buildConfigurations'] = []
for configuration in configurations:
new_build_config = copy.copy(build_config_template)
new_build_config['name'] = configuration
value['buildConfigurations'].append(
project.AddObject('products', new_build_config))
for object_id in objects_to_remove:
del project.objects[object_id]
source = GetOrCreateRootGroup(project, json_data['rootObject'], 'Source')
AddMarkdownToProject(project, root_dir, source)
SortFileReferencesByName(project, source)
objects = collections.OrderedDict(sorted(project.objects.items()))
WriteXcodeProject(project_dir, json.dumps(json_data))
def CreateGroup(project, parent_group, group_name, path=None):
group_object = {
'children': [],
'isa': 'PBXGroup',
'name': group_name,
'sourceTree': '<group>',
}
if path is not None:
group_object['path'] = path
parent_group_name = parent_group.get('name', '')
group_object_key = project.AddObject(parent_group_name, group_object)
parent_group['children'].append(group_object_key)
return group_object
def GetOrCreateRootGroup(project, root_object, group_name):
main_group = project.objects[project.objects[root_object]['mainGroup']]
for child_key in main_group['children']:
child = project.objects[child_key]
if child['name'] == group_name:
return child
return CreateGroup(project, main_group, group_name, path='../..')
class ObjectKey(object):
"""Wrapper around PBXFileReference and PBXGroup for sorting.
A PBXGroup represents a "directory" containing a list of files in an
Xcode project; it can contain references to a list of directories or
files.
A PBXFileReference represents a "file".
The type is stored in the object "isa" property as a string. Since we
want to sort all directories before all files, the < and > operators
are defined so that if "isa" is different, they are sorted in the
reverse of alphabetic ordering, otherwise the name (or path) property
is checked and compared in alphabetic order.
"""
def __init__(self, obj):
self.isa = obj['isa']
if 'name' in obj:
self.name = obj['name']
else:
self.name = obj['path']
def __lt__(self, other):
if self.isa != other.isa:
return self.isa > other.isa
return self.name < other.name
def __gt__(self, other):
if self.isa != other.isa:
return self.isa < other.isa
return self.name > other.name
def __eq__(self, other):
return self.isa == other.isa and self.name == other.name
def SortFileReferencesByName(project, group_object):
SortFileReferencesByNameWithSortKey(
project, group_object, lambda ref: ObjectKey(project.objects[ref]))
def SortFileReferencesByNameWithSortKey(project, group_object, sort_key):
group_object['children'].sort(key=sort_key)
for key in group_object['children']:
child = project.objects[key]
if child['isa'] == 'PBXGroup':
SortFileReferencesByNameWithSortKey(project, child, sort_key)
def AddMarkdownToProject(project, root_dir, group_object):
list_files_cmd = ['git', '-C', root_dir, 'ls-files', '*.md']
paths = check_output(list_files_cmd).splitlines()
ios_internal_dir = os.path.join(root_dir, 'ios_internal')
if os.path.exists(ios_internal_dir):
list_files_cmd = ['git', '-C', ios_internal_dir, 'ls-files', '*.md']
ios_paths = check_output(list_files_cmd).splitlines()
paths.extend([os.path.join("ios_internal", path) for path in ios_paths])
for path in paths:
new_markdown_entry = {
"fileEncoding": "4",
"isa": "PBXFileReference",
"lastKnownFileType": "net.daringfireball.markdown",
"name": os.path.basename(path),
"path": path,
"sourceTree": "<group>"
}
new_markdown_entry_id = project.AddObject('sources', new_markdown_entry)
folder = GetFolderForPath(project, group_object, os.path.dirname(path))
folder['children'].append(new_markdown_entry_id)
def GetFolderForPath(project, group_object, path):
objects = project.objects
if not path:
return group_object
for folder in path.split('/'):
children = group_object['children']
new_root = None
for child in children:
if objects[child]['isa'] == 'PBXGroup' and \
objects[child]['name'] == folder:
new_root = objects[child]
break
if not new_root:
# If the folder isn't found we could just cram it into the leaf existing
# folder, but that leads to folders with tons of README.md inside.
new_root = CreateGroup(project, group_object, folder)
group_object = new_root
return group_object
def ConvertGnXcodeProject(root_dir, input_dir, output_dir, configurations):
'''Tweak the Xcode project generated by gn to support multiple configurations.
The Xcode projects generated by "gn gen --ide" only supports a single
platform and configuration (as the platform and configuration are set
per output directory). This method takes as input such projects and
add support for multiple configurations and platforms (to allow devs
to select them in Xcode).
Args:
input_dir: directory containing the XCode projects created by "gn gen --ide"
output_dir: directory where the tweaked Xcode projects will be saved
configurations: list of string corresponding to the configurations that
need to be supported by the tweaked Xcode projects, must contains at
least one value.
'''
# Update the project (supports legacy name "products.xcodeproj" or the new
# project name "all.xcodeproj").
for project_name in ('all.xcodeproj', 'products.xcodeproj'):
if os.path.exists(os.path.join(input_dir, project_name)):
UpdateXcodeProject(
os.path.join(input_dir, project_name),
configurations, root_dir)
CopyTreeIfChanged(os.path.join(input_dir, project_name),
os.path.join(output_dir, project_name))
else:
shutil.rmtree(os.path.join(output_dir, project_name), ignore_errors=True)
# Copy all.xcworkspace if it exists (will be removed in a future gn version).
workspace_name = 'all.xcworkspace'
if os.path.exists(os.path.join(input_dir, workspace_name)):
CopyTreeIfChanged(os.path.join(input_dir, workspace_name),
os.path.join(output_dir, workspace_name))
else:
shutil.rmtree(os.path.join(output_dir, workspace_name), ignore_errors=True)
def Main(args):
parser = argparse.ArgumentParser(
description='Convert GN Xcode projects for iOS.')
parser.add_argument(
'input',
help='directory containing [product|all] Xcode projects.')
parser.add_argument(
'output',
help='directory where to generate the iOS configuration.')
parser.add_argument(
'--add-config', dest='configurations', default=[], action='append',
help='configuration to add to the Xcode project')
parser.add_argument(
'--root', type=os.path.abspath, required=True,
help='root directory of the project')
args = parser.parse_args(args)
if not os.path.isdir(args.input):
sys.stderr.write('Input directory does not exists.\n')
return 1
# Depending on the version of "gn", there should be either one project file
# named "all.xcodeproj" or a project file named "products.xcodeproj" and a
# workspace named "all.xcworkspace".
required_files_sets = [
set(("all.xcodeproj",)),
set(("products.xcodeproj", "all.xcworkspace")),
]
for required_files in required_files_sets:
if required_files.issubset(os.listdir(args.input)):
break
else:
sys.stderr.write(
'Input directory does not contain all necessary Xcode projects.\n')
return 1
if not args.configurations:
sys.stderr.write('At least one configuration required, see --add-config.\n')
return 1
ConvertGnXcodeProject(args.root, args.input, args.output, args.configurations)
if __name__ == '__main__':
sys.exit(Main(sys.argv[1:]))

View File

@ -0,0 +1,39 @@
# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
[goma]
# Controls whether goma is enabled or not. If you generally use goma but
# want to disable goma for a single build, consider using the environment
# variable GOMA_DISABLED.
enabled = False
install = "$GOMA_DIR"
[xcode]
# Controls settings for the generated Xcode project. If jobs is non-zero
# it will be passed to the ninja invocation in Xcode project.
jobs = 0
[build]
# Controls the build output. The only supported values are "64-bit", "32-bit"
# and "fat" (for a fat binary supporting both "32-bit" and "64-bit" cpus).
arch = "64-bit"
[gn_args]
# Values in that section will be copied verbatim in the generated args.gn file.
target_os = "ios"
[filters]
# List of target files to pass to --filters argument of gn gen when generating
# the Xcode project. By default, list all targets from ios/ and ios_internal/
# and the targets corresponding to the unit tests run on the bots.

View File

@ -0,0 +1,348 @@
#!/usr/bin/env python
# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import convert_gn_xcodeproj
import errno
import os
import re
import shutil
import subprocess
import sys
import tempfile
try:
import configparser
except ImportError:
import ConfigParser as configparser
try:
import StringIO as io
except ImportError:
import io
SUPPORTED_TARGETS = ('iphoneos', 'iphonesimulator')
SUPPORTED_CONFIGS = ('Debug', 'Release', 'Profile', 'Official', 'Coverage')
class ConfigParserWithStringInterpolation(configparser.SafeConfigParser):
'''A .ini file parser that supports strings and environment variables.'''
ENV_VAR_PATTERN = re.compile(r'\$([A-Za-z0-9_]+)')
def values(self, section):
return map(lambda kv: self._UnquoteString(self._ExpandEnvVar(kv[1])),
configparser.ConfigParser.items(self, section))
def getstring(self, section, option):
return self._UnquoteString(self._ExpandEnvVar(self.get(section,
option)))
def _UnquoteString(self, string):
if not string or string[0] != '"' or string[-1] != '"':
return string
return string[1:-1]
def _ExpandEnvVar(self, value):
match = self.ENV_VAR_PATTERN.search(value)
if not match:
return value
name, (begin, end) = match.group(1), match.span(0)
prefix, suffix = value[:begin], self._ExpandEnvVar(value[end:])
return prefix + os.environ.get(name, '') + suffix
class GnGenerator(object):
'''Holds configuration for a build and method to generate gn default
files.'''
FAT_BUILD_DEFAULT_ARCH = '64-bit'
TARGET_CPU_VALUES = {
'iphoneos': {
'32-bit': '"arm"',
'64-bit': '"arm64"',
},
'iphonesimulator': {
'32-bit': '"x86"',
'64-bit': '"x64"',
}
}
def __init__(self, settings, config, target):
assert target in SUPPORTED_TARGETS
assert config in SUPPORTED_CONFIGS
self._settings = settings
self._config = config
self._target = target
def _GetGnArgs(self):
"""Build the list of arguments to pass to gn.
Returns:
A list of tuple containing gn variable names and variable values (it
is not a dictionary as the order needs to be preserved).
"""
args = []
args.append(('is_debug', self._config in ('Debug', 'Coverage')))
if os.environ.get('FORCE_MAC_TOOLCHAIN', '0') == '1':
args.append(('use_system_xcode', False))
cpu_values = self.TARGET_CPU_VALUES[self._target]
build_arch = self._settings.getstring('build', 'arch')
if build_arch == 'fat':
target_cpu = cpu_values[self.FAT_BUILD_DEFAULT_ARCH]
args.append(('target_cpu', target_cpu))
args.append(
('additional_target_cpus',
[cpu for cpu in cpu_values.itervalues() if cpu != target_cpu]))
else:
args.append(('target_cpu', cpu_values[build_arch]))
# Add user overrides after the other configurations so that they can
# refer to them and override them.
args.extend(self._settings.items('gn_args'))
return args
def Generate(self, gn_path, root_path, out_path):
buf = io.StringIO()
self.WriteArgsGn(buf)
WriteToFileIfChanged(os.path.join(out_path, 'args.gn'),
buf.getvalue(),
overwrite=True)
subprocess.check_call(
self.GetGnCommand(gn_path, root_path, out_path, True))
def CreateGnRules(self, gn_path, root_path, out_path):
buf = io.StringIO()
self.WriteArgsGn(buf)
WriteToFileIfChanged(os.path.join(out_path, 'args.gn'),
buf.getvalue(),
overwrite=True)
buf = io.StringIO()
gn_command = self.GetGnCommand(gn_path, root_path, out_path, False)
self.WriteBuildNinja(buf, gn_command)
WriteToFileIfChanged(os.path.join(out_path, 'build.ninja'),
buf.getvalue(),
overwrite=False)
buf = io.StringIO()
self.WriteBuildNinjaDeps(buf)
WriteToFileIfChanged(os.path.join(out_path, 'build.ninja.d'),
buf.getvalue(),
overwrite=False)
def WriteArgsGn(self, stream):
stream.write('# This file was generated by setup-gn.py. Do not edit\n')
stream.write('# but instead use ~/.setup-gn or $repo/.setup-gn files\n')
stream.write('# to configure settings.\n')
stream.write('\n')
if self._settings.has_section('$imports$'):
for import_rule in self._settings.values('$imports$'):
stream.write('import("%s")\n' % import_rule)
stream.write('\n')
gn_args = self._GetGnArgs()
for name, value in gn_args:
if isinstance(value, bool):
stream.write('%s = %s\n' % (name, str(value).lower()))
elif isinstance(value, list):
stream.write('%s = [%s' %
(name, '\n' if len(value) > 1 else ''))
if len(value) == 1:
prefix = ' '
suffix = ' '
else:
prefix = ' '
suffix = ',\n'
for item in value:
if isinstance(item, bool):
stream.write('%s%s%s' %
(prefix, str(item).lower(), suffix))
else:
stream.write('%s%s%s' % (prefix, item, suffix))
stream.write(']\n')
else:
stream.write('%s = %s\n' % (name, value))
def WriteBuildNinja(self, stream, gn_command):
stream.write('rule gn\n')
stream.write(' command = %s\n' % NinjaEscapeCommand(gn_command))
stream.write(' description = Regenerating ninja files\n')
stream.write('\n')
stream.write('build build.ninja: gn\n')
stream.write(' generator = 1\n')
stream.write(' depfile = build.ninja.d\n')
def WriteBuildNinjaDeps(self, stream):
stream.write('build.ninja: nonexistant_file.gn\n')
def GetGnCommand(self, gn_path, src_path, out_path, generate_xcode_project):
gn_command = [gn_path, '--root=%s' % os.path.realpath(src_path), '-q']
if generate_xcode_project:
gn_command.append('--ide=xcode')
gn_command.append('--ninja-executable=autoninja')
if self._settings.has_section('filters'):
target_filters = self._settings.values('filters')
if target_filters:
gn_command.append('--filters=%s' % ';'.join(target_filters))
else:
gn_command.append('--check')
gn_command.append('gen')
gn_command.append('//%s' % os.path.relpath(os.path.abspath(out_path),
os.path.abspath(src_path)))
return gn_command
def WriteToFileIfChanged(filename, content, overwrite):
'''Write |content| to |filename| if different. If |overwrite| is False
and the file already exists it is left untouched.'''
if os.path.exists(filename):
if not overwrite:
return
with open(filename) as file:
if file.read() == content:
return
if not os.path.isdir(os.path.dirname(filename)):
os.makedirs(os.path.dirname(filename))
with open(filename, 'w') as file:
file.write(content)
def NinjaNeedEscape(arg):
'''Returns True if |arg| needs to be escaped when written to .ninja file.'''
return ':' in arg or '*' in arg or ';' in arg
def NinjaEscapeCommand(command):
'''Escapes |command| in order to write it to .ninja file.'''
result = []
for arg in command:
if NinjaNeedEscape(arg):
arg = arg.replace(':', '$:')
arg = arg.replace(';', '\\;')
arg = arg.replace('*', '\\*')
else:
result.append(arg)
return ' '.join(result)
def FindGn():
'''Returns absolute path to gn binary looking at the PATH env variable.'''
for path in os.environ['PATH'].split(os.path.pathsep):
gn_path = os.path.join(path, 'gn')
if os.path.isfile(gn_path) and os.access(gn_path, os.X_OK):
return gn_path
return None
def GenerateXcodeProject(gn_path, root_dir, out_dir, settings):
'''Convert GN generated Xcode project into multi-configuration Xcode
project.'''
temp_path = tempfile.mkdtemp(
prefix=os.path.abspath(os.path.join(out_dir, '_temp')))
try:
generator = GnGenerator(settings, 'Debug', 'iphonesimulator')
generator.Generate(gn_path, root_dir, temp_path)
convert_gn_xcodeproj.ConvertGnXcodeProject(
root_dir, os.path.join(temp_path), os.path.join(out_dir, 'build'),
SUPPORTED_CONFIGS)
finally:
if os.path.exists(temp_path):
shutil.rmtree(temp_path)
def GenerateGnBuildRules(gn_path, root_dir, out_dir, settings):
'''Generates all template configurations for gn.'''
for config in SUPPORTED_CONFIGS:
for target in SUPPORTED_TARGETS:
build_dir = os.path.join(out_dir, '%s-%s' % (config, target))
generator = GnGenerator(settings, config, target)
generator.CreateGnRules(gn_path, root_dir, build_dir)
def Main(args):
default_root = os.path.normpath(
os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
parser = argparse.ArgumentParser(
description='Generate build directories for use with gn.')
parser.add_argument(
'root',
default=default_root,
nargs='?',
help='root directory where to generate multiple out configurations')
parser.add_argument('--import',
action='append',
dest='import_rules',
default=[],
help='path to file defining default gn variables')
parser.add_argument('--gn-path',
default=None,
help='path to gn binary (default: look up in $PATH)')
parser.add_argument(
'--build-dir',
default='out',
help='path where the build should be created (default: %(default)s)')
args = parser.parse_args(args)
# Load configuration (first global and then any user overrides).
settings = ConfigParserWithStringInterpolation()
settings.read([
os.path.splitext(__file__)[0] + '.config',
os.path.expanduser('~/.setup-gn'),
])
# Add private sections corresponding to --import argument.
if args.import_rules:
settings.add_section('$imports$')
for i, import_rule in enumerate(args.import_rules):
if not import_rule.startswith('//'):
import_rule = '//%s' % os.path.relpath(
os.path.abspath(import_rule), os.path.abspath(args.root))
settings.set('$imports$', '$rule%d$' % i, import_rule)
# Validate settings.
if settings.getstring('build', 'arch') not in ('64-bit', '32-bit', 'fat'):
sys.stderr.write('ERROR: invalid value for build.arch: %s\n' %
settings.getstring('build', 'arch'))
sys.exit(1)
# Find path to gn binary either from command-line or in PATH.
if args.gn_path:
gn_path = args.gn_path
else:
gn_path = FindGn()
if gn_path is None:
sys.stderr.write('ERROR: cannot find gn in PATH\n')
sys.exit(1)
out_dir = os.path.join(args.root, args.build_dir)
if not os.path.isdir(out_dir):
os.makedirs(out_dir)
GenerateXcodeProject(gn_path, args.root, out_dir, settings)
GenerateGnBuildRules(gn_path, args.root, out_dir, settings)
if __name__ == '__main__':
sys.exit(Main(sys.argv[1:]))

View File

@ -0,0 +1,479 @@
#!/usr/bin/env python
# coding: utf-8
# Copyright 2014 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import print_function
import argparse
import os
import pipes
import posixpath
import re
import subprocess
import sys
import tempfile
import uuid
CRASHPAD_DIR = os.path.join(os.path.dirname(os.path.abspath(__file__)),
os.pardir)
IS_WINDOWS_HOST = sys.platform.startswith('win')
def _FindGNFromBinaryDir(binary_dir):
"""Attempts to determine the path to a GN binary used to generate the build
files in the given binary_dir. This is necessary because `gn` might not be
in the path or might be in a non-standard location, particularly on build
machines."""
build_ninja = os.path.join(binary_dir, 'build.ninja')
if os.path.isfile(build_ninja):
with open(build_ninja, 'rb') as f:
# Look for the always-generated regeneration rule of the form:
#
# rule gn
# command = <gn binary> ... arguments ...
#
# to extract the gn binary's full path.
found_rule_gn = False
for line in f:
if line.strip() == 'rule gn':
found_rule_gn = True
continue
if found_rule_gn:
if len(line) == 0 or line[0] != ' ':
return None
if line.startswith(' command = '):
gn_command_line_parts = line.strip().split(' ')
if len(gn_command_line_parts) > 2:
return os.path.join(binary_dir,
gn_command_line_parts[2])
return None
def _BinaryDirTargetOS(binary_dir):
"""Returns the apparent target OS of binary_dir, or None if none appear to
be explicitly specified."""
gn_path = _FindGNFromBinaryDir(binary_dir)
if gn_path:
# Look for a GN “target_os”.
popen = subprocess.Popen([
gn_path, '--root=' + CRASHPAD_DIR, 'args', binary_dir,
'--list=target_os', '--short'
],
shell=IS_WINDOWS_HOST,
stdout=subprocess.PIPE,
stderr=open(os.devnull))
value = popen.communicate()[0]
if popen.returncode == 0:
match = re.match('target_os = "(.*)"$', value.decode('utf-8'))
if match:
return match.group(1)
# For GYP with Ninja, look for the appearance of “linux-android” in the path
# to ar. This path is configured by gyp_crashpad_android.py.
build_ninja_path = os.path.join(binary_dir, 'build.ninja')
if os.path.exists(build_ninja_path):
with open(build_ninja_path) as build_ninja_file:
build_ninja_content = build_ninja_file.read()
match = re.search('-linux-android(eabi)?-ar$', build_ninja_content,
re.MULTILINE)
if match:
return 'android'
return None
def _EnableVTProcessingOnWindowsConsole():
"""Enables virtual terminal processing for ANSI/VT100-style escape sequences
on a Windows console attached to standard output. Returns True on success.
Returns False if standard output is not a console or if virtual terminal
processing is not supported. The feature was introduced in Windows 10.
"""
import pywintypes
import win32console
import winerror
stdout_console = win32console.GetStdHandle(win32console.STD_OUTPUT_HANDLE)
try:
console_mode = stdout_console.GetConsoleMode()
except pywintypes.error as e:
if e.winerror == winerror.ERROR_INVALID_HANDLE:
# Standard output is not a console.
return False
raise
try:
# From <wincon.h>. This would be
# win32console.ENABLE_VIRTUAL_TERMINAL_PROCESSING, but its too new to
# be defined there.
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004
stdout_console.SetConsoleMode(console_mode |
ENABLE_VIRTUAL_TERMINAL_PROCESSING)
except pywintypes.error as e:
if e.winerror == winerror.ERROR_INVALID_PARAMETER:
# ANSI/VT100-style escape sequence processing isnt supported before
# Windows 10.
return False
raise
return True
def _RunOnAndroidTarget(binary_dir, test, android_device, extra_command_line):
local_test_path = os.path.join(binary_dir, test)
MAYBE_UNSUPPORTED_TESTS = (
'crashpad_client_test',
'crashpad_handler_test',
'crashpad_minidump_test',
'crashpad_snapshot_test',
)
if not os.path.exists(local_test_path) and test in MAYBE_UNSUPPORTED_TESTS:
print('This test is not present and may not be supported, skipping')
return
def _adb(*args):
# Flush all of this scripts own buffered stdout output before running
# adb, which will likely produce its own output on stdout.
sys.stdout.flush()
adb_command = ['adb', '-s', android_device]
adb_command.extend(args)
subprocess.check_call(adb_command, shell=IS_WINDOWS_HOST)
def _adb_push(sources, destination):
args = list(sources)
args.append(destination)
_adb('push', *args)
def _adb_shell(command_args, env={}):
# Build a command to execute via “sh -c” instead of invoking it
# directly. Heres why:
#
# /system/bin/env isnt normally present prior to Android 6.0 (M), where
# toybox was introduced (Android platform/manifest 9a2c01e8450b).
# Instead, set environment variables by using the shells internal
# “export” command.
#
# adbd prior to Android 7.0 (N), and the adb client prior to SDK
# platform-tools version 24, dont know how to communicate a shell
# commands exit status. This was added in Android platform/system/core
# 606835ae5c4b). With older adb servers and clients, adb will “exit 0”
# indicating success even if the command failed on the device. This
# makes subprocess.check_call() semantics difficult to implement
# directly. As a workaround, have the device send the commands exit
# status over stdout and pick it back up in this function.
#
# Both workarounds are implemented by giving the device a simple script,
# which adbd will run as an “sh -c” argument.
adb_command = ['adb', '-s', android_device, 'shell']
script_commands = []
for k, v in env.items():
script_commands.append('export %s=%s' %
(pipes.quote(k), pipes.quote(v)))
script_commands.extend([
' '.join(pipes.quote(x) for x in command_args), 'status=${?}',
'echo "status=${status}"', 'exit ${status}'
])
adb_command.append('; '.join(script_commands))
child = subprocess.Popen(adb_command,
shell=IS_WINDOWS_HOST,
stdin=open(os.devnull),
stdout=subprocess.PIPE)
FINAL_LINE_RE = re.compile('status=(\d+)$')
final_line = None
while True:
# Use readline so that the test output appears “live” when running.
data = child.stdout.readline().decode('utf-8')
if data == '':
break
if final_line is not None:
# It wasnt really the final line.
print(final_line, end='')
final_line = None
if FINAL_LINE_RE.match(data.rstrip()):
final_line = data
else:
print(data, end='')
if final_line is None:
# Maybe there was some stderr output after the end of stdout. Old
# versions of adb, prior to when the exit status could be
# communicated, smush the two together.
raise subprocess.CalledProcessError(-1, adb_command)
status = int(FINAL_LINE_RE.match(final_line.rstrip()).group(1))
if status != 0:
raise subprocess.CalledProcessError(status, adb_command)
child.wait()
if child.returncode != 0:
raise subprocess.CalledProcessError(subprocess.returncode,
adb_command)
# /system/bin/mktemp isnt normally present prior to Android 6.0 (M), where
# toybox was introduced (Android platform/manifest 9a2c01e8450b). Fake it
# with a host-generated name. This wont retry if the name is in use, but
# with 122 bits of randomness, it should be OK. This uses “mkdir” instead of
# “mkdir -p”because the latter will not indicate failure if the directory
# already exists.
device_temp_dir = '/data/local/tmp/%s.%s' % (test, uuid.uuid4().hex)
_adb_shell(['mkdir', device_temp_dir])
try:
# Specify test dependencies that must be pushed to the device. This
# could be determined automatically in a GN build, following the example
# used for Fuchsia. Since nothing like that exists for GYP, hard-code it
# for supported tests.
test_build_artifacts = [test, 'crashpad_handler']
test_data = ['test/test_paths_test_data_root.txt']
if test == 'crashpad_test_test':
test_build_artifacts.append(
'crashpad_test_test_multiprocess_exec_test_child')
elif test == 'crashpad_util_test':
test_data.append('util/net/testdata/')
# Establish the directory structure on the device.
device_out_dir = posixpath.join(device_temp_dir, 'out')
device_mkdirs = [device_out_dir]
for source_path in test_data:
# A trailing slash could reasonably mean to copy an entire
# directory, but will interfere with whats needed from the path
# split. All parent directories of any source_path need to be be
# represented in device_mkdirs, but its important that no
# source_path itself wind up in device_mkdirs, even if source_path
# names a directory, because that would cause the “adb push” of the
# directory below to behave incorrectly.
if source_path.endswith(posixpath.sep):
source_path = source_path[:-1]
device_source_path = posixpath.join(device_temp_dir, source_path)
device_mkdir = posixpath.split(device_source_path)[0]
if device_mkdir not in device_mkdirs:
device_mkdirs.append(device_mkdir)
adb_mkdir_command = ['mkdir', '-p']
adb_mkdir_command.extend(device_mkdirs)
_adb_shell(adb_mkdir_command)
# Push the test binary and any other build output to the device.
local_test_build_artifacts = []
for artifact in test_build_artifacts:
local_test_build_artifacts.append(os.path.join(
binary_dir, artifact))
_adb_push(local_test_build_artifacts, device_out_dir)
# Push test data to the device.
for source_path in test_data:
_adb_push([os.path.join(CRASHPAD_DIR, source_path)],
posixpath.join(device_temp_dir, source_path))
# Run the test on the device. Pass the test data root in the
# environment.
#
# Because the test will not run with its standard output attached to a
# pseudo-terminal device, Google Test will not normally enable colored
# output, so mimic Google Tests own logic for deciding whether to
# enable color by checking this scripts own standard output connection.
# The list of TERM values comes from Google Tests
# googletest/src/gtest.cc testing::internal::ShouldUseColor().
env = {'CRASHPAD_TEST_DATA_ROOT': device_temp_dir}
gtest_color = os.environ.get('GTEST_COLOR')
if gtest_color in ('auto', None):
if (sys.stdout.isatty() and
(os.environ.get('TERM')
in ('xterm', 'xterm-color', 'xterm-256color', 'screen',
'screen-256color', 'tmux', 'tmux-256color', 'rxvt-unicode',
'rxvt-unicode-256color', 'linux', 'cygwin') or
(IS_WINDOWS_HOST and _EnableVTProcessingOnWindowsConsole()))):
gtest_color = 'yes'
else:
gtest_color = 'no'
env['GTEST_COLOR'] = gtest_color
_adb_shell([posixpath.join(device_out_dir, test)] + extra_command_line,
env)
finally:
_adb_shell(['rm', '-rf', device_temp_dir])
def _RunOnIOSTarget(binary_dir, test, is_xcuitest=False):
"""Runs the given iOS |test| app on iPhone 8 with the default OS version."""
def xctest(binary_dir, test):
"""Returns a dict containing the xctestrun data needed to run an
XCTest-based test app."""
test_path = os.path.join(CRASHPAD_DIR, binary_dir)
module_data = {
'TestBundlePath': os.path.join(test_path, test + '_module.xctest'),
'TestHostPath': os.path.join(test_path, test + '.app'),
'TestingEnvironmentVariables': {
'DYLD_FRAMEWORK_PATH': '__TESTROOT__/Debug-iphonesimulator:',
'DYLD_INSERT_LIBRARIES':
('__PLATFORMS__/iPhoneSimulator.platform/Developer/'
'usr/lib/libXCTestBundleInject.dylib'),
'DYLD_LIBRARY_PATH': '__TESTROOT__/Debug-iphonesimulator',
'IDEiPhoneInternalTestBundleName': test + '.app',
'XCInjectBundleInto': '__TESTHOST__/' + test,
}
}
return {test: module_data}
def xcuitest(binary_dir, test):
"""Returns a dict containing the xctestrun data needed to run an
XCUITest-based test app."""
test_path = os.path.join(CRASHPAD_DIR, binary_dir)
runner_path = os.path.join(test_path, test + '_module-Runner.app')
bundle_path = os.path.join(runner_path, 'PlugIns',
test + '_module.xctest')
target_app_path = os.path.join(test_path, test + '.app')
module_data = {
'IsUITestBundle': True,
'IsXCTRunnerHostedTestBundle': True,
'TestBundlePath': bundle_path,
'TestHostPath': runner_path,
'UITargetAppPath': target_app_path,
'DependentProductPaths': [
bundle_path, runner_path, target_app_path
],
'TestingEnvironmentVariables': {
'DYLD_FRAMEWORK_PATH': '__TESTROOT__/Debug-iphonesimulator:',
'DYLD_INSERT_LIBRARIES':
('__PLATFORMS__/iPhoneSimulator.platform/Developer/'
'usr/lib/libXCTestBundleInject.dylib'),
'DYLD_LIBRARY_PATH': '__TESTROOT__/Debug-iphonesimulator',
'XCInjectBundleInto': '__TESTHOST__/' + test + '_module-Runner',
},
}
return {test: module_data}
with tempfile.NamedTemporaryFile() as f:
import plistlib
xctestrun_path = f.name
print(xctestrun_path)
if is_xcuitest:
plistlib.writePlist(xcuitest(binary_dir, test), xctestrun_path)
else:
plistlib.writePlist(xctest(binary_dir, test), xctestrun_path)
subprocess.check_call([
'xcodebuild', 'test-without-building', '-xctestrun', xctestrun_path,
'-destination', 'platform=iOS Simulator,name=iPhone 8'
])
# This script is primarily used from the waterfall so that the list of tests
# that are run is maintained in-tree, rather than in a separate infrastructure
# location in the recipe.
def main(args):
parser = argparse.ArgumentParser(description='Run Crashpad unittests.')
parser.add_argument('binary_dir', help='Root of build dir')
parser.add_argument('test', nargs='*', help='Specific test(s) to run.')
parser.add_argument(
'--gtest_filter',
help='Google Test filter applied to Google Test binary runs.')
args = parser.parse_args()
# Tell 64-bit Windows tests where to find 32-bit test executables, for
# cross-bitted testing. This relies on the fact that the GYP build by
# default uses {Debug,Release} for the 32-bit build and {Debug,Release}_x64
# for the 64-bit build. This is not a universally valid assumption, and if
# its not met, 64-bit tests that require 32-bit build output will disable
# themselves dynamically.
if (sys.platform == 'win32' and args.binary_dir.endswith('_x64') and
'CRASHPAD_TEST_32_BIT_OUTPUT' not in os.environ):
binary_dir_32 = args.binary_dir[:-4]
if os.path.isdir(binary_dir_32):
os.environ['CRASHPAD_TEST_32_BIT_OUTPUT'] = binary_dir_32
target_os = _BinaryDirTargetOS(args.binary_dir)
is_android = target_os == 'android'
is_ios = target_os == 'ios'
tests = [
'crashpad_client_test',
'crashpad_handler_test',
'crashpad_minidump_test',
'crashpad_snapshot_test',
'crashpad_test_test',
'crashpad_util_test',
]
if is_android:
android_device = os.environ.get('ANDROID_DEVICE')
if not android_device:
adb_devices = subprocess.check_output(['adb', 'devices'],
shell=IS_WINDOWS_HOST)
devices = []
for line in adb_devices.splitlines():
line = line.decode('utf-8')
if (line == 'List of devices attached' or
re.match('^\* daemon .+ \*$', line) or line == ''):
continue
(device, ignore) = line.split('\t')
devices.append(device)
if len(devices) != 1:
print("Please set ANDROID_DEVICE to your device's id",
file=sys.stderr)
return 2
android_device = devices[0]
print('Using autodetected Android device:', android_device)
elif is_ios:
tests.append('ios_crash_xcuitests')
elif IS_WINDOWS_HOST:
tests.append('snapshot/win/end_to_end_test.py')
if args.test:
for t in args.test:
if t not in tests:
print('Unrecognized test:', t, file=sys.stderr)
return 3
tests = args.test
for test in tests:
print('-' * 80)
print(test)
print('-' * 80)
if test.endswith('.py'):
subprocess.check_call([
sys.executable,
os.path.join(CRASHPAD_DIR, test), args.binary_dir
])
else:
extra_command_line = []
if args.gtest_filter:
extra_command_line.append('--gtest_filter=' + args.gtest_filter)
if is_android:
_RunOnAndroidTarget(args.binary_dir, test, android_device,
extra_command_line)
elif is_ios:
_RunOnIOSTarget(args.binary_dir,
test,
is_xcuitest=test.startswith('ios'))
else:
subprocess.check_call([os.path.join(args.binary_dir, test)] +
extra_command_line)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -0,0 +1,49 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("crashpad_buildconfig.gni")
if (crashpad_is_in_chromium) {
import("//testing/test.gni")
} else {
template("test") {
if (crashpad_is_ios) {
import("//third_party/mini_chromium/mini_chromium/build/ios/rules.gni")
_launch_image_bundle_target = target_name + "_launch_image"
bundle_data(_launch_image_bundle_target) {
forward_variables_from(invoker, [ "testonly" ])
sources = [ "//build/ios/Default.png" ]
outputs = [ "{{bundle_contents_dir}}/{{source_file_part}}" ]
}
ios_xctest_test(target_name) {
testonly = true
xctest_module_target = "//test/ios:google_test_runner"
info_plist = "//build/ios/Unittest-Info.plist"
extra_substitutions = [ "GTEST_BUNDLE_ID_SUFFIX=$target_name" ]
forward_variables_from(invoker, "*")
if (!defined(deps)) {
deps = []
}
deps += [ ":$_launch_image_bundle_target" ]
}
} else {
executable(target_name) {
testonly = true
forward_variables_from(invoker, "*")
}
}
}
}

View File

@ -0,0 +1,208 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
crashpad_static_library("client") {
sources = [
"crashpad_client.h",
"prune_crash_reports.cc",
"prune_crash_reports.h",
"simulate_crash.h",
]
if (crashpad_is_mac) {
sources += [
"crashpad_client_mac.cc",
"simulate_crash_mac.cc",
"simulate_crash_mac.h",
]
}
if (crashpad_is_ios) {
sources += [
"crashpad_client_ios.cc",
"ios_handler/exception_processor.h",
"ios_handler/exception_processor.mm",
"ios_handler/in_process_handler.cc",
"ios_handler/in_process_handler.h",
"ios_handler/in_process_intermediate_dump_handler.cc",
"ios_handler/in_process_intermediate_dump_handler.h",
"ios_handler/prune_intermediate_dumps_and_crash_reports_thread.cc",
"ios_handler/prune_intermediate_dumps_and_crash_reports_thread.h",
"simulate_crash_ios.h",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"crashpad_client_linux.cc",
"simulate_crash_linux.h",
]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [
"client_argv_handling.cc",
"client_argv_handling.h",
]
}
if (crashpad_is_win) {
sources += [
"crashpad_client_win.cc",
"simulate_crash_win.h",
]
}
if (crashpad_is_fuchsia) {
sources += [ "crashpad_client_fuchsia.cc" ]
}
public_configs = [ "..:crashpad_config" ]
public_deps = [
":common",
"$mini_chromium_source_parent:base",
"../util",
]
deps = [
":common",
"$mini_chromium_source_parent:chromeos_buildflags",
]
if (crashpad_is_win) {
libs = [ "rpcrt4.lib" ]
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
if (crashpad_is_ios) {
deps += [
"../handler:common",
"../minidump",
"../snapshot",
]
}
if (crashpad_is_linux || crashpad_is_android) {
deps += [ "../third_party/lss" ]
}
if (crashpad_is_fuchsia) {
deps += [ "../third_party/fuchsia" ]
if (crashpad_is_in_fuchsia) {
deps += [ "//sdk/lib/fdio" ]
}
}
}
static_library("common") {
sources = [
"annotation.cc",
"annotation.h",
"annotation_list.cc",
"annotation_list.h",
"crash_report_database.cc",
"crash_report_database.h",
"crashpad_info.cc",
"crashpad_info.h",
"settings.cc",
"settings.h",
"simple_address_range_bag.h",
"simple_string_dictionary.h",
]
if (crashpad_is_mac || crashpad_is_ios) {
sources += [ "crash_report_database_mac.mm" ]
}
if (crashpad_is_win) {
sources += [ "crash_report_database_win.cc" ]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [
"crash_report_database_generic.cc",
"crashpad_info_note.S",
]
}
public_configs = [ "..:crashpad_config" ]
public_deps = [
"$mini_chromium_source_parent:base",
"../util",
]
deps = [ "../util" ]
}
source_set("client_test") {
testonly = true
sources = [
"annotation_list_test.cc",
"annotation_test.cc",
"crash_report_database_test.cc",
"prune_crash_reports_test.cc",
"settings_test.cc",
"simple_address_range_bag_test.cc",
"simple_string_dictionary_test.cc",
]
if (crashpad_is_mac) {
sources += [ "simulate_crash_mac_test.cc" ]
}
if (crashpad_is_win) {
sources += [ "crashpad_client_win_test.cc" ]
}
if (crashpad_is_ios) {
sources += [
"crashpad_client_ios_test.mm",
"ios_handler/exception_processor_test.mm",
"ios_handler/in_process_handler_test.cc",
"ios_handler/in_process_intermediate_dump_handler_test.cc",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [ "crashpad_client_linux_test.cc" ]
}
deps = [
":client",
"$mini_chromium_source_parent:base",
"../compat",
"../snapshot",
"../test",
"../third_party/googletest:googlemock",
"../third_party/googletest:googletest",
"../util",
]
if (!crashpad_is_ios && !crashpad_is_fuchsia) {
data_deps = [ "../handler:crashpad_handler" ]
}
if (crashpad_is_win) {
data_deps += [ "../handler:crashpad_handler_console" ]
}
}
if (crashpad_is_linux || crashpad_is_android) {
source_set("pthread_create") {
sources = [ "pthread_create_linux.cc" ]
deps = [ ":client" ]
}
}

View File

@ -0,0 +1,156 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
config("compat_config") {
include_dirs = []
if (crashpad_is_mac || crashpad_is_ios) {
include_dirs += [ "mac" ]
}
if (crashpad_is_ios) {
include_dirs += [ "ios" ]
}
if (crashpad_is_linux || crashpad_is_android) {
include_dirs += [ "linux" ]
}
if (crashpad_is_android) {
include_dirs += [ "android" ]
}
if (crashpad_is_win) {
include_dirs += [ "win" ]
} else {
include_dirs += [ "non_win" ]
}
}
template("compat_target") {
if (crashpad_is_mac || crashpad_is_ios) {
# There are no sources to compile, which doesnt mix will with a
# static_library.
group(target_name) {
forward_variables_from(invoker, "*")
not_needed([ "configs" ])
}
} else {
crashpad_static_library(target_name) {
forward_variables_from(invoker, "*", [ "configs" ])
if (!defined(configs)) {
configs = []
}
if (defined(invoker.configs)) {
configs += invoker.configs
}
}
}
}
compat_target("compat") {
sources = []
if (crashpad_is_mac || crashpad_is_ios) {
sources += [
"mac/Availability.h",
"mac/AvailabilityVersions.h",
"mac/kern/exc_resource.h",
"mac/mach-o/loader.h",
"mac/mach/i386/thread_state.h",
"mac/mach/mach.h",
"mac/sys/resource.h",
]
} else {
sources += [ "non_mac/mach/mach.h" ]
}
if (crashpad_is_ios) {
sources += [
"ios/mach/exc.defs",
"ios/mach/mach_exc.defs",
"ios/mach/mach_types.defs",
"ios/mach/machine/machine_types.defs",
"ios/mach/std_types.defs",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/signal.h",
"linux/sys/mman.h",
"linux/sys/mman_memfd_create.cc",
"linux/sys/ptrace.h",
"linux/sys/user.h",
]
}
if (crashpad_is_android) {
sources += [
"android/dlfcn_internal.cc",
"android/dlfcn_internal.h",
"android/elf.h",
"android/linux/elf.h",
"android/linux/prctl.h",
"android/linux/ptrace.h",
"android/sched.h",
"android/sys/epoll.cc",
"android/sys/epoll.h",
"android/sys/mman.h",
"android/sys/mman_mmap.cc",
"android/sys/syscall.h",
"android/sys/user.h",
]
}
if (crashpad_is_win) {
sources += [
"win/getopt.h",
"win/strings.cc",
"win/strings.h",
"win/sys/types.h",
"win/time.cc",
"win/time.h",
"win/winbase.h",
"win/winnt.h",
"win/winternl.h",
]
} else {
sources += [
"non_win/dbghelp.h",
"non_win/minwinbase.h",
"non_win/timezoneapi.h",
"non_win/verrsrc.h",
"non_win/windows.h",
"non_win/winnt.h",
]
}
public_configs = [
":compat_config",
"..:crashpad_config",
]
if (!crashpad_is_win) {
public_deps = [ "$mini_chromium_source_parent:base" ]
}
deps = [ "../util:no_cfi_icall" ]
if (crashpad_is_win) {
deps += [ "../third_party/getopt" ]
}
}

View File

@ -0,0 +1,356 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
static_library("handler") {
sources = [
"handler_main.cc",
"handler_main.h",
"prune_crash_reports_thread.cc",
"prune_crash_reports_thread.h",
"user_stream_data_source.cc",
"user_stream_data_source.h",
]
if (crashpad_is_mac) {
sources += [
"mac/crash_report_exception_handler.cc",
"mac/crash_report_exception_handler.h",
"mac/exception_handler_server.cc",
"mac/exception_handler_server.h",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/capture_snapshot.cc",
"linux/capture_snapshot.h",
"linux/crash_report_exception_handler.cc",
"linux/crash_report_exception_handler.h",
"linux/exception_handler_server.cc",
"linux/exception_handler_server.h",
]
}
if (crashpad_is_linux) {
sources += [
"linux/cros_crash_report_exception_handler.cc",
"linux/cros_crash_report_exception_handler.h",
]
}
if (crashpad_is_win) {
sources += [
"win/crash_report_exception_handler.cc",
"win/crash_report_exception_handler.h",
]
}
public_configs = [ "..:crashpad_config" ]
public_deps = [
":common",
"../client",
"../third_party/mini_chromium:base",
"../util",
]
deps = [
":common",
"../minidump",
"../snapshot",
"../third_party/mini_chromium:chromeos_buildflags",
"../tools:tool_support",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
if (crashpad_is_android) {
# CrashpadHandlerMain is defined in a separate target so that it can be
# overriden by implementers
source_set("crashpad_handler_main") {
sources = [ "crashpad_handler_main.cc" ]
deps = [ ":handler" ]
}
}
static_library("common") {
sources = [
"crash_report_upload_thread.cc",
"crash_report_upload_thread.h",
"minidump_to_upload_parameters.cc",
"minidump_to_upload_parameters.h",
]
if (crashpad_is_mac || crashpad_is_ios) {
sources += [
"mac/file_limit_annotation.cc",
"mac/file_limit_annotation.h",
]
}
public_configs = [ "..:crashpad_config" ]
public_deps = [
"../third_party/mini_chromium:base",
"../util",
]
deps = [
"../client:common",
"../snapshot",
"../util",
"../util:net",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
source_set("handler_test") {
testonly = true
sources = [ "minidump_to_upload_parameters_test.cc" ]
if (crashpad_is_linux || crashpad_is_android) {
sources += [ "linux/exception_handler_server_test.cc" ]
}
if (crashpad_is_win) {
sources += [ "crashpad_handler_test.cc" ]
}
deps = [
":handler",
"../client",
"../compat",
"../snapshot",
"../snapshot:test_support",
"../test",
"../third_party/googletest:googletest",
"../third_party/mini_chromium:base",
"../util",
]
if (crashpad_is_win) {
deps += [ "../minidump:test_support" ]
data_deps = [
":crashpad_handler_test_extended_handler",
":fake_handler_that_crashes_at_startup",
]
}
}
if (!crashpad_is_ios) {
crashpad_executable("crashpad_handler") {
sources = [ "main.cc" ]
deps = [
":handler",
"../build:default_exe_manifest_win",
"../compat",
"../third_party/mini_chromium:base",
"../tools:tool_support",
]
if (crashpad_is_win) {
if (crashpad_is_in_chromium || crashpad_is_in_dart) {
remove_configs = [ "//build/config/win:console" ]
configs = [ "//build/config/win:windowed" ]
} else if (crashpad_is_external) {
remove_configs =
[ "//../../mini_chromium/mini_chromium/build/config:win_console" ]
configs =
[ "//../../mini_chromium/mini_chromium/build/config:win_windowed" ]
} else {
remove_configs = [
"//third_party/mini_chromium/mini_chromium/build/config:win_console",
]
configs = [
"//third_party/mini_chromium/mini_chromium/build/config:win_windowed",
]
}
}
if (crashpad_is_linux) {
deps += [ "../client:pthread_create" ]
}
}
}
# There is not any normal way to package native executables in an Android APK.
# It is normal to package native code as a loadable module but Android's APK
# installer will ignore files not named like a shared object, so give the
# handler executable an acceptable name.
if (crashpad_is_android) {
copy("crashpad_handler_named_as_so") {
deps = [ ":crashpad_handler" ]
sources = [ "$root_out_dir/crashpad_handler" ]
outputs = [ "$root_out_dir/libcrashpad_handler.so" ]
}
crashpad_executable("crashpad_handler_trampoline") {
output_name = "libcrashpad_handler_trampoline.so"
sources = [ "linux/handler_trampoline.cc" ]
deps = [ "../util:no_cfi_icall" ]
libs = [ "log" ]
if (crashpad_is_in_chromium) {
# Chromium's sanitizer runtime libraries do not include an unwinder,
# so add Chromium's standard dependencies to link against the in-tree
# libunwind.
import("//build/config/sanitizers/sanitizers.gni")
no_default_deps = !using_sanitizer
remove_configs =
[ "//build/config/android:default_orderfile_instrumentation" ]
}
}
}
if (!crashpad_is_ios) {
crashpad_executable("crashpad_handler_test_extended_handler") {
testonly = true
sources = [ "crashpad_handler_test_extended_handler.cc" ]
deps = [
":handler",
"../build:default_exe_manifest_win",
"../compat",
"../minidump:test_support",
"../third_party/mini_chromium:base",
"../tools:tool_support",
]
}
}
if (crashpad_is_win) {
crashpad_executable("crashpad_handler_com") {
sources = [ "main.cc" ]
# Avoid .exp, .ilk, and .lib file collisions with crashpad_handler.exe by
# having this target produce crashpad_handler_com.com. Dont use this target
# directly. Instead, use crashpad_handler_console.
output_extension = "com"
deps = [
":handler",
"../build:default_exe_manifest_win",
"../compat",
"../third_party/mini_chromium:base",
"../tools:tool_support",
]
}
copy("crashpad_handler_console") {
deps = [ ":crashpad_handler_com" ]
sources = [ "$root_out_dir/crashpad_handler_com.com" ]
outputs = [ "$root_out_dir/crashpad_handler.com" ]
}
crashpad_executable("crash_other_program") {
testonly = true
sources = [ "win/crash_other_program.cc" ]
deps = [
"../client",
"../test",
"../third_party/googletest:googletest",
"../third_party/mini_chromium:base",
]
}
crashpad_executable("crashy_program") {
testonly = true
sources = [ "win/crashy_test_program.cc" ]
deps = [
"../client",
"../third_party/mini_chromium:base",
]
}
crashpad_executable("crashy_signal") {
testonly = true
sources = [ "win/crashy_signal.cc" ]
cflags = [ "/wd4702" ] # Unreachable code.
deps = [
"../client",
"../third_party/mini_chromium:base",
]
}
crashpad_executable("fake_handler_that_crashes_at_startup") {
testonly = true
sources = [ "win/fake_handler_that_crashes_at_startup.cc" ]
}
crashpad_executable("hanging_program") {
testonly = true
sources = [ "win/hanging_program.cc" ]
deps = [
"../client",
"../third_party/mini_chromium:base",
]
}
crashpad_loadable_module("loader_lock_dll") {
testonly = true
sources = [ "win/loader_lock_dll.cc" ]
}
crashpad_executable("self_destroying_program") {
testonly = true
sources = [ "win/self_destroying_test_program.cc" ]
deps = [
"../client",
"../compat",
"../snapshot",
"../third_party/mini_chromium:base",
]
}
if (current_cpu == "x86") {
# Cannot create an x64 DLL with embedded debug info.
crashpad_executable("crashy_z7_loader") {
testonly = true
sources = [ "win/crashy_test_z7_loader.cc" ]
deps = [
"../client",
"../test",
"../third_party/mini_chromium:base",
]
}
}
}

View File

@ -0,0 +1,168 @@
.. _BuildingLibunwind:
==================
Building libunwind
==================
.. contents::
:local:
.. _build instructions:
Getting Started
===============
On Mac OS, the easiest way to get this library is to link with -lSystem.
However if you want to build tip-of-trunk from here (getting the bleeding
edge), read on.
The basic steps needed to build libc++ are:
#. Checkout LLVM, libunwind, and related projects:
* ``cd where-you-want-llvm-to-live``
* ``git clone https://github.com/llvm/llvm-project.git``
#. Configure and build libunwind:
CMake is the only supported configuration system.
Clang is the preferred compiler when building and using libunwind.
* ``cd where you want to build llvm``
* ``mkdir build``
* ``cd build``
* ``cmake -G <generator> -DLLVM_ENABLE_PROJECTS=libunwind [options] <path to llvm sources>``
For more information about configuring libunwind see :ref:`CMake Options`.
* ``make unwind`` --- will build libunwind.
* ``make check-unwind`` --- will run the test suite.
Shared and static libraries for libunwind should now be present in llvm/build/lib.
#. **Optional**: Install libunwind
If your system already provides an unwinder, it is important to be careful
not to replace it. Remember Use the CMake option ``CMAKE_INSTALL_PREFIX`` to
select a safe place to install libunwind.
* ``make install-unwind`` --- Will install the libraries and the headers
It is sometimes beneficial to build outside of the LLVM tree. An out-of-tree
build would look like this:
.. code-block:: bash
$ cd where-you-want-libunwind-to-live
$ # Check out llvm, and libunwind
$ ``svn co https://llvm.org/svn/llvm-project/llvm/trunk llvm``
$ ``svn co https://llvm.org/svn/llvm-project/libunwind/trunk libunwind``
$ cd where-you-want-to-build
$ mkdir build && cd build
$ export CC=clang CXX=clang++
$ cmake -DLLVM_PATH=path/to/llvm \
path/to/libunwind
$ make
.. _CMake Options:
CMake Options
=============
Here are some of the CMake variables that are used often, along with a
brief explanation and LLVM-specific notes. For full documentation, check the
CMake docs or execute ``cmake --help-variable VARIABLE_NAME``.
**CMAKE_BUILD_TYPE**:STRING
Sets the build type for ``make`` based generators. Possible values are
Release, Debug, RelWithDebInfo and MinSizeRel. On systems like Visual Studio
the user sets the build type with the IDE settings.
**CMAKE_INSTALL_PREFIX**:PATH
Path where LLVM will be installed if "make install" is invoked or the
"INSTALL" target is built.
**CMAKE_CXX_COMPILER**:STRING
The C++ compiler to use when building and testing libunwind.
.. _libunwind-specific options:
libunwind specific options
--------------------------
.. option:: LIBUNWIND_BUILD_32_BITS:BOOL
**Default**: Same as LLVM_BUILD_32_BITS
Toggle whether libunwind should be built with -m32.
.. option:: LIBUNWIND_ENABLE_ASSERTIONS:BOOL
**Default**: ``ON``
Toggle assertions independent of the build mode.
.. option:: LIBUNWIND_ENABLE_PEDANTIC:BOOL
**Default**: ``ON``
Compile with -Wpedantic.
.. option:: LIBUNWIND_ENABLE_WERROR:BOOL
**Default**: ``ON``
Compile with -Werror
.. option:: LIBUNWIND_ENABLE_SHARED:BOOL
**Default**: ``ON``
Build libunwind as a shared library.
.. option:: LIBUNWIND_ENABLE_STATIC:BOOL
**Default**: ``ON``
Build libunwind as a static archive.
.. option:: LIBUNWIND_ENABLE_CROSS_UNWINDING:BOOL
**Default**: ``OFF``
Enable cross-platform unwinding support.
.. option:: LIBUNWIND_ENABLE_ARM_WMMX:BOOL
**Default**: ``OFF``
Enable unwinding support for ARM WMMX registers.
.. option:: LIBUNWIND_ENABLE_THREADS:BOOL
**Default**: ``ON``
Build libunwind with threading support.
.. option:: LIBUNWIND_TARGET_TRIPLE:STRING
Target triple for cross compiling
.. option:: LIBUNWIND_GCC_TOOLCHAIN:PATH
GCC toolchain for cross compiling
.. option:: LIBUNWIND_SYSROOT
Sysroot for cross compiling
.. option:: LIBUNWIND_INSTALL_LIBRARY_DIR:PATH
**Default**: ``lib${LIBUNWIND_LIBDIR_SUFFIX}``
Path where built libunwind libraries should be installed. If a relative path,
relative to ``CMAKE_INSTALL_PREFIX``.

View File

@ -0,0 +1,189 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
crashpad_static_library("minidump") {
sources = [
"minidump_annotation_writer.cc",
"minidump_annotation_writer.h",
"minidump_byte_array_writer.cc",
"minidump_byte_array_writer.h",
"minidump_context_writer.cc",
"minidump_context_writer.h",
"minidump_crashpad_info_writer.cc",
"minidump_crashpad_info_writer.h",
"minidump_exception_writer.cc",
"minidump_exception_writer.h",
"minidump_file_writer.cc",
"minidump_file_writer.h",
"minidump_handle_writer.cc",
"minidump_handle_writer.h",
"minidump_memory_info_writer.cc",
"minidump_memory_info_writer.h",
"minidump_memory_writer.cc",
"minidump_memory_writer.h",
"minidump_misc_info_writer.cc",
"minidump_misc_info_writer.h",
"minidump_module_crashpad_info_writer.cc",
"minidump_module_crashpad_info_writer.h",
"minidump_module_writer.cc",
"minidump_module_writer.h",
"minidump_rva_list_writer.cc",
"minidump_rva_list_writer.h",
"minidump_simple_string_dictionary_writer.cc",
"minidump_simple_string_dictionary_writer.h",
"minidump_stream_writer.cc",
"minidump_stream_writer.h",
"minidump_string_writer.cc",
"minidump_string_writer.h",
"minidump_system_info_writer.cc",
"minidump_system_info_writer.h",
"minidump_thread_id_map.cc",
"minidump_thread_id_map.h",
"minidump_thread_writer.cc",
"minidump_thread_writer.h",
"minidump_unloaded_module_writer.cc",
"minidump_unloaded_module_writer.h",
"minidump_user_extension_stream_data_source.cc",
"minidump_user_extension_stream_data_source.h",
"minidump_user_stream_writer.cc",
"minidump_user_stream_writer.h",
"minidump_writable.cc",
"minidump_writable.h",
"minidump_writer_util.cc",
"minidump_writer_util.h",
]
public_configs = [ "..:crashpad_config" ]
public_deps = [
":format",
"../compat",
]
deps = [
"../snapshot",
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_win) {
cflags = [
"/wd4201", # nonstandard extension used : nameless struct/union
"/wd4324", # 'struct' : structure was padded due to __declspec(align())
]
}
}
# :format is the only part of minidump that snapshot may depend on.
static_library("format") {
sources = [
"minidump_context.h",
"minidump_extensions.cc",
"minidump_extensions.h",
]
public_configs = [ "..:crashpad_config" ]
public_deps = [ "../compat" ]
deps = [
"../snapshot:context",
"$mini_chromium_source_parent:base",
"../util",
]
}
static_library("test_support") {
testonly = true
sources = [
"test/minidump_byte_array_writer_test_util.cc",
"test/minidump_byte_array_writer_test_util.h",
"test/minidump_context_test_util.cc",
"test/minidump_context_test_util.h",
"test/minidump_file_writer_test_util.cc",
"test/minidump_file_writer_test_util.h",
"test/minidump_memory_writer_test_util.cc",
"test/minidump_memory_writer_test_util.h",
"test/minidump_rva_list_test_util.cc",
"test/minidump_rva_list_test_util.h",
"test/minidump_string_writer_test_util.cc",
"test/minidump_string_writer_test_util.h",
"test/minidump_user_extension_stream_util.cc",
"test/minidump_user_extension_stream_util.h",
"test/minidump_writable_test_util.cc",
"test/minidump_writable_test_util.h",
]
public_configs = [ "..:crashpad_config" ]
public_deps = [ ":minidump" ]
deps = [
"../snapshot:test_support",
"../test",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
source_set("minidump_test") {
testonly = true
sources = [
"minidump_annotation_writer_test.cc",
"minidump_byte_array_writer_test.cc",
"minidump_context_writer_test.cc",
"minidump_crashpad_info_writer_test.cc",
"minidump_exception_writer_test.cc",
"minidump_file_writer_test.cc",
"minidump_handle_writer_test.cc",
"minidump_memory_info_writer_test.cc",
"minidump_memory_writer_test.cc",
"minidump_misc_info_writer_test.cc",
"minidump_module_crashpad_info_writer_test.cc",
"minidump_module_writer_test.cc",
"minidump_rva_list_writer_test.cc",
"minidump_simple_string_dictionary_writer_test.cc",
"minidump_string_writer_test.cc",
"minidump_system_info_writer_test.cc",
"minidump_thread_id_map_test.cc",
"minidump_thread_writer_test.cc",
"minidump_unloaded_module_writer_test.cc",
"minidump_user_stream_writer_test.cc",
"minidump_writable_test.cc",
]
configs += [ "../build:crashpad_is_in_fuchsia" ]
deps = [
":test_support",
"../snapshot:test_support",
"../test",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}

View File

@ -0,0 +1,643 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
import("../build/crashpad_fuzzer_test.gni")
if (crashpad_is_in_chromium) {
import("//build/config/compiler/compiler.gni")
}
crashpad_static_library("snapshot") {
sources = [
"annotation_snapshot.cc",
"annotation_snapshot.h",
"capture_memory.cc",
"capture_memory.h",
"crashpad_info_client_options.cc",
"crashpad_info_client_options.h",
"exception_snapshot.h",
"handle_snapshot.cc",
"handle_snapshot.h",
"memory_snapshot.cc",
"memory_snapshot.h",
"memory_snapshot_generic.h",
"minidump/exception_snapshot_minidump.cc",
"minidump/exception_snapshot_minidump.h",
"minidump/memory_snapshot_minidump.cc",
"minidump/memory_snapshot_minidump.h",
"minidump/minidump_annotation_reader.cc",
"minidump/minidump_annotation_reader.h",
"minidump/minidump_context_converter.cc",
"minidump/minidump_context_converter.h",
"minidump/minidump_simple_string_dictionary_reader.cc",
"minidump/minidump_simple_string_dictionary_reader.h",
"minidump/minidump_stream.h",
"minidump/minidump_string_list_reader.cc",
"minidump/minidump_string_list_reader.h",
"minidump/minidump_string_reader.cc",
"minidump/minidump_string_reader.h",
"minidump/module_snapshot_minidump.cc",
"minidump/module_snapshot_minidump.h",
"minidump/process_snapshot_minidump.cc",
"minidump/process_snapshot_minidump.h",
"minidump/system_snapshot_minidump.cc",
"minidump/system_snapshot_minidump.h",
"minidump/thread_snapshot_minidump.cc",
"minidump/thread_snapshot_minidump.h",
"module_snapshot.h",
"process_snapshot.h",
"snapshot_constants.h",
"system_snapshot.h",
"thread_snapshot.h",
"unloaded_module_snapshot.cc",
"unloaded_module_snapshot.h",
]
if (crashpad_is_posix || crashpad_is_fuchsia) {
sources += [
"posix/timezone.cc",
"posix/timezone.h",
]
}
if (crashpad_is_mac) {
sources += [
"mac/cpu_context_mac.cc",
"mac/cpu_context_mac.h",
"mac/exception_snapshot_mac.cc",
"mac/exception_snapshot_mac.h",
"mac/mach_o_image_annotations_reader.cc",
"mac/mach_o_image_annotations_reader.h",
"mac/mach_o_image_reader.cc",
"mac/mach_o_image_reader.h",
"mac/mach_o_image_segment_reader.cc",
"mac/mach_o_image_segment_reader.h",
"mac/mach_o_image_symbol_table_reader.cc",
"mac/mach_o_image_symbol_table_reader.h",
"mac/module_snapshot_mac.cc",
"mac/module_snapshot_mac.h",
"mac/process_reader_mac.cc",
"mac/process_reader_mac.h",
"mac/process_snapshot_mac.cc",
"mac/process_snapshot_mac.h",
"mac/process_types.cc",
"mac/process_types.h",
"mac/process_types/custom.cc",
"mac/process_types/flavors.h",
"mac/process_types/internal.h",
"mac/process_types/traits.h",
"mac/system_snapshot_mac.cc",
"mac/system_snapshot_mac.h",
"mac/thread_snapshot_mac.cc",
"mac/thread_snapshot_mac.h",
]
}
if (crashpad_is_ios) {
sources += [
"ios/exception_snapshot_ios_intermediate_dump.cc",
"ios/exception_snapshot_ios_intermediate_dump.h",
"ios/intermediate_dump_reader_util.cc",
"ios/intermediate_dump_reader_util.h",
"ios/memory_snapshot_ios_intermediate_dump.cc",
"ios/memory_snapshot_ios_intermediate_dump.h",
"ios/module_snapshot_ios_intermediate_dump.cc",
"ios/module_snapshot_ios_intermediate_dump.h",
"ios/process_snapshot_ios_intermediate_dump.cc",
"ios/process_snapshot_ios_intermediate_dump.h",
"ios/system_snapshot_ios_intermediate_dump.cc",
"ios/system_snapshot_ios_intermediate_dump.h",
"ios/thread_snapshot_ios_intermediate_dump.cc",
"ios/thread_snapshot_ios_intermediate_dump.h",
"mac/cpu_context_mac.cc",
"mac/cpu_context_mac.h",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/capture_memory_delegate_linux.cc",
"linux/capture_memory_delegate_linux.h",
"linux/cpu_context_linux.cc",
"linux/cpu_context_linux.h",
"linux/debug_rendezvous.cc",
"linux/debug_rendezvous.h",
"linux/exception_snapshot_linux.cc",
"linux/exception_snapshot_linux.h",
"linux/process_reader_linux.cc",
"linux/process_reader_linux.h",
"linux/process_snapshot_linux.cc",
"linux/process_snapshot_linux.h",
"linux/signal_context.h",
"linux/system_snapshot_linux.cc",
"linux/system_snapshot_linux.h",
"linux/thread_snapshot_linux.cc",
"linux/thread_snapshot_linux.h",
"sanitized/memory_snapshot_sanitized.cc",
"sanitized/memory_snapshot_sanitized.h",
"sanitized/module_snapshot_sanitized.cc",
"sanitized/module_snapshot_sanitized.h",
"sanitized/process_snapshot_sanitized.cc",
"sanitized/process_snapshot_sanitized.h",
"sanitized/sanitization_information.cc",
"sanitized/sanitization_information.h",
"sanitized/thread_snapshot_sanitized.cc",
"sanitized/thread_snapshot_sanitized.h",
]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia ||
crashpad_is_win) {
sources += [
"crashpad_types/crashpad_info_reader.cc",
"crashpad_types/crashpad_info_reader.h",
]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [
"crashpad_types/image_annotation_reader.cc",
"crashpad_types/image_annotation_reader.h",
"elf/elf_dynamic_array_reader.cc",
"elf/elf_dynamic_array_reader.h",
"elf/elf_image_reader.cc",
"elf/elf_image_reader.h",
"elf/elf_symbol_table_reader.cc",
"elf/elf_symbol_table_reader.h",
"elf/module_snapshot_elf.cc",
"elf/module_snapshot_elf.h",
]
}
if (crashpad_is_win) {
sources += [
"win/capture_memory_delegate_win.cc",
"win/capture_memory_delegate_win.h",
"win/cpu_context_win.cc",
"win/cpu_context_win.h",
"win/exception_snapshot_win.cc",
"win/exception_snapshot_win.h",
"win/memory_map_region_snapshot_win.cc",
"win/memory_map_region_snapshot_win.h",
"win/module_snapshot_win.cc",
"win/module_snapshot_win.h",
"win/pe_image_annotations_reader.cc",
"win/pe_image_annotations_reader.h",
"win/pe_image_reader.cc",
"win/pe_image_reader.h",
"win/pe_image_resource_reader.cc",
"win/pe_image_resource_reader.h",
"win/process_reader_win.cc",
"win/process_reader_win.h",
"win/process_snapshot_win.cc",
"win/process_snapshot_win.h",
"win/process_subrange_reader.cc",
"win/process_subrange_reader.h",
"win/system_snapshot_win.cc",
"win/system_snapshot_win.h",
"win/thread_snapshot_win.cc",
"win/thread_snapshot_win.h",
]
}
if (crashpad_is_fuchsia) {
sources += [
"fuchsia/cpu_context_fuchsia.cc",
"fuchsia/cpu_context_fuchsia.h",
"fuchsia/exception_snapshot_fuchsia.cc",
"fuchsia/exception_snapshot_fuchsia.h",
"fuchsia/memory_map_fuchsia.cc",
"fuchsia/memory_map_fuchsia.h",
"fuchsia/memory_map_region_snapshot_fuchsia.cc",
"fuchsia/memory_map_region_snapshot_fuchsia.h",
"fuchsia/process_reader_fuchsia.cc",
"fuchsia/process_reader_fuchsia.h",
"fuchsia/process_snapshot_fuchsia.cc",
"fuchsia/process_snapshot_fuchsia.h",
"fuchsia/system_snapshot_fuchsia.cc",
"fuchsia/system_snapshot_fuchsia.h",
"fuchsia/thread_snapshot_fuchsia.cc",
"fuchsia/thread_snapshot_fuchsia.h",
]
}
if (current_cpu == "x86" || current_cpu == "x64" ||
(crashpad_is_mac && current_cpu == "mac_universal")) {
sources += [
"x86/cpuid_reader.cc",
"x86/cpuid_reader.h",
]
}
public_configs = [ "..:crashpad_config" ]
public_deps = [ ":context" ]
deps = [
"$mini_chromium_source_parent:base",
"../client:common",
"../compat",
"../minidump:format",
"../util",
]
if (crashpad_is_win) {
deps += [ "../client" ]
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
libs = [ "powrprof.lib" ]
}
}
# :context is the only part of snapshot that minidump may depend on.
static_library("context") {
sources = [
"cpu_architecture.h",
"cpu_context.cc",
"cpu_context.h",
]
public_configs = [ "..:crashpad_config" ]
deps = [
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
if (crashpad_is_linux) {
crashpad_fuzzer_test("elf_image_reader_fuzzer") {
sources = [ "elf/elf_image_reader_fuzzer.cc" ]
deps = [
":snapshot",
"$mini_chromium_source_parent:base",
"../util:util",
]
seed_corpus = "elf/elf_image_reader_fuzzer_corpus"
}
}
static_library("test_support") {
testonly = true
sources = [
"test/test_cpu_context.cc",
"test/test_cpu_context.h",
"test/test_exception_snapshot.cc",
"test/test_exception_snapshot.h",
"test/test_memory_map_region_snapshot.cc",
"test/test_memory_map_region_snapshot.h",
"test/test_memory_snapshot.cc",
"test/test_memory_snapshot.h",
"test/test_module_snapshot.cc",
"test/test_module_snapshot.h",
"test/test_process_snapshot.cc",
"test/test_process_snapshot.h",
"test/test_system_snapshot.cc",
"test/test_system_snapshot.h",
"test/test_thread_snapshot.cc",
"test/test_thread_snapshot.h",
]
public_configs = [ "..:crashpad_config" ]
public_deps = [ ":snapshot" ]
deps = [
"$mini_chromium_source_parent:base",
"../compat",
"../util",
]
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
config("snapshot_test_link") {
visibility = [ ":*" ]
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
# Theres no way to make the link depend on this file. “inputs” doesnt have
# the intended effect in a config. https://crbug.com/781858,
# https://crbug.com/796187.
inputs = [ "elf/test_exported_symbols.sym" ]
ldflags = [ "-Wl,--dynamic-list," + rebase_path(inputs[0], root_build_dir) ]
}
}
source_set("snapshot_test") {
testonly = true
sources = [
"cpu_context_test.cc",
"memory_snapshot_test.cc",
"minidump/process_snapshot_minidump_test.cc",
]
if (crashpad_is_mac) {
sources += [
"mac/cpu_context_mac_test.cc",
"mac/mach_o_image_annotations_reader_test.cc",
"mac/mach_o_image_reader_test.cc",
"mac/mach_o_image_segment_reader_test.cc",
"mac/process_reader_mac_test.cc",
"mac/process_types_test.cc",
"mac/system_snapshot_mac_test.cc",
]
}
if (crashpad_is_ios) {
sources += [
"ios/process_snapshot_ios_intermediate_dump_test.cc",
"mac/cpu_context_mac_test.cc",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/debug_rendezvous_test.cc",
"linux/exception_snapshot_linux_test.cc",
"linux/process_reader_linux_test.cc",
"linux/system_snapshot_linux_test.cc",
"linux/test_modules.cc",
"linux/test_modules.h",
"sanitized/process_snapshot_sanitized_test.cc",
"sanitized/sanitization_information_test.cc",
]
} else if (!crashpad_is_ios) {
sources += [ "crashpad_info_client_options_test.cc" ]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia ||
crashpad_is_win) {
sources += [ "crashpad_types/crashpad_info_reader_test.cc" ]
}
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [
"crashpad_types/image_annotation_reader_test.cc",
"elf/elf_image_reader_test.cc",
"elf/elf_image_reader_test_note.S",
]
}
if (crashpad_is_win) {
sources += [
"win/cpu_context_win_test.cc",
"win/exception_snapshot_win_test.cc",
"win/extra_memory_ranges_test.cc",
"win/module_snapshot_win_test.cc",
"win/pe_image_reader_test.cc",
"win/process_reader_win_test.cc",
"win/process_snapshot_win_test.cc",
"win/system_snapshot_win_test.cc",
]
} else if (!crashpad_is_fuchsia) {
# Timezones are currently non-functional on Fuchsia:
# https://fuchsia.googlesource.com/zircon/+/master/third_party/ulib/musl/src/time/__tz.c#9
# https://crashpad.chromium.org/bug/196. Relevant upstream bugs are ZX-337
# and ZX-1731.
sources += [ "posix/timezone_test.cc" ]
}
if (crashpad_is_fuchsia) {
sources += [
"fuchsia/process_reader_fuchsia_test.cc",
"fuchsia/process_snapshot_fuchsia_test.cc",
]
}
# public_configs isnt quite right. snapshot_test_link sets ldflags, and
# whats really needed is a way to push ldflags to dependent targets that
# produce linker output. Luckily in this case, all dependents do produce
# linker output. https://crbug.com/796183.
public_configs = [ ":snapshot_test_link" ]
deps = [
":test_support",
"$mini_chromium_source_parent:base",
"../client:common",
"../compat",
"../minidump:format",
"../test",
"../third_party/googletest:googlemock",
"../third_party/googletest:googletest",
"../util",
]
if (crashpad_is_win) {
deps += [ "../client" ]
}
if (crashpad_is_ios) {
deps += [
":snapshot_test_ios_data",
"../minidump",
]
}
data_deps = [
":crashpad_snapshot_test_module",
":crashpad_snapshot_test_module_large",
":crashpad_snapshot_test_module_small",
]
if (crashpad_is_mac) {
frameworks = [ "OpenCL.framework" ]
data_deps += [
":crashpad_snapshot_test_module_crashy_initializer",
":crashpad_snapshot_test_no_op",
]
}
if (crashpad_is_linux || crashpad_is_android) {
libs = [ "dl" ]
}
if ((crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) &&
target_cpu != "mipsel" && target_cpu != "mips64el") {
data_deps += [ ":crashpad_snapshot_test_both_dt_hash_styles" ]
}
if (crashpad_is_win) {
cflags = [ "/wd4201" ] # nonstandard extension used : nameless struct/union
data_deps += [
":crashpad_snapshot_test_annotations",
":crashpad_snapshot_test_crashing_child",
":crashpad_snapshot_test_dump_without_crashing",
":crashpad_snapshot_test_extra_memory_ranges",
":crashpad_snapshot_test_image_reader",
":crashpad_snapshot_test_image_reader_module",
]
}
}
bundle_data("snapshot_test_ios_data") {
testonly = true
sources = [
"ios/testdata/crash-1fa088dda0adb41459d063078a0f384a0bb8eefa",
"ios/testdata/crash-5726011582644224",
]
outputs = [ "{{bundle_resources_dir}}/crashpad_test_data/" +
"{{source_root_relative_dir}}/{{source_file_part}}" ]
}
crashpad_loadable_module("crashpad_snapshot_test_module") {
testonly = true
sources = [ "crashpad_info_client_options_test_module.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
]
}
crashpad_loadable_module("crashpad_snapshot_test_module_large") {
testonly = true
sources = [ "crashpad_info_size_test_module.cc" ]
deps = []
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [ "crashpad_info_size_test_note.S" ]
deps += [ "../util" ]
}
defines = [ "CRASHPAD_INFO_SIZE_TEST_MODULE_LARGE" ]
deps += [ "$mini_chromium_source_parent:base" ]
}
crashpad_loadable_module("crashpad_snapshot_test_module_small") {
testonly = true
sources = [ "crashpad_info_size_test_module.cc" ]
deps = []
if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) {
sources += [ "crashpad_info_size_test_note.S" ]
deps += [ "../util" ]
}
defines = [ "CRASHPAD_INFO_SIZE_TEST_MODULE_SMALL" ]
deps += [ "$mini_chromium_source_parent:base" ]
}
if ((crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) &&
target_cpu != "mipsel" && target_cpu != "mips64el") {
crashpad_loadable_module("crashpad_snapshot_test_both_dt_hash_styles") {
testonly = true
sources = [ "hash_types_test.cc" ]
# This makes `ld` emit both .hash and .gnu.hash sections.
ldflags = [ "-Wl,--hash-style=both" ]
}
}
if (crashpad_is_mac || crashpad_is_ios) {
crashpad_loadable_module("crashpad_snapshot_test_module_crashy_initializer") {
testonly = true
sources = [
"mac/mach_o_image_annotations_reader_test_module_crashy_initializer.cc",
]
}
crashpad_executable("crashpad_snapshot_test_no_op") {
testonly = true
sources = [ "mac/mach_o_image_annotations_reader_test_no_op.cc" ]
}
}
if (crashpad_is_win) {
crashpad_executable("crashpad_snapshot_test_annotations") {
testonly = true
sources = [ "win/crashpad_snapshot_test_annotations.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
"../compat",
]
}
crashpad_executable("crashpad_snapshot_test_crashing_child") {
testonly = true
sources = [ "win/crashpad_snapshot_test_crashing_child.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
"../compat",
"../util",
]
}
crashpad_executable("crashpad_snapshot_test_dump_without_crashing") {
testonly = true
sources = [ "win/crashpad_snapshot_test_dump_without_crashing.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
"../compat",
"../util",
]
}
crashpad_executable("crashpad_snapshot_test_extra_memory_ranges") {
testonly = true
sources = [ "win/crashpad_snapshot_test_extra_memory_ranges.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
"../compat",
]
}
crashpad_executable("crashpad_snapshot_test_image_reader") {
testonly = true
sources = [ "win/crashpad_snapshot_test_image_reader.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
"../compat",
"../util",
]
if (crashpad_is_in_chromium) {
if (symbol_level == 0) {
# The tests that use this executable rely on at least minimal debug
# info.
remove_configs = [ "//build/config/compiler:default_symbols" ]
configs = [ "//build/config/compiler:minimal_symbols" ]
}
}
}
crashpad_loadable_module("crashpad_snapshot_test_image_reader_module") {
testonly = true
sources = [ "win/crashpad_snapshot_test_image_reader_module.cc" ]
deps = [
"$mini_chromium_source_parent:base",
"../client",
]
if (crashpad_is_in_chromium) {
if (symbol_level == 0) {
# The tests that use this module rely on at least minimal debug info.
remove_configs = [ "//build/config/compiler:default_symbols" ]
configs = [ "//build/config/compiler:minimal_symbols" ]
}
}
}
}

View File

@ -0,0 +1,263 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
static_library("test") {
testonly = true
sources = [
"errors.cc",
"errors.h",
"file.cc",
"file.h",
"filesystem.cc",
"filesystem.h",
"gtest_death.h",
"hex_string.cc",
"hex_string.h",
"main_arguments.cc",
"main_arguments.h",
"multiprocess.h",
"multiprocess_exec.cc",
"multiprocess_exec.h",
"process_type.cc",
"process_type.h",
"scoped_guarded_page.h",
"scoped_module_handle.cc",
"scoped_module_handle.h",
"scoped_temp_dir.cc",
"scoped_temp_dir.h",
"test_paths.cc",
"test_paths.h",
]
if (crashpad_is_posix || crashpad_is_fuchsia) {
sources += [
"scoped_guarded_page_posix.cc",
"scoped_temp_dir_posix.cc",
]
if (!crashpad_is_fuchsia && !crashpad_is_ios) {
sources += [
"multiprocess_exec_posix.cc",
"multiprocess_posix.cc",
]
}
}
if (crashpad_is_mac || crashpad_is_ios) {
sources += [
"mac/mach_errors.cc",
"mac/mach_errors.h",
]
}
if (crashpad_is_mac) {
sources += [
"mac/dyld.cc",
"mac/dyld.h",
"mac/exception_swallower.cc",
"mac/exception_swallower.h",
"mac/mach_multiprocess.cc",
"mac/mach_multiprocess.h",
]
}
if (crashpad_is_ios) {
sources -= [
"multiprocess.h",
"multiprocess_exec.cc",
"multiprocess_exec.h",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/fake_ptrace_connection.cc",
"linux/fake_ptrace_connection.h",
"linux/get_tls.cc",
"linux/get_tls.h",
]
}
if (crashpad_is_win) {
sources += [
"multiprocess_exec_win.cc",
"scoped_guarded_page_win.cc",
"scoped_temp_dir_win.cc",
"win/child_launcher.cc",
"win/child_launcher.h",
"win/win_child_process.cc",
"win/win_child_process.h",
"win/win_multiprocess.cc",
"win/win_multiprocess.h",
"win/win_multiprocess_with_temp_dir.cc",
"win/win_multiprocess_with_temp_dir.h",
]
}
if (crashpad_is_fuchsia) {
sources += [ "multiprocess_exec_fuchsia.cc" ]
}
public_configs = [ "..:crashpad_config" ]
configs += [
"../build:crashpad_is_in_chromium",
"../build:crashpad_is_in_fuchsia",
]
data = [ "test_paths_test_data_root.txt" ]
deps = [
"../compat",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_mac) {
libs = [ "bsm" ]
deps += [
"../handler",
"../snapshot",
]
}
if (crashpad_is_ios) {
deps += [ ":test_bundle_data" ]
}
if (crashpad_is_win) {
libs = [ "shell32.lib" ]
}
if (crashpad_is_fuchsia) {
public_deps = [ "../third_party/fuchsia" ]
if (crashpad_is_in_fuchsia) {
deps += [ "//sdk/lib/fdio" ]
}
}
}
if (crashpad_is_ios) {
bundle_data("test_bundle_data") {
testonly = true
sources = [ "test_paths_test_data_root.txt" ]
outputs = [ "{{bundle_resources_dir}}/crashpad_test_data/" +
"{{source_root_relative_dir}}/{{source_file_part}}" ]
}
}
source_set("test_test") {
testonly = true
sources = [
"hex_string_test.cc",
"main_arguments_test.cc",
"multiprocess_exec_test.cc",
"scoped_guarded_page_test.cc",
"scoped_temp_dir_test.cc",
"test_paths_test.cc",
]
# TODO(crbug.com/812974): Remove !crashpad_is_fuchsia when Fuchsia is no
# longer treated as a posix platform.
if (crashpad_is_posix && !crashpad_is_fuchsia && !crashpad_is_ios) {
sources += [ "multiprocess_posix_test.cc" ]
}
if (crashpad_is_mac) {
sources += [ "mac/mach_multiprocess_test.cc" ]
}
if (crashpad_is_ios) {
sources -= [
"multiprocess_exec_test.cc",
"scoped_guarded_page_test.cc",
]
}
if (crashpad_is_win) {
sources += [
"win/win_child_process_test.cc",
"win/win_multiprocess_test.cc",
]
}
deps = [
":test",
"../compat",
"../third_party/googletest:googlemock",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"../util",
]
data_deps = [ ":crashpad_test_test_multiprocess_exec_test_child" ]
if (crashpad_is_ios) {
data_deps -= [ ":crashpad_test_test_multiprocess_exec_test_child" ]
}
}
if (!crashpad_is_ios) {
crashpad_executable("crashpad_test_test_multiprocess_exec_test_child") {
sources = [ "multiprocess_exec_test_child.cc" ]
deps = [ "$mini_chromium_source_parent:base" ]
}
}
static_library("googlemock_main") {
testonly = true
sources = [ "gtest_main.cc" ]
configs += [ "../build:crashpad_is_in_chromium" ]
defines = [ "CRASHPAD_TEST_LAUNCHER_GOOGLEMOCK" ]
deps = [
":test",
"../third_party/googletest:googlemock",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"$mini_chromium_source_parent:base_test_support",
]
if (crashpad_is_android) {
deps += [ "../util" ]
}
if (crashpad_is_ios) {
deps += [ "ios:google_test_setup" ]
}
}
static_library("googletest_main") {
testonly = true
sources = [ "gtest_main.cc" ]
configs += [ "../build:crashpad_is_in_chromium" ]
defines = [ "CRASHPAD_TEST_LAUNCHER_GOOGLETEST" ]
deps = [
":test",
"../third_party/googletest:googletest",
"$mini_chromium_source_parent:base",
"$mini_chromium_source_parent:base_test_support",
]
if (crashpad_is_android) {
deps += [ "../util" ]
}
if (crashpad_is_ios) {
deps += [ "ios:google_test_setup" ]
}
}

View File

@ -0,0 +1,83 @@
# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
if (crashpad_is_in_chromium) {
import("//build/config/ios/ios_test_runner_xcuitest.gni")
import("//build/config/ios/rules.gni")
} else if (crashpad_is_standalone) {
import("//third_party/mini_chromium/mini_chromium/build/ios/rules.gni")
}
group("all_tests") {
testonly = true
deps = [
":ios_crash_xcuitests_module",
"host:ios_crash_xcuitests",
]
}
source_set("google_test_runner_shared_headers") {
testonly = true
sources = [ "cptest_google_test_runner_delegate.h" ]
}
source_set("google_test_runner") {
testonly = true
sources = [ "cptest_google_test_runner.mm" ]
configs += [ "../..:crashpad_config" ]
deps = [
"../$mini_chromium_source_parent:base",
"../../build:ios_enable_arc",
"../../build:ios_xctest",
"../../test/ios:google_test_runner_shared_headers",
]
frameworks = [ "UIKit.framework" ]
}
source_set("google_test_setup") {
testonly = true
sources = [
"google_test_setup.h",
"google_test_setup.mm",
]
configs += [ "../..:crashpad_config" ]
deps = [
":google_test_runner_shared_headers",
"../$mini_chromium_source_parent:base",
"../../build:ios_enable_arc",
"../../third_party/googletest:googletest",
]
frameworks = [ "UIKit.framework" ]
}
source_set("xcuitests") {
testonly = true
sources = [ "crash_type_xctest.mm" ]
configs += [ "../..:crashpad_config" ]
deps = [
"../../build:ios_enable_arc",
"../../build:ios_xctest",
"../../test/ios/host:app_shared_sources",
"../../third_party/edo",
"../../util",
]
}
ios_test_runner_xcuitest("ios_crash_xcuitests_module") {
xcode_test_application_name = "ios_crash_xcuitests"
deps = [ ":xcuitests" ]
data_deps = [ "host:ios_crash_xcuitests" ]
}

View File

@ -0,0 +1,71 @@
# Copyright 2020 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../../build/crashpad_buildconfig.gni")
if (crashpad_is_in_chromium) {
import("//build/config/ios/rules.gni")
} else if (crashpad_is_standalone) {
import("//third_party/mini_chromium/mini_chromium/build/ios/rules.gni")
}
source_set("app_shared_sources") {
testonly = true
sources = [ "cptest_shared_object.h" ]
configs += [ "../../..:crashpad_config" ]
deps = [ "../../../build:ios_enable_arc" ]
frameworks = [ "UIKit.framework" ]
}
static_library("app_host_sources") {
testonly = true
sources = [
"cptest_application_delegate.h",
"cptest_application_delegate.mm",
"cptest_crash_view_controller.h",
"cptest_crash_view_controller.mm",
"main.mm",
]
configs += [ "../../..:crashpad_config" ]
deps = [
":app_shared_sources",
"../../../build:ios_enable_arc",
"../../../client",
"../../../snapshot",
"../../../third_party/edo",
]
frameworks = [
"Foundation.framework",
"UIKit.framework",
]
}
# TODO(justincohen): Codesign crashy_initializer.so so it can run on devices.
bundle_data("crashy_module_bundle") {
testonly = true
sources =
[ "$root_out_dir/crashpad_snapshot_test_module_crashy_initializer.so" ]
outputs = [ "{{bundle_contents_dir}}/crashpad_snapshot_test_module_crashy_initializer.so" ]
public_deps =
[ "../../../snapshot:crashpad_snapshot_test_module_crashy_initializer" ]
}
ios_app_bundle("ios_crash_xcuitests") {
info_plist = "Info.plist"
testonly = true
deps = [
":app_host_sources",
":crashy_module_bundle",
]
}

View File

@ -0,0 +1,20 @@
# Copyright 2018 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source_set("cpp-httplib") {
testonly = true
include_dirs = [ "cpp-httplib" ]
sources = [ "cpp-httplib/httplib.h" ]
deps = [ "../zlib" ]
}

View File

@ -0,0 +1,146 @@
# Copyright 2018 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/crashpad_buildconfig.gni")
if (crashpad_is_in_chromium) {
group("edo") {
testonly = true
public_deps = [
"//ios/third_party/edo",
]
}
} else {
config("config") {
include_dirs = [ "../../third_party/edo/edo" ]
}
source_set("edo") {
testonly = true
sources = [
"edo/Channel/Sources/EDOBlockingQueue.h",
"edo/Channel/Sources/EDOBlockingQueue.m",
"edo/Channel/Sources/EDOChannel.h",
"edo/Channel/Sources/EDOChannelErrors.h",
"edo/Channel/Sources/EDOChannelErrors.m",
"edo/Channel/Sources/EDOChannelForwarder.h",
"edo/Channel/Sources/EDOChannelForwarder.m",
"edo/Channel/Sources/EDOChannelMultiplexer.h",
"edo/Channel/Sources/EDOChannelMultiplexer.m",
"edo/Channel/Sources/EDOChannelPool.h",
"edo/Channel/Sources/EDOChannelPool.m",
"edo/Channel/Sources/EDOChannelUtil.h",
"edo/Channel/Sources/EDOChannelUtil.m",
"edo/Channel/Sources/EDOHostPort.h",
"edo/Channel/Sources/EDOHostPort.m",
"edo/Channel/Sources/EDOListenSocket.h",
"edo/Channel/Sources/EDOListenSocket.m",
"edo/Channel/Sources/EDOSocket.h",
"edo/Channel/Sources/EDOSocket.m",
"edo/Channel/Sources/EDOSocketChannel.h",
"edo/Channel/Sources/EDOSocketChannel.m",
"edo/Channel/Sources/EDOSocketPort.h",
"edo/Channel/Sources/EDOSocketPort.m",
"edo/Device/Sources/EDODeviceChannel.h",
"edo/Device/Sources/EDODeviceChannel.m",
"edo/Device/Sources/EDODeviceConnector.h",
"edo/Device/Sources/EDODeviceConnector.m",
"edo/Device/Sources/EDODeviceDetector.h",
"edo/Device/Sources/EDODeviceDetector.m",
"edo/Device/Sources/EDOUSBMuxUtil.h",
"edo/Device/Sources/EDOUSBMuxUtil.m",
"edo/DeviceForwarder/Sources/EDODeviceForwardersManager.h",
"edo/DeviceForwarder/Sources/EDODeviceForwardersManager.m",
"edo/Measure/Sources/EDONumericMeasure.h",
"edo/Measure/Sources/EDONumericMeasure.m",
"edo/Service/Sources/EDOBlockObject.h",
"edo/Service/Sources/EDOBlockObject.m",
"edo/Service/Sources/EDOClassMessage.h",
"edo/Service/Sources/EDOClassMessage.m",
"edo/Service/Sources/EDOClientService+Private.h",
"edo/Service/Sources/EDOClientService.h",
"edo/Service/Sources/EDOClientService.m",
"edo/Service/Sources/EDOClientServiceStatsCollector.h",
"edo/Service/Sources/EDOClientServiceStatsCollector.m",
"edo/Service/Sources/EDODeallocationTracker.h",
"edo/Service/Sources/EDODeallocationTracker.m",
"edo/Service/Sources/EDOExecutor.h",
"edo/Service/Sources/EDOExecutor.m",
"edo/Service/Sources/EDOExecutorMessage.h",
"edo/Service/Sources/EDOExecutorMessage.m",
"edo/Service/Sources/EDOHostNamingService+Private.h",
"edo/Service/Sources/EDOHostNamingService.h",
"edo/Service/Sources/EDOHostNamingService.m",
"edo/Service/Sources/EDOHostService+Handlers.h",
"edo/Service/Sources/EDOHostService+Handlers.m",
"edo/Service/Sources/EDOHostService+Private.h",
"edo/Service/Sources/EDOHostService.h",
"edo/Service/Sources/EDOHostService.m",
"edo/Service/Sources/EDOInvocationMessage.h",
"edo/Service/Sources/EDOInvocationMessage.m",
"edo/Service/Sources/EDOMessage.h",
"edo/Service/Sources/EDOMessage.m",
"edo/Service/Sources/EDOMethodSignatureMessage.h",
"edo/Service/Sources/EDOMethodSignatureMessage.m",
"edo/Service/Sources/EDOObject+EDOParameter.m",
"edo/Service/Sources/EDOObject+Invocation.m",
"edo/Service/Sources/EDOObject+Private.h",
"edo/Service/Sources/EDOObject.h",
"edo/Service/Sources/EDOObject.m",
"edo/Service/Sources/EDOObjectAliveMessage.h",
"edo/Service/Sources/EDOObjectAliveMessage.m",
"edo/Service/Sources/EDOObjectMessage.h",
"edo/Service/Sources/EDOObjectMessage.m",
"edo/Service/Sources/EDOObjectReleaseMessage.h",
"edo/Service/Sources/EDOObjectReleaseMessage.m",
"edo/Service/Sources/EDOParameter.h",
"edo/Service/Sources/EDOParameter.m",
"edo/Service/Sources/EDOProtocolObject.h",
"edo/Service/Sources/EDOProtocolObject.m",
"edo/Service/Sources/EDORemoteException.h",
"edo/Service/Sources/EDORemoteException.m",
"edo/Service/Sources/EDORemoteVariable.h",
"edo/Service/Sources/EDORemoteVariable.m",
"edo/Service/Sources/EDOServiceError.h",
"edo/Service/Sources/EDOServiceError.m",
"edo/Service/Sources/EDOServiceException.h",
"edo/Service/Sources/EDOServiceException.m",
"edo/Service/Sources/EDOServicePort.h",
"edo/Service/Sources/EDOServicePort.m",
"edo/Service/Sources/EDOServiceRequest.h",
"edo/Service/Sources/EDOServiceRequest.m",
"edo/Service/Sources/EDOTimingFunctions.h",
"edo/Service/Sources/EDOTimingFunctions.m",
"edo/Service/Sources/EDOValueObject+EDOParameter.m",
"edo/Service/Sources/EDOValueObject.h",
"edo/Service/Sources/EDOValueObject.m",
"edo/Service/Sources/EDOValueType.m",
"edo/Service/Sources/EDOWeakObject.h",
"edo/Service/Sources/EDOWeakObject.m",
"edo/Service/Sources/NSBlock+EDOInvocation.m",
"edo/Service/Sources/NSKeyedArchiver+EDOAdditions.h",
"edo/Service/Sources/NSKeyedArchiver+EDOAdditions.m",
"edo/Service/Sources/NSKeyedUnarchiver+EDOAdditions.h",
"edo/Service/Sources/NSKeyedUnarchiver+EDOAdditions.m",
"edo/Service/Sources/NSObject+EDOBlockedType.h",
"edo/Service/Sources/NSObject+EDOBlockedType.m",
"edo/Service/Sources/NSObject+EDOParameter.h",
"edo/Service/Sources/NSObject+EDOParameter.m",
"edo/Service/Sources/NSObject+EDOValue.h",
"edo/Service/Sources/NSObject+EDOValue.m",
"edo/Service/Sources/NSObject+EDOValueObject.h",
"edo/Service/Sources/NSObject+EDOValueObject.m",
"edo/Service/Sources/NSObject+EDOWeakObject.h",
"edo/Service/Sources/NSObject+EDOWeakObject.m",
"edo/Service/Sources/NSProxy+EDOParameter.h",
"edo/Service/Sources/NSProxy+EDOParameter.m",
]
public_configs = [ ":config" ]
deps = [
"../../build:ios_enable_arc",
]
}
}

View File

@ -0,0 +1,38 @@
# Copyright 2018 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
if (crashpad_is_in_fuchsia) {
group("fuchsia") {
public_deps = [
"//sdk/lib/fdio",
"//zircon/public/lib/zx",
]
}
} else if (crashpad_is_in_chromium) {
group("fuchsia") {
public_deps = [
"//third_party/fuchsia-sdk/sdk/pkg/fdio",
"//third_party/fuchsia-sdk/sdk/pkg/zx",
]
}
} else {
group("fuchsia") {
public_deps = [
"//third_party/fuchsia/sdk/$host_os-amd64/pkg/fdio",
"//third_party/fuchsia/sdk/$host_os-amd64/pkg/zx",
]
}
}

View File

@ -0,0 +1,20 @@
# Copyright 2014 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
static_library("getopt") {
sources = [
"getopt.cc",
"getopt.h",
]
}

View File

@ -0,0 +1,17 @@
# Copyright 2019 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source_set("glibc") {
sources = [ "elf/elf.h" ]
}

View File

@ -0,0 +1,371 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
import("../../build/test.gni")
if (crashpad_is_in_chromium) {
group("googletest") {
testonly = true
public_deps = [ "//testing/gtest" ]
}
group("googlemock") {
testonly = true
public_deps = [ "//testing/gmock" ]
}
} else if (crashpad_is_in_dart || crashpad_is_in_fuchsia) {
group("googletest") {
testonly = true
public_deps = [ "//third_party/googletest:gtest" ]
}
group("googlemock") {
testonly = true
public_deps = [ "//third_party/googletest:gmock" ]
}
} else if (crashpad_is_standalone || crashpad_is_external) {
if (crashpad_is_standalone) {
googletest_dir = "googletest"
mini_chromium_dir = "//third_party/mini_chromium/mini_chromium"
} else if (crashpad_is_external) {
googletest_dir = "../../../../googletest"
mini_chromium_dir = "//../../mini_chromium/mini_chromium"
}
config("googletest_private_config") {
visibility = [ ":*" ]
include_dirs = [ "$googletest_dir/googletest" ]
defines = [ "GUNIT_NO_GOOGLE3=1" ]
}
config("googletest_public_config") {
include_dirs = [ "$googletest_dir/googletest/include" ]
}
static_library("googletest") {
testonly = true
sources = [
"$googletest_dir/googletest/include/gtest/gtest-death-test.h",
"$googletest_dir/googletest/include/gtest/gtest-matchers.h",
"$googletest_dir/googletest/include/gtest/gtest-message.h",
"$googletest_dir/googletest/include/gtest/gtest-param-test.h",
"$googletest_dir/googletest/include/gtest/gtest-printers.h",
"$googletest_dir/googletest/include/gtest/gtest-spi.h",
"$googletest_dir/googletest/include/gtest/gtest-test-part.h",
"$googletest_dir/googletest/include/gtest/gtest-typed-test.h",
"$googletest_dir/googletest/include/gtest/gtest.h",
"$googletest_dir/googletest/include/gtest/gtest_pred_impl.h",
"$googletest_dir/googletest/include/gtest/gtest_prod.h",
"$googletest_dir/googletest/include/gtest/internal/custom/gtest-port.h",
"$googletest_dir/googletest/include/gtest/internal/custom/gtest-printers.h",
"$googletest_dir/googletest/include/gtest/internal/custom/gtest.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-death-test-internal.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-filepath.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-internal.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-param-util.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-port-arch.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-port.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-string.h",
"$googletest_dir/googletest/include/gtest/internal/gtest-type-util.h",
"$googletest_dir/googletest/src/gtest-all.cc",
"$googletest_dir/googletest/src/gtest-death-test.cc",
"$googletest_dir/googletest/src/gtest-filepath.cc",
"$googletest_dir/googletest/src/gtest-internal-inl.h",
"$googletest_dir/googletest/src/gtest-matchers.cc",
"$googletest_dir/googletest/src/gtest-port.cc",
"$googletest_dir/googletest/src/gtest-printers.cc",
"$googletest_dir/googletest/src/gtest-test-part.cc",
"$googletest_dir/googletest/src/gtest-typed-test.cc",
"$googletest_dir/googletest/src/gtest.cc",
]
sources -= [ "$googletest_dir/googletest/src/gtest-all.cc" ]
public_configs = [ ":googletest_public_config" ]
configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ]
configs += [ ":googletest_private_config" ]
if (crashpad_is_fuchsia) {
deps = [ "../fuchsia" ]
}
}
static_library("googletest_main") {
# Tests outside of this file should use ../../test:googletest_main instead.
visibility = [ ":*" ]
testonly = true
sources = [ "$googletest_dir/googletest/src/gtest_main.cc" ]
deps = [ ":googletest" ]
}
test("gtest_all_test") {
sources = [
"$googletest_dir/googletest/test/googletest-death-test-test.cc",
"$googletest_dir/googletest/test/googletest-filepath-test.cc",
"$googletest_dir/googletest/test/googletest-message-test.cc",
"$googletest_dir/googletest/test/googletest-options-test.cc",
"$googletest_dir/googletest/test/googletest-port-test.cc",
"$googletest_dir/googletest/test/googletest-test-part-test.cc",
"$googletest_dir/googletest/test/gtest-typed-test2_test.cc",
"$googletest_dir/googletest/test/gtest-typed-test_test.cc",
"$googletest_dir/googletest/test/gtest-typed-test_test.h",
"$googletest_dir/googletest/test/gtest_main_unittest.cc",
"$googletest_dir/googletest/test/gtest_pred_impl_unittest.cc",
"$googletest_dir/googletest/test/gtest_prod_test.cc",
"$googletest_dir/googletest/test/gtest_skip_test.cc",
"$googletest_dir/googletest/test/gtest_unittest.cc",
"$googletest_dir/googletest/test/production.cc",
"$googletest_dir/googletest/test/production.h",
]
if (!crashpad_is_win) {
# TODO: Fix error C2015: too many characters in constant. As this error
# cannot be suppressed, removing the test on Windows. See
# https://chromium-review.googlesource.com/c/crashpad/crashpad/+/2855854/2
# for details.
sources +=
[ "$googletest_dir/googletest/test/googletest-printers-test.cc" ]
}
configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ]
configs += [ ":googletest_private_config" ]
deps = [
":googletest",
":googletest_main",
]
if (crashpad_is_win) {
cflags = [ "/wd4702" ] # unreachable code
}
}
test("gtest_environment_test") {
sources = [ "$googletest_dir/googletest/test/gtest_environment_test.cc" ]
configs += [ ":googletest_private_config" ]
deps = [ ":googletest" ]
}
test("gtest_listener_test") {
sources = [ "$googletest_dir/googletest/test/googletest-listener-test.cc" ]
deps = [ ":googletest" ]
}
test("gtest_macro_stack_footprint_test") {
sources = [ "$googletest_dir/googletest/test/gtest_test_macro_stack_footprint_test.cc" ]
deps = [ ":googletest" ]
}
test("gtest_no_test") {
sources = [ "$googletest_dir/googletest/test/gtest_no_test_unittest.cc" ]
deps = [ ":googletest" ]
}
test("gtest_param_test") {
sources = [
"$googletest_dir/googletest/test/googletest-param-test-test.cc",
"$googletest_dir/googletest/test/googletest-param-test-test.h",
"$googletest_dir/googletest/test/googletest-param-test2-test.cc",
]
configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ]
configs += [ ":googletest_private_config" ]
deps = [ ":googletest" ]
if (crashpad_is_clang) {
cflags_cc = [
# For googletest/googlemock/test/gmock-matchers_test.ccs
# Unstreamable::value_.
"-Wno-unused-private-field",
]
}
}
test("gtest_premature_exit_test") {
sources = [ "$googletest_dir/googletest/test/gtest_premature_exit_test.cc" ]
deps = [ ":googletest" ]
}
test("gtest_repeat_test") {
sources = [ "$googletest_dir/googletest/test/gtest_repeat_test.cc" ]
configs += [ ":googletest_private_config" ]
deps = [ ":googletest" ]
}
test("gtest_skip_in_environment_setup_test") {
sources = [
"$googletest_dir/googletest/test/gtest_skip_in_environment_setup_test.cc",
]
deps = [ ":googletest" ]
}
test("gtest_sole_header_test") {
sources = [ "$googletest_dir/googletest/test/gtest_sole_header_test.cc" ]
deps = [
":googletest",
":googletest_main",
]
}
test("gtest_stress_test") {
sources = [ "$googletest_dir/googletest/test/gtest_stress_test.cc" ]
configs += [ ":googletest_private_config" ]
deps = [ ":googletest" ]
}
test("gtest_unittest_api_test") {
sources = [ "$googletest_dir/googletest/test/gtest-unittest-api_test.cc" ]
deps = [ ":googletest" ]
}
group("googletest_all_tests") {
testonly = true
deps = [
":gtest_all_test",
":gtest_environment_test",
":gtest_listener_test",
":gtest_macro_stack_footprint_test",
":gtest_no_test",
":gtest_param_test",
":gtest_premature_exit_test",
":gtest_repeat_test",
":gtest_skip_in_environment_setup_test",
":gtest_sole_header_test",
":gtest_stress_test",
":gtest_unittest_api_test",
]
}
config("googlemock_private_config") {
visibility = [ ":*" ]
include_dirs = [ "$googletest_dir/googlemock" ]
}
config("googlemock_public_config") {
include_dirs = [ "$googletest_dir/googlemock/include" ]
}
static_library("googlemock") {
testonly = true
sources = [
"$googletest_dir/googlemock/include/gmock/gmock-actions.h",
"$googletest_dir/googlemock/include/gmock/gmock-cardinalities.h",
"$googletest_dir/googlemock/include/gmock/gmock-function-mocker.h",
"$googletest_dir/googlemock/include/gmock/gmock-matchers.h",
"$googletest_dir/googlemock/include/gmock/gmock-more-actions.h",
"$googletest_dir/googlemock/include/gmock/gmock-more-matchers.h",
"$googletest_dir/googlemock/include/gmock/gmock-nice-strict.h",
"$googletest_dir/googlemock/include/gmock/gmock-spec-builders.h",
"$googletest_dir/googlemock/include/gmock/gmock.h",
"$googletest_dir/googlemock/include/gmock/internal/custom/gmock-generated-actions.h",
"$googletest_dir/googlemock/include/gmock/internal/custom/gmock-matchers.h",
"$googletest_dir/googlemock/include/gmock/internal/custom/gmock-port.h",
"$googletest_dir/googlemock/include/gmock/internal/gmock-internal-utils.h",
"$googletest_dir/googlemock/include/gmock/internal/gmock-port.h",
"$googletest_dir/googlemock/include/gmock/internal/gmock-pp.h",
"$googletest_dir/googlemock/src/gmock-all.cc",
"$googletest_dir/googlemock/src/gmock-cardinalities.cc",
"$googletest_dir/googlemock/src/gmock-internal-utils.cc",
"$googletest_dir/googlemock/src/gmock-matchers.cc",
"$googletest_dir/googlemock/src/gmock-spec-builders.cc",
"$googletest_dir/googlemock/src/gmock.cc",
]
sources -= [ "$googletest_dir/googlemock/src/gmock-all.cc" ]
public_configs = [ ":googlemock_public_config" ]
configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ]
configs += [ ":googlemock_private_config" ]
deps = [ ":googletest" ]
}
static_library("googlemock_main") {
# Tests outside of this file should use ../../test:googlemock_main instead.
visibility = [ ":*" ]
testonly = true
sources = [ "$googletest_dir/googlemock/src/gmock_main.cc" ]
deps = [
":googlemock",
":googletest",
]
}
test("gmock_all_test") {
sources = [
"$googletest_dir/googlemock/test/gmock-actions_test.cc",
"$googletest_dir/googlemock/test/gmock-cardinalities_test.cc",
"$googletest_dir/googlemock/test/gmock-function-mocker_test.cc",
"$googletest_dir/googlemock/test/gmock-internal-utils_test.cc",
"$googletest_dir/googlemock/test/gmock-matchers_test.cc",
"$googletest_dir/googlemock/test/gmock-more-actions_test.cc",
"$googletest_dir/googlemock/test/gmock-nice-strict_test.cc",
"$googletest_dir/googlemock/test/gmock-port_test.cc",
"$googletest_dir/googlemock/test/gmock-pp-string_test.cc",
"$googletest_dir/googlemock/test/gmock-pp_test.cc",
"$googletest_dir/googlemock/test/gmock-spec-builders_test.cc",
"$googletest_dir/googlemock/test/gmock_test.cc",
]
configs += [
":googlemock_private_config",
":googletest_private_config",
]
deps = [
":googlemock",
":googlemock_main",
":googletest",
]
if (crashpad_is_clang) {
cflags_cc = [
# googletest/googlemock/test/gmock-function-mocker_test.cc does not
# always use the override modifier with MOCK_METHOD.
"-Wno-inconsistent-missing-override",
# For googletest/googlemock/test/gmock-matchers_test.ccs
# testing::googlemock_matchers_test::Unprintable::c_.
"-Wno-unused-private-field",
]
}
if (crashpad_is_win) {
# TODO: Correct SDK in vc\tools\msvc\14.14.26428\include\functional
cflags = [ "/wd4789" ] # VAR of size N bytes will be overrun
}
}
test("gmock_link_test") {
sources = [
"$googletest_dir/googlemock/test/gmock_link2_test.cc",
"$googletest_dir/googlemock/test/gmock_link_test.cc",
"$googletest_dir/googlemock/test/gmock_link_test.h",
]
configs += [ ":googlemock_private_config" ]
deps = [
":googlemock",
":googlemock_main",
":googletest",
]
}
test("gmock_stress_test") {
sources = [ "$googletest_dir/googlemock/test/gmock_stress_test.cc" ]
configs -= [ "$mini_chromium_dir/build/config:Wexit_time_destructors" ]
configs += [ ":googlemock_private_config" ]
deps = [
":googlemock",
":googletest",
]
}
group("googlemock_all_tests") {
testonly = true
deps = [
":gmock_all_test",
":gmock_link_test",
":gmock_stress_test",
]
}
}

View File

@ -0,0 +1,31 @@
# Copyright 2019 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
config("lss_config") {
if (crashpad_is_in_chromium) {
defines = [ "CRASHPAD_LSS_SOURCE_EXTERNAL" ]
} else if (crashpad_is_in_fuchsia) {
defines = [ "CRASHPAD_LSS_SOURCE_FUCHSIA" ]
} else {
defines = [ "CRASHPAD_LSS_SOURCE_EMBEDDED" ]
}
}
source_set("lss") {
public_configs = [ ":lss_config" ]
sources = [ "lss.h" ]
}

View File

@ -0,0 +1,66 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
group("base") {
if (crashpad_is_in_chromium) {
public_deps = [ "//base" ]
} else if (crashpad_is_standalone) {
public_deps = [ "mini_chromium/base" ]
} else if (crashpad_is_in_fuchsia) {
public_deps = [ "//third_party/mini_chromium/base" ]
} else if (crashpad_is_external) {
public_deps = [ "../../../../mini_chromium/mini_chromium/base" ]
} else if (crashpad_is_in_dart) {
public_deps = [ "//third_party/mini_chromium/mini_chromium/base" ]
}
}
group("base_test_support") {
testonly = true
if (crashpad_is_in_chromium) {
public_deps = [ "//base/test:test_support" ]
}
}
group("build") {
if (crashpad_is_in_chromium) {
# Chromium has no build target.
} else if (crashpad_is_standalone) {
public_deps = [ "mini_chromium/build" ]
} else if (crashpad_is_in_fuchsia) {
public_deps = [ "//third_party/mini_chromium/build" ]
} else if (crashpad_is_external) {
public_deps = [ "../../../../mini_chromium/mini_chromium/build" ]
} else if (crashpad_is_in_dart) {
public_deps = [ "//third_party/mini_chromium/mini_chromium/build" ]
}
}
group("chromeos_buildflags") {
if (crashpad_is_in_chromium) {
public_deps = [ "//build:chromeos_buildflags" ]
} else if (crashpad_is_standalone) {
public_deps = [ "mini_chromium/build:chromeos_buildflags" ]
} else if (crashpad_is_in_fuchsia) {
public_deps = [ "//third_party/mini_chromium/build:chromeos_buildflags" ]
} else if (crashpad_is_external) {
public_deps = [ "../../../../mini_chromium/mini_chromium/build:chromeos_buildflags" ]
} else if (crashpad_is_in_dart) {
public_deps = [ "//third_party/mini_chromium/mini_chromium/build:chromeos_buildflags" ]
}
}

View File

@ -0,0 +1,13 @@
// This header should be generated by `build/write_buildflag_header.py`,
// but we rather hardcode it to simplify CMake scripts, as we do not
// support building on chromeos anyway.
#ifndef MINI_CHROMIUM_BUILD_CHROMEOS_BUILDFLAGS_H_
#define MINI_CHROMIUM_BUILD_CHROMEOS_BUILDFLAGS_H_
#include "build/buildflag.h"
#define BUILDFLAG_INTERNAL_IS_CHROMEOS_LACROS() (0)
#define BUILDFLAG_INTERNAL_IS_CHROMEOS_ASH() (0)
#endif // MINI_CHROMIUM_BUILD_CHROMEOS_BUILDFLAGS_H_

View File

@ -0,0 +1,7 @@
# 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.
group("mini_chromium") {
deps = [ "//base" ]
}

View File

@ -0,0 +1,171 @@
# 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("../build/platform.gni")
static_library("base") {
sources = [
"atomicops.h",
"atomicops_internals_atomicword_compat.h",
"atomicops_internals_portable.h",
"auto_reset.h",
"bit_cast.h",
"check.h",
"check_op.h",
"compiler_specific.h",
"cxx17_backports.h",
"debug/alias.cc",
"debug/alias.h",
"files/file_path.cc",
"files/file_path.h",
"files/file_util.h",
"files/scoped_file.cc",
"files/scoped_file.h",
"format_macros.h",
"ignore_result.h",
"logging.cc",
"logging.h",
"memory/free_deleter.h",
"memory/page_size.h",
"memory/scoped_policy.h",
"metrics/histogram_functions.h",
"metrics/histogram_macros.h",
"metrics/persistent_histogram_allocator.h",
"notreached.h",
"numerics/checked_math.h",
"numerics/checked_math_impl.h",
"numerics/clamped_math.h",
"numerics/clamped_math_impl.h",
"numerics/safe_conversions.h",
"numerics/safe_conversions_arm_impl.h",
"numerics/safe_conversions_impl.h",
"numerics/safe_math.h",
"numerics/safe_math_arm_impl.h",
"numerics/safe_math_clang_gcc_impl.h",
"numerics/safe_math_shared_impl.h",
"process/memory.cc",
"process/memory.h",
"rand_util.cc",
"rand_util.h",
"scoped_clear_last_error.h",
"scoped_generic.h",
"strings/string_number_conversions.cc",
"strings/string_number_conversions.h",
"strings/string_piece.h",
"strings/string_util.h",
"strings/stringprintf.cc",
"strings/stringprintf.h",
"strings/sys_string_conversions.h",
"strings/utf_string_conversion_utils.cc",
"strings/utf_string_conversion_utils.h",
"strings/utf_string_conversions.cc",
"strings/utf_string_conversions.h",
"synchronization/condition_variable.h",
"synchronization/lock.cc",
"synchronization/lock.h",
"synchronization/lock_impl.h",
"sys_byteorder.h",
"template_util.h",
"third_party/icu/icu_utf.cc",
"third_party/icu/icu_utf.h",
"threading/thread_local_storage.cc",
"threading/thread_local_storage.h",
]
if (mini_chromium_is_posix || mini_chromium_is_fuchsia) {
sources += [
"files/file_util_posix.cc",
"memory/page_size_posix.cc",
"posix/eintr_wrapper.h",
"posix/safe_strerror.cc",
"posix/safe_strerror.h",
"strings/string_util_posix.h",
"synchronization/condition_variable_posix.cc",
"synchronization/lock_impl_posix.cc",
"threading/thread_local_storage_posix.cc",
]
}
if (mini_chromium_is_mac) {
sources += [
"mac/close_nocancel.cc",
"mac/foundation_util.h",
"mac/foundation_util.mm",
"mac/mach_logging.cc",
"mac/mach_logging.h",
"mac/scoped_cftyperef.h",
"mac/scoped_ioobject.h",
"mac/scoped_launch_data.h",
"mac/scoped_mach_port.cc",
"mac/scoped_mach_port.h",
"mac/scoped_mach_vm.cc",
"mac/scoped_mach_vm.h",
"mac/scoped_nsautorelease_pool.h",
"mac/scoped_nsautorelease_pool.mm",
"mac/scoped_nsobject.h",
"mac/scoped_typeref.h",
"strings/sys_string_conversions_mac.mm",
]
frameworks = [
"ApplicationServices.framework",
"CoreFoundation.framework",
"Foundation.framework",
"IOKit.framework",
"Security.framework",
]
} else if (mini_chromium_is_ios) {
sources += [
"mac/foundation_util.h",
"mac/foundation_util.mm",
"mac/mach_logging.cc",
"mac/mach_logging.h",
"mac/scoped_cftyperef.h",
"mac/scoped_mach_port.cc",
"mac/scoped_mach_port.h",
"mac/scoped_mach_vm.cc",
"mac/scoped_mach_vm.h",
"mac/scoped_nsautorelease_pool.h",
"mac/scoped_nsautorelease_pool.mm",
"mac/scoped_nsobject.h",
"mac/scoped_typeref.h",
"strings/sys_string_conversions_mac.mm",
]
frameworks = [
"CoreFoundation.framework",
"CoreGraphics.framework",
"CoreText.framework",
"Foundation.framework",
"Security.framework",
]
} else if (mini_chromium_is_win) {
sources += [
"memory/page_size_win.cc",
"scoped_clear_last_error_win.cc",
"strings/string_util_win.cc",
"strings/string_util_win.h",
"synchronization/lock_impl_win.cc",
"threading/thread_local_storage_win.cc",
]
libs = [ "advapi32.lib" ]
} else if (mini_chromium_is_fuchsia) {
sources += [
"fuchsia/fuchsia_logging.cc",
"fuchsia/fuchsia_logging.h",
]
if (defined(is_fuchsia_tree) && is_fuchsia_tree) {
deps = [ "//zircon/system/ulib/syslog" ]
} else {
deps = [ "//third_party/fuchsia/sdk/$host_os-amd64/pkg/syslog" ]
}
}
public_configs = [ "../build:mini_chromium_config" ]
public_deps = [ "../build" ]
if (mini_chromium_is_android) {
libs = [ "log" ]
}
}

View File

@ -0,0 +1,36 @@
# Copyright 2020 The Crashpad 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 separate from build/config/BUILD.gn to avoid including various .gni
# that it requires, which in turn conflict with settings from BUILDCONFIG.gn
# when building in other trees.
import("./buildflag_header.gni")
import("./platform.gni")
config("mini_chromium_config") {
include_dirs = [
"..",
root_gen_dir
]
}
source_set("build") {
sources = [ "build_config.h" ]
public_configs = [ ":mini_chromium_config" ]
}
source_set("buildflag_header_h") {
sources = [ "buildflag.h" ]
}
buildflag_header("chromeos_buildflags") {
header = "chromeos_buildflags.h"
header_dir = "build"
flags = [
"IS_CHROMEOS_LACROS=$mini_chromium_is_chromeos_lacros",
"IS_CHROMEOS_ASH=$mini_chromium_is_chromeos_ash",
]
}

View File

@ -0,0 +1,101 @@
// Copyright 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.
#ifndef MINI_CHROMIUM_BUILD_BUILD_CONFIG_H_
#define MINI_CHROMIUM_BUILD_BUILD_CONFIG_H_
#if defined(__APPLE__)
#define OS_APPLE 1
#elif defined(__ANDROID__)
#define OS_ANDROID 1
#elif defined(__linux__)
#define OS_LINUX 1
#elif defined(_WIN32)
#define OS_WIN 1
#elif defined(__Fuchsia__)
#define OS_FUCHSIA 1
#else
#error Please add support for your platform in build/build_config.h
#endif
#if defined(OS_APPLE)
#include <TargetConditionals.h>
#if defined(TARGET_OS_OSX) && TARGET_OS_OSX
#define OS_MAC 1
#elif defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
#define OS_IOS 1
#endif // TARGET_OS_*
#endif // defined(OS_APPLE)
#if defined(OS_APPLE) || defined(OS_LINUX) || defined(OS_ANDROID) || \
defined(OS_FUCHSIA)
#define OS_POSIX 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
#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
#elif defined(_M_ARM64) || defined(__aarch64__)
#define ARCH_CPU_ARM_FAMILY 1
#define ARCH_CPU_ARM64 1
#define ARCH_CPU_64_BITS 1
#if defined(_M_ARM64)
#define ARCH_CPU_LITTLE_ENDIAN 1
#endif
#elif defined(__MIPSEL__)
#define ARCH_CPU_MIPS_FAMILY 1
#if !defined(__LP64__)
#define ARCH_CPU_MIPSEL 1
#define ARCH_CPU_32_BITS 1
#else
#define ARCH_CPU_MIPS64EL 1
#define ARCH_CPU_64_BITS 1
#endif
#else
#error Please add support for your architecture in build/build_config.h
#endif
#if !defined(ARCH_CPU_LITTLE_ENDIAN) && !defined(ARCH_CPU_BIG_ENDIAN)
#if defined(__LITTLE_ENDIAN__) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define ARCH_CPU_LITTLE_ENDIAN 1
#elif defined(__BIG_ENDIAN__) || \
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define ARCH_CPU_BIG_ENDIAN 1
#else
#error Please add support for your architecture in build/build_config.h
#endif
#endif
#if defined(OS_POSIX) && defined(COMPILER_GCC) && \
defined(__WCHAR_MAX__) && \
(__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff)
#define WCHAR_T_IS_UTF32
#elif defined(OS_WIN)
#define WCHAR_T_IS_UTF16
#else
#error Please add support for your compiler in build/build_config.h
#endif
#endif // MINI_CHROMIUM_BUILD_BUILD_CONFIG_H_

View File

@ -0,0 +1,13 @@
// 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.
#ifndef BUILD_BUILDFLAG_H_
#define BUILD_BUILDFLAG_H_
#define BUILDFLAG_CAT_INDIRECT(a, b) a ## b
#define BUILDFLAG_CAT(a, b) BUILDFLAG_CAT_INDIRECT(a, b)
#define BUILDFLAG(flag) (BUILDFLAG_CAT(BUILDFLAG_INTERNAL_, flag)())
#endif // BUILD_BUILDFLAG_H_

View File

@ -0,0 +1,56 @@
# 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.
template("buildflag_header") {
action(target_name) {
script = "write_buildflag_header.py"
if (defined(invoker.header_dir)) {
header_file = "${invoker.header_dir}/${invoker.header}"
} else {
# Compute the path from the root to this file.
header_file = rebase_path(".", "//") + "/${invoker.header}"
}
outputs = [ "$root_gen_dir/$header_file" ]
# Write flags to a file just in case they exceed the system's maximum
# command line length.
#
# Using write_file instead of response_file_contents to avoid a spurious
# rule variable cycle in generated command in Ninja.
#
# See more details from the following bugs:
# * https://bugs.fuchsia.dev/p/fuchsia/issues/detail?id=76068
# * https://github.com/ninja-build/ninja/issues/1966
flags = [ "--flags" ]
if (defined(invoker.flags)) {
flags += invoker.flags
}
flags_file = "${root_gen_dir}/${header_file}.flags"
write_file(flags_file, flags)
inputs = [ flags_file ]
args = [
"--output",
header_file, # Not rebased, Python script puts it inside gen-dir.
"--rulename",
get_label_info(":$target_name", "label_no_toolchain"),
"--gen-dir",
rebase_path(root_gen_dir, root_build_dir),
"--definitions",
rebase_path(flags_file, root_build_dir),
]
forward_variables_from(invoker,
[
"deps",
"public_deps",
"testonly",
"visibility",
])
public_deps = [ ":buildflag_header_h" ]
}
}

View File

@ -0,0 +1,7 @@
# Copyright 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.
import("platform.gni")
mini_chromium_is_clang = mini_chromium_is_posix || mini_chromium_is_fuchsia

View File

@ -0,0 +1,746 @@
# 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.
################################################################################
# DEFAULT BUILD CONFIGURATION
################################################################################
import("../compiler.gni")
import("../platform.gni")
import("../sysroot.gni")
if (mini_chromium_is_mac) {
declare_args() {
# The minimum runtime macOS version that built products are expected to run
# on. If empty, the toolchain will choose its own default, typically the
# older of the SDK version and the build hosts OS version.
mac_deployment_target = "10.9"
}
} else if (mini_chromium_is_ios) {
import("../ios/ios_sdk.gni")
} else if (mini_chromium_is_android) {
declare_args() {
android_ndk_root = ""
android_api_level = 21
}
} else if (mini_chromium_is_linux) {
declare_args() {
# Path to the Clang toolchain. If unset, uses the system-installed Clang.
clang_path = ""
# If set, link against libstdc++ statically.
link_libstdcpp_statically = false
}
} else if (mini_chromium_is_fuchsia) {
declare_args() {
# Path to the Fuchsia Clang toolchain.
clang_path = "//third_party/fuchsia/clang/" + host_os + "-amd64"
}
} else if (mini_chromium_is_win) {
declare_args() {
# Path to the Windows toolchain. If "<autodetect>", discovery of the
# system-installed toolchain will be attempted. Otherwise,
# win_sdk\bin\SetEnv.cmd inside this path will be used to configure the
# Windows toolchain.
win_toolchain_path = "<autodetect>"
}
}
declare_args() {
# Extra flags passed to the C compiler.
# Space-separated string of flags.
# "cflags" are passed to all invocations of the C, C++, Objective-C, and
# Objective-C++ compilers.
extra_cflags = ""
# Extra flags passed to the C compiler.
# Space-separated string of flags.
extra_cflags_c = ""
# Extra flags passed to the C++ compiler.
# Space-separated string of flags.
extra_cflags_cc = ""
# Extra flags passed to the Objective-C compiler.
# Space-separated string of flags.
extra_cflags_objc = ""
# Extra flags passed to the Objective-C++ compiler.
# Space-separated string of flags.
extra_cflags_objcc = ""
# Extra flags passed to the linker.
# Space-separated string of flags.
# These flags are passed on the command-line to the linker and generally
# specify various linking options.
extra_ldflags = ""
# Extra arguments passed to static_library archiver
# Space-separated string of flags.
# A list of flags passed to the archive/lib command that creates static
# libraries.
extra_arflags = ""
}
config("debug") {
if (!mini_chromium_is_win) {
cflags = [ "-g" ]
}
}
config("release") {
defines = [ "NDEBUG" ]
if (mini_chromium_is_posix || mini_chromium_is_fuchsia) {
cflags = [ "-O3" ]
if (mini_chromium_is_mac || mini_chromium_is_ios) {
ldflags = [ "-Wl,-dead_strip" ]
} else {
cflags += [
"-fdata-sections",
"-ffunction-sections",
]
ldflags = [
"-Wl,-O1",
"-Wl,--gc-sections",
]
}
} else if (mini_chromium_is_win) {
cflags = [
"/GL", # LTCG.
"/O2",
"/Ob2", # Both explicit and auto inlining.
"/Oy-", # Disable omitting frame pointers, must be after /O2.
"/Zc:inline", # Remove unreferenced COMDAT (faster links).
"/d2Zi+", # Improve debugging of optimized code.
]
ldflags = [
"/OPT:ICF",
"/OPT:REF",
"/LTCG",
]
arflags = [ "/LTCG" ]
}
}
config("default") {
common_flags = []
asmflags = []
ldflags = []
if (mini_chromium_is_posix || mini_chromium_is_fuchsia) {
cflags = [
"-Wall",
"-Wendif-labels",
"-Werror",
"-Wextra",
"-Wextra-semi",
"-Wheader-hygiene",
"-Wnewline-eof",
"-Wno-missing-field-initializers",
"-Wno-unused-parameter",
"-Wsign-compare",
"-Wstring-conversion",
"-Wvla",
"-fno-exceptions",
"-fno-rtti",
"-fno-strict-aliasing", # See https://crbug.com/32204
"-fobjc-call-cxx-cdtors",
"-fstack-protector-all", # Implies -fstack-protector
"-fvisibility-inlines-hidden",
"-fvisibility=hidden",
]
cflags_c = [ "-std=c11" ]
cflags_cc = [ "-std=c++14" ]
cflags_objc = cflags_c
cflags_objcc = cflags_cc
if (sysroot != "") {
if (sysroot == rebase_path(sysroot)) {
# If its already system-absolute, leave it alone.
sysroot_path = sysroot
} else {
sysroot_path = rebase_path(sysroot, root_build_dir)
}
if (mini_chromium_is_mac || mini_chromium_is_ios) {
common_flags += [
"-isysroot",
sysroot_path,
]
} else {
common_flags += [ "--sysroot=" + sysroot_path ]
}
}
if (mini_chromium_is_mac || mini_chromium_is_ios) {
if (current_cpu == "x86") {
common_flags += [
"-arch",
"i386",
]
} else if (current_cpu == "x64") {
common_flags += [
"-arch",
"x86_64",
]
} else if (current_cpu == "arm64") {
common_flags += [
"-arch",
"arm64",
]
} else if (mini_chromium_is_mac && current_cpu == "mac_universal") {
common_flags += [
"-arch",
"x86_64",
"-arch",
"arm64",
]
} else {
assert(false, "Unsupported architecture")
}
}
if (mini_chromium_is_fuchsia) {
common_flags += [
# The Fuchsia SDK no longer dumps everything in the sysroot, preferring
# the layout described in
# https://fuchsia.googlesource.com/docs/+/master/development/sdk/layout.md.
# Eventually /sysroot will be replaced by /pkg/system, but this work is
# not yet complete.
"-isystem",
rebase_path(fuchsia_sdk + "/pkg/fdio/include", root_build_dir),
]
lib_dirs = [ fuchsia_sdk + "/arch/$target_cpu/lib" ]
}
}
if (mini_chromium_is_mac) {
if (mac_deployment_target != "") {
common_flags += [ "-mmacosx-version-min=" + mac_deployment_target ]
}
}
if (mini_chromium_is_ios) {
if (ios_deployment_target != "") {
if (current_cpu == "x64") {
common_flags +=
[ "-mios-simulator-version-min=" + ios_deployment_target ]
} else if (current_cpu == "arm64") {
common_flags += [ "-mios-version-min=" + ios_deployment_target ]
}
}
}
if (mini_chromium_is_win) {
cflags = [
"/DNOMINMAX",
"/DUNICODE",
"/DWIN32_LEAN_AND_MEAN",
"/D_CRT_SECURE_NO_WARNINGS",
"/D_HAS_EXCEPTIONS=0",
"/D_UNICODE",
"/FS",
"/W4",
"/WX",
"/Zi",
"/bigobj", # Support larger number of sections in obj file.
"/wd4100", # Unreferenced formal parameter.
"/wd4127", # Conditional expression is constant.
"/wd4324", # Structure was padded due to alignment specifier.
"/wd4351", # New behavior: elements of array will be default initialized.
"/wd4577", # 'noexcept' used with no exception handling mode specified.
"/wd4996", # 'X' was declared deprecated.
]
ldflags += [ "/DEBUG" ]
libs = [ "kernel32.lib" ]
}
if (mini_chromium_is_linux) {
defines = [ "_FILE_OFFSET_BITS=64" ]
common_flags += [ "-pthread" ]
if (current_cpu == "x86") {
common_flags += [
"-m32",
]
} else if (current_cpu == "x64") {
common_flags += [
"-m64",
]
} else {
assert(false, "Unsupported architecture")
}
# This is currently required by the clang toolchain build that DEPS uses
# from the Fuchsia team. Only a static libc++ is provided, and it requires
# both -ldl and -pthread. (-pthread was already needed by mini_chromium and
# Crashpad). Eventually, the clang build should automatically add these
# when needed, but it does not do that yet, so manually add libdl here for
# now.
libs = [ "dl" ]
if (link_libstdcpp_statically) {
# The sysroot being built against is based on Stretch, which is newer than
# the libstdc++ that's on Trusty (14.04) which is the Chromium minspec.
# This minspec determines what the available buildbots are. Chromium
# doesn't have a problem with libstdc++ despite this, because it links
# against a local copy of libc++ instead. As this build file only affects
# the standalone Crashpad build, when this flag is set link libstdc++
# statically to avoid the problem on the bots.
cflags += [ "-stdlib=libstdc++" ]
ldflags += [
"-rtlib=libgcc",
"-static-libstdc++",
"-stdlib=libstdc++",
]
}
}
if (mini_chromium_is_fuchsia) {
if (target_cpu == "arm64") {
common_flags += [ "--target=aarch64-fuchsia" ]
} else if (target_cpu == "x64") {
common_flags += [ "--target=x86_64-fuchsia" ]
} else {
assert(false, "Unsupported architecture")
}
# fdio is listed in ldflags instead of libs because its important for it to
# be loaded in Fuchsia processes that expect POSIX-like file descriptor
# semantics, even if they dont explicitly reference anything in the fdio
# library. To avoid inadvertently losing the runtime dependency, it must
# come before -Wl,--as-needed below. fdio needs zircon (and zircon needs to
# be in every process anyway).
ldflags += [
"-lfdio",
"-lzircon",
]
}
if ((mini_chromium_is_posix && !mini_chromium_is_mac &&
!mini_chromium_is_ios) || mini_chromium_is_fuchsia) {
cflags += [ "-fPIC" ]
ldflags += [
# This must follow Fuchsias fdio library above.
"-Wl,--as-needed",
"-Wl,-z,noexecstack",
]
}
cflags += common_flags
asmflags += common_flags
ldflags += common_flags
if (is_debug) {
configs = [ ":debug" ]
} else {
configs = [ ":release" ]
}
}
config("executable") {
if (mini_chromium_is_linux) {
ldflags = [ "-pie" ]
}
}
config("ios_enable_arc") {
if (mini_chromium_is_ios) {
common_flags = [ "-fobjc-arc" ]
cflags_objc = common_flags
cflags_objcc = common_flags
}
}
config("Wexit_time_destructors") {
if (mini_chromium_is_clang) {
cflags = [ "-Wexit-time-destructors" ]
}
}
config("Wimplicit_fallthrough") {
if (mini_chromium_is_clang) {
cflags = [ "-Wimplicit-fallthrough" ]
}
}
config("win_console") {
if (mini_chromium_is_win) {
ldflags = [ "/SUBSYSTEM:CONSOLE" ]
}
}
config("win_windowed") {
if (mini_chromium_is_win) {
ldflags = [ "/SUBSYSTEM:WINDOWS" ]
}
}
################################################################################
# TOOLCHAIN DEFINITIONS
################################################################################
toolchain("gcc_like_toolchain") {
lib_switch = "-l"
lib_dir_switch = "-L"
if ((mini_chromium_is_linux || mini_chromium_is_fuchsia) &&
clang_path != "") {
cc = rebase_path(clang_path, root_build_dir) + "/bin/clang"
cxx = rebase_path(clang_path, root_build_dir) + "/bin/clang++"
asm = cxx
ar = rebase_path(clang_path, root_build_dir) + "/bin/llvm-ar"
ld = cxx
} else if (mini_chromium_is_android) {
assert(android_ndk_root != "", "Android builds must set android_ndk_root")
if (host_os == "linux") {
ndk_host_arch = "linux-x86_64"
} else if (host_os == "mac") {
ndk_host_arch = "darwin-x86_64"
} else if (host_os == "win") {
ndk_host_arch = "windows-x86_64"
}
ndk_bin_dir = string_join("/", [android_ndk_root, "toolchains", "llvm",
"prebuilt", ndk_host_arch, "bin", ""])
if (target_cpu == "arm") {
tool_prefix = "arm-linux-androideabi"
} else if (target_cpu == "arm64") {
tool_prefix = "aarch64-linux-android"
} else if (target_cpu == "x86") {
tool_prefix = "i686-linux-android"
} else if (target_cpu == "x64") {
tool_prefix = "x86_64-linux-android"
}
if (target_cpu == "arm") {
clang_prefix = "armv7a-linux-androideabi" + android_api_level
} else {
clang_prefix = tool_prefix + android_api_level
}
cc = ndk_bin_dir + clang_prefix + "-clang"
cxx = ndk_bin_dir + clang_prefix + "-clang++"
asm = cxx
ld = cxx
ar = ndk_bin_dir + tool_prefix + "-ar"
} else {
cc = "clang"
cxx = "clang++"
asm = cxx
ld = cxx
if (!mini_chromium_is_mac && !mini_chromium_is_ios) {
# macOS uses libtool instead of ar.
ar = "ar"
}
}
if (defined(extra_cflags) && extra_cflags != "") {
extra_cflags = " " + extra_cflags
} else {
extra_cflags = ""
}
if (defined(extra_cflags_c) && extra_cflags_c != "") {
extra_cflags_c = " " + extra_cflags_c
} else {
extra_cflags_c = ""
}
if (defined(extra_cflags_cc) && extra_cflags_cc != "") {
extra_cflags_cc = " " + extra_cflags_cc
} else {
extra_cflags_cc = ""
}
if (defined(extra_ldflags) && extra_ldflags != "") {
extra_ldflags = " " + extra_ldflags
} else {
extra_ldflags = ""
}
if (defined(extra_arflags) && extra_arflags != "") {
extra_arflags = " " + extra_arflags
} else {
extra_arflags = ""
}
tool("cc") {
depfile = "{{output}}.d"
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_c}}${extra_cflags}${extra_cflags_c} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CC {{output}}"
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
}
tool("cxx") {
depfile = "{{output}}.d"
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_cc}}${extra_cflags}${extra_cflags_cc} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "CXX {{output}}"
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
}
if (mini_chromium_is_mac || mini_chromium_is_ios) {
if (defined(extra_cflags_objc) && extra_cflags_objc != "") {
extra_cflags_objc = " " + extra_cflags_objc
} else {
extra_cflags_objc = ""
}
if (defined(extra_cflags_objcc) && extra_cflags_objcc != "") {
extra_cflags_objcc = " " + extra_cflags_objcc
} else {
extra_cflags_objcc = ""
}
tool("objc") {
depfile = "{{output}}.d"
command = "$cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_objc}}${extra_cflags}${extra_cflags_objc} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "OBJC {{output}}"
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
}
tool("objcxx") {
depfile = "{{output}}.d"
command = "$cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_objcc}}${extra_cflags}${extra_cflags_objcc} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "OBJCXX {{output}}"
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
}
# TODO(justincohen): Clean this up to use the more correct timestamp
# preserving -a in the fallback case once bots are all running macOS ≥ 11.
tool("copy_bundle_data") {
command =
"rm -rf {{output}} && cp -fRc {{source}} {{output}} 2>/dev/null " +
"|| (rm -rf {{output}} && cp -fR {{source}} {{output}})"
description = "COPY_BUNDLE_DATA {{source}} {{output}}"
}
tool("compile_xcassets") {
command = "/bin/true"
}
}
tool("asm") {
depfile = "{{output}}.d"
command = "$asm -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
depsformat = "gcc"
description = "ASM {{output}}"
outputs = [ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.o" ]
}
tool("alink") {
if (mini_chromium_is_mac || mini_chromium_is_ios) {
command = "libtool -static -no_warning_for_no_symbols {{arflags}}${extra_arflags} -o {{output}} {{inputs}}"
} else {
command = "rm -f {{output}}; $ar rcsD {{arflags}}${extra_arflags} {{output}} {{inputs}}"
}
description = "AR {{output}}"
default_output_dir = "{{target_out_dir}}"
default_output_extension = ".a"
output_prefix = "lib"
outputs = [ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ]
}
tool("solink_module") {
# TODO(scottmg): This will need to do -framework, etc. for macOS.
soname = "{{target_output_name}}{{output_extension}}" # e.g. "libfoo.so".
sofile = "{{output_dir}}/$soname"
soname_flag = ""
start_whole_flag = ""
end_whole_flag = ""
if (mini_chromium_is_mac || mini_chromium_is_ios) {
soname_flag = "-Wl,-install_name,\"$soname\""
} else {
soname_flag = "-Wl,-soname=\"$soname\""
start_whole_flag = "-Wl,--whole-archive"
end_whole_flag = "-Wl,--no-whole-archive "
}
command = "$ld -shared {{ldflags}}${extra_ldflags} -o \"$sofile\" $soname_flag $start_whole_flag {{inputs}} {{solibs}} {{frameworks}} $end_whole_flag {{libs}}"
description = "SOLINK_MODULE $sofile"
default_output_dir = "{{root_out_dir}}"
default_output_extension = ".so"
outputs = [ sofile ]
}
tool("link") {
exename = "{{target_output_name}}{{output_extension}}"
outfile = "{{output_dir}}/$exename"
start_group_flag = ""
end_group_flag = ""
if (!mini_chromium_is_mac && !mini_chromium_is_ios) {
start_group_flag = "-Wl,--start-group"
end_group_flag = "-Wl,--end-group"
}
command = "$ld {{ldflags}}${extra_ldflags} -o \"$outfile\" $start_group_flag {{inputs}} {{solibs}} {{frameworks}} $end_group_flag {{libs}}"
description = "LINK $outfile"
default_output_dir = "{{root_out_dir}}"
default_output_extension = ""
outputs = [ outfile ]
}
tool("stamp") {
command = "touch {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "ln -f {{source}} {{output}} 2>/dev/null || (rm -rf {{output}} && cp -af {{source}} {{output}})"
description = "COPY {{source}} {{output}}"
}
}
if (mini_chromium_is_win) {
helper_path = rebase_path("../win_helper.py")
toolchain_data = exec_script(helper_path,
[
"get-visual-studio-data",
rebase_path(root_build_dir),
rebase_path(win_toolchain_path),
],
"scope")
# Required arguments:
# - environment_file: Path to saved environment file (see win_helper.py).
# - current_cpu: The cpu to target with this toolchain.
template("msvc_toolchain") {
toolchain("msvc_toolchain_$target_name") {
# @rsp files are not used for simplicity, and because mini_chromium and
# Crashpad shouldn't require them in any configurations.
cc = "cl.exe"
cxx = "cl.exe"
ar = "lib.exe"
ld = "link.exe"
lib_switch = ""
lib_dir_switch = "/LIBPATH:"
env = invoker.environment_file
if (defined(invoker.extra_cflags) && invoker.extra_cflags != "") {
extra_cflags = " " + invoker.extra_cflags
} else {
extra_cflags = ""
}
if (defined(invoker.extra_cflags_c) && invoker.extra_cflags_c != "") {
extra_cflags_c = " " + invoker.extra_cflags_c
} else {
extra_cflags_c = ""
}
if (defined(invoker.extra_cflags_cc) && invoker.extra_cflags_cc != "") {
extra_cflags_cc = " " + invoker.extra_cflags_cc
} else {
extra_cflags_cc = ""
}
if (defined(invoker.extra_ldflags) && invoker.extra_ldflags != "") {
extra_ldflags = " " + invoker.extra_ldflags
} else {
extra_ldflags = ""
}
if (defined(invoker.extra_arflags) && invoker.extra_arflags != "") {
extra_arflags = " " + invoker.extra_arflags
} else {
extra_arflags = ""
}
tool("cc") {
depfile = "{{output}}.d"
pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb"
command = "ninja -t msvc -e $env -- $cc /nologo /showIncludes {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cflags}${extra_cflags_c} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
depsformat = "msvc"
description = "CC {{output}}"
outputs =
[ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
}
tool("cxx") {
depfile = "{{output}}.d"
pdbname = "{{target_out_dir}}/{{label_name}}_cc.pdb"
command = "ninja -t msvc -e $env -- $cxx /nologo /showIncludes {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}}${extra_cflags}${extra_cflags_cc} /c {{source}} /Fo{{output}} /Fd\"$pdbname\""
depsformat = "msvc"
description = "CXX {{output}}"
outputs =
[ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
}
tool("alink") {
command = "$python_path $helper_path link-wrapper $env $ar /nologo /out:{{output}} {{arflags}}${extra_arflags} {{inputs}}"
description = "AR {{output}}"
outputs =
[ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ]
default_output_dir = "{{target_out_dir}}"
default_output_extension = ".lib"
output_prefix = ""
}
tool("solink_module") {
outputs =
[ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ]
command = "$python_path $helper_path link-wrapper $env $ld /nologo /DLL /OUT:{{output}} {{ldflags}}${extra_ldflags} {{inputs}} {{solibs}} {{libs}}"
description = "SOLINK_MODULE {{output}}"
default_output_dir = "{{root_out_dir}}"
default_output_extension = ".dll"
}
tool("link") {
outputs =
[ "{{output_dir}}/{{target_output_name}}{{output_extension}}" ]
command = "$python_path $helper_path link-wrapper $env $ld /nologo /OUT:{{output}} {{ldflags}}${extra_ldflags} {{inputs}} {{solibs}} {{libs}}"
description = "LINK {{output}}"
default_output_dir = "{{root_out_dir}}"
default_output_extension = ".exe"
}
tool("asm") {
if (invoker.current_cpu == "arm64") {
ml = "armasm64.exe"
command = "$python_path $helper_path asm-wrapper $env $ml {{include_dirs}} {{asmflags}} -o {{output}} {{source}}"
} else {
if (invoker.current_cpu == "x86") {
ml = "ml.exe"
} else {
ml = "ml64.exe"
}
command = "$python_path $helper_path asm-wrapper $env $ml {{defines}} {{include_dirs}} {{asmflags}} /c /Fo{{output}} {{source}}"
}
description = "ASM {{output}}"
outputs =
[ "{{source_out_dir}}/{{label_name}}.{{source_name_part}}.obj" ]
}
tool("stamp") {
command = "$python_path $helper_path stamp {{output}}"
description = "STAMP {{output}}"
}
tool("copy") {
command = "cmd /c copy /y {{source}} {{output}} >nul"
description = "COPY {{source}} {{output}}"
}
}
}
msvc_toolchain("x64") {
environment_file = toolchain_data.x64_environment_file
current_cpu = "x64"
}
msvc_toolchain("x86") {
environment_file = toolchain_data.x86_environment_file
current_cpu = "x86"
}
msvc_toolchain("arm64") {
environment_file = toolchain_data.arm64_environment_file
current_cpu = "arm64"
}
}

View File

@ -0,0 +1,164 @@
#!/usr/bin/env python
# coding: utf-8
# Copyright 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.
from __future__ import print_function
import argparse
import distutils.version
import os
import re
import subprocess
import sys
import textwrap
def _AsVersion(string):
return distutils.version.StrictVersion(string)
def _RunXCRun(args, sdk=None):
xcrun_args = ['xcrun']
if sdk is not None:
xcrun_args.extend(['--sdk', sdk])
xcrun_args.extend(args)
return subprocess.check_output(xcrun_args).decode('utf-8').rstrip()
def _SDKPath(sdk=None):
return _RunXCRun(['--show-sdk-path'], sdk)
def _SDKVersion(sdk=None):
return _AsVersion(_RunXCRun(['--show-sdk-version'], sdk))
class DidNotMeetCriteria(Exception):
pass
def _FindPlatformSDKWithMinimumVersion(platform, minimum_sdk_version_str):
minimum_sdk_version = _AsVersion(minimum_sdk_version_str)
# Try the SDKs that Xcode knows about.
xcodebuild_showsdks_subprocess = subprocess.Popen(
['xcodebuild', '-showsdks'],
stdout=subprocess.PIPE,
stderr=open(os.devnull, 'w'))
xcodebuild_showsdks_output = (
xcodebuild_showsdks_subprocess.communicate()[0].decode('utf-8'))
if xcodebuild_showsdks_subprocess.returncode == 0:
# Collect strings instead of version objects to preserve the precise
# format used to identify each SDK.
sdk_version_strs = []
for line in xcodebuild_showsdks_output.splitlines():
match = re.match('[ \t].+[ \t]-sdk ' + re.escape(platform) + '(.+)$',
line)
if match:
sdk_version_str = match.group(1)
if _AsVersion(sdk_version_str) >= minimum_sdk_version:
sdk_version_strs.append(sdk_version_str)
if len(sdk_version_strs) == 0:
raise DidNotMeetCriteria({'minimum': minimum_sdk_version_str,
'platform': platform})
sdk_version_str = sorted(sdk_version_strs, key=_AsVersion)[0]
sdk_path = _SDKPath(platform + sdk_version_str)
sdk_version = _AsVersion(sdk_version_str)
else:
# Xcode may not be installed. If the command-line tools are installed, use
# the systems default SDK if it meets the requirements.
sdk_path = _SDKPath()
sdk_version = _SDKVersion()
if sdk_version < minimum_sdk_version:
raise DidNotMeetCriteria({'minimum': minimum_sdk_version_str,
'platform': platform,
'sdk_path': sdk_path,
'sdk_version': str(sdk_version)})
return (sdk_version, sdk_path)
def main(args):
parser = argparse.ArgumentParser(
description='Find an appropriate platform SDK',
epilog='Two lines will be written to standard output: the version of the '
'selected SDK, and its path.')
parser.add_argument('--developer-dir',
help='path to Xcode or Command Line Tools')
parser.add_argument('--exact', help='an exact SDK version to find')
parser.add_argument('--minimum', help='the minimum SDK version to find')
parser.add_argument('--path', help='a known SDK path to validate')
parser.add_argument('--platform',
default='macosx',
help='the platform to target')
parsed = parser.parse_args(args)
if parsed.developer_dir is not None:
os.environ['DEVELOPER_DIR'] = parsed.developer_dir
if (os.environ.get('DEVELOPER_DIR') is None and
subprocess.call(['xcode-select', '--print-path'],
stdout=open(os.devnull, 'w'),
stderr=open(os.devnull, 'w')) != 0):
# This is friendlier than letting the first invocation of xcrun or
# xcodebuild show the UI prompting to install developer tools at an
# inopportune time.
hint = 'Install Xcode and run "sudo xcodebuild -license"'
if parsed.platform == 'macosx':
hint += ', or install Command Line Tools with "xcode-select --install"'
hint += ('. If necessary, run "sudo xcode-select --switch" to select an '
'active developer tools installation.')
hint = '\n'.join(textwrap.wrap(hint, 80))
print(os.path.basename(sys.argv[0]) +
': No developer tools found.\n' +
hint,
file=sys.stderr)
return 1
if parsed.path is not None:
# _SDKVersion() doesnt work with a relative pathname argument or one thats
# a symbolic link. Such paths are suitable for other purposes, like “clang
# -isysroot”, so use an absolute non-symbolic link path for _SDKVersion(),
# but preserve the users path in sdk_path.
sdk_version = _SDKVersion(os.path.realpath(parsed.path))
sdk_path = parsed.path
elif parsed.exact is None and parsed.minimum is None:
# Use the platforms default SDK.
sdk_version = _SDKVersion(parsed.platform)
sdk_path = _SDKPath(parsed.platform)
elif parsed.exact is not None:
sdk_version = _SDKVersion(parsed.platform + parsed.exact)
sdk_path = _SDKPath(parsed.platform + parsed.exact)
else:
(sdk_version,
sdk_path) = _FindPlatformSDKWithMinimumVersion(parsed.platform,
parsed.minimum)
# These checks may be redundant depending on how the SDK was chosen.
if ((parsed.exact is not None and sdk_version != _AsVersion(parsed.exact)) or
(parsed.minimum is not None and
sdk_version < _AsVersion(parsed.minimum))):
raise DidNotMeetCriteria({'developer_dir': parsed.developer_dir,
'exact': parsed.exact,
'minimum': parsed.minimum,
'path': parsed.path,
'platform': parsed.platform,
'sdk_path': sdk_path,
'sdk_version': str(sdk_version)})
# Nobody wants trailing slashes. This is true even if “/” is the SDK: its
# better to return an empty string, which will be interpreted as “no sysroot.”
sdk_path = sdk_path.rstrip(os.path.sep)
print(sdk_version)
print(sdk_path)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))

View File

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${IOS_BUNDLE_ID_PREFIX}.googletest.${EXECUTABLE_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIApplicationDelegate</key>
<string>MiniChromiumApplicationDelegate</string>
<key>UILaunchImages</key>
<array>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{320, 480}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{320, 568}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{375, 667}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{414, 736}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{375, 812}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{414, 896}</string>
</dict>
</array>
<key>UILaunchImages~ipad</key>
<array>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{768, 1024}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{1024, 1366}</string>
</dict>
<dict>
<key>UILaunchImageMinimumOSVersion</key>
<string>9.0</string>
<key>UILaunchImageName</key>
<string>Default</string>
<key>UILaunchImageSize</key>
<string>{832, 1114}</string>
</dict>
</array>
<key>UISupportedInterfaceOrientation</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,20 @@
# 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("ios_sdk.gni")
config("xctest_config") {
common_flags = [
"-F",
"$ios_sdk_platform_path/Developer/Library/Frameworks",
]
cflags = common_flags
ldflags = common_flags
frameworks = [
"Foundation.framework",
"XCTest.framework",
]
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>BuildMachineOSBuild</key>
<string>${BUILD_MACHINE_OS_BUILD}</string>
<key>CFBundleSupportedPlatforms</key>
<array>
<string>${IOS_SUPPORTED_PLATFORM}</string>
</array>
<key>DTCompiler</key>
<string>${GCC_VERSION}</string>
<key>DTPlatformBuild</key>
<string>${IOS_PLATFORM_BUILD}</string>
<key>DTPlatformName</key>
<string>${IOS_PLATFORM_NAME}</string>
<key>DTPlatformVersion</key>
<string>${IOS_PLATFORM_VERSION}</string>
<key>DTSDKBuild</key>
<string>${IOS_SDK_BUILD}</string>
<key>DTSDKName</key>
<string>${IOS_SDK_NAME}</string>
<key>DTXcode</key>
<string>${XCODE_VERSION}</string>
<key>DTXcodeBuild</key>
<string>${XCODE_BUILD}</string>
<key>MinimumOSVersion</key>
<string>${IOS_DEPLOYMENT_TARGET}</string>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
</dict>
</plist>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>${IOS_BUNDLE_ID_PREFIX}.${MODULE_BUNDLE_ID:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>NSPrincipalClass</key>
<string>${XCTEST_BUNDLE_PRINCIPAL_CLASS}</string>
</dict>
</plist>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.apple.test.${EXECUTABLE_NAME}</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
</dict>
</plist>

View File

@ -0,0 +1,537 @@
#!/usr/bin/env python
# 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 codecs
import datetime
import fnmatch
import glob
import os
import plistlib
import shutil
import subprocess
import sys
import tempfile
def GetProvisioningProfilesDir():
"""Returns the location of the installed mobile provisioning profiles.
Returns:
The path to the directory containing the installed mobile provisioning
profiles as a string.
"""
return os.path.join(
os.environ['HOME'], 'Library', 'MobileDevice', 'Provisioning Profiles')
def LoadPlistFile(plist_path):
"""Loads property list file at |plist_path|.
Args:
plist_path: path to the property list file to load.
Returns:
The content of the property list file as a python object.
"""
return plistlib.readPlistFromString(subprocess.check_output([
'xcrun', 'plutil', '-convert', 'xml1', '-o', '-', plist_path]))
class Bundle(object):
"""Wraps a bundle."""
def __init__(self, bundle_path):
"""Initializes the Bundle object with data from bundle Info.plist file."""
self._path = bundle_path
self._data = LoadPlistFile(os.path.join(self._path, 'Info.plist'))
@property
def path(self):
return self._path
@property
def identifier(self):
return self._data['CFBundleIdentifier']
@property
def binary_path(self):
return os.path.join(self._path, self._data['CFBundleExecutable'])
def Validate(self, expected_mappings):
"""Checks that keys in the bundle have the expected value.
Args:
expected_mappings: a dictionary of string to object, each mapping will
be looked up in the bundle data to check it has the same value (missing
values will be ignored)
Returns:
A dictionary of the key with a different value between expected_mappings
and the content of the bundle (i.e. errors) so that caller can format the
error message. The dictionary will be empty if there are no errors.
"""
errors = {}
for key, expected_value in expected_mappings.iteritems():
if key in self._data:
value = self._data[key]
if value != expected_value:
errors[key] = (value, expected_value)
return errors
class ProvisioningProfile(object):
"""Wraps a mobile provisioning profile file."""
def __init__(self, provisioning_profile_path):
"""Initializes the ProvisioningProfile with data from profile file."""
self._path = provisioning_profile_path
self._data = plistlib.readPlistFromString(subprocess.check_output([
'xcrun', 'security', 'cms', '-D', '-u', 'certUsageAnyCA',
'-i', provisioning_profile_path]))
@property
def path(self):
return self._path
@property
def application_identifier_pattern(self):
return self._data.get('Entitlements', {}).get('application-identifier', '')
@property
def team_identifier(self):
return self._data.get('TeamIdentifier', [''])[0]
@property
def entitlements(self):
return self._data.get('Entitlements', {})
@property
def expiration_date(self):
return self._data.get('ExpirationDate', datetime.datetime.now())
def ValidToSignBundle(self, bundle_identifier):
"""Checks whether the provisioning profile can sign bundle_identifier.
Args:
bundle_identifier: the identifier of the bundle that needs to be signed.
Returns:
True if the mobile provisioning profile can be used to sign a bundle
with the corresponding bundle_identifier, False otherwise.
"""
return fnmatch.fnmatch(
'%s.%s' % (self.team_identifier, bundle_identifier),
self.application_identifier_pattern)
def Install(self, installation_path):
"""Copies mobile provisioning profile info to |installation_path|."""
shutil.copy2(self.path, installation_path)
class Entitlements(object):
"""Wraps an Entitlement plist file."""
def __init__(self, entitlements_path):
"""Initializes Entitlements object from entitlement file."""
self._path = entitlements_path
self._data = LoadPlistFile(self._path)
@property
def path(self):
return self._path
def ExpandVariables(self, substitutions):
self._data = self._ExpandVariables(self._data, substitutions)
def _ExpandVariables(self, data, substitutions):
if isinstance(data, str):
for key, substitution in substitutions.iteritems():
data = data.replace('$(%s)' % (key,), substitution)
return data
if isinstance(data, dict):
for key, value in data.iteritems():
data[key] = self._ExpandVariables(value, substitutions)
return data
if isinstance(data, list):
for i, value in enumerate(data):
data[i] = self._ExpandVariables(value, substitutions)
return data
def LoadDefaults(self, defaults):
for key, value in defaults.iteritems():
if key not in self._data:
self._data[key] = value
def WriteTo(self, target_path):
plistlib.writePlist(self._data, target_path)
def FindProvisioningProfile(bundle_identifier, required):
"""Finds mobile provisioning profile to use to sign bundle.
Args:
bundle_identifier: the identifier of the bundle to sign.
Returns:
The ProvisioningProfile object that can be used to sign the Bundle
object or None if no matching provisioning profile was found.
"""
provisioning_profile_paths = glob.glob(
os.path.join(GetProvisioningProfilesDir(), '*.mobileprovision'))
# Iterate over all installed mobile provisioning profiles and filter those
# that can be used to sign the bundle, ignoring expired ones.
now = datetime.datetime.now()
valid_provisioning_profiles = []
one_hour = datetime.timedelta(0, 3600)
for provisioning_profile_path in provisioning_profile_paths:
provisioning_profile = ProvisioningProfile(provisioning_profile_path)
if provisioning_profile.expiration_date - now < one_hour:
sys.stderr.write(
'Warning: ignoring expired provisioning profile: %s.\n' %
provisioning_profile_path)
continue
if provisioning_profile.ValidToSignBundle(bundle_identifier):
valid_provisioning_profiles.append(provisioning_profile)
if not valid_provisioning_profiles:
if required:
sys.stderr.write(
'Error: no mobile provisioning profile found for "%s".\n' %
bundle_identifier)
sys.exit(1)
return None
# Select the most specific mobile provisioning profile, i.e. the one with
# the longest application identifier pattern (prefer the one with the latest
# expiration date as a secondary criteria).
selected_provisioning_profile = max(
valid_provisioning_profiles,
key=lambda p: (len(p.application_identifier_pattern), p.expiration_date))
one_week = datetime.timedelta(7)
if selected_provisioning_profile.expiration_date - now < 2 * one_week:
sys.stderr.write(
'Warning: selected provisioning profile will expire soon: %s' %
selected_provisioning_profile.path)
return selected_provisioning_profile
def CodeSignBundle(bundle_path, identity, extra_args):
process = subprocess.Popen(['xcrun', 'codesign', '--force', '--sign',
identity, '--timestamp=none'] + list(extra_args) + [bundle_path],
stderr=subprocess.PIPE)
_, stderr = process.communicate()
if process.returncode:
sys.stderr.write(stderr)
sys.exit(process.returncode)
for line in stderr.splitlines():
if line.endswith(': replacing existing signature'):
# Ignore warning about replacing existing signature as this should only
# happen when re-signing system frameworks (and then it is expected).
continue
sys.stderr.write(line)
sys.stderr.write('\n')
def InstallSystemFramework(framework_path, bundle_path, args):
"""Install framework from |framework_path| to |bundle| and code-re-sign it."""
installed_framework_path = os.path.join(
bundle_path, 'Frameworks', os.path.basename(framework_path))
if os.path.isfile(framework_path):
shutil.copy(framework_path, installed_framework_path)
elif os.path.isdir(framework_path):
if os.path.exists(installed_framework_path):
shutil.rmtree(installed_framework_path)
shutil.copytree(framework_path, installed_framework_path)
CodeSignBundle(installed_framework_path, args.identity,
['--deep', '--preserve-metadata=identifier,entitlements,flags'])
def GenerateEntitlements(path, provisioning_profile, bundle_identifier):
"""Generates an entitlements file.
Args:
path: path to the entitlements template file
provisioning_profile: ProvisioningProfile object to use, may be None
bundle_identifier: identifier of the bundle to sign.
"""
entitlements = Entitlements(path)
if provisioning_profile:
entitlements.LoadDefaults(provisioning_profile.entitlements)
app_identifier_prefix = provisioning_profile.team_identifier + '.'
else:
app_identifier_prefix = '*.'
entitlements.ExpandVariables({
'CFBundleIdentifier': bundle_identifier,
'AppIdentifierPrefix': app_identifier_prefix,
})
return entitlements
def GenerateBundleInfoPlist(bundle_path, plist_compiler, partial_plist):
"""Generates the bundle Info.plist for a list of partial .plist files.
Args:
bundle_path: path to the bundle
plist_compiler: string, path to the Info.plist compiler
partial_plist: list of path to partial .plist files to merge
"""
# Filter empty partial .plist files (this happens if an application
# does not include need to compile any asset catalog, in which case
# the partial .plist file from the asset catalog compilation step is
# just a stamp file).
filtered_partial_plist = []
for plist in partial_plist:
plist_size = os.stat(plist).st_size
if plist_size:
filtered_partial_plist.append(plist)
# Invoke the plist_compiler script. It needs to be a python script.
subprocess.check_call([
'python', plist_compiler, 'merge', '-f', 'binary1',
'-o', os.path.join(bundle_path, 'Info.plist'),
] + filtered_partial_plist)
class Action(object):
"""Class implementing one action supported by the script."""
@classmethod
def Register(cls, subparsers):
parser = subparsers.add_parser(cls.name, help=cls.help)
parser.set_defaults(func=cls._Execute)
cls._Register(parser)
class CodeSignBundleAction(Action):
"""Class implementing the code-sign-bundle action."""
name = 'code-sign-bundle'
help = 'perform code signature for a bundle'
@staticmethod
def _Register(parser):
parser.add_argument(
'--entitlements', '-e', dest='entitlements_path',
help='path to the entitlements file to use')
parser.add_argument(
'path', help='path to the iOS bundle to codesign')
parser.add_argument(
'--identity', '-i', required=True,
help='identity to use to codesign')
parser.add_argument(
'--binary', '-b', required=True,
help='path to the iOS bundle binary')
parser.add_argument(
'--framework', '-F', action='append', default=[], dest='frameworks',
help='install and resign system framework')
parser.add_argument(
'--disable-code-signature', action='store_true', dest='no_signature',
help='disable code signature')
parser.add_argument(
'--disable-embedded-mobileprovision', action='store_false',
default=True, dest='embedded_mobileprovision',
help='disable finding and embedding mobileprovision')
parser.add_argument(
'--platform', '-t', required=True,
help='platform the signed bundle is targeting')
parser.add_argument(
'--partial-info-plist', '-p', action='append', default=[],
help='path to partial Info.plist to merge to create bundle Info.plist')
parser.add_argument(
'--plist-compiler-path', '-P', action='store',
help='path to the plist compiler script (for --partial-info-plist)')
parser.set_defaults(no_signature=False)
@staticmethod
def _Execute(args):
if not args.identity:
args.identity = '-'
if args.partial_info_plist:
GenerateBundleInfoPlist(
args.path,
args.plist_compiler_path,
args.partial_info_plist)
bundle = Bundle(args.path)
# According to Apple documentation, the application binary must be the same
# as the bundle name without the .app suffix. See crbug.com/740476 for more
# information on what problem this can cause.
#
# To prevent this class of error, fail with an error if the binary name is
# incorrect in the Info.plist as it is not possible to update the value in
# Info.plist at this point (the file has been copied by a different target
# and ninja would consider the build dirty if it was updated).
#
# Also checks that the name of the bundle is correct too (does not cause the
# build to be considered dirty, but still terminate the script in case of an
# incorrect bundle name).
#
# Apple documentation is available at:
# https://developer.apple.com/library/content/documentation/CoreFoundation/Conceptual/CFBundles/BundleTypes/BundleTypes.html
bundle_name = os.path.splitext(os.path.basename(bundle.path))[0]
errors = bundle.Validate({
'CFBundleName': bundle_name,
'CFBundleExecutable': bundle_name,
})
if errors:
for key in sorted(errors):
value, expected_value = errors[key]
sys.stderr.write('%s: error: %s value incorrect: %s != %s\n' % (
bundle.path, key, value, expected_value))
sys.stderr.flush()
sys.exit(1)
# Delete existing embedded mobile provisioning.
embedded_provisioning_profile = os.path.join(
bundle.path, 'embedded.mobileprovision')
if os.path.isfile(embedded_provisioning_profile):
os.unlink(embedded_provisioning_profile)
# Delete existing code signature.
signature_file = os.path.join(args.path, '_CodeSignature', 'CodeResources')
if os.path.isfile(signature_file):
shutil.rmtree(os.path.dirname(signature_file))
# Install system frameworks if requested.
for framework_path in args.frameworks:
InstallSystemFramework(framework_path, args.path, args)
# Copy main binary into bundle.
if os.path.isfile(bundle.binary_path):
os.unlink(bundle.binary_path)
shutil.copy(args.binary, bundle.binary_path)
if args.no_signature:
return
codesign_extra_args = []
if args.embedded_mobileprovision:
# Find mobile provisioning profile and embeds it into the bundle (if a
# code signing identify has been provided, fails if no valid mobile
# provisioning is found).
provisioning_profile_required = args.identity != '-'
provisioning_profile = FindProvisioningProfile(
bundle.identifier, provisioning_profile_required)
if provisioning_profile and args.platform != 'iphonesimulator':
provisioning_profile.Install(embedded_provisioning_profile)
if args.entitlements_path is not None:
temporary_entitlements_file = \
tempfile.NamedTemporaryFile(suffix='.xcent')
codesign_extra_args.extend(
['--entitlements', temporary_entitlements_file.name])
entitlements = GenerateEntitlements(
args.entitlements_path, provisioning_profile, bundle.identifier)
entitlements.WriteTo(temporary_entitlements_file.name)
CodeSignBundle(bundle.path, args.identity, codesign_extra_args)
class CodeSignFileAction(Action):
"""Class implementing code signature for a single file."""
name = 'code-sign-file'
help = 'code-sign a single file'
@staticmethod
def _Register(parser):
parser.add_argument(
'path', help='path to the file to codesign')
parser.add_argument(
'--identity', '-i', required=True,
help='identity to use to codesign')
parser.add_argument(
'--output', '-o',
help='if specified copy the file to that location before signing it')
parser.set_defaults(sign=True)
@staticmethod
def _Execute(args):
if not args.identity:
args.identity = '-'
install_path = args.path
if args.output:
if os.path.isfile(args.output):
os.unlink(args.output)
elif os.path.isdir(args.output):
shutil.rmtree(args.output)
if os.path.isfile(args.path):
shutil.copy(args.path, args.output)
elif os.path.isdir(args.path):
shutil.copytree(args.path, args.output)
install_path = args.output
CodeSignBundle(install_path, args.identity,
['--deep', '--preserve-metadata=identifier,entitlements'])
class GenerateEntitlementsAction(Action):
"""Class implementing the generate-entitlements action."""
name = 'generate-entitlements'
help = 'generate entitlements file'
@staticmethod
def _Register(parser):
parser.add_argument(
'--entitlements', '-e', dest='entitlements_path',
help='path to the entitlements file to use')
parser.add_argument(
'path', help='path to the entitlements file to generate')
parser.add_argument(
'--info-plist', '-p', required=True,
help='path to the bundle Info.plist')
@staticmethod
def _Execute(args):
info_plist = LoadPlistFile(args.info_plist)
bundle_identifier = info_plist['CFBundleIdentifier']
provisioning_profile = FindProvisioningProfile(bundle_identifier, False)
entitlements = GenerateEntitlements(
args.entitlements_path, provisioning_profile, bundle_identifier)
entitlements.WriteTo(args.path)
def Main():
# Cache this codec so that plistlib can find it. See
# https://crbug.com/999461#c12 for more details.
codecs.lookup('utf-8')
parser = argparse.ArgumentParser('codesign iOS bundles')
subparsers = parser.add_subparsers()
actions = [
CodeSignBundleAction,
CodeSignFileAction,
GenerateEntitlementsAction,
]
for action in actions:
action.Register(subparsers)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
sys.exit(Main())

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>$(AppIdentifierPrefix)$(CFBundleIdentifier)</string>
</dict>
</plist>

View File

@ -0,0 +1,46 @@
#!/usr/bin/env python
# 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.
from __future__ import print_function
import argparse
import os
import subprocess
import sys
import re
def ListIdentities():
return subprocess.check_output([
'xcrun',
'security',
'find-identity',
'-v',
'-p',
'codesigning',
])
def FindValidIdentity(identity_description):
lines = list(map(str.strip, ListIdentities().splitlines()))
# Look for something like "2) XYZ "iPhone Developer: Name (ABC)""
exp = re.compile('[0-9]+\) ([A-F0-9]+) "([^"]*)"')
for line in lines:
res = exp.match(line)
if res is None:
continue
if identity_description in res.group(2):
yield res.group(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser('codesign iOS bundles')
parser.add_argument(
'--identity-description', required=True,
help='Text description used to select the code signing identity.')
args = parser.parse_args()
for identity in FindValidIdentity(args.identity_description):
print(identity)

View File

@ -0,0 +1,101 @@
# 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() {
# The minimum runtime iOS version that built products are expected to run
# on. If empty, the toolchain will choose its own default, typically the
# most recent OS version.
ios_deployment_target = "12.0"
# SDK path to use. When empty this will use the default SDK based on the
# value of use_ios_simulator.
ios_sdk_path = ""
# Prefix for CFBundleIdentifier property of iOS bundles (correspond to the
# "Organization Identifier" in Xcode). Code signing will fail if no mobile
# provisioning for the selected code signing identify support that prefix.
ios_app_bundle_id_prefix = "org.chromium"
# The iOS Code signing identity to use
ios_enable_code_signing = true
ios_code_signing_identity = ""
ios_code_signing_identity_description = "Apple Development"
}
use_ios_simulator = current_cpu == "x86" || current_cpu == "x64"
if (ios_sdk_path == "") {
# Compute default target.
if (use_ios_simulator) {
ios_sdk_name = "iphonesimulator"
ios_sdk_platform = "iPhoneSimulator"
} else {
ios_sdk_name = "iphoneos"
ios_sdk_platform = "iPhoneOS"
}
ios_sdk_info_args = [ "--get_sdk_info" ]
ios_sdk_info_args += [ ios_sdk_name ]
_ios_sdk_result = exec_script("sdk_info.py", ios_sdk_info_args, "scope")
ios_sdk_path = _ios_sdk_result.sdk_path
ios_sdk_version = _ios_sdk_result.sdk_version
ios_sdk_platform_path = _ios_sdk_result.sdk_platform_path
ios_sdk_build = _ios_sdk_result.sdk_build
xcode_version = _ios_sdk_result.xcode_version
xcode_version_int = _ios_sdk_result.xcode_version_int
xcode_build = _ios_sdk_result.xcode_build
machine_os_build = _ios_sdk_result.machine_os_build
if (use_ios_simulator) {
# This is weird, but Xcode sets DTPlatformBuild to an empty field for
# simulator builds.
ios_platform_build = ""
} else {
ios_platform_build = ios_sdk_build
}
}
if (ios_enable_code_signing && !use_ios_simulator) {
find_signing_identity_args = [
"--identity-description",
ios_code_signing_identity_description,
]
# If an identity is not provided, look for one on the host
if (ios_code_signing_identity == "") {
_ios_identities = exec_script("find_signing_identity.py",
find_signing_identity_args,
"list lines")
if (_ios_identities == []) {
print("Automatic code signing identity selection was enabled but could")
print("not find exactly one code signing identity matching")
print("$ios_code_signing_identity_description. Check that your keychain")
print("is accessible and that there is a valid code signing identity")
print("listed by `xcrun security find-identity -v -p codesigning`")
print("TIP: Simulator builds don't require code signing...")
assert(false)
} else {
_ios_identities_len = 0
foreach(_, _ios_identities) {
_ios_identities_len += 1
}
ios_code_signing_identity = _ios_identities[0]
if (_ios_identities_len != 1) {
print("Warning: Multiple codesigning identities match " +
"\"$ios_code_signing_identity_description\"")
foreach(_ios_identity, _ios_identities) {
_selected = ""
if (ios_code_signing_identity == _ios_identity) {
_selected = " (selected)"
}
print("Warning: - $_ios_identity$_selected")
}
print("Warning: Please use either ios_code_signing_identity or ")
print("Warning: ios_code_signing_identity_description variable to ")
print("Warning: control which identity is selected.")
print()
}
}
}
}

View File

@ -0,0 +1,228 @@
#!/usr/bin/env python
# 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 plistlib
import os
import re
import subprocess
import sys
import tempfile
import shlex
# Xcode substitutes variables like ${PRODUCT_NAME} or $(PRODUCT_NAME) when
# compiling Info.plist. It also supports supports modifiers like :identifier
# or :rfc1034identifier. SUBSTITUTION_REGEXP_LIST is a list of regular
# expressions matching a variable substitution pattern with an optional
# modifier, while INVALID_CHARACTER_REGEXP matches all characters that are
# not valid in an "identifier" value (used when applying the modifier).
INVALID_CHARACTER_REGEXP = re.compile(r'[_/\s]')
SUBSTITUTION_REGEXP_LIST = (
re.compile(r'\$\{(?P<id>[^}]*?)(?P<modifier>:[^}]*)?\}'),
re.compile(r'\$\((?P<id>[^}]*?)(?P<modifier>:[^}]*)?\)'),
)
class SubstitutionError(Exception):
def __init__(self, key):
super(SubstitutionError, self).__init__()
self.key = key
def __str__(self):
return "SubstitutionError: {}".format(self.key)
def InterpolateString(value, substitutions):
"""Interpolates variable references into |value| using |substitutions|.
Inputs:
value: a string
substitutions: a mapping of variable names to values
Returns:
A new string with all variables references ${VARIABLES} replaced by their
value in |substitutions|. Raises SubstitutionError if a variable has no
substitution.
"""
def repl(match):
variable = match.group('id')
if variable not in substitutions:
raise SubstitutionError(variable)
# Some values need to be identifier and thus the variables references may
# contains :modifier attributes to indicate how they should be converted
# to identifiers ("identifier" replaces all invalid characters by '_' and
# "rfc1034identifier" replaces them by "-" to make valid URI too).
modifier = match.group('modifier')
if modifier == ':identifier':
return INVALID_CHARACTER_REGEXP.sub('_', substitutions[variable])
elif modifier == ':rfc1034identifier':
return INVALID_CHARACTER_REGEXP.sub('-', substitutions[variable])
else:
return substitutions[variable]
for substitution_regexp in SUBSTITUTION_REGEXP_LIST:
value = substitution_regexp.sub(repl, value)
return value
def Interpolate(value, substitutions):
"""Interpolates variable references into |value| using |substitutions|.
Inputs:
value: a value, can be a dictionary, list, string or other
substitutions: a mapping of variable names to values
Returns:
A new value with all variables references ${VARIABLES} replaced by their
value in |substitutions|. Raises SubstitutionError if a variable has no
substitution.
"""
if isinstance(value, dict):
return {k: Interpolate(v, substitutions) for k, v in value.iteritems()}
if isinstance(value, list):
return [Interpolate(v, substitutions) for v in value]
if isinstance(value, str):
return InterpolateString(value, substitutions)
return value
def LoadPList(path):
"""Loads Plist at |path| and returns it as a dictionary."""
fd, name = tempfile.mkstemp()
try:
subprocess.check_call(['plutil', '-convert', 'xml1', '-o', name, path])
with os.fdopen(fd, 'r') as f:
return plistlib.readPlist(f)
finally:
os.unlink(name)
def SavePList(path, format, data):
"""Saves |data| as a Plist to |path| in the specified |format|."""
fd, name = tempfile.mkstemp()
try:
# "plutil" does not replace the destination file but update it in place,
# so if more than one hardlink points to destination all of them will be
# modified. This is not what is expected, so delete destination file if
# it does exist.
if os.path.exists(path):
os.unlink(path)
with os.fdopen(fd, 'w') as f:
plistlib.writePlist(data, f)
subprocess.check_call(['plutil', '-convert', format, '-o', path, name])
finally:
os.unlink(name)
def MergePList(plist1, plist2):
"""Merges |plist1| with |plist2| recursively.
Creates a new dictionary representing a Property List (.plist) files by
merging the two dictionary |plist1| and |plist2| recursively (only for
dictionary values). List value will be concatenated.
Args:
plist1: a dictionary representing a Property List (.plist) file
plist2: a dictionary representing a Property List (.plist) file
Returns:
A new dictionary representing a Property List (.plist) file by merging
|plist1| with |plist2|. If any value is a dictionary, they are merged
recursively, otherwise |plist2| value is used. If values are list, they
are concatenated.
"""
result = plist1.copy()
for key, value in plist2.iteritems():
if isinstance(value, dict):
old_value = result.get(key)
if isinstance(old_value, dict):
value = MergePList(old_value, value)
if isinstance(value, list):
value = plist1.get(key, []) + plist2.get(key, [])
result[key] = value
return result
class Action(object):
"""Class implementing one action supported by the script."""
@classmethod
def Register(cls, subparsers):
parser = subparsers.add_parser(cls.name, help=cls.help)
parser.set_defaults(func=cls._Execute)
cls._Register(parser)
class MergeAction(Action):
"""Class to merge multiple plist files."""
name = 'merge'
help = 'merge multiple plist files'
@staticmethod
def _Register(parser):
parser.add_argument(
'-o', '--output', required=True,
help='path to the output plist file')
parser.add_argument(
'-f', '--format', required=True, choices=('xml1', 'binary1', 'json'),
help='format of the plist file to generate')
parser.add_argument(
'path', nargs="+",
help='path to plist files to merge')
@staticmethod
def _Execute(args):
data = {}
for filename in args.path:
data = MergePList(data, LoadPList(filename))
SavePList(args.output, args.format, data)
class SubstituteAction(Action):
"""Class implementing the variable substitution in a plist file."""
name = 'substitute'
help = 'perform pattern substitution in a plist file'
@staticmethod
def _Register(parser):
parser.add_argument(
'-o', '--output', required=True,
help='path to the output plist file')
parser.add_argument(
'-t', '--template', required=True,
help='path to the template file')
parser.add_argument(
'-s', '--substitution', action='append', default=[],
help='substitution rule in the format key=value')
parser.add_argument(
'-f', '--format', required=True, choices=('xml1', 'binary1', 'json'),
help='format of the plist file to generate')
@staticmethod
def _Execute(args):
substitutions = {}
for substitution in args.substitution:
key, value = substitution.split('=', 1)
substitutions[key] = value
data = Interpolate(LoadPList(args.template), substitutions)
SavePList(args.output, args.format, data)
def Main():
parser = argparse.ArgumentParser(description='manipulate plist files')
subparsers = parser.add_subparsers()
for action in [MergeAction, SubstituteAction]:
action.Register(subparsers)
args = parser.parse_args()
args.func(args)
if __name__ == '__main__':
sys.exit(Main())

View File

@ -0,0 +1,662 @@
# 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("ios_sdk.gni")
# Constants corresponding to the bundle type identifier for XCTest and XCUITest
# targets.
_ios_xcode_xctest_bundle_id = "com.apple.product-type.bundle.unit-test"
_ios_xcode_xcuitest_bundle_id = "com.apple.product-type.bundle.ui-testing"
template("create_signed_bundle") {
assert(defined(invoker.output_name),
"output_name must be defined for $target_name")
assert(defined(invoker.product_type),
"product_type must be defined for $target_name")
assert(defined(invoker.bundle_extension),
"bundle_extension must be defined for $target_name")
assert(defined(invoker.bundle_binary_target) !=
defined(invoker.bundle_executable_path),
"Only one of bundle_binary_target or bundle_executable_path may be " +
"specified for $target_name")
if (defined(invoker.xcode_test_application_name)) {
assert(
invoker.product_type == _ios_xcode_xctest_bundle_id ||
invoker.product_type == _ios_xcode_xcuitest_bundle_id,
"xcode_test_application_name can be only defined for Xcode unit or " +
"ui test target.")
}
if (defined(invoker.bundle_executable_path)) {
_bundle_executable_path = invoker.bundle_executable_path
} else {
_bundle_binary_target = invoker.bundle_binary_target
_bundle_binary_output = get_label_info(_bundle_binary_target, "name")
if (defined(invoker.bundle_binary_output)) {
_bundle_binary_output = invoker.bundle_binary_output
}
_bundle_executable_path =
get_label_info(_bundle_binary_target, "target_out_dir") +
"/$_bundle_binary_output"
}
_output_name = invoker.output_name
_bundle_gen_dir = root_out_dir
_bundle_extension = invoker.bundle_extension
create_bundle(target_name) {
forward_variables_from(invoker,
[
"data_deps",
"deps",
"product_type",
"public_configs",
"public_deps",
"testonly",
"visibility",
"xcode_test_application_name",
])
bundle_root_dir = "$_bundle_gen_dir/$_output_name$_bundle_extension"
bundle_contents_dir = bundle_root_dir
bundle_resources_dir = bundle_contents_dir
bundle_executable_dir = bundle_contents_dir
code_signing_script =
"//third_party/mini_chromium/mini_chromium/build/ios/codesign.py"
code_signing_sources = [ _bundle_executable_path ]
code_signing_outputs = [ "$bundle_executable_dir/$_output_name" ]
if (ios_enable_code_signing) {
code_signing_outputs +=
[ "$bundle_contents_dir/_CodeSignature/CodeResources" ]
}
if (defined(invoker.extra_system_frameworks)) {
foreach(_framework, invoker.extra_system_frameworks) {
code_signing_outputs += [ "$bundle_contents_dir/Frameworks/" +
get_path_info(_framework, "file") ]
}
}
code_signing_args = [
"code-sign-bundle",
"-t=" + ios_sdk_name,
"-i=" + ios_code_signing_identity,
"-b=" + rebase_path(_bundle_executable_path, root_build_dir),
]
code_signing_args += [ rebase_path(bundle_root_dir, root_build_dir) ]
if (!ios_enable_code_signing) {
code_signing_args += [ "--disable-code-signature" ]
}
if (defined(invoker.extra_system_frameworks)) {
# All framework in extra_system_frameworks are expected to be
# system framework and the path to be already system absolute
# so do not use rebase_path here.
foreach(_framework, invoker.extra_system_frameworks) {
code_signing_args += [ "-F=" + _framework ]
}
}
_entitlements_path =
"//third_party/mini_chromium/mini_chromium/build/ios/entitlements.plist"
code_signing_args +=
[ "-e=" + rebase_path(_entitlements_path, root_build_dir) ]
# Bundle ID should respect rfc1034 and replace _ with -.
_xcode_product_bundle_id =
string_replace("$ios_app_bundle_id_prefix.googletest.$_output_name",
"_",
"-")
xcode_extra_attributes = {
IPHONEOS_DEPLOYMENT_TARGET = ios_deployment_target
CODE_SIGN_STYLE = "Manual"
CODE_SIGN_IDENTITY = ""
PRODUCT_BUNDLE_IDENTIFIER = _xcode_product_bundle_id
if (defined(invoker.xcode_extra_attributes)) {
forward_variables_from(invoker.xcode_extra_attributes, "*")
}
}
if (!defined(public_deps)) {
public_deps = []
}
if (defined(invoker.bundle_binary_target)) {
public_deps += [ invoker.bundle_binary_target ]
}
if (defined(invoker.bundle_deps)) {
if (!defined(deps)) {
deps = []
}
deps += invoker.bundle_deps
}
}
}
template("info_plist") {
assert(defined(invoker.plist_templates),
"A template plist file must be specified for $target_name")
assert(defined(invoker.executable_name),
"The executable_name must be specified for $target_name")
_plist_templates = invoker.plist_templates
_executable_name = invoker.executable_name
_target_name = target_name
_output_name = "$target_gen_dir/$_target_name.plist"
_format = "binary1"
_substitutions = [
"BUILD_MACHINE_OS_BUILD=$machine_os_build",
"EXECUTABLE_NAME=$_executable_name",
"GCC_VERSION=com.apple.compilers.llvm.clang.1_0",
"PRODUCT_NAME=$_executable_name",
"XCODE_BUILD=$xcode_build",
"XCODE_VERSION=$xcode_version",
"IOS_DEPLOYMENT_TARGET=$ios_deployment_target",
"IOS_BUNDLE_ID_PREFIX=$ios_app_bundle_id_prefix",
"IOS_PLATFORM_BUILD=$ios_platform_build",
"IOS_PLATFORM_NAME=$ios_sdk_name",
"IOS_PLATFORM_VERSION=$ios_sdk_version",
"IOS_SDK_BUILD=$ios_sdk_build",
"IOS_SDK_NAME=$ios_sdk_name$ios_sdk_version",
"IOS_SUPPORTED_PLATFORM=$ios_sdk_platform",
]
if (defined(invoker.extra_substitutions)) {
foreach(_substitution, invoker.extra_substitutions) {
_substitutions += [ _substitution ]
}
}
_merge_plist_target = _target_name + "_merge_plist"
_merged_plist_output_name = "$target_gen_dir/${_target_name}_merged.plist"
action(_merge_plist_target) {
forward_variables_from(invoker,
[
"testonly",
"deps",
])
script = "//third_party/mini_chromium/mini_chromium/build/ios/plist_util.py"
sources = _plist_templates
outputs = [ _merged_plist_output_name ]
args = [
"merge",
"-f=xml1",
"-o=" + rebase_path(_merged_plist_output_name, root_build_dir),
] + rebase_path(sources, root_build_dir)
}
action(target_name) {
forward_variables_from(invoker,
[
"testonly",
"visibility",
])
script = "//third_party/mini_chromium/mini_chromium/build/ios/plist_util.py"
sources = [ _merged_plist_output_name ]
outputs = [ _output_name ]
args = [
"substitute",
"-f=" + _format,
"-o=" + rebase_path(_output_name, root_build_dir),
"-t=" + rebase_path(_merged_plist_output_name, root_build_dir),
]
foreach(_substitution, _substitutions) {
args += [ "-s=$_substitution" ]
}
deps = [ ":$_merge_plist_target" ]
}
}
template("ios_app_bundle") {
_output_name = target_name
_target_name = target_name
_plist_templates = []
if (defined(invoker.info_plist)) {
_plist_templates += [ invoker.info_plist ]
}
_plist_extra_substitutions = []
if (defined(invoker.extra_substitutions)) {
_plist_extra_substitutions += invoker.extra_substitutions
}
_executable_sources_target = _target_name + "_executable_sources"
_generate_executable_target = _target_name + "_generate_executable"
source_set(_executable_sources_target) {
forward_variables_from(invoker,
"*",
[
"bundle_deps",
"extra_system_frameworks",
"visibility",
"plist_templates",
"plist_extra_substitutions",
])
visibility = [ ":$_generate_executable_target" ]
}
executable(_generate_executable_target) {
visibility = [ ":$_target_name" ]
forward_variables_from(invoker,
"*",
[
"bundle_deps",
"extra_system_frameworks",
"sources",
"visibility",
"plist_templates",
"plist_extra_substitutions",
])
if (!defined(deps)) {
deps = []
}
deps += [ ":$_executable_sources_target" ]
if (!defined(frameworks)) {
frameworks = []
}
frameworks += [ "UIKit.framework" ]
if (!defined(ldflags)) {
ldflags = []
}
ldflags += [
"-Wl,-rpath,@executable_path/Frameworks",
"-Wl,-objc_abi_version,2",
]
output_name = _output_name
output_prefix_override = true
output_dir = "$target_out_dir"
}
_generate_info_plist_target = target_name + "_generate_info_plist"
_bundle_info_plist_target = target_name + "_bundle_info_plist"
info_plist(_generate_info_plist_target) {
visibility = [ ":$_bundle_info_plist_target" ]
forward_variables_from(invoker, [ "testonly" ])
executable_name = _output_name
plist_templates = [
"//third_party/mini_chromium/mini_chromium/build/ios/BuildInfo.plist",
"//third_party/mini_chromium/mini_chromium/build/ios/Application-Info.plist",
]
plist_templates += _plist_templates
extra_substitutions = _plist_extra_substitutions
}
bundle_data(_bundle_info_plist_target) {
visibility = [ ":$_target_name" ]
forward_variables_from(invoker, [ "testonly" ])
sources = get_target_outputs(":$_generate_info_plist_target")
outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
public_deps = [ ":$_generate_info_plist_target" ]
}
_bundle_executable_path = get_label_info(":$_generate_executable_target",
"target_out_dir") + "/$_output_name"
create_signed_bundle(_target_name) {
forward_variables_from(invoker,
[
"bundle_deps",
"data_deps",
"deps",
"extra_system_frameworks",
"public_configs",
"public_deps",
"testonly",
"visibility",
])
output_name = _output_name
product_type = "com.apple.product-type.application"
bundle_extension = ".app"
bundle_executable_path = _bundle_executable_path
if (!defined(deps)) {
deps = []
}
deps += [
":$_bundle_info_plist_target",
":$_generate_executable_target",
]
}
}
template("ios_xctest_bundle") {
assert(defined(invoker.deps), "deps must be defined for $target_name")
assert(defined(invoker.product_type),
"product_type must be defined for $target_name")
assert(invoker.product_type == _ios_xcode_xctest_bundle_id ||
invoker.product_type == _ios_xcode_xcuitest_bundle_id,
"product_type defined for $target_name is invalid.")
assert(defined(invoker.host_target),
"host_target must be defined for $target_name")
assert(defined(invoker.xcode_test_application_name),
"xcode_test_application_name must be defined for $target_name")
assert(invoker.xcode_test_application_name != target_name)
_target_name = target_name
_output_name = target_name
if (defined(invoker.output_name)) {
_output_name = invoker.output_name
}
_loadable_module_source = _target_name + "_loadable_module_source"
_loadable_module_target = _target_name + "_loadable_module"
source_set(_loadable_module_source) {
forward_variables_from(invoker, [ "deps" ])
testonly = true
visibility = [ ":$_loadable_module_target" ]
}
loadable_module(_loadable_module_target) {
testonly = true
visibility = [ ":$_target_name" ]
deps = [ ":$_loadable_module_source" ]
configs +=
[ "//third_party/mini_chromium/mini_chromium/build/ios:xctest_config" ]
output_dir = "$target_out_dir"
output_name = _output_name
output_prefix_override = true
output_extension = ""
}
_info_plist_target = _target_name + "_info_plist"
_info_plist_bundle = _target_name + "_info_plist_bundle"
info_plist(_info_plist_target) {
testonly = true
visibility = [ ":$_info_plist_bundle" ]
plist_templates = [
"//third_party/mini_chromium/mini_chromium/build/ios/Module-Info.plist",
]
executable_name = _output_name
if (defined(invoker.xctest_bundle_principal_class)) {
_principal_class = invoker.xctest_bundle_principal_class
} else {
# Fall back to a reasonable default value.
_principal_class = "NSObject"
}
extra_substitutions = [
"XCTEST_BUNDLE_PRINCIPAL_CLASS=${_principal_class}",
"MODULE_BUNDLE_ID=googletest.$_output_name",
]
}
bundle_data(_info_plist_bundle) {
testonly = true
visibility = [ ":$_target_name" ]
public_deps = [ ":$_info_plist_target" ]
sources = get_target_outputs(":$_info_plist_target")
outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
}
_xctest_bundle = _target_name + "_bundle"
create_signed_bundle(_target_name) {
forward_variables_from(invoker,
[
"enable_code_signing",
"product_type",
"xcode_test_application_name",
])
testonly = true
visibility = [ ":$_xctest_bundle" ]
bundle_extension = ".xctest"
output_name = _output_name
bundle_executable_path = get_label_info(":$_loadable_module_target",
"target_out_dir") + "/$_output_name"
# Test files need to be known to Xcode for proper indexing and discovery
# of tests function for XCTest, but the compilation is done via ninja and
# thus must prevent Xcode from linking object files via this hack.
xcode_extra_attributes = {
OTHER_LDFLAGS = "-help"
ONLY_ACTIVE_ARCH = "YES"
DEBUG_INFORMATION_FORMAT = "dwarf"
# For XCUITest, Xcode requires specifying the host application name via
# the TEST_TARGET_NAME attribute.
if (invoker.product_type == _ios_xcode_xcuitest_bundle_id) {
TEST_TARGET_NAME = invoker.xcode_test_application_name
}
# For XCTest, Xcode requires specifying the host application path via
# both BUNDLE_LOADER and TEST_HOST attributes.
if (invoker.product_type == _ios_xcode_xctest_bundle_id) {
BUNDLE_LOADER = "\$(TEST_HOST)"
TEST_HOST =
"\$(BUILT_PRODUCTS_DIR)/${invoker.xcode_test_application_name}" +
".app/${invoker.xcode_test_application_name}"
}
}
deps = [ ":$_info_plist_bundle" ]
public_deps = [ ":$_loadable_module_target" ]
}
bundle_data(_xctest_bundle) {
forward_variables_from(invoker, [ "host_target" ])
testonly = true
visibility = [ ":$host_target" ]
public_deps = [ ":$_target_name" ]
sources = [ "$root_out_dir/$_output_name.xctest" ]
outputs = [ "{{bundle_contents_dir}}/PlugIns/$_output_name.xctest" ]
}
}
template("ios_xctest_test") {
# Invokers must specify their own target for the xctest module.
assert(defined(invoker.xctest_module_target),
"xctest_module_target is required.")
_target_name = target_name
_output_name = target_name
_xctest_target = _target_name + "_module"
_xctest_output = _output_name + "_module"
_host_target = _target_name
_host_output = _output_name
_xctest_module_target = invoker.xctest_module_target
ios_xctest_bundle(_xctest_target) {
output_name = _xctest_output
product_type = _ios_xcode_xctest_bundle_id
host_target = _host_target
xcode_test_application_name = _host_output
deps = [ _xctest_module_target ]
}
ios_app_bundle(_host_target) {
forward_variables_from(invoker, "*", [ "testonly" ])
testonly = true
# Xcode needs the following frameworks installed in the application (and
# signed) for the XCTest to run, so install them using
# extra_system_frameworks.
_ios_platform_library = "$ios_sdk_platform_path/Developer/Library"
extra_system_frameworks = [
"$_ios_platform_library/Frameworks/XCTest.framework",
"$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework",
"$ios_sdk_platform_path/Developer/usr/lib/libXCTestBundleInject.dylib",
]
_xctest_bundle = _xctest_target + "_bundle"
if (!defined(bundle_deps)) {
bundle_deps = []
}
bundle_deps += [ ":$_xctest_bundle" ]
if (!defined(ldflags)) {
ldflags = []
}
ldflags += [
"-Wl,-rpath,@executable_path/Frameworks",
"-Wl,-rpath,@loader_path/Frameworks",
]
}
}
template("ios_xcuitest_test_runner_bundle") {
assert(defined(invoker.xctest_bundle),
"xctest_bundle must be defined for $target_name")
_target_name = target_name
_output_name = target_name
if (defined(invoker.output_name)) {
_output_name = invoker.output_name
}
_xctrunner_path =
"$ios_sdk_platform_path/Developer/Library/Xcode/Agents/XCTRunner.app"
# When creating the test runner for an XCUITest, the arm64e slice of the binary
# must be removed (at least until the app ships with arm64e slice which is not
# yet supported by Apple).
action("xctest_runner_without_arm64e") {
testonly = true
script =
"//third_party/mini_chromium/mini_chromium/build/ios/strip_arm64e.py"
sources = [ "$_xctrunner_path/XCTRunner" ]
outputs = [ "$target_out_dir/XCTRunner" ]
args = [
"--output",
rebase_path(outputs[0], root_build_dir),
"--input",
rebase_path(sources[0], root_build_dir),
]
}
_info_plist_target = _target_name + "_info_plist"
_info_plist_bundle = _target_name + "_info_plist_bundle"
info_plist(_info_plist_target) {
testonly = true
visibility = [ ":$_info_plist_bundle" ]
executable_name = _output_name
plist_templates = [
"$_xctrunner_path/Info.plist",
# NOTE: The XCTRunnerAddition+Info.plist must come after the Info.plist
# because it overrides the values under "CFBundleIdentifier" and
# "CFBundleName".
"//third_party/mini_chromium/mini_chromium/build/ios/XCTRunnerAddition+Info.plist",
]
}
bundle_data(_info_plist_bundle) {
testonly = true
visibility = [ ":$_target_name" ]
public_deps = [ ":$_info_plist_target" ]
sources = get_target_outputs(":$_info_plist_target")
outputs = [ "{{bundle_contents_dir}}/Info.plist" ]
}
_pkginfo_bundle = _target_name + "_pkginfo_bundle"
bundle_data(_pkginfo_bundle) {
testonly = true
visibility = [ ":$_target_name" ]
sources = [ "$_xctrunner_path/PkgInfo" ]
outputs = [ "{{bundle_contents_dir}}/PkgInfo" ]
}
_xctest_bundle = invoker.xctest_bundle
create_signed_bundle(_target_name) {
testonly = true
bundle_binary_target = ":xctest_runner_without_arm64e"
bundle_binary_output = "XCTRunner"
bundle_extension = ".app"
product_type = "com.apple.product-type.application"
output_name = _output_name
# Xcode needs the following frameworks installed in the application
# (and signed) for the XCUITest to run, so install them using
# extra_system_frameworks.
extra_system_frameworks = [
"$ios_sdk_platform_path/Developer/Library/Frameworks/XCTest.framework",
"$ios_sdk_platform_path/Developer/Library/PrivateFrameworks/XCTAutomationSupport.framework",
]
bundle_deps = []
if (defined(invoker.bundle_deps)) {
bundle_deps += invoker.bundle_deps
}
bundle_deps += [
":$_info_plist_bundle",
":$_pkginfo_bundle",
":$_xctest_bundle",
]
}
}
template("ios_xcuitest_test") {
assert(defined(invoker.deps), "deps must be defined for $target_name")
assert(defined(invoker.xcode_test_application_name),
"xcode_test_application_name must be defined for $target_name")
_xcuitest_target = target_name
_xcuitest_runner_target = _xcuitest_target + "_runner"
_xcuitest_module_target = _xcuitest_target + "_module"
group(_xcuitest_target) {
testonly = true
deps = [ ":$_xcuitest_runner_target" ]
}
_xcuitest_module_output = _xcuitest_target
ios_xctest_bundle(_xcuitest_module_target) {
forward_variables_from(invoker,
[
"xcode_test_application_name",
"xctest_bundle_principal_class",
])
product_type = _ios_xcode_xcuitest_bundle_id
host_target = _xcuitest_runner_target
output_name = _xcuitest_module_output
deps = invoker.deps
}
_xcuitest_runner_output = _xcuitest_target + "-Runner"
ios_xcuitest_test_runner_bundle(_xcuitest_runner_target) {
output_name = _xcuitest_runner_output
xctest_bundle = _xcuitest_module_target + "_bundle"
forward_variables_from(invoker, [ "bundle_deps" ])
}
}
template("ios_test_runner_xcuitest") {
ios_xcuitest_test(target_name) {
forward_variables_from(invoker, "*", ["data_deps"])
}
}

View File

@ -0,0 +1,116 @@
#!/usr/bin/env python
# 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.
from __future__ import print_function
import argparse
import doctest
import itertools
import os
import plistlib
import subprocess
import sys
# This script prints information about the build system, the operating
# system and the iOS or Mac SDK (depending on the platform "iphonesimulator",
# "iphoneos" or "macosx" generally).
def SplitVersion(version):
"""Splits the Xcode version to 3 values.
>>> list(SplitVersion('8.2.1.1'))
['8', '2', '1']
>>> list(SplitVersion('9.3'))
['9', '3', '0']
>>> list(SplitVersion('10.0'))
['10', '0', '0']
"""
version = version.split('.')
return itertools.islice(itertools.chain(version, itertools.repeat('0')), 0, 3)
def FormatVersion(version):
"""Converts Xcode version to a format required for DTXcode in Info.plist
>>> FormatVersion('8.2.1')
'0821'
>>> FormatVersion('9.3')
'0930'
>>> FormatVersion('10.0')
'1000'
"""
major, minor, patch = SplitVersion(version)
return ('%2s%s%s' % (major, minor, patch)).replace(' ', '0')
def FillXcodeVersion(settings, developer_dir):
"""Fills the Xcode version and build number into |settings|."""
if developer_dir:
xcode_version_plist_path = os.path.join(
developer_dir, 'Contents/version.plist')
version_plist = plistlib.readPlist(xcode_version_plist_path)
settings['xcode_version'] = FormatVersion(
version_plist['CFBundleShortVersionString'])
settings['xcode_version_int'] = int(settings['xcode_version'], 10)
settings['xcode_build'] = version_plist['ProductBuildVersion']
return
lines = subprocess.check_output(['xcodebuild', '-version']).splitlines()
settings['xcode_version'] = FormatVersion(lines[0].split()[-1])
settings['xcode_version_int'] = int(settings['xcode_version'], 10)
settings['xcode_build'] = lines[-1].split()[-1]
def FillMachineOSBuild(settings):
"""Fills OS build number into |settings|."""
settings['machine_os_build'] = subprocess.check_output(
['sw_vers', '-buildVersion']).strip()
def FillSDKPathAndVersion(settings, platform, xcode_version):
"""Fills the SDK path and version for |platform| into |settings|."""
settings['sdk_path'] = subprocess.check_output([
'xcrun', '-sdk', platform, '--show-sdk-path']).strip()
settings['sdk_version'] = subprocess.check_output([
'xcrun', '-sdk', platform, '--show-sdk-version']).strip()
settings['sdk_platform_path'] = subprocess.check_output([
'xcrun', '-sdk', platform, '--show-sdk-platform-path']).strip()
# TODO: unconditionally use --show-sdk-build-version once Xcode 7.2 or
# higher is required to build Chrome for iOS or OS X.
if xcode_version >= '0720':
settings['sdk_build'] = subprocess.check_output([
'xcrun', '-sdk', platform, '--show-sdk-build-version']).strip()
else:
settings['sdk_build'] = settings['sdk_version']
if __name__ == '__main__':
doctest.testmod()
parser = argparse.ArgumentParser()
parser.add_argument("--developer_dir", required=False)
parser.add_argument("--get_sdk_info",
action="store_true", dest="get_sdk_info", default=False,
help="Returns SDK info in addition to xcode/machine info.")
args, unknownargs = parser.parse_known_args()
if args.developer_dir:
os.environ['DEVELOPER_DIR'] = args.developer_dir
if len(unknownargs) != 1:
sys.stderr.write(
'usage: %s [iphoneos|iphonesimulator|macosx]\n' %
os.path.basename(sys.argv[0]))
sys.exit(1)
settings = {}
FillMachineOSBuild(settings)
FillXcodeVersion(settings, args.developer_dir)
if args.get_sdk_info:
FillSDKPathAndVersion(settings, unknownargs[0], settings['xcode_version'])
for key in sorted(settings):
value = settings[key]
if isinstance(value, str):
value = '"%s"' % value
print('%s=%s' % (key, value))

View File

@ -0,0 +1,72 @@
#!/usr/bin/env python
# Copyright 2020 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.
"""Strip arm64e architecture from a binary if present."""
import argparse
import os
import shutil
import subprocess
import sys
def check_output(command):
"""Returns the output from |command| or propagates error, quitting script."""
process = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
outs, errs = process.communicate()
if process.returncode:
sys.stderr.write('error: command failed with retcode %d: %s\n\n' %
(process.returncode, ' '.join(map(repr, command))))
sys.stderr.write(errs)
sys.exit(process.returncode)
return outs
def check_call(command):
"""Invokes |command| or propagates error."""
check_output(command)
def parse_args(args):
"""Parses the command-line."""
parser = argparse.ArgumentParser()
parser.add_argument('--input', required=True, help='Path to input binary')
parser.add_argument('--output', required=True, help='Path to output binary')
return parser.parse_args(args)
def get_archs(path):
"""Extracts the architectures present in binary at |path|."""
outputs = check_output(["xcrun", "lipo", "-info", os.path.abspath(path)])
return outputs.split(': ')[-1].split()
def main(args):
parsed = parse_args(args)
outdir = os.path.dirname(parsed.output)
if not os.path.isdir(outdir):
os.makedirs(outdir)
if os.path.exists(parsed.output):
os.unlink(parsed.output)
# As "lipo" fails with an error if asked to remove an architecture that is
# not included, only use it if "arm64e" is present in the binary. Otherwise
# simply copy the file.
if 'arm64e' in get_archs(parsed.input):
check_output([
"xcrun", "lipo", "-remove", "arm64e", "-output",
os.path.abspath(parsed.output),
os.path.abspath(parsed.input)
])
else:
shutil.copy(parsed.input, parsed.output)
if __name__ == '__main__':
main(sys.argv[1:])

View File

@ -0,0 +1,38 @@
# Copyright 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.
mini_chromium_is_mac = false
mini_chromium_is_ios = false
mini_chromium_is_win = false
mini_chromium_is_linux = false
mini_chromium_is_android = false
mini_chromium_is_fuchsia = false
if (current_os == "mac") {
mini_chromium_is_mac = true
} else if (current_os == "ios") {
mini_chromium_is_ios = true
} else if (current_os == "win") {
mini_chromium_is_win = true
} else if (current_os == "android") {
mini_chromium_is_android = true
} else if (current_os == "linux") {
mini_chromium_is_linux = true
} else if (current_os == "fuchsia") {
mini_chromium_is_fuchsia = true
}
mini_chromium_is_posix = mini_chromium_is_mac || mini_chromium_is_ios ||
mini_chromium_is_linux || mini_chromium_is_android
declare_args() {
mini_chromium_is_chromeos_lacros = false
mini_chromium_is_chromeos_ash = false
}
assert(!mini_chromium_is_chromeos_lacros || !mini_chromium_is_chromeos_ash)
assert(!(mini_chromium_is_chromeos_lacros || mini_chromium_is_chromeos_ash) ||
mini_chromium_is_linux)

View File

@ -0,0 +1,70 @@
# 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("platform.gni")
if (mini_chromium_is_posix || mini_chromium_is_fuchsia) {
declare_args() {
# A directory containing the systems header files and libraries. If empty,
# a suitable default will be chosen.
target_sysroot = ""
}
}
if (mini_chromium_is_mac) {
declare_args() {
# The version of the macOS SDK to use. If |target_sysroot| is empty, this
# will inform which SDK version will be chosen. If |mac_sdk| is also empty,
# a suitable default will be chosen. See also |mac_sdk_min|.
mac_sdk = ""
# The minimum version of the macOS system SDK to use. SDK versions older
# than this will be rejected. If |target_sysroot| and |mac_sdk| are both
# empty, the oldest SDK thats at least this version will be chosen. If
# empty, the systems default SDK will be chosen.
mac_sdk_min = ""
}
find_mac_sdk_args = []
if (mac_sdk != "") {
find_mac_sdk_args += [
"--exact",
mac_sdk,
]
}
if (mac_sdk_min != "") {
find_mac_sdk_args += [
"--minimum",
mac_sdk_min,
]
}
if (target_sysroot != "") {
find_mac_sdk_args += [
"--path",
target_sysroot,
]
}
find_mac_sdk_output =
exec_script("find_mac_sdk.py", find_mac_sdk_args, "list lines")
mac_sdk = find_mac_sdk_output[0]
target_sysroot = find_mac_sdk_output[1]
} else if (mini_chromium_is_ios) {
import("ios/ios_sdk.gni")
target_sysroot = ios_sdk_path
} else if (mini_chromium_is_fuchsia) {
# Declares fuchsia_sdk.
import("//third_party/fuchsia/sdk/$host_os-amd64/build/config/config.gni")
if (target_sysroot == "") {
target_sysroot = fuchsia_sdk + "/arch/$target_cpu/sysroot"
}
}
if ((mini_chromium_is_posix || mini_chromium_is_fuchsia) &&
(current_os == target_os && current_cpu == target_cpu)) {
sysroot = target_sysroot
} else {
sysroot = ""
}

View File

@ -0,0 +1,220 @@
#!/usr/bin/env python
# Copyright 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.
import _winreg
import os
import re
import subprocess
import sys
def _RegistryGetValue(key, value):
"""Use the _winreg module to obtain the value of a registry key.
Args:
key: The registry key.
value: The particular registry value to read.
Return:
contents of the registry key's value, or None on failure.
"""
try:
root, subkey = key.split('\\', 1)
assert root == 'HKLM' # Only need HKLM for now.
with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
return _winreg.QueryValueEx(hkey, value)[0]
except WindowsError:
return None
def _ExtractImportantEnvironment(output_of_set):
"""Extracts environment variables required for the toolchain to run from
a textual dump output by the cmd.exe 'set' command."""
envvars_to_save = (
'include',
'lib',
'libpath',
'path',
'pathext',
'systemroot',
'temp',
'tmp',
)
env = {}
for line in output_of_set.splitlines():
for envvar in envvars_to_save:
if re.match(envvar + '=', line.lower()):
var, setting = line.split('=', 1)
env[var.upper()] = setting
break
for required in ('SYSTEMROOT', 'TEMP', 'TMP'):
if required not in env:
raise Exception('Environment variable "%s" '
'required to be set to valid path' % required)
return env
def _FormatAsEnvironmentBlock(envvar_dict):
"""Format as an 'environment block' directly suitable for CreateProcess.
Briefly this is a list of key=value\0, terminated by an additional \0. See
CreateProcess() documentation for more details."""
block = ''
nul = '\0'
for key, value in envvar_dict.iteritems():
block += key + '=' + value + nul
block += nul
return block
def _GenerateEnvironmentFiles(install_dir, out_dir, script_path):
"""It's not sufficient to have the absolute path to the compiler, linker, etc.
on Windows, as those tools rely on .dlls being in the PATH. We also need to
support both x86 and x64 compilers. Different architectures require a
different compiler binary, and different supporting environment variables
(INCLUDE, LIB, LIBPATH). So, we extract the environment here, wrap all
invocations of compiler tools (cl, link, lib, rc, midl, etc.) to set up the
environment, and then do not prefix the compiler with an absolute path,
instead preferring something like "cl.exe" in the rule which will then run
whichever the environment setup has put in the path."""
archs = ('x86', 'amd64', 'arm64')
result = []
for arch in archs:
# Extract environment variables for subprocesses.
args = [os.path.join(install_dir, script_path)]
script_arch_name = arch
if script_path.endswith('SetEnv.cmd') and arch == 'amd64':
script_arch_name = '/x64'
if arch == 'arm64':
script_arch_name = 'x86_arm64'
args.extend((script_arch_name, '&&', 'set'))
popen = subprocess.Popen(
args, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
variables, _ = popen.communicate()
if popen.returncode != 0:
raise Exception('"%s" failed with error %d' % (args, popen.returncode))
env = _ExtractImportantEnvironment(variables)
env_block = _FormatAsEnvironmentBlock(env)
basename = 'environment.' + arch
with open(os.path.join(out_dir, basename), 'wb') as f:
f.write(env_block)
result.append(basename)
return result
def _GetEnvAsDict(arch):
"""Gets the saved environment from a file for a given architecture."""
# The environment is saved as an "environment block" (see CreateProcess()
# for details, which is the format required for ninja). We convert to a dict
# here. Drop last 2 NULs, one for list terminator, one for trailing vs.
# separator.
pairs = open(arch).read()[:-2].split('\0')
kvs = [item.split('=', 1) for item in pairs]
return dict(kvs)
class WinTool(object):
def Dispatch(self, args):
"""Dispatches a string command to a method."""
if len(args) < 1:
raise Exception("Not enough arguments")
method = "Exec%s" % self._CommandifyName(args[0])
return getattr(self, method)(*args[1:])
def _CommandifyName(self, name_string):
"""Transforms a tool name like recursive-mirror to RecursiveMirror."""
return name_string.title().replace('-', '')
def ExecLinkWrapper(self, arch, *args):
"""Filter diagnostic output from link that looks like:
' Creating library ui.dll.lib and object ui.dll.exp'
This happens when there are exports from the dll or exe.
"""
env = _GetEnvAsDict(arch)
args = list(args) # *args is a tuple by default, which is read-only.
args[0] = args[0].replace('/', '\\')
link = subprocess.Popen(args, env=env, shell=True, stdout=subprocess.PIPE)
out, _ = link.communicate()
for line in out.splitlines():
if (not line.startswith(' Creating library ') and
not line.startswith('Generating code') and
not line.startswith('Finished generating code')):
print line
return link.returncode
def ExecAsmWrapper(self, arch, *args):
"""Filter logo banner from invocations of asm.exe."""
env = _GetEnvAsDict(arch)
popen = subprocess.Popen(args, env=env, shell=True,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = popen.communicate()
for line in out.splitlines():
if (not line.startswith('Copyright (C) Microsoft Corporation') and
not line.startswith('Microsoft (R) Macro Assembler') and
not line.startswith(' Assembling: ') and
line):
print line
return popen.returncode
def ExecGetVisualStudioData(self, outdir, toolchain_path):
setenv_path = os.path.join('win_sdk', 'bin', 'SetEnv.cmd')
def explicit():
if os.path.exists(os.path.join(toolchain_path, setenv_path)):
return toolchain_path, setenv_path
def env():
from_env = os.environ.get('VSINSTALLDIR')
if from_env and os.path.exists(os.path.join(from_env, setenv_path)):
return from_env, setenv_path
def autodetect():
# Try vswhere, which will find VS2017.2+. Note that earlier VS2017s will
# not be found.
vswhere_path = os.path.join(os.environ.get('ProgramFiles(x86)'),
'Microsoft Visual Studio', 'Installer', 'vswhere.exe')
if os.path.exists(vswhere_path):
installation_path = subprocess.check_output(
[vswhere_path, '-latest', '-property', 'installationPath']).strip()
if installation_path:
return (installation_path,
os.path.join('VC', 'Auxiliary', 'Build', 'vcvarsall.bat'))
# Otherwise, try VS2015.
version = '14.0'
keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version,
r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version]
for key in keys:
path = _RegistryGetValue(key, 'InstallDir')
if not path:
continue
return (os.path.normpath(os.path.join(path, os.pardir, os.pardir)),
os.path.join('VC', 'vcvarsall.bat'))
def fail(): raise Exception('Visual Studio installation dir not found')
# Use an explicitly specified toolchain path, if provided and found.
# Otherwise, try using a standard environment variable. Finally, try
# autodetecting using vswhere.
install_dir, script_path = (explicit() or env() or autodetect() or fail())
x86_file, x64_file, arm64_file = _GenerateEnvironmentFiles(
install_dir, outdir, script_path)
result = '''install_dir = "%s"
x86_environment_file = "%s"
x64_environment_file = "%s"
arm64_environment_file = "%s"''' % (install_dir, x86_file, x64_file, arm64_file)
print result
return 0
def ExecStamp(self, path):
"""Simple stamp command."""
open(path, 'w').close()
return 0
if __name__ == '__main__':
sys.exit(WinTool().Dispatch(sys.argv[1:]))

View File

@ -0,0 +1,98 @@
#!/usr/bin/env python
# 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 writes headers for build flags. See buildflag_header.gni for usage of
# this system as a whole.
#
# The parameters are passed in a response file so we don't have to worry
# about command line lengths. The name of the response file is passed on the
# command line.
#
# The format of the response file is:
# [--flags <list of one or more flag values>]
import optparse
import os
import shlex
import sys
class Options:
def __init__(self, output, rulename, header_guard, flags):
self.output = output
self.rulename = rulename
self.header_guard = header_guard
self.flags = flags
def GetOptions():
parser = optparse.OptionParser()
parser.add_option('--output', help="Output header name inside --gen-dir.")
parser.add_option('--rulename',
help="Helpful name of build rule for including in the " +
"comment at the top of the file.")
parser.add_option('--gen-dir',
help="Path to root of generated file directory tree.")
parser.add_option('--definitions',
help="Name of the response file containing the flags.")
cmdline_options, cmdline_flags = parser.parse_args()
# Compute header guard by replacing some chars with _ and upper-casing.
header_guard = cmdline_options.output.upper()
header_guard = \
header_guard.replace('/', '_').replace('\\', '_').replace('.', '_')
header_guard += '_'
# The actual output file is inside the gen dir.
output = os.path.join(cmdline_options.gen_dir, cmdline_options.output)
# Definition file in GYP is newline separated, in GN they are shell formatted.
# shlex can parse both of these.
with open(cmdline_options.definitions, 'r') as def_file:
defs = shlex.split(def_file.read())
flags_index = defs.index('--flags')
# Everything after --flags are flags. true/false are remapped to 1/0,
# everything else is passed through.
flags = []
for flag in defs[flags_index + 1 :]:
equals_index = flag.index('=')
key = flag[:equals_index]
value = flag[equals_index + 1:]
# Canonicalize and validate the value.
if value == 'true':
value = '1'
elif value == 'false':
value = '0'
flags.append((key, str(value)))
return Options(output=output,
rulename=cmdline_options.rulename,
header_guard=header_guard,
flags=flags)
def WriteHeader(options):
with open(options.output, 'w') as output_file:
output_file.write("// Generated by build/write_buildflag_header.py\n")
if options.rulename:
output_file.write('// From "' + options.rulename + '"\n')
output_file.write('\n#ifndef %s\n' % options.header_guard)
output_file.write('#define %s\n\n' % options.header_guard)
output_file.write('#include "build/buildflag.h"\n\n')
for pair in options.flags:
output_file.write('#define BUILDFLAG_INTERNAL_%s() (%s)\n' % pair)
output_file.write('\n#endif // %s\n' % options.header_guard)
def main():
options = GetOptions()
WriteHeader(options)
if __name__ == "__main__":
sys.exit(main())

View File

@ -0,0 +1,17 @@
# Copyright 2019 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
source_set("xnu") {
sources = [ "EXTERNAL_HEADERS/mach-o/loader.h" ]
}

View File

@ -0,0 +1,145 @@
# Copyright 2017 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../../build/crashpad_buildconfig.gni")
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia || crashpad_is_in_dart) {
zlib_source = "external"
} else if (!crashpad_is_win && !crashpad_is_fuchsia) {
zlib_source = "system"
} else if (crashpad_is_standalone) {
zlib_source = "embedded"
} else if (crashpad_is_external) {
zlib_source = "external_with_embedded_build"
}
config("zlib_config") {
if (zlib_source == "external") {
defines = [ "CRASHPAD_ZLIB_SOURCE_EXTERNAL" ]
} else if (zlib_source == "system") {
defines = [ "CRASHPAD_ZLIB_SOURCE_SYSTEM" ]
} else if (zlib_source == "embedded") {
defines = [ "CRASHPAD_ZLIB_SOURCE_EMBEDDED" ]
include_dirs = [ "zlib" ]
} else if (zlib_source == "external_with_embedded_build") {
defines = [ "CRASHPAD_ZLIB_SOURCE_EXTERNAL_WITH_EMBEDDED_BUILD" ]
include_dirs = [ "../../../../zlib/src" ]
}
}
if (zlib_source == "external") {
group("zlib") {
public_configs = [ ":zlib_config" ]
public_deps = [ "//third_party/zlib" ]
}
} else if (zlib_source == "system") {
source_set("zlib") {
public_configs = [ ":zlib_config" ]
libs = [ "z" ]
}
} else if (zlib_source == "embedded" ||
zlib_source == "external_with_embedded_build") {
static_library("zlib") {
if (zlib_source == "embedded") {
zlib_dir = "zlib"
} else if (zlib_source == "external_with_embedded_build") {
zlib_dir = "../../../../zlib/src"
}
sources = [
"$zlib_dir/adler32.c",
"$zlib_dir/compress.c",
"$zlib_dir/crc32.c",
"$zlib_dir/crc32.h",
"$zlib_dir/deflate.c",
"$zlib_dir/deflate.h",
"$zlib_dir/gzclose.c",
"$zlib_dir/gzguts.h",
"$zlib_dir/gzlib.c",
"$zlib_dir/gzread.c",
"$zlib_dir/gzwrite.c",
"$zlib_dir/infback.c",
"$zlib_dir/inffast.c",
"$zlib_dir/inffast.h",
"$zlib_dir/inffixed.h",
"$zlib_dir/inflate.c",
"$zlib_dir/inflate.h",
"$zlib_dir/inftrees.c",
"$zlib_dir/inftrees.h",
"$zlib_dir/trees.c",
"$zlib_dir/trees.h",
"$zlib_dir/uncompr.c",
"$zlib_dir/zconf.h",
"$zlib_dir/zlib.h",
"$zlib_dir/zutil.c",
"$zlib_dir/zutil.h",
"zlib_crashpad.h",
]
cflags = []
defines = [ "HAVE_STDARG_H" ]
public_configs = [ ":zlib_config" ]
if (crashpad_is_win) {
cflags += [
"/wd4131", # uses old-style declarator
"/wd4244", # conversion from 't1' to 't2', possible loss of data
"/wd4245", # conversion from 't1' to 't2', signed/unsigned mismatch
"/wd4267", # conversion from 'size_t' to 't', possible loss of data
"/wd4324", # structure was padded due to alignment specifier
"/wd4702", # unreachable code
]
if (current_cpu == "arm64" && !crashpad_is_clang) {
# Select code path for clang in zlib to avoid using MSVC x86/x64
# intrinsics for Windows ARM64.
# TODO: https://crashpad.chromium.org/bug/267
defines += [ "__clang__" ]
}
} else {
defines += [
"HAVE_HIDDEN",
"HAVE_UNISTD_H",
]
}
if (crashpad_is_standalone) {
configs -= [ "//third_party/mini_chromium/mini_chromium/build/config:Wimplicit_fallthrough" ]
} else if (crashpad_is_external) {
configs -= [ "//../../mini_chromium/mini_chromium/build/config:Wimplicit_fallthrough" ]
}
if (zlib_source == "embedded") {
sources += [ "$zlib_dir/names.h" ]
if (current_cpu == "x86" || current_cpu == "x64") {
sources += [
"$zlib_dir/crc_folding.c",
"$zlib_dir/fill_window_sse.c",
"$zlib_dir/x86.c",
"$zlib_dir/x86.h",
]
if (!crashpad_is_win || crashpad_is_clang) {
cflags += [
"-msse4.2",
"-mpclmul",
]
}
if (crashpad_is_clang) {
cflags += [ "-Wno-incompatible-pointer-types" ]
}
} else {
sources += [ "$zlib_dir/simd_stub.c" ]
}
}
}
}

View File

@ -0,0 +1,161 @@
# 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.
config("zlib_config") {
include_dirs = [ "." ]
}
static_library("zlib_x86_simd") {
if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
sources = [
"crc_folding.c",
"fill_window_sse.c",
]
if (!is_win || is_clang) {
cflags = [
"-msse4.2",
"-mpclmul",
]
}
} else {
sources = [
"simd_stub.c",
]
}
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
}
config("zlib_warnings") {
if (is_clang && !is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
cflags = [ "-Wno-incompatible-pointer-types" ]
}
}
static_library("zlib") {
if (!is_win) {
# Don't stomp on "libzlib" on other platforms.
output_name = "chrome_zlib"
}
sources = [
"adler32.c",
"compress.c",
"crc32.c",
"crc32.h",
"deflate.c",
"deflate.h",
"gzclose.c",
"gzguts.h",
"gzlib.c",
"gzread.c",
"gzwrite.c",
"infback.c",
"inffast.c",
"inffast.h",
"inffixed.h",
"inflate.c",
"inflate.h",
"inftrees.c",
"inftrees.h",
"names.h",
"trees.c",
"trees.h",
"uncompr.c",
"x86.h",
"zconf.h",
"zlib.h",
"zutil.c",
"zutil.h",
]
if (!is_ios && (current_cpu == "x86" || current_cpu == "x64")) {
sources += [ "x86.c" ]
}
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
# Must be after no_chromium_code for warning flags to be ordered correctly.
":zlib_warnings",
]
public_configs = [ ":zlib_config" ]
deps = [
":zlib_x86_simd",
]
}
config("minizip_warnings") {
visibility = [ ":*" ]
if (is_clang) {
# zlib uses `if ((a == b))` for some reason.
cflags = [ "-Wno-parentheses-equality" ]
}
}
static_library("minizip") {
sources = [
"contrib/minizip/ioapi.c",
"contrib/minizip/ioapi.h",
"contrib/minizip/iowin32.c",
"contrib/minizip/iowin32.h",
"contrib/minizip/unzip.c",
"contrib/minizip/unzip.h",
"contrib/minizip/zip.c",
"contrib/minizip/zip.h",
]
if (!is_win) {
sources -= [
"contrib/minizip/iowin32.c",
"contrib/minizip/iowin32.h",
]
}
if (is_mac || is_ios || is_android) {
# Mac, Android and the BSDs don't have fopen64, ftello64, or fseeko64. We
# use fopen, ftell, and fseek instead on these systems.
defines = [ "USE_FILE32API" ]
}
deps = [
":zlib",
]
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [
"//build/config/compiler:no_chromium_code",
# Must be after no_chromium_code for warning flags to be ordered correctly.
":minizip_warnings",
]
public_configs = [ ":zlib_config" ]
}
static_library("zip") {
sources = [
"google/zip.cc",
"google/zip.h",
"google/zip_internal.cc",
"google/zip_internal.h",
"google/zip_reader.cc",
"google/zip_reader.h",
]
deps = [
":minizip",
"//base",
]
}
static_library("compression_utils") {
sources = [
"google/compression_utils.cc",
"google/compression_utils.h",
]
deps = [
":zlib",
]
}

View File

@ -0,0 +1,162 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
source_set("tool_support") {
sources = [
"tool_support.cc",
"tool_support.h",
]
public_configs = [ "..:crashpad_config" ]
deps = [ "$mini_chromium_source_parent:base" ]
}
if (!crashpad_is_ios) {
crashpad_executable("crashpad_database_util") {
sources = [ "crashpad_database_util.cc" ]
deps = [
":tool_support",
"../build:default_exe_manifest_win",
"../client",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
]
}
crashpad_executable("crashpad_http_upload") {
sources = [ "crashpad_http_upload.cc" ]
deps = [
":tool_support",
"../build:default_exe_manifest_win",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
"../util:net",
]
}
}
crashpad_executable("base94_encoder") {
sources = [ "base94_encoder.cc" ]
deps = [
":tool_support",
"../build:default_exe_manifest_win",
"$mini_chromium_source_parent:base",
"../util",
]
}
if (!crashpad_is_fuchsia && !crashpad_is_ios) {
crashpad_executable("generate_dump") {
sources = [ "generate_dump.cc" ]
deps = [
":tool_support",
"../build:default_exe_manifest_win",
"../compat",
"../minidump",
"../snapshot",
"$mini_chromium_source_parent:base",
"../util",
]
if (crashpad_is_mac) {
# This would be better as a config so that it could be shared with
# exception_port_tool, but configs cant alter “inputs”.
# https://crbug.com/781858.
inputs = [ "mac/sectaskaccess_info.plist" ]
ldflags = [
"-sectcreate",
"__TEXT",
"__info_plist",
rebase_path(inputs[0], root_build_dir),
]
}
if (crashpad_is_win) {
cflags =
[ "/wd4201" ] # nonstandard extension used : nameless struct/union
}
}
}
if (crashpad_is_mac || crashpad_is_fuchsia) {
crashpad_executable("run_with_crashpad") {
sources = [ "run_with_crashpad.cc" ]
deps = [
":tool_support",
"../client",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
]
}
}
if (crashpad_is_mac) {
crashpad_executable("catch_exception_tool") {
sources = [ "mac/catch_exception_tool.cc" ]
deps = [
":tool_support",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
]
}
crashpad_executable("exception_port_tool") {
sources = [ "mac/exception_port_tool.cc" ]
# This would be better as a config so that it could be shared with
# generate_dump, but configs cant alter “inputs”. https://crbug.com/781858.
inputs = [ "mac/sectaskaccess_info.plist" ]
ldflags = [
"-sectcreate",
"__TEXT",
"__info_plist",
rebase_path(inputs[0], root_build_dir),
]
deps = [
":tool_support",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
]
}
crashpad_executable("on_demand_service_tool") {
sources = [ "mac/on_demand_service_tool.mm" ]
frameworks = [
"CoreFoundation.framework",
"Foundation.framework",
]
deps = [
":tool_support",
"../compat",
"$mini_chromium_source_parent:base",
"../util",
]
}
}

View File

@ -0,0 +1,967 @@
# Copyright 2015 The Crashpad Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import("../build/crashpad_buildconfig.gni")
import("net/tls.gni")
if (crashpad_is_in_chromium) {
import("//build/config/sanitizers/sanitizers.gni")
}
if (crashpad_is_mac || crashpad_is_ios) {
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
import("//build/config/sysroot.gni")
} else {
import("$mini_chromium_import_root/build/sysroot.gni")
}
action_foreach("mig") {
script = "mach/mig.py"
inputs = [
"mach/mig_fix.py",
"mach/mig_gen.py",
]
if (crashpad_is_in_fuchsia) {
# TODO(https://fxbug.dev/68780): Remove suppression when fixed.
hermetic_deps = false
all_outputs_fresh = false
}
if (crashpad_is_mac) {
sources = [
"$sysroot/usr/include/mach/exc.defs",
"$sysroot/usr/include/mach/mach_exc.defs",
"$sysroot/usr/include/mach/notify.defs",
"mach/child_port.defs",
]
} else if (crashpad_is_ios) {
sources = [
# The iOS SDK doesnt have any .defs files. Get them directly from xnu.
"../third_party/xnu/osfmk/mach/exc.defs",
"../third_party/xnu/osfmk/mach/mach_exc.defs",
]
}
outputs = [
"$target_gen_dir/mach/{{source_name_part}}User.c",
"$target_gen_dir/mach/{{source_name_part}}Server.c",
"$target_gen_dir/mach/{{source_name_part}}.h",
"$target_gen_dir/mach/{{source_name_part}}Server.h",
]
args = [ "{{source}}" ]
args += rebase_path(outputs, root_build_dir)
if (crashpad_is_in_chromium) {
if (!use_system_xcode) {
import("//build/config/clang/clang.gni")
import("//build/config/mac/mac_sdk.gni")
clang_path =
rebase_path("$clang_base_path/bin/", root_build_dir) + "clang"
mig_path = "$mac_bin_path" + "mig"
migcom_path = "$mac_bin_path" + "../libexec/migcom"
args += [
"--clang-path",
clang_path,
"--mig-path",
mig_path,
"--migcom-path",
migcom_path,
]
}
if (crashpad_is_mac) {
deps = [ "//build/config/mac:sdk_inputs" ]
}
}
if (sysroot != "") {
if (crashpad_is_in_chromium) {
# Chromium often brings along its own SDK and wants to keep paths
# relative…
args += [
"--sdk",
rebase_path(sysroot, root_build_dir),
]
} else {
# …but thats not an option in the standalone Crashpad build, where the
# SDK is installed on the system and is absolute. (But use rebase_path
# just to be sure.)
args += [
"--sdk",
rebase_path(sysroot, ""),
]
}
}
args += [
"--include",
rebase_path("..", root_build_dir),
"--include",
rebase_path("../compat/mac", root_build_dir),
]
if (crashpad_is_ios) {
args += [
"--include",
rebase_path("../compat/ios", root_build_dir),
]
}
if (current_cpu == "x86") {
args += [
"--arch",
"i386",
]
} else if (current_cpu == "x64") {
args += [
"--arch",
"x86_64",
]
} else if (current_cpu == "arm") {
args += [
"--arch",
"armv7",
]
} else if (current_cpu == "arm64") {
args += [
"--arch",
"arm64",
]
} else if (crashpad_is_mac && current_cpu == "mac_universal") {
args += [
"--arch",
"x86_64",
"--arch",
"arm64",
]
} else {
assert(false, "Unsupported architecture")
}
}
static_library("mig_output") {
deps = [ ":mig" ]
sources = get_target_outputs(":mig")
if (crashpad_is_in_chromium) {
# mig output contains unreachable code, which irks -Wunreachable-code.
configs -= [ "//build/config/compiler:chromium_code" ]
configs += [ "//build/config/compiler:no_chromium_code" ]
}
public_configs = [ "..:crashpad_config" ]
}
}
crashpad_static_library("util") {
sources = [
"file/delimited_file_reader.cc",
"file/delimited_file_reader.h",
"file/directory_reader.h",
"file/file_helper.cc",
"file/file_helper.h",
"file/file_io.cc",
"file/file_io.h",
"file/file_reader.cc",
"file/file_reader.h",
"file/file_seeker.cc",
"file/file_seeker.h",
"file/file_writer.cc",
"file/file_writer.h",
"file/filesystem.h",
"file/output_stream_file_writer.cc",
"file/output_stream_file_writer.h",
"file/scoped_remove_file.cc",
"file/scoped_remove_file.h",
"file/string_file.cc",
"file/string_file.h",
"misc/address_sanitizer.h",
"misc/address_types.h",
"misc/arraysize.h",
"misc/as_underlying_type.h",
"misc/capture_context.h",
"misc/clock.h",
"misc/elf_note_types.h",
"misc/from_pointer_cast.h",
"misc/implicit_cast.h",
"misc/initialization_state.h",
"misc/initialization_state_dcheck.cc",
"misc/initialization_state_dcheck.h",
"misc/lexing.cc",
"misc/lexing.h",
"misc/memory_sanitizer.h",
"misc/metrics.cc",
"misc/metrics.h",
"misc/paths.h",
"misc/pdb_structures.cc",
"misc/pdb_structures.h",
"misc/random_string.cc",
"misc/random_string.h",
"misc/range_set.cc",
"misc/range_set.h",
"misc/reinterpret_bytes.cc",
"misc/reinterpret_bytes.h",
"misc/scoped_forbid_return.cc",
"misc/scoped_forbid_return.h",
"misc/symbolic_constants_common.h",
"misc/time.cc",
"misc/time.h",
"misc/tri_state.h",
"misc/uuid.cc",
"misc/uuid.h",
"misc/zlib.cc",
"misc/zlib.h",
"numeric/checked_address_range.cc",
"numeric/checked_address_range.h",
"numeric/checked_range.h",
"numeric/checked_vm_address_range.h",
"numeric/in_range_cast.h",
"numeric/int128.h",
"numeric/safe_assignment.h",
"process/process_id.h",
"process/process_memory.cc",
"process/process_memory.h",
"process/process_memory_native.h",
"process/process_memory_range.cc",
"process/process_memory_range.h",
"stdlib/aligned_allocator.cc",
"stdlib/aligned_allocator.h",
"stdlib/map_insert.h",
"stdlib/objc.h",
"stdlib/string_number_conversion.cc",
"stdlib/string_number_conversion.h",
"stdlib/strlcpy.cc",
"stdlib/strlcpy.h",
"stdlib/strnlen.cc",
"stdlib/strnlen.h",
"stdlib/thread_safe_vector.h",
"stream/base94_output_stream.cc",
"stream/base94_output_stream.h",
"stream/file_encoder.cc",
"stream/file_encoder.h",
"stream/file_output_stream.cc",
"stream/file_output_stream.h",
"stream/log_output_stream.cc",
"stream/log_output_stream.h",
"stream/output_stream_interface.h",
"stream/zlib_output_stream.cc",
"stream/zlib_output_stream.h",
"string/split_string.cc",
"string/split_string.h",
"synchronization/semaphore.h",
"thread/stoppable.h",
"thread/thread.cc",
"thread/thread.h",
"thread/thread_log_messages.cc",
"thread/thread_log_messages.h",
"thread/worker_thread.cc",
"thread/worker_thread.h",
]
defines = [ "ZLIB_CONST" ]
if (crashpad_is_posix || crashpad_is_fuchsia) {
sources += [
"file/directory_reader_posix.cc",
"file/file_io_posix.cc",
"file/filesystem_posix.cc",
"misc/clock_posix.cc",
"posix/close_stdio.cc",
"posix/close_stdio.h",
"posix/scoped_dir.cc",
"posix/scoped_dir.h",
"posix/scoped_mmap.cc",
"posix/scoped_mmap.h",
"posix/signals.cc",
"posix/signals.h",
"synchronization/semaphore_posix.cc",
"thread/thread_posix.cc",
]
if (!crashpad_is_fuchsia) {
sources += [
"posix/close_multiple.cc",
"posix/close_multiple.h",
"posix/double_fork_and_exec.cc",
"posix/double_fork_and_exec.h",
"posix/drop_privileges.cc",
"posix/drop_privileges.h",
"posix/process_info.h",
# These map signals to and from strings. While Fuchsia defines some of
# the common SIGx defines, signals are never raised on Fuchsia, so
# there's need to include this mapping code.
"posix/symbolic_constants_posix.cc",
"posix/symbolic_constants_posix.h",
]
}
}
if (crashpad_is_mac || crashpad_is_ios) {
sources += [
"mac/xattr.cc",
"mac/xattr.h",
"mach/composite_mach_message_server.cc",
"mach/composite_mach_message_server.h",
"mach/exc_client_variants.cc",
"mach/exc_client_variants.h",
"mach/exc_server_variants.cc",
"mach/exc_server_variants.h",
"mach/exception_behaviors.cc",
"mach/exception_behaviors.h",
"mach/exception_ports.cc",
"mach/exception_ports.h",
"mach/mach_extensions.cc",
"mach/mach_extensions.h",
"mach/mach_message.cc",
"mach/mach_message.h",
"mach/mach_message_server.cc",
"mach/mach_message_server.h",
"mach/symbolic_constants_mach.cc",
"mach/symbolic_constants_mach.h",
"misc/capture_context_mac.S",
"misc/clock_mac.cc",
"misc/paths_mac.cc",
"synchronization/semaphore_mac.cc",
]
}
if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
sources += [
"mac/checked_mach_address_range.h",
"mac/launchd.h",
"mac/launchd.mm",
"mac/mac_util.cc",
"mac/mac_util.h",
"mac/service_management.cc",
"mac/service_management.h",
"mac/sysctl.cc",
"mac/sysctl.h",
"mach/bootstrap.cc",
"mach/bootstrap.h",
"mach/child_port_handshake.cc",
"mach/child_port_handshake.h",
"mach/child_port_server.cc",
"mach/child_port_server.h",
"mach/child_port_types.h",
"mach/exception_types.cc",
"mach/exception_types.h",
"mach/notify_server.cc",
"mach/notify_server.h",
"mach/scoped_task_suspend.cc",
"mach/scoped_task_suspend.h",
"mach/task_for_pid.cc",
"mach/task_for_pid.h",
"posix/process_info_mac.cc",
"process/process_memory_mac.cc",
"process/process_memory_mac.h",
]
}
if (crashpad_is_ios) {
sources += [
"ios/ios_intermediate_dump_data.cc",
"ios/ios_intermediate_dump_data.h",
"ios/ios_intermediate_dump_format.h",
"ios/ios_intermediate_dump_interface.cc",
"ios/ios_intermediate_dump_interface.h",
"ios/ios_intermediate_dump_list.cc",
"ios/ios_intermediate_dump_list.h",
"ios/ios_intermediate_dump_map.cc",
"ios/ios_intermediate_dump_map.h",
"ios/ios_intermediate_dump_object.cc",
"ios/ios_intermediate_dump_object.h",
"ios/ios_intermediate_dump_reader.cc",
"ios/ios_intermediate_dump_reader.h",
"ios/ios_intermediate_dump_writer.cc",
"ios/ios_intermediate_dump_writer.h",
"ios/ios_system_data_collector.h",
"ios/ios_system_data_collector.mm",
"ios/raw_logging.cc",
"ios/raw_logging.h",
"ios/scoped_vm_read.cc",
"ios/scoped_vm_read.h",
]
}
deps = []
if (crashpad_is_android) {
sources += [
"linux/initial_signal_dispositions.cc",
"linux/initial_signal_dispositions.h",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/address_types.h",
"linux/auxiliary_vector.cc",
"linux/auxiliary_vector.h",
"linux/checked_linux_address_range.h",
"linux/direct_ptrace_connection.cc",
"linux/direct_ptrace_connection.h",
"linux/exception_handler_client.cc",
"linux/exception_handler_client.h",
"linux/exception_handler_protocol.cc",
"linux/exception_handler_protocol.h",
"linux/exception_information.h",
"linux/memory_map.cc",
"linux/memory_map.h",
"linux/proc_stat_reader.cc",
"linux/proc_stat_reader.h",
"linux/proc_task_reader.cc",
"linux/proc_task_reader.h",
"linux/ptrace_broker.cc",
"linux/ptrace_broker.h",
"linux/ptrace_client.cc",
"linux/ptrace_client.h",
"linux/ptrace_connection.h",
"linux/ptracer.cc",
"linux/ptracer.h",
"linux/scoped_pr_set_dumpable.cc",
"linux/scoped_pr_set_dumpable.h",
"linux/scoped_pr_set_ptracer.cc",
"linux/scoped_pr_set_ptracer.h",
"linux/scoped_ptrace_attach.cc",
"linux/scoped_ptrace_attach.h",
"linux/socket.cc",
"linux/socket.h",
"linux/thread_info.cc",
"linux/thread_info.h",
"linux/traits.h",
"misc/capture_context_linux.S",
"misc/paths_linux.cc",
"misc/time_linux.cc",
"posix/process_info_linux.cc",
"process/process_memory_linux.cc",
"process/process_memory_linux.h",
"process/process_memory_sanitized.cc",
"process/process_memory_sanitized.h",
]
}
if (crashpad_is_win) {
sources += [
"file/directory_reader_win.cc",
"file/file_io_win.cc",
"file/filesystem_win.cc",
"misc/clock_win.cc",
"misc/paths_win.cc",
"misc/time_win.cc",
"process/process_memory_win.cc",
"process/process_memory_win.h",
"synchronization/semaphore_win.cc",
"thread/thread_win.cc",
"win/address_types.h",
"win/checked_win_address_range.h",
"win/command_line.cc",
"win/command_line.h",
"win/context_wrappers.h",
"win/critical_section_with_debug_info.cc",
"win/critical_section_with_debug_info.h",
"win/exception_handler_server.cc",
"win/exception_handler_server.h",
"win/get_function.cc",
"win/get_function.h",
"win/get_module_information.cc",
"win/get_module_information.h",
"win/handle.cc",
"win/handle.h",
"win/initial_client_data.cc",
"win/initial_client_data.h",
"win/loader_lock.cc",
"win/loader_lock.h",
"win/module_version.cc",
"win/module_version.h",
"win/nt_internals.cc",
"win/nt_internals.h",
"win/ntstatus_logging.cc",
"win/ntstatus_logging.h",
"win/process_info.cc",
"win/process_info.h",
"win/process_structs.h",
"win/registration_protocol_win.cc",
"win/registration_protocol_win.h",
"win/safe_terminate_process.h",
"win/scoped_handle.cc",
"win/scoped_handle.h",
"win/scoped_local_alloc.cc",
"win/scoped_local_alloc.h",
"win/scoped_process_suspend.cc",
"win/scoped_process_suspend.h",
"win/scoped_registry_key.h",
"win/scoped_set_event.cc",
"win/scoped_set_event.h",
"win/session_end_watcher.cc",
"win/session_end_watcher.h",
"win/termination_codes.h",
"win/traits.h",
"win/xp_compat.h",
]
# There's no ml.exe yet in cross builds, so provide broken-but-not-asm
# versions of the functions defined in .asm files.
#
# CaptureContext() in capture_context_broken.cc just calls CHECK(false).
# SafeTerminateProcess() in safe_terminate_process.cc just calls regular
# TerminateProcess() without the protection against broken third-party
# patching of TerminateProcess().
#
# TODO(thakis): Use the .asm file in cross builds somehow,
# https://crbug.com/762167.
if (host_os == "win") {
if (current_cpu != "arm64") {
sources += [
"misc/capture_context_win.asm",
"win/safe_terminate_process.asm",
]
} else {
# Most Crashpad builds use Microsoft's armasm64.exe macro assembler for
# .asm source files. When building in Chromium, clang-cl is used as the
# assembler instead. Since the two assemblers recognize different
# assembly dialects, the same .asm file can't be used for each. As a
# workaround, use a prebuilt .obj file when the Microsoft-dialect
# assembler isn't available.
if (crashpad_is_in_chromium) {
sources += [ "misc/capture_context_win_arm64.obj" ]
} else {
sources += [ "misc/capture_context_win_arm64.asm" ]
}
}
} else {
sources += [
"misc/capture_context_broken.cc",
"win/safe_terminate_process_broken.cc",
]
}
}
if (crashpad_is_fuchsia) {
sources += [
"fuchsia/koid_utilities.cc",
"fuchsia/koid_utilities.h",
"fuchsia/scoped_task_suspend.cc",
"fuchsia/scoped_task_suspend.h",
"fuchsia/traits.h",
"misc/capture_context_fuchsia.S",
"misc/paths_fuchsia.cc",
"process/process_memory_fuchsia.cc",
"process/process_memory_fuchsia.h",
]
}
public_configs = [ "..:crashpad_config" ]
# Include generated files starting with "util".
if (crashpad_is_in_fuchsia) {
include_dirs = [ "$root_gen_dir/third_party/crashpad" ]
} else {
include_dirs = [ "$root_gen_dir/third_party/crashpad/crashpad" ]
}
public_deps = [
":no_cfi_icall",
"../compat",
"../third_party/zlib",
]
deps += [
"$mini_chromium_source_parent:base",
"$mini_chromium_source_parent:chromeos_buildflags",
]
if (crashpad_is_mac || crashpad_is_ios) {
include_dirs += [ "$root_build_dir/gen" ]
deps += [ ":mig_output" ]
}
if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
libs = [ "bsm" ]
frameworks = [
"CoreFoundation.framework",
"Foundation.framework",
"IOKit.framework",
]
}
if (crashpad_is_win) {
libs = [
"user32.lib",
# TODO(jperaza): version.lib is needed for Windows 7 compatibility.
# mincore.lib may be linked against instead when targeting Windows 8+.
"version.lib",
"winhttp.lib",
]
cflags = [ "/wd4201" ] # nonstandard extension used: nameless struct/union.
if (current_cpu == "x86") {
asmflags = [ "/safeseh" ]
}
}
if (crashpad_is_fuchsia) {
public_deps += [ "../third_party/fuchsia" ]
}
if (crashpad_is_android || crashpad_is_linux) {
deps += [ "../third_party/lss" ]
}
}
# net is split into a separate target from util so that client code does
# not have to depend on it.
crashpad_static_library("net") {
sources = [
"net/http_body.cc",
"net/http_body.h",
"net/http_body_gzip.cc",
"net/http_body_gzip.h",
"net/http_headers.h",
"net/http_multipart_builder.cc",
"net/http_multipart_builder.h",
"net/http_transport.cc",
"net/http_transport.h",
"net/url.cc",
"net/url.h",
]
deps = [
":util",
"$mini_chromium_source_parent:base",
]
if (crashpad_is_mac && !crashpad_is_in_fuchsia) {
sources += [ "net/http_transport_mac.mm" ]
}
if (crashpad_is_ios) {
sources += [ "net/http_transport_mac.mm" ]
}
if (crashpad_is_win) {
sources += [ "net/http_transport_win.cc" ]
}
if (crashpad_http_transport_impl == "socket") {
sources += [ "net/http_transport_socket.cc" ]
if (crashpad_use_boringssl_for_http_transport_socket) {
defines += [ "CRASHPAD_USE_BORINGSSL" ]
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
deps += [ "//third_party/boringssl" ]
} else {
libs = [
"crypto",
"ssl",
]
}
}
} else if (crashpad_http_transport_impl == "libcurl") {
sources += [ "net/http_transport_libcurl.cc" ]
if (crashpad_is_in_fuchsia) {
# Host Linux builds in Fuchsia don't have libcurl in a sysroot.
deps += [ "//third_party/curl:libcurl" ]
}
}
}
if (!crashpad_is_android && !crashpad_is_ios) {
crashpad_executable("http_transport_test_server") {
testonly = true
sources = [ "net/http_transport_test_server.cc" ]
deps = [
":net",
":util",
"$mini_chromium_source_parent:base",
"../third_party/cpp-httplib",
"../third_party/zlib",
"../tools:tool_support",
]
# TODO(b/189353575): make these relocatable using $mini_chromium_ variables
if (crashpad_is_standalone) {
remove_configs = [ "//third_party/mini_chromium/mini_chromium/build/config:Wexit_time_destructors" ]
} else if (crashpad_is_external) {
remove_configs = [ "//../../mini_chromium/mini_chromium/build/config:Wexit_time_destructors" ]
}
if (crashpad_is_win) {
libs = [ "ws2_32.lib" ]
}
if (crashpad_use_boringssl_for_http_transport_socket) {
defines = [ "CRASHPAD_USE_BORINGSSL" ]
if (crashpad_is_in_chromium || crashpad_is_in_fuchsia) {
deps += [ "//third_party/boringssl" ]
} else {
libs = [
"crypto",
"ssl",
]
}
}
}
}
# This exists as a separate target from util so that compat may depend on it
# without cycles.
source_set("no_cfi_icall") {
sources = [ "misc/no_cfi_icall.h" ]
public_configs = [ "..:crashpad_config" ]
public_deps = [ "$mini_chromium_source_parent:build" ]
}
source_set("util_test") {
testonly = true
sources = [
"file/delimited_file_reader_test.cc",
"file/directory_reader_test.cc",
"file/file_io_test.cc",
"file/file_reader_test.cc",
"file/filesystem_test.cc",
"file/string_file_test.cc",
"misc/arraysize_test.cc",
"misc/capture_context_test.cc",
"misc/capture_context_test_util.h",
"misc/clock_test.cc",
"misc/from_pointer_cast_test.cc",
"misc/initialization_state_dcheck_test.cc",
"misc/initialization_state_test.cc",
"misc/no_cfi_icall_test.cc",
"misc/paths_test.cc",
"misc/random_string_test.cc",
"misc/range_set_test.cc",
"misc/reinterpret_bytes_test.cc",
"misc/scoped_forbid_return_test.cc",
"misc/time_test.cc",
"misc/uuid_test.cc",
"net/http_body_gzip_test.cc",
"net/http_body_test.cc",
"net/http_body_test_util.cc",
"net/http_body_test_util.h",
"net/http_multipart_builder_test.cc",
"net/url_test.cc",
"numeric/checked_address_range_test.cc",
"numeric/checked_range_test.cc",
"numeric/in_range_cast_test.cc",
"numeric/int128_test.cc",
"process/process_memory_range_test.cc",
"process/process_memory_test.cc",
"stdlib/aligned_allocator_test.cc",
"stdlib/map_insert_test.cc",
"stdlib/string_number_conversion_test.cc",
"stdlib/strlcpy_test.cc",
"stdlib/strnlen_test.cc",
"stdlib/thread_safe_vector_test.cc",
"stream/base94_output_stream_test.cc",
"stream/file_encoder_test.cc",
"stream/log_output_stream_test.cc",
"stream/test_output_stream.cc",
"stream/test_output_stream.h",
"stream/zlib_output_stream_test.cc",
"string/split_string_test.cc",
"synchronization/semaphore_test.cc",
"thread/thread_log_messages_test.cc",
"thread/thread_test.cc",
"thread/worker_thread_test.cc",
]
if (!crashpad_is_android && !crashpad_is_ios) {
# Android requires an HTTPTransport implementation.
sources += [ "net/http_transport_test.cc" ]
}
if (crashpad_is_posix || crashpad_is_fuchsia) {
if (!crashpad_is_fuchsia && !crashpad_is_ios) {
sources += [
"posix/process_info_test.cc",
"posix/signals_test.cc",
"posix/symbolic_constants_posix_test.cc",
]
}
sources += [ "posix/scoped_mmap_test.cc" ]
}
if (crashpad_is_mac || crashpad_is_ios) {
sources += [
"mac/xattr_test.cc",
"mach/composite_mach_message_server_test.cc",
"mach/exc_server_variants_test.cc",
"mach/exception_behaviors_test.cc",
"mach/mach_extensions_test.cc",
"mach/mach_message_test.cc",
"mach/symbolic_constants_mach_test.cc",
"misc/capture_context_test_util_mac.cc",
]
}
if (crashpad_is_mac) {
sources += [
"mac/launchd_test.mm",
"mac/mac_util_test.mm",
"mac/service_management_test.mm",
"mac/sysctl_test.cc",
"mach/bootstrap_test.cc",
"mach/child_port_handshake_test.cc",
"mach/child_port_server_test.cc",
"mach/exc_client_variants_test.cc",
"mach/exception_ports_test.cc",
"mach/exception_types_test.cc",
"mach/mach_message_server_test.cc",
"mach/notify_server_test.cc",
"mach/scoped_task_suspend_test.cc",
"process/process_memory_mac_test.cc",
]
}
if (crashpad_is_ios) {
sources += [
"ios/ios_intermediate_dump_reader_test.cc",
"ios/ios_intermediate_dump_writer_test.cc",
"ios/scoped_vm_read_test.cc",
]
sources -= [
"process/process_memory_range_test.cc",
"process/process_memory_test.cc",
]
}
if (crashpad_is_linux || crashpad_is_android) {
sources += [
"linux/auxiliary_vector_test.cc",
"linux/memory_map_test.cc",
"linux/proc_stat_reader_test.cc",
"linux/proc_task_reader_test.cc",
"linux/ptrace_broker_test.cc",
"linux/ptracer_test.cc",
"linux/scoped_ptrace_attach_test.cc",
"linux/socket_test.cc",
"misc/capture_context_test_util_linux.cc",
"process/process_memory_sanitized_test.cc",
]
}
if (crashpad_is_fuchsia) {
sources += [ "misc/capture_context_test_util_fuchsia.cc" ]
}
if (crashpad_is_win) {
sources += [
"misc/capture_context_test_util_win.cc",
"win/command_line_test.cc",
"win/critical_section_with_debug_info_test.cc",
"win/exception_handler_server_test.cc",
"win/get_function_test.cc",
"win/handle_test.cc",
"win/initial_client_data_test.cc",
"win/loader_lock_test.cc",
"win/process_info_test.cc",
"win/registration_protocol_win_test.cc",
"win/safe_terminate_process_test.cc",
"win/scoped_process_suspend_test.cc",
"win/session_end_watcher_test.cc",
]
if (crashpad_is_in_chromium && is_asan && is_component_build) {
# TODO(crbug.com/856174): Re-enable these once Windows ASan is fixed.
sources -= [ "stdlib/string_number_conversion_test.cc" ]
}
}
data = [
"net/testdata/ascii_http_body.txt",
"net/testdata/binary_http_body.dat",
"net/testdata/crashpad_util_test_cert.pem",
"net/testdata/crashpad_util_test_key.pem",
]
deps = [
":net",
":util",
"$mini_chromium_source_parent:base",
"../client",
"../compat",
"../test",
"../third_party/googletest:googlemock",
"../third_party/googletest:googletest",
"../third_party/zlib",
]
if (!crashpad_is_android && !crashpad_is_ios) {
data_deps = [ ":http_transport_test_server" ]
if (crashpad_use_boringssl_for_http_transport_socket) {
defines = [ "CRASHPAD_USE_BORINGSSL" ]
}
}
if (crashpad_is_mac) {
frameworks = [ "Foundation.framework" ]
}
if (crashpad_is_ios) {
deps += [ ":util_test_bundle_data" ]
}
if (crashpad_is_android || crashpad_is_linux) {
deps += [ "../third_party/lss" ]
}
if (crashpad_is_win) {
libs = [
"rpcrt4.lib",
"dbghelp.lib",
]
data_deps += [
":crashpad_util_test_loader_lock_test",
":crashpad_util_test_process_info_test_child",
":crashpad_util_test_safe_terminate_process_test_child",
]
}
}
if (crashpad_is_ios) {
bundle_data("util_test_bundle_data") {
testonly = true
sources = [
"net/testdata/ascii_http_body.txt",
"net/testdata/binary_http_body.dat",
]
outputs = [ "{{bundle_resources_dir}}/crashpad_test_data/" +
"{{source_root_relative_dir}}/{{source_file_part}}" ]
}
}
if (crashpad_is_win) {
crashpad_executable("crashpad_util_test_process_info_test_child") {
testonly = true
sources = [ "win/process_info_test_child.cc" ]
}
crashpad_executable("crashpad_util_test_safe_terminate_process_test_child") {
testonly = true
sources = [ "win/safe_terminate_process_test_child.cc" ]
}
crashpad_loadable_module("crashpad_util_test_loader_lock_test") {
testonly = true
sources = [ "win/loader_lock_test_dll.cc" ]
deps = [ ":util" ]
}
}

View File

@ -0,0 +1,55 @@
name: Build
on:
push:
branches:
- master
pull_request:
jobs:
build:
strategy:
fail-fast: false
matrix:
include:
- name: Android (API 16, NDK 20)
ANDROID_API: 16
ANDROID_NDK: 20.1.5948944
- name: Android (API 30, NDK 22)
ANDROID_API: 30
ANDROID_NDK: 22.1.7171670
runs-on: macos-latest
env:
ANDROID_API: ${{ matrix.ANDROID_API }}
ANDROID_NDK: ${{ matrix.ANDROID_NDK }}
steps:
- uses: actions/checkout@v2
with:
submodules: "recursive"
- name: Installing Android SDK Dependencies
run: |
echo "Downloading ndk;$ANDROID_NDK"
echo "y" | $ANDROID_HOME/tools/bin/sdkmanager --install \
"ndk;$ANDROID_NDK" | \
grep -v "\[=" || true # suppress the progress bar, so we get meaningful logs
- name: Build x86_64
run: |
cmake -B build -S cmake \
-D CMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-D ANDROID_NATIVE_API_LEVEL=$ANDROID_API \
-D ANDROID_ABI=x86_64
cmake --build build --parallel
- name: Build arm64-v8a
run: |
rm -rf build
cmake -B build -S cmake \
-D CMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/$ANDROID_NDK/build/cmake/android.toolchain.cmake \
-D ANDROID_NATIVE_API_LEVEL=$ANDROID_API \
-D ANDROID_ABI=arm64-v8a
cmake --build build --parallel