Update DEPS to fix mac build failure
Change-Id: I1cf95d5da8e3b950300cd61cd9286e957ef653ce
This commit is contained in:
parent
644629c616
commit
23f2913248
|
@ -9,7 +9,8 @@
|
|||
/out*
|
||||
/packager/base/
|
||||
/packager/build/
|
||||
/packager/buildtools/
|
||||
/packager/buildtools/third_party/libc++/trunk/
|
||||
/packager/buildtools/third_party/libc++abi/trunk/
|
||||
/packager/docs/
|
||||
/packager/testing/gmock/
|
||||
/packager/testing/gtest/
|
||||
|
|
58
DEPS
58
DEPS
|
@ -14,19 +14,22 @@ vars = {
|
|||
|
||||
deps = {
|
||||
"src/packager/base":
|
||||
Var("chromium_git") + "/chromium/src/base@d24f251a44cd0304e56406d843644b79138c584b", #339798
|
||||
Var("chromium_git") + "/chromium/src/base@a34eabec0d807cf03dc8cfc1a6240156ac2bbd01", #409071
|
||||
|
||||
"src/packager/build":
|
||||
Var("chromium_git") + "/chromium/src/build@8316b2d4d47438a9eed3e89d2ba5dd625e8c8aef", #339877
|
||||
Var("chromium_git") + "/chromium/src/build@f0243d787961584ac95a86e7dae897b9b60ea674", #409966
|
||||
|
||||
'src/packager/buildtools':
|
||||
Var("chromium_git") + '/chromium/buildtools.git@5fc8d3943e163ee627c8af50366c700c0325bba2',
|
||||
"src/packager/buildtools/third_party/libc++/trunk":
|
||||
"https://github.com/llvm-mirror/libcxx.git@8c22696675a2c5ea1c79fc64a4d7dfe1c2f4ca8b",
|
||||
|
||||
"src/packager/buildtools/third_party/libc++abi/trunk":
|
||||
"https://github.com/llvm-mirror/libcxxabi.git@6092bfa6c153ad712e2fc90c7b9e536420bf3c57",
|
||||
|
||||
"src/packager/testing/gmock":
|
||||
Var("chromium_git") + "/external/googlemock@29763965ab52f24565299976b936d1265cb6a271", #501
|
||||
Var("chromium_git") + "/external/googlemock@0421b6f358139f02e102c9c332ce19a33faf75be", #566
|
||||
|
||||
"src/packager/testing/gtest":
|
||||
Var("chromium_git") + "/external/googletest@00a70a9667d92a4695d84e4fa36b64f611f147da", #725
|
||||
Var("chromium_git") + "/external/github.com/google/googletest@6f8a66431cb592dad629028a50b3dd418a408c87",
|
||||
|
||||
# Make sure the version matches the one in
|
||||
# src/packager/third_party/boringssl, which contains perl generated files.
|
||||
|
@ -36,32 +39,30 @@ deps = {
|
|||
"src/packager/third_party/curl/source":
|
||||
Var("curl_url") + "@79e63a53bb9598af863b0afe49ad662795faeef4", #7_50_0
|
||||
|
||||
|
||||
"src/packager/third_party/gflags/src":
|
||||
Var("chromium_git") + "/external/github.com/gflags/gflags@03bebcb065c83beff83d50ae025a55a4bf94dfca",
|
||||
|
||||
|
||||
# Required by libxml.
|
||||
"src/packager/third_party/icu":
|
||||
Var("chromium_git") + "/chromium/third_party/icu46@78597121d71a5922f5726e715c6ad06c50ae6cdc",
|
||||
Var("chromium_git") + "/chromium/deps/icu@ef5c735307d0f86c7622f69620994c9468beba99",
|
||||
|
||||
"src/packager/third_party/libwebm/src":
|
||||
Var("chromium_git") + "/webm/libwebm@1ad314e297a43966605c4ef23a6442bb58e1d9be",
|
||||
|
||||
"src/packager/third_party/modp_b64":
|
||||
Var("chromium_git") + "/chromium/src/third_party/modp_b64@3a0e3b4ef6c54678a2d14522533df56b33b56119",
|
||||
Var("chromium_git") + "/chromium/src/third_party/modp_b64@aae60754fa997799e8037f5e8ca1f56d58df763d", #405651
|
||||
|
||||
"src/packager/third_party/tcmalloc/chromium":
|
||||
Var("chromium_git") + "/chromium/src/third_party/tcmalloc/chromium@fa1492f75861094061043a17c0f779c3d35780bf",
|
||||
Var("chromium_git") + "/chromium/src/third_party/tcmalloc/chromium@58a93bea442dbdcb921e9f63e9d8b0009eea8fdb", #374449
|
||||
|
||||
"src/packager/third_party/zlib":
|
||||
Var("chromium_git") + "/chromium/src/third_party/zlib@830b5c25b5fbe37e032ea09dd011d57042dd94df",
|
||||
Var("chromium_git") + "/chromium/src/third_party/zlib@830b5c25b5fbe37e032ea09dd011d57042dd94df", #408157
|
||||
|
||||
"src/packager/tools/clang":
|
||||
Var("chromium_git") + "/chromium/src/tools/clang@0de8f3bb6af64e13876273c601704795d5e00faf",
|
||||
Var("chromium_git") + "/chromium/src/tools/clang@0b06ba9e49a0cba97f6accd71a974c1623d69e16", #409802
|
||||
|
||||
"src/packager/tools/gyp":
|
||||
Var("chromium_git") + "/external/gyp@5122240c5e5c4d8da12c543d82b03d6089eb77c5",
|
||||
Var("chromium_git") + "/external/gyp@e7079f0e0e14108ab0dba58728ff219637458563",
|
||||
|
||||
"src/packager/tools/valgrind":
|
||||
Var("chromium_git") + "/chromium/deps/valgrind@3a97aa8142b6e63f16789b22daafb42d202f91dc",
|
||||
|
@ -76,11 +77,31 @@ deps_os = {
|
|||
"win": {
|
||||
# Required by boringssl.
|
||||
"src/packager/third_party/yasm/source/patched-yasm":
|
||||
Var("chromium_git") + "/chromium/deps/yasm/patched-yasm.git@4671120cd8558ce62ee8672ebf3eb6f5216f909b",
|
||||
Var("chromium_git") + "/chromium/deps/yasm/patched-yasm.git@7da28c6c7c6a1387217352ce02b31754deb54d2a",
|
||||
},
|
||||
}
|
||||
|
||||
hooks = [
|
||||
{
|
||||
# Downloads the current stable linux sysroot to build/linux/ if needed.
|
||||
# This script is a no-op except for linux.
|
||||
'name': 'sysroot',
|
||||
'pattern': '.',
|
||||
'action': ['python', 'src/packager/build/linux/sysroot_scripts/install-sysroot.py',
|
||||
'--running-as-hook'],
|
||||
},
|
||||
{
|
||||
# Update the Windows toolchain if necessary.
|
||||
'name': 'win_toolchain',
|
||||
'pattern': '.',
|
||||
'action': ['python', 'src/packager/build/vs_toolchain.py', 'update'],
|
||||
},
|
||||
{
|
||||
# Update the Mac toolchain if necessary.
|
||||
'name': 'mac_toolchain',
|
||||
'pattern': '.',
|
||||
'action': ['python', 'src/packager/build/mac_toolchain.py'],
|
||||
},
|
||||
{
|
||||
# Pull clang if needed or requested via GYP_DEFINES (GYP_DEFINES="clang=1").
|
||||
# Note: On Win, this should run after win_toolchain, as it may use it.
|
||||
|
@ -93,4 +114,11 @@ hooks = [
|
|||
"pattern": ".",
|
||||
"action": ["python", "src/gyp_packager.py", "--depth=src/packager"],
|
||||
},
|
||||
{
|
||||
# Update LASTCHANGE.
|
||||
'name': 'lastchange',
|
||||
'pattern': '.',
|
||||
'action': ['python', 'src/packager/build/util/lastchange.py',
|
||||
'-o', 'src/packager/build/util/LASTCHANGE'],
|
||||
},
|
||||
]
|
||||
|
|
|
@ -40,7 +40,6 @@ src_dir = os.path.join(checkout_dir, 'packager')
|
|||
# pylint: disable=g-import-not-at-top,g-bad-import-order
|
||||
|
||||
sys.path.insert(0, os.path.join(src_dir, 'build'))
|
||||
import detect_host_arch
|
||||
import gyp_helper
|
||||
|
||||
sys.path.insert(0, os.path.join(src_dir, 'tools', 'gyp', 'pylib'))
|
||||
|
@ -66,17 +65,17 @@ if __name__ == '__main__':
|
|||
'use_openssl': 1,
|
||||
'use_x11': 0,
|
||||
'linux_use_gold_binary': 0,
|
||||
'linux_use_gold_flags': 0}
|
||||
|
||||
# Disable clang on 32 bit systems by default, which is not supported.
|
||||
if detect_host_arch.HostArch() == 'ia32':
|
||||
_DEFAULT_DEFINES['clang'] = 0
|
||||
'linux_use_gold_flags': 0,
|
||||
'clang_use_chrome_plugins': 0}
|
||||
|
||||
gyp_defines = (os.environ['GYP_DEFINES'] if os.environ.get('GYP_DEFINES') else
|
||||
'')
|
||||
for key in _DEFAULT_DEFINES:
|
||||
if key not in gyp_defines:
|
||||
gyp_defines += ' {0}={1}'.format(key, _DEFAULT_DEFINES[key])
|
||||
# Somehow gcc don't like use_sysroot.
|
||||
if 'clang=0' in gyp_defines and 'use_sysroot' not in gyp_defines:
|
||||
gyp_defines += ' use_sysroot=0'
|
||||
os.environ['GYP_DEFINES'] = gyp_defines.strip()
|
||||
|
||||
# Default to ninja, but only if no generator has explicitly been set.
|
||||
|
|
|
@ -59,13 +59,14 @@ ExitStatus CheckRequiredFlags() {
|
|||
ExitStatus RunMpdGenerator() {
|
||||
DCHECK_EQ(CheckRequiredFlags(), kSuccess);
|
||||
std::vector<std::string> base_urls;
|
||||
std::vector<std::string> input_files;
|
||||
typedef std::vector<std::string>::const_iterator Iterator;
|
||||
|
||||
base::SplitString(FLAGS_input, ',', &input_files);
|
||||
std::vector<std::string> input_files = base::SplitString(
|
||||
FLAGS_input, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
|
||||
|
||||
if (!FLAGS_base_urls.empty()) {
|
||||
base::SplitString(FLAGS_base_urls, ',', &base_urls);
|
||||
base_urls = base::SplitString(FLAGS_base_urls, ",", base::KEEP_WHITESPACE,
|
||||
base::SPLIT_WANT_ALL);
|
||||
}
|
||||
|
||||
MpdWriter mpd_writer;
|
||||
|
|
|
@ -286,7 +286,7 @@ bool CreateRemuxJobs(const StreamDescriptorList& stream_descriptors,
|
|||
}
|
||||
|
||||
if (mpd_notifier) {
|
||||
uint32 unused;
|
||||
uint32_t unused;
|
||||
if (!mpd_notifier->NotifyNewContainer(text_media_info, &unused)) {
|
||||
LOG(ERROR) << "Failed to process text file " << stream_iter->input;
|
||||
} else {
|
||||
|
@ -469,8 +469,8 @@ bool RunPackager(const StreamDescriptorList& stream_descriptors) {
|
|||
if (!FLAGS_mpd_output.empty()) {
|
||||
DashProfile profile =
|
||||
FLAGS_single_segment ? kOnDemandProfile : kLiveProfile;
|
||||
std::vector<std::string> base_urls;
|
||||
base::SplitString(FLAGS_base_urls, ',', &base_urls);
|
||||
std::vector<std::string> base_urls = base::SplitString(
|
||||
FLAGS_base_urls, ",", base::KEEP_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
|
||||
if (FLAGS_generate_dash_if_iop_compliant_mpd) {
|
||||
mpd_notifier.reset(new DashIopMpdNotifier(profile, mpd_options, base_urls,
|
||||
FLAGS_mpd_output));
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
# Copyright 2015 The Chromium Authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import("//build/config/sanitizers/sanitizers.gni")
|
||||
import("//build/toolchain/toolchain.gni")
|
||||
|
||||
# Used by libc++ and libc++abi.
|
||||
config("config") {
|
||||
defines = [ "LIBCXX_BUILDING_LIBCXXABI" ]
|
||||
cflags = [
|
||||
"-fPIC",
|
||||
"-fstrict-aliasing",
|
||||
"-pthread",
|
||||
]
|
||||
cflags_cc = [
|
||||
"-nostdinc++",
|
||||
"-isystem" + rebase_path("trunk/include", root_build_dir),
|
||||
"-isystem" + rebase_path("../libc++abi/trunk/include", root_build_dir),
|
||||
"-std=c++11",
|
||||
]
|
||||
}
|
||||
|
||||
shared_library("libc++") {
|
||||
sources = [
|
||||
"trunk/src/algorithm.cpp",
|
||||
"trunk/src/any.cpp",
|
||||
"trunk/src/bind.cpp",
|
||||
"trunk/src/chrono.cpp",
|
||||
"trunk/src/condition_variable.cpp",
|
||||
"trunk/src/debug.cpp",
|
||||
"trunk/src/exception.cpp",
|
||||
"trunk/src/future.cpp",
|
||||
"trunk/src/hash.cpp",
|
||||
"trunk/src/ios.cpp",
|
||||
"trunk/src/iostream.cpp",
|
||||
"trunk/src/locale.cpp",
|
||||
"trunk/src/memory.cpp",
|
||||
"trunk/src/mutex.cpp",
|
||||
"trunk/src/new.cpp",
|
||||
"trunk/src/optional.cpp",
|
||||
"trunk/src/random.cpp",
|
||||
"trunk/src/regex.cpp",
|
||||
"trunk/src/shared_mutex.cpp",
|
||||
"trunk/src/stdexcept.cpp",
|
||||
"trunk/src/string.cpp",
|
||||
"trunk/src/strstream.cpp",
|
||||
"trunk/src/system_error.cpp",
|
||||
"trunk/src/thread.cpp",
|
||||
"trunk/src/typeinfo.cpp",
|
||||
"trunk/src/utility.cpp",
|
||||
"trunk/src/valarray.cpp",
|
||||
]
|
||||
configs -= [
|
||||
"//build/config/compiler:chromium_code",
|
||||
"//build/config/compiler:no_rtti",
|
||||
"//build/config/gcc:no_exceptions",
|
||||
"//build/config/gcc:symbol_visibility_hidden",
|
||||
]
|
||||
configs += [
|
||||
":config",
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
"//build/config/compiler:rtti",
|
||||
"//build/config/gcc:symbol_visibility_default",
|
||||
"//build/config/sanitizers:sanitizer_options_link_helper",
|
||||
]
|
||||
|
||||
ldflags = [ "-nodefaultlibs" ]
|
||||
|
||||
# TODO(GYP): Remove "-pthread" from ldflags.
|
||||
# -nodefaultlibs turns -pthread into a no-op, causing an unused argument
|
||||
# warning. Explicitly link with -lpthread instead.
|
||||
|
||||
libs = [
|
||||
"m",
|
||||
]
|
||||
|
||||
if (!is_mac) {
|
||||
libs += [
|
||||
"c",
|
||||
"gcc_s",
|
||||
"pthread",
|
||||
"rt",
|
||||
]
|
||||
}
|
||||
|
||||
# libc++abi is linked statically into libc++.so. This allows us to get both
|
||||
# libc++ and libc++abi by passing '-stdlib=libc++'. If libc++abi was a
|
||||
# separate DSO, we'd have to link against it explicitly.
|
||||
deps = [
|
||||
"//buildtools/third_party/libc++abi",
|
||||
]
|
||||
|
||||
if (is_mac && using_sanitizer) {
|
||||
# -nodefaultlibs on mac doesn't add any kind of runtime libraries.
|
||||
# These runtimes have to be added manually.
|
||||
lib_dirs = [ "//third_party/llvm-build/Release+Asserts/lib/clang/$clang_version/lib/darwin" ]
|
||||
|
||||
if (is_asan) {
|
||||
libs += [ "clang_rt.asan_osx_dynamic" ]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
group("libcxx_proxy") {
|
||||
deps = [
|
||||
":libc++",
|
||||
]
|
||||
public_configs = [ ":link_helper" ]
|
||||
}
|
||||
|
||||
# This config is only used by binaries and shared library targets.
|
||||
# //build/config/sanitizers:default_sanitizer_flags sets the include paths for
|
||||
# everything else.
|
||||
config("link_helper") {
|
||||
ldflags = [
|
||||
"-stdlib=libc++",
|
||||
]
|
||||
|
||||
if (!is_mac) {
|
||||
ldflags += [
|
||||
# Normally the generator takes care of RPATH. Our case is special because
|
||||
# the generator is unaware of the libc++.so dependency. Note that setting
|
||||
# RPATH here is a potential security issue. See the following for another
|
||||
# example of this issue: https://code.google.com/p/gyp/issues/detail?id=315
|
||||
"-Wl,-rpath,\$ORIGIN/",
|
||||
]
|
||||
}
|
||||
|
||||
lib_dirs = [ root_build_dir ]
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
Name: libcxx
|
||||
Short Name: libc++
|
||||
URL: http://libcxx.llvm.org/
|
||||
Version: 1.0
|
||||
License: MIT, University of Illinois/NCSA Open Source License
|
||||
License File: trunk/LICENSE.TXT
|
||||
Security Critical: no
|
||||
|
||||
Description:
|
||||
|
||||
libc++ for Chromium.
|
||||
This is intended for instrumented builds, not for release.
|
||||
There was no security review for this library.
|
|
@ -0,0 +1,126 @@
|
|||
# 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.
|
||||
|
||||
{
|
||||
'variables': {
|
||||
'libcxx_root': '../../packager/buildtools/third_party/libc++',
|
||||
},
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'libcxx_proxy',
|
||||
'type': 'none',
|
||||
'toolsets': ['host', 'target'],
|
||||
'dependencies=': [
|
||||
'libc++',
|
||||
],
|
||||
# Do not add dependency on libc++.so to dependents of this target. We
|
||||
# don't want to pass libc++.so on the command line to the linker, as that
|
||||
# would cause it to be linked into C executables which don't need it.
|
||||
# Instead, we supply -stdlib=libc++ and let the clang driver decide.
|
||||
'dependencies_traverse': 0,
|
||||
'variables': {
|
||||
# Don't add this target to the dependencies of targets with type=none.
|
||||
'link_dependency': 1,
|
||||
},
|
||||
'all_dependent_settings': {
|
||||
'target_conditions': [
|
||||
['_type!="none"', {
|
||||
'cflags_cc': [
|
||||
'-nostdinc++',
|
||||
'-isystem<(libcxx_root)/trunk/include',
|
||||
'-isystem<(libcxx_root)/../libc++abi/trunk/include',
|
||||
],
|
||||
'ldflags': [
|
||||
'-stdlib=libc++',
|
||||
# Normally the generator takes care of RPATH. Our case is special
|
||||
# because the generator is unaware of the libc++.so dependency.
|
||||
# Note that setting RPATH here is a potential security issue. See:
|
||||
# https://code.google.com/p/gyp/issues/detail?id=315
|
||||
'-Wl,-rpath,\$$ORIGIN/lib/',
|
||||
],
|
||||
'library_dirs': [
|
||||
'<(PRODUCT_DIR)/lib/',
|
||||
],
|
||||
}],
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
'target_name': 'libc++',
|
||||
'type': 'shared_library',
|
||||
'toolsets': ['host', 'target'],
|
||||
'dependencies=': [
|
||||
# libc++abi is linked statically into libc++.so. This allows us to get
|
||||
# both libc++ and libc++abi by passing '-stdlib=libc++'. If libc++abi
|
||||
# was a separate DSO, we'd have to link against it explicitly.
|
||||
'../libc++abi/libc++abi.gyp:libc++abi',
|
||||
],
|
||||
'sources': [
|
||||
'trunk/src/algorithm.cpp',
|
||||
'trunk/src/any.cpp',
|
||||
'trunk/src/bind.cpp',
|
||||
'trunk/src/chrono.cpp',
|
||||
'trunk/src/condition_variable.cpp',
|
||||
'trunk/src/debug.cpp',
|
||||
'trunk/src/exception.cpp',
|
||||
'trunk/src/future.cpp',
|
||||
'trunk/src/hash.cpp',
|
||||
'trunk/src/ios.cpp',
|
||||
'trunk/src/iostream.cpp',
|
||||
'trunk/src/locale.cpp',
|
||||
'trunk/src/memory.cpp',
|
||||
'trunk/src/mutex.cpp',
|
||||
'trunk/src/new.cpp',
|
||||
'trunk/src/optional.cpp',
|
||||
'trunk/src/random.cpp',
|
||||
'trunk/src/regex.cpp',
|
||||
'trunk/src/shared_mutex.cpp',
|
||||
'trunk/src/stdexcept.cpp',
|
||||
'trunk/src/string.cpp',
|
||||
'trunk/src/strstream.cpp',
|
||||
'trunk/src/system_error.cpp',
|
||||
'trunk/src/thread.cpp',
|
||||
'trunk/src/typeinfo.cpp',
|
||||
'trunk/src/utility.cpp',
|
||||
'trunk/src/valarray.cpp',
|
||||
],
|
||||
'cflags': [
|
||||
'-fPIC',
|
||||
'-fstrict-aliasing',
|
||||
'-pthread',
|
||||
],
|
||||
'cflags_cc': [
|
||||
'-nostdinc++',
|
||||
'-isystem<(libcxx_root)/trunk/include',
|
||||
'-isystem<(libcxx_root)/../libc++abi/trunk/include',
|
||||
'-std=c++11',
|
||||
],
|
||||
'cflags_cc!': [
|
||||
'-fno-exceptions',
|
||||
'-fno-rtti',
|
||||
],
|
||||
'cflags!': [
|
||||
'-fvisibility=hidden',
|
||||
],
|
||||
'defines': [
|
||||
'LIBCXX_BUILDING_LIBCXXABI',
|
||||
],
|
||||
'ldflags': [
|
||||
'-nodefaultlibs',
|
||||
],
|
||||
'ldflags!': [
|
||||
# -nodefaultlibs turns -pthread into a no-op, causing an unused argument
|
||||
# warning. Explicitly link with -lpthread instead.
|
||||
'-pthread',
|
||||
],
|
||||
'libraries': [
|
||||
'-lc',
|
||||
'-lgcc_s',
|
||||
'-lm',
|
||||
'-lpthread',
|
||||
'-lrt',
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
# 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.
|
||||
|
||||
config("libc++abi_warnings") {
|
||||
if (is_clang) {
|
||||
# http://llvm.org/PR25978
|
||||
cflags = [ "-Wno-unused-function" ]
|
||||
}
|
||||
}
|
||||
|
||||
static_library("libc++abi") {
|
||||
sources = [
|
||||
"trunk/src/abort_message.cpp",
|
||||
"trunk/src/cxa_aux_runtime.cpp",
|
||||
"trunk/src/cxa_default_handlers.cpp",
|
||||
"trunk/src/cxa_demangle.cpp",
|
||||
"trunk/src/cxa_exception.cpp",
|
||||
"trunk/src/cxa_exception_storage.cpp",
|
||||
"trunk/src/cxa_guard.cpp",
|
||||
"trunk/src/cxa_handlers.cpp",
|
||||
"trunk/src/cxa_new_delete.cpp",
|
||||
"trunk/src/cxa_personality.cpp",
|
||||
"trunk/src/cxa_thread_atexit.cpp",
|
||||
"trunk/src/cxa_unexpected.cpp",
|
||||
"trunk/src/cxa_vector.cpp",
|
||||
"trunk/src/cxa_virtual.cpp",
|
||||
"trunk/src/exception.cpp",
|
||||
"trunk/src/private_typeinfo.cpp",
|
||||
"trunk/src/stdexcept.cpp",
|
||||
"trunk/src/typeinfo.cpp",
|
||||
]
|
||||
configs -= [
|
||||
"//build/config/compiler:chromium_code",
|
||||
"//build/config/compiler:no_rtti",
|
||||
"//build/config/gcc:no_exceptions",
|
||||
"//build/config/gcc:symbol_visibility_hidden",
|
||||
]
|
||||
configs += [
|
||||
"//build/config/compiler:no_chromium_code",
|
||||
"//build/config/compiler:rtti",
|
||||
"//build/config/gcc:symbol_visibility_default",
|
||||
"//buildtools/third_party/libc++:config",
|
||||
# Must be after no_chromium_code.
|
||||
":libc++abi_warnings",
|
||||
]
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
Name: libcxxabi
|
||||
Short Name: libc++abi
|
||||
URL: http://libcxxabi.llvm.org/
|
||||
Version: 1.0
|
||||
License: MIT, University of Illinois/NCSA Open Source License
|
||||
License File: trunk/LICENSE.TXT
|
||||
Security Critical: no
|
||||
|
||||
Description:
|
||||
|
||||
libc++abi for Chromium.
|
||||
This is intended for instrumented builds, not for release.
|
||||
There was no security review for this library.
|
|
@ -0,0 +1,58 @@
|
|||
# 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.
|
||||
|
||||
{
|
||||
'targets': [
|
||||
{
|
||||
'target_name': 'libc++abi',
|
||||
'type': 'static_library',
|
||||
'toolsets': ['host', 'target'],
|
||||
'dependencies=': [],
|
||||
'sources': [
|
||||
'trunk/src/abort_message.cpp',
|
||||
'trunk/src/cxa_aux_runtime.cpp',
|
||||
'trunk/src/cxa_default_handlers.cpp',
|
||||
'trunk/src/cxa_demangle.cpp',
|
||||
'trunk/src/cxa_exception.cpp',
|
||||
'trunk/src/cxa_exception_storage.cpp',
|
||||
'trunk/src/cxa_guard.cpp',
|
||||
'trunk/src/cxa_handlers.cpp',
|
||||
'trunk/src/cxa_new_delete.cpp',
|
||||
'trunk/src/cxa_personality.cpp',
|
||||
'trunk/src/cxa_thread_atexit.cpp',
|
||||
'trunk/src/cxa_unexpected.cpp',
|
||||
'trunk/src/cxa_vector.cpp',
|
||||
'trunk/src/cxa_virtual.cpp',
|
||||
'trunk/src/exception.cpp',
|
||||
'trunk/src/private_typeinfo.cpp',
|
||||
'trunk/src/stdexcept.cpp',
|
||||
'trunk/src/typeinfo.cpp',
|
||||
],
|
||||
'include_dirs': [
|
||||
'trunk/include',
|
||||
'../libc++/trunk/include'
|
||||
],
|
||||
'variables': {
|
||||
'clang_warning_flags': [
|
||||
# http://llvm.org/PR25978
|
||||
'-Wno-unused-function',
|
||||
],
|
||||
},
|
||||
'cflags': [
|
||||
'-fPIC',
|
||||
'-fstrict-aliasing',
|
||||
'-nostdinc++',
|
||||
'-pthread',
|
||||
'-std=c++11',
|
||||
],
|
||||
'cflags_cc!': [
|
||||
'-fno-exceptions',
|
||||
'-fno-rtti',
|
||||
],
|
||||
'cflags!': [
|
||||
'-fvisibility=hidden',
|
||||
],
|
||||
},
|
||||
]
|
||||
}
|
|
@ -75,8 +75,12 @@ TEST_F(ClosureThreadTest, Basic) {
|
|||
}
|
||||
|
||||
TEST_F(ClosureThreadTest, CheckInteraction) {
|
||||
base::WaitableEvent event_in_thread(true, false);
|
||||
base::WaitableEvent event_in_main(true, false);
|
||||
base::WaitableEvent event_in_thread(
|
||||
base::WaitableEvent::ResetPolicy::MANUAL,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED);
|
||||
base::WaitableEvent event_in_main(
|
||||
base::WaitableEvent::ResetPolicy::MANUAL,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED);
|
||||
set_val(8);
|
||||
|
||||
// Expect the operation to be invoked twice:
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "packager/media/base/fixed_key_source.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_number_conversions.h"
|
||||
|
||||
|
|
|
@ -40,8 +40,8 @@ bool ValidateSegmentTemplate(const std::string& segment_template) {
|
|||
if (segment_template.empty())
|
||||
return false;
|
||||
|
||||
std::vector<std::string> splits;
|
||||
base::SplitString(segment_template, '$', &splits);
|
||||
std::vector<std::string> splits = base::SplitString(
|
||||
segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
|
||||
|
||||
// ISO/IEC 23009-1:2012 5.3.9.4.4 Template-based Segment URL construction.
|
||||
// Allowed identifiers: $$, $RepresentationID$, $Number$, $Bandwidth$, $Time$.
|
||||
|
@ -105,8 +105,8 @@ std::string GetSegmentName(const std::string& segment_template,
|
|||
uint32_t bandwidth) {
|
||||
DCHECK(ValidateSegmentTemplate(segment_template));
|
||||
|
||||
std::vector<std::string> splits;
|
||||
base::SplitString(segment_template, '$', &splits);
|
||||
std::vector<std::string> splits = base::SplitString(
|
||||
segment_template, "$", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
|
||||
// "$" always appears in pairs, so there should be odd number of splits.
|
||||
DCHECK_EQ(1u, splits.size() % 2);
|
||||
|
||||
|
|
|
@ -301,7 +301,10 @@ enum Operation {
|
|||
class MultiThreadProducerConsumerQueueStopTest
|
||||
: public ::testing::TestWithParam<Operation> {
|
||||
public:
|
||||
MultiThreadProducerConsumerQueueStopTest() : queue_(1), event_(true, false) {}
|
||||
MultiThreadProducerConsumerQueueStopTest()
|
||||
: queue_(1),
|
||||
event_(base::WaitableEvent::ResetPolicy::MANUAL,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED) {}
|
||||
~MultiThreadProducerConsumerQueueStopTest() override {}
|
||||
|
||||
public:
|
||||
|
|
|
@ -144,7 +144,8 @@ WidevineKeySource::WidevineKeySource(const std::string& server_url,
|
|||
crypto_period_count_(kDefaultCryptoPeriodCount),
|
||||
add_common_pssh_(add_common_pssh),
|
||||
key_production_started_(false),
|
||||
start_key_production_(false, false),
|
||||
start_key_production_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED),
|
||||
first_crypto_period_index_(0) {
|
||||
key_production_thread_.Start();
|
||||
}
|
||||
|
|
|
@ -99,8 +99,7 @@ std::string AVCDecoderConfigurationRecord::GetCodecString(
|
|||
uint8_t avc_level) {
|
||||
const uint8_t bytes[] = {profile_indication, profile_compatibility,
|
||||
avc_level};
|
||||
return "avc1." +
|
||||
base::StringToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
||||
return "avc1." + base::ToLowerASCII(base::HexEncode(bytes, arraysize(bytes)));
|
||||
}
|
||||
|
||||
} // namespace media
|
||||
|
|
|
@ -179,8 +179,8 @@ static const int kTableSarWidth[] = {
|
|||
static const int kTableSarHeight[] = {
|
||||
0, 1, 11, 11, 11, 33, 11, 11, 11, 33, 11, 11, 33, 99, 3, 2, 1
|
||||
};
|
||||
COMPILE_ASSERT(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
|
||||
sar_tables_must_have_same_size);
|
||||
static_assert(arraysize(kTableSarWidth) == arraysize(kTableSarHeight),
|
||||
"sar_tables_must_have_same_size");
|
||||
|
||||
H264Parser::H264Parser() {}
|
||||
|
||||
|
|
|
@ -12,9 +12,11 @@ namespace media {
|
|||
|
||||
// Utility function to create side data item for decoder buffer.
|
||||
template <typename T>
|
||||
void MakeSideData(T id_begin, T id_end,
|
||||
T settings_begin, T settings_end,
|
||||
std::vector<uint8>* side_data) {
|
||||
void MakeSideData(T id_begin,
|
||||
T id_end,
|
||||
T settings_begin,
|
||||
T settings_end,
|
||||
std::vector<uint8_t>* side_data) {
|
||||
// The DecoderBuffer only supports a single side data item. In the case of
|
||||
// a WebVTT cue, we can have potentially two side data items. In order to
|
||||
// avoid disrupting DecoderBuffer any more than we need to, we copy both
|
||||
|
|
|
@ -244,8 +244,8 @@ void SetContentProtectionFields(
|
|||
|
||||
std::string CreateUUIDString(const std::vector<uint8_t>& data) {
|
||||
DCHECK_EQ(16u, data.size());
|
||||
std::string uuid = base::HexEncode(data.data(), data.size());
|
||||
base::StringToLowerASCII(&uuid);
|
||||
std::string uuid =
|
||||
base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
|
||||
uuid.insert(20, "-");
|
||||
uuid.insert(16, "-");
|
||||
uuid.insert(12, "-");
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include <algorithm>
|
||||
#include <memory>
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/strings/string_util.h"
|
||||
#include "packager/media/file/local_file.h"
|
||||
#include "packager/media/file/memory_file.h"
|
||||
#include "packager/media/file/threaded_io_file.h"
|
||||
|
@ -57,7 +56,7 @@ bool DeleteLocalFile(const char* file_name) {
|
|||
}
|
||||
|
||||
File* CreateUdpFile(const char* file_name, const char* mode) {
|
||||
if (base::strcasecmp(mode, "r")) {
|
||||
if (strcmp(mode, "r")) {
|
||||
NOTIMPLEMENTED() << "UdpFile only supports read (receive) mode.";
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -160,14 +160,14 @@ TEST_F(LocalFileTest, WriteRead) {
|
|||
}
|
||||
|
||||
TEST_F(LocalFileTest, WriteFlushCheckSize) {
|
||||
const uint32 kNumCycles(10);
|
||||
const uint32 kNumWrites(10);
|
||||
const uint32_t kNumCycles(10);
|
||||
const uint32_t kNumWrites(10);
|
||||
|
||||
for (uint32 cycle_idx = 0; cycle_idx < kNumCycles; ++cycle_idx) {
|
||||
for (uint32_t cycle_idx = 0; cycle_idx < kNumCycles; ++cycle_idx) {
|
||||
// Write file using File API, using file name directly (without prefix).
|
||||
File* file = File::Open(local_file_name_no_prefix_.c_str(), "w");
|
||||
ASSERT_TRUE(file != NULL);
|
||||
for (uint32 write_idx = 0; write_idx < kNumWrites; ++write_idx)
|
||||
for (uint32_t write_idx = 0; write_idx < kNumWrites; ++write_idx)
|
||||
EXPECT_EQ(kDataSize, file->Write(data_.data(), kDataSize));
|
||||
ASSERT_NO_FATAL_FAILURE(file->Flush());
|
||||
EXPECT_TRUE(file->Close());
|
||||
|
|
|
@ -21,8 +21,10 @@ namespace media {
|
|||
|
||||
IoCache::IoCache(uint64_t cache_size)
|
||||
: cache_size_(cache_size),
|
||||
read_event_(false, false),
|
||||
write_event_(false, false),
|
||||
read_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED),
|
||||
write_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED),
|
||||
// Make the buffer one byte larger than the cache so that when the
|
||||
// condition r_ptr == w_ptr is unambiguous (buffer empty).
|
||||
circular_buffer_(cache_size + 1),
|
||||
|
|
|
@ -138,7 +138,7 @@ TEST_F(IoCacheTest, LotsOfUnalignedBlocks) {
|
|||
EXPECT_EQ(kUnalignBlockSize,
|
||||
cache_->Read(read_buffer1.data(), kUnalignBlockSize));
|
||||
EXPECT_EQ(write_buffer1, read_buffer1);
|
||||
std::vector<uint8> verify_buffer;
|
||||
std::vector<uint8_t> verify_buffer;
|
||||
for (uint64_t idx = 0; idx < kNumWrites; ++idx)
|
||||
verify_buffer.insert(verify_buffer.end(),
|
||||
write_buffer2.begin(),
|
||||
|
|
|
@ -30,9 +30,11 @@ ThreadedIoFile::ThreadedIoFile(std::unique_ptr<File, FileCloser> internal_file,
|
|||
size_(0),
|
||||
eof_(false),
|
||||
flushing_(false),
|
||||
flush_complete_event_(false, false),
|
||||
flush_complete_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED),
|
||||
internal_file_error_(0),
|
||||
task_exit_event_(false, false) {
|
||||
task_exit_event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
||||
base::WaitableEvent::InitialState::NOT_SIGNALED) {
|
||||
DCHECK(internal_file_);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@ Fragmenter::Fragmenter(scoped_refptr<StreamInfo> info, TrackFragment* traf)
|
|||
fragment_initialized_(false),
|
||||
fragment_finalized_(false),
|
||||
fragment_duration_(0),
|
||||
presentation_start_time_(kInvalidTime),
|
||||
earliest_presentation_time_(kInvalidTime),
|
||||
first_sap_time_(kInvalidTime) {
|
||||
DCHECK(traf);
|
||||
|
|
|
@ -90,7 +90,6 @@ class Fragmenter {
|
|||
bool fragment_initialized_;
|
||||
bool fragment_finalized_;
|
||||
uint64_t fragment_duration_;
|
||||
int64_t presentation_start_time_;
|
||||
int64_t earliest_presentation_time_;
|
||||
int64_t first_sap_time_;
|
||||
std::unique_ptr<BufferWriter> data_;
|
||||
|
|
|
@ -46,8 +46,8 @@ struct ProtectionPattern {
|
|||
uint8_t skip_byte_block;
|
||||
};
|
||||
|
||||
COMPILE_ASSERT(arraysize(kKeyRotationDefaultKeyId) == kCencKeyIdSize,
|
||||
cenc_key_id_must_be_size_16);
|
||||
static_assert(arraysize(kKeyRotationDefaultKeyId) == kCencKeyIdSize,
|
||||
"cenc_key_id_must_be_size_16");
|
||||
|
||||
uint64_t Rescale(uint64_t time_in_old_scale,
|
||||
uint32_t old_scale,
|
||||
|
|
|
@ -137,7 +137,6 @@ class Segmenter {
|
|||
std::vector<Fragmenter*> fragmenters_;
|
||||
std::vector<uint64_t> segment_durations_;
|
||||
std::map<const MediaStream*, uint32_t> stream_map_;
|
||||
bool end_of_segment_;
|
||||
MuxerListener* muxer_listener_;
|
||||
ProgressListener* progress_listener_;
|
||||
uint64_t progress_target_;
|
||||
|
|
|
@ -45,7 +45,7 @@ Status CreateContentEncryption(mkvmuxer::Track* track, EncryptionKey* key) {
|
|||
|
||||
if (!key->key_id.empty() &&
|
||||
!encoding->SetEncryptionID(
|
||||
reinterpret_cast<const uint8*>(key->key_id.data()),
|
||||
reinterpret_cast<const uint8_t*>(key->key_id.data()),
|
||||
key->key_id.size())) {
|
||||
return Status(error::INTERNAL_ERROR, "Error setting encryption ID.");
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ Status Encryptor::EncryptFrame(scoped_refptr<MediaSample> sample,
|
|||
memcpy(sample_data + kWebMSignalByteSize, encryptor_->iv().data(),
|
||||
iv_size);
|
||||
sample_data[kWebMSignalByteSize + kWebMIvSize] = num_partitions;
|
||||
uint32 partition_offset = 0;
|
||||
uint32_t partition_offset = 0;
|
||||
BufferWriter offsets_buffer(kWebMPartitionOffsetSize * num_partitions);
|
||||
for (const auto& vpx_frame : vpx_frames) {
|
||||
uint32_t encrypted_size =
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// encrypted request for comments specification is here
|
||||
// http://wiki.webmproject.org/encryption/webm-encryption-rfc
|
||||
|
||||
#include <iomanip>
|
||||
#include <limits>
|
||||
|
||||
#include "packager/base/logging.h"
|
||||
#include "packager/base/numerics/safe_conversions.h"
|
||||
|
@ -469,7 +469,7 @@ static int ParseWebMElementHeaderField(const uint8_t* buf,
|
|||
}
|
||||
|
||||
if (all_ones)
|
||||
*num = kint64max;
|
||||
*num = std::numeric_limits<int64_t>::max();
|
||||
|
||||
return bytes_used;
|
||||
}
|
||||
|
@ -492,7 +492,7 @@ int WebMParseElementHeader(const uint8_t* buf,
|
|||
if (num_id_bytes <= 0)
|
||||
return num_id_bytes;
|
||||
|
||||
if (tmp == kint64max)
|
||||
if (tmp == std::numeric_limits<int64_t>::max())
|
||||
tmp = kWebMReservedId;
|
||||
|
||||
*id = static_cast<int>(tmp);
|
||||
|
@ -504,7 +504,7 @@ int WebMParseElementHeader(const uint8_t* buf,
|
|||
if (num_size_bytes <= 0)
|
||||
return num_size_bytes;
|
||||
|
||||
if (tmp == kint64max)
|
||||
if (tmp == std::numeric_limits<int64_t>::max())
|
||||
tmp = kWebMUnknownSize;
|
||||
|
||||
*element_size = tmp;
|
||||
|
|
|
@ -91,7 +91,6 @@ namespace wvm {
|
|||
WvmMediaParser::WvmMediaParser()
|
||||
: is_initialized_(false),
|
||||
parse_state_(StartCode1),
|
||||
is_psm_needed_(true),
|
||||
skip_bytes_(0),
|
||||
metadata_is_complete_(false),
|
||||
current_program_id_(0),
|
||||
|
|
|
@ -223,7 +223,6 @@ class WvmMediaParser : public MediaParser {
|
|||
// Internal content parsing state.
|
||||
State parse_state_;
|
||||
|
||||
bool is_psm_needed_;
|
||||
uint32_t skip_bytes_;
|
||||
bool metadata_is_complete_;
|
||||
uint8_t current_program_id_;
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
#include "packager/media/test/test_data_util.h"
|
||||
|
||||
namespace {
|
||||
const int64_t kNoTimestamp = std::numeric_limits<int64_t>::min();
|
||||
const char kWvmFile[] = "bear-640x360.wvm";
|
||||
// Constants associated with kWvmFile follows.
|
||||
const uint32_t kExpectedStreams = 4;
|
||||
|
|
|
@ -37,8 +37,8 @@ TEST(BandwidthEstimatorTest, FiveBlocksFiveBlocksAdded) {
|
|||
18
|
||||
};
|
||||
|
||||
COMPILE_ASSERT(kNumBlocksForEstimate == arraysize(kExpectedResults),
|
||||
incorrect_number_of_expectations);
|
||||
static_assert(kNumBlocksForEstimate == arraysize(kExpectedResults),
|
||||
"incorrect_number_of_expectations");
|
||||
for (uint64_t i = 1; i <= arraysize(kExpectedResults); ++i) {
|
||||
be.AddBlock(i, kDuration);
|
||||
EXPECT_EQ(kExpectedResults[i - 1], be.Estimate());
|
||||
|
|
|
@ -1037,8 +1037,8 @@ TEST_F(CommonMpdBuilderTest,
|
|||
|
||||
// Then set 480p to be 5fps (10/2) so that maxFrameRate is set.
|
||||
const uint32_t k5FPSFrameDuration = 2;
|
||||
COMPILE_ASSERT(k5FPSFrameDuration < kSameFrameDuration,
|
||||
frame_duration_must_be_shorter_for_max_frame_rate);
|
||||
static_assert(k5FPSFrameDuration < kSameFrameDuration,
|
||||
"frame_duration_must_be_shorter_for_max_frame_rate");
|
||||
representation_480p->SetSampleDuration(k5FPSFrameDuration);
|
||||
|
||||
xml::scoped_xml_ptr<xmlNode> max_frame_rate(adaptation_set->GetXml());
|
||||
|
@ -1467,7 +1467,7 @@ TEST_F(StaticMpdBuilderTest, ForceSetsubsegmentAlignment) {
|
|||
// Use different starting times to make the segments "not aligned".
|
||||
const uint64_t kStartTime1 = 1u;
|
||||
const uint64_t kStartTime2 = 2u;
|
||||
COMPILE_ASSERT(kStartTime1 != kStartTime2, StartTimesShouldBeDifferent);
|
||||
static_assert(kStartTime1 != kStartTime2, "StartTimesShouldBeDifferent");
|
||||
const uint64_t kDuration = 10u;
|
||||
const uint64_t kAnySize = 19834u;
|
||||
representation_480p->AddNewSegment(kStartTime1, kDuration, kAnySize);
|
||||
|
@ -2427,9 +2427,9 @@ TEST_F(TimeShiftBufferDepthTest, HugeGap) {
|
|||
first_s_element_end_time +
|
||||
(kTimeShiftBufferDepth + 1) * DefaultTimeScale();
|
||||
const uint64_t kSecondSElementRepeat = 9;
|
||||
COMPILE_ASSERT(
|
||||
static_assert(
|
||||
kSecondSElementRepeat < static_cast<uint64_t>(kTimeShiftBufferDepth),
|
||||
second_s_element_repeat_must_be_less_than_time_shift_buffer_depth);
|
||||
"second_s_element_repeat_must_be_less_than_time_shift_buffer_depth");
|
||||
AddSegments(gap_s_element_start_time, kDuration, kSize, kSecondSElementRepeat);
|
||||
|
||||
std::string expected_s_element = base::StringPrintf(kSElementTemplate,
|
||||
|
|
|
@ -182,7 +182,7 @@ bool HexToUUID(const std::string& data, std::string* uuid_format) {
|
|||
}
|
||||
|
||||
const std::string hex_encoded =
|
||||
base::StringToLowerASCII(base::HexEncode(data.data(), data.size()));
|
||||
base::ToLowerASCII(base::HexEncode(data.data(), data.size()));
|
||||
DCHECK_EQ(hex_encoded.size(), kExpectedUUIDSize * 2);
|
||||
base::StringPiece all(hex_encoded);
|
||||
// Note UUID has 5 parts separated with dashes.
|
||||
|
|
|
@ -92,6 +92,12 @@
|
|||
],
|
||||
}],
|
||||
],
|
||||
'variables': {
|
||||
'clang_warning_flags': [
|
||||
# TODO(kqyang): Fix curl bug.
|
||||
'-Wno-varargs',
|
||||
],
|
||||
},
|
||||
'include_dirs': [
|
||||
'source/lib',
|
||||
'source/include',
|
||||
|
|
Loading…
Reference in New Issue