mirror of
https://bitbucket.org/chromiumembedded/cef
synced 2025-06-05 21:39:12 +02:00
mac: Convert cef_sandbox to a shared library (see #3928)
Replace statically linked cef_sandbox.a with dynamically loaded libcef_sandbox.dylib. See the SandboxSetup Wiki page for details.
This commit is contained in:
31
BUILD.gn
31
BUILD.gn
@ -1229,7 +1229,7 @@ if (is_win) {
|
||||
}
|
||||
|
||||
if (is_mac) {
|
||||
static_library("cef_sandbox") {
|
||||
shared_library("cef_sandbox") {
|
||||
sources = [ "libcef_dll/sandbox/sandbox_mac.mm" ]
|
||||
configs += [ ":libcef_includes_config" ]
|
||||
deps = [
|
||||
@ -1634,6 +1634,33 @@ if (is_mac) {
|
||||
]
|
||||
}
|
||||
|
||||
# We need to copy the CEF libraries so that the bundle_data dependencies have
|
||||
# a "copy" target type. Otherwise for "shared_library" target types it will
|
||||
# try to link things into the CEF Framework when we want to keep the libraries
|
||||
# separate instead.
|
||||
copy("cef_library_copy") {
|
||||
sources = [
|
||||
"$root_out_dir/libcef_sandbox.dylib",
|
||||
]
|
||||
outputs = [ "$root_out_dir/cef_intermediates/{{source_file_part}}" ]
|
||||
deps = [
|
||||
":cef_sandbox",
|
||||
]
|
||||
}
|
||||
|
||||
# Add the CEF .dylibs in the MODULE_DIR of the Framework app bundle.
|
||||
bundle_data("cef_framework_cef_binaries") {
|
||||
sources = [
|
||||
"$root_out_dir/cef_intermediates/libcef_sandbox.dylib",
|
||||
]
|
||||
outputs = [
|
||||
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
|
||||
]
|
||||
public_deps = [
|
||||
":cef_library_copy",
|
||||
]
|
||||
}
|
||||
|
||||
# Add the SwiftShader .dylibs in the MODULE_DIR of the Framework app bundle.
|
||||
bundle_data("cef_framework_swiftshader_binaries") {
|
||||
sources = [
|
||||
@ -1664,6 +1691,7 @@ if (is_mac) {
|
||||
|
||||
deps = libcef_deps_common + [
|
||||
":cef_framework_angle_binaries",
|
||||
":cef_framework_cef_binaries",
|
||||
":cef_framework_resources",
|
||||
":cef_framework_swiftshader_binaries",
|
||||
]
|
||||
@ -1828,7 +1856,6 @@ if (is_mac) {
|
||||
|
||||
deps = [
|
||||
":cef_make_headers",
|
||||
":cef_sandbox",
|
||||
":libcef_dll_wrapper",
|
||||
]
|
||||
if (defined(invoker.helper_deps)) {
|
||||
|
@ -166,6 +166,7 @@
|
||||
],
|
||||
'libcef_dll_wrapper_sources_mac': [
|
||||
'libcef_dll/wrapper/cef_library_loader_mac.mm',
|
||||
'libcef_dll/wrapper/cef_scoped_sandbox_context_mac.mm',
|
||||
'libcef_dll/wrapper/libcef_dll_dylib.cc',
|
||||
],
|
||||
'shared_sources_browser': [
|
||||
|
@ -48,14 +48,8 @@ extern "C" {
|
||||
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
|
||||
/// directly accessing system resources. This helps to protect the user from
|
||||
/// untrusted and potentially malicious Web content. See
|
||||
/// http://www.chromium.org/developers/design-documents/sandbox for complete
|
||||
/// details.
|
||||
///
|
||||
/// To enable the sandbox on macOS the following requirements must be met:
|
||||
/// 1. Link the helper process executable with the cef_sandbox static library.
|
||||
/// 2. Call the cef_sandbox_initialize() function at the beginning of the
|
||||
/// helper executable main() function and before loading the CEF framework
|
||||
/// library. See include/wrapper/cef_library_loader.h for example usage.
|
||||
/// https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md for usage
|
||||
/// details. See include/wrapper/cef_library_loader.h for example usage.
|
||||
///
|
||||
|
||||
///
|
||||
@ -76,7 +70,7 @@ CEF_EXPORT void cef_sandbox_destroy(void* sandbox_context);
|
||||
///
|
||||
/// Scoped helper for managing the life span of a sandbox context handle.
|
||||
///
|
||||
class CEF_EXPORT CefScopedSandboxContext {
|
||||
class CefScopedSandboxContext final {
|
||||
public:
|
||||
CefScopedSandboxContext();
|
||||
~CefScopedSandboxContext();
|
||||
@ -87,7 +81,8 @@ class CEF_EXPORT CefScopedSandboxContext {
|
||||
bool Initialize(int argc, char** argv);
|
||||
|
||||
private:
|
||||
void* sandbox_context_;
|
||||
void* library_handle_ = nullptr;
|
||||
void* sandbox_context_ = nullptr;
|
||||
};
|
||||
#endif // __cplusplus
|
||||
|
||||
|
@ -50,38 +50,9 @@ extern "C" {
|
||||
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
|
||||
/// directly accessing system resources. This helps to protect the user from
|
||||
/// untrusted and potentially malicious Web content. See
|
||||
/// http://www.chromium.org/developers/design-documents/sandbox for complete
|
||||
/// https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md for usage
|
||||
/// details.
|
||||
///
|
||||
/// To enable the sandbox on Windows the same executable must be used for all
|
||||
/// processes (browser process and sub-processes). This executable must link the
|
||||
/// cef_sandbox static library and initialize the sandbox by calling
|
||||
/// cef_sandbox_info_create. The resulting |sandbox_info| value must then be
|
||||
/// passed to CefExecuteProcess and CefInitialize.
|
||||
///
|
||||
/// Beginning with M138 the cef_sandbox static library can only be linked with
|
||||
/// applications built as part of the CEF/Chromium build. This is due to
|
||||
/// unavoidable dependencies on Chromium's bundled Clang/LLVM/libc++ toolchain.
|
||||
/// Client applications therefore have 3 options for sandbox integration:
|
||||
///
|
||||
/// 1. Build the client application (or a custom bootstrap executable) as part
|
||||
/// of the CEF/Chromium build using Chromium's bundled Clang/LLVM/libc++
|
||||
/// toolchain. For details of this option see
|
||||
/// https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md
|
||||
/// 2. Build the client application as a DLL using any toolchain and run using
|
||||
/// the provided bootstrap.exe or bootstrapc.exe. The DLL implements
|
||||
/// RunWinMain or RunConsoleMain respectively and gets passed the
|
||||
/// |sandbox_info| parameter which it then forwards to CefExecuteProcess
|
||||
/// and CefInitialize. The provided bootstrap executables can optionally be
|
||||
/// renamed or modified [1] to meet client branding needs.
|
||||
/// 3. Build the client application as an executable using any toolchain with
|
||||
/// the sandbox disabled. Pass nullptr as the |sandbox_info| parameter to
|
||||
/// CefExecuteProcess and CefInitialize.
|
||||
///
|
||||
/// [1] Embedded executable resources such as icons and file properties can be
|
||||
/// modified using Visual Studio or Resource Hacker tools. Be sure to code
|
||||
/// sign all binaries after modification and before distribution to users.
|
||||
///
|
||||
|
||||
///
|
||||
/// Create the sandbox information object for this process. It is safe to create
|
||||
@ -101,7 +72,7 @@ void cef_sandbox_info_destroy(void* sandbox_info);
|
||||
///
|
||||
/// Manages the life span of a sandbox information object.
|
||||
///
|
||||
class CefScopedSandboxInfo {
|
||||
class CefScopedSandboxInfo final {
|
||||
public:
|
||||
CefScopedSandboxInfo() { sandbox_info_ = cef_sandbox_info_create(); }
|
||||
~CefScopedSandboxInfo() { cef_sandbox_info_destroy(sandbox_info_); }
|
||||
|
@ -84,7 +84,8 @@ int cef_unload_library(void);
|
||||
/// #include "include/wrapper/cef_library_loader.h"
|
||||
///
|
||||
/// int main(int argc, char* argv[]) {
|
||||
/// // Initialize the macOS sandbox for this helper process.
|
||||
/// // Dynamically load and initialize the macOS sandbox for this helper
|
||||
/// // process.
|
||||
/// CefScopedSandboxContext sandbox_context;
|
||||
/// if (!sandbox_context.Initialize(argc, argv))
|
||||
/// return 1;
|
||||
|
@ -47,19 +47,3 @@ void cef_sandbox_destroy(void* sandbox_context) {
|
||||
delete static_cast<sandbox::SeatbeltExecServer::CreateFromArgumentsResult*>(
|
||||
sandbox_context);
|
||||
}
|
||||
|
||||
CefScopedSandboxContext::CefScopedSandboxContext() : sandbox_context_(NULL) {}
|
||||
|
||||
CefScopedSandboxContext::~CefScopedSandboxContext() {
|
||||
if (sandbox_context_) {
|
||||
cef_sandbox_destroy(sandbox_context_);
|
||||
}
|
||||
}
|
||||
|
||||
bool CefScopedSandboxContext::Initialize(int argc, char** argv) {
|
||||
if (sandbox_context_) {
|
||||
return false;
|
||||
}
|
||||
sandbox_context_ = cef_sandbox_initialize(argc, argv);
|
||||
return !!sandbox_context_;
|
||||
}
|
||||
|
113
libcef_dll/wrapper/cef_scoped_sandbox_context_mac.mm
Normal file
113
libcef_dll/wrapper/cef_scoped_sandbox_context_mac.mm
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2025 The Chromium Embedded Framework Authors. Portions 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.
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
#include "include/cef_sandbox_mac.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Relative path to the library from the Helper executable.
|
||||
constexpr char kLibraryPath[] =
|
||||
"../../../Chromium Embedded Framework.framework/"
|
||||
"Libraries/libcef_sandbox.dylib";
|
||||
|
||||
std::string GetLibraryPath() {
|
||||
uint32_t exec_path_size = 0;
|
||||
int rv = _NSGetExecutablePath(NULL, &exec_path_size);
|
||||
if (rv != -1) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
std::unique_ptr<char[]> exec_path(new char[exec_path_size]);
|
||||
rv = _NSGetExecutablePath(exec_path.get(), &exec_path_size);
|
||||
if (rv != 0) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Get the directory path of the executable.
|
||||
const char* parent_dir = dirname(exec_path.get());
|
||||
if (!parent_dir) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
// Append the relative path to the library.
|
||||
std::stringstream ss;
|
||||
ss << parent_dir << "/" << kLibraryPath;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void* LoadLibrary(const char* path) {
|
||||
void* handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
|
||||
if (!handle) {
|
||||
fprintf(stderr, "dlopen %s: %s\n", path, dlerror());
|
||||
return nullptr;
|
||||
}
|
||||
return handle;
|
||||
}
|
||||
|
||||
void UnloadLibrary(void* handle) {
|
||||
// Returns 0 on success.
|
||||
if (dlclose(handle)) {
|
||||
fprintf(stderr, "dlclose: %s\n", dlerror());
|
||||
}
|
||||
}
|
||||
|
||||
void* GetLibraryPtr(void* handle, const char* name) {
|
||||
void* ptr = dlsym(handle, name);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "dlsym: %s\n", dlerror());
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void* SandboxInitialize(void* handle, int argc, char** argv) {
|
||||
if (auto* ptr = (decltype(&cef_sandbox_initialize))GetLibraryPtr(
|
||||
handle, "cef_sandbox_initialize")) {
|
||||
return ptr(argc, argv);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SandboxDestroy(void* handle, void* sandbox_context) {
|
||||
if (auto* ptr = (decltype(&cef_sandbox_destroy))GetLibraryPtr(
|
||||
handle, "cef_sandbox_destroy")) {
|
||||
ptr(sandbox_context);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CefScopedSandboxContext::CefScopedSandboxContext() = default;
|
||||
|
||||
CefScopedSandboxContext::~CefScopedSandboxContext() {
|
||||
if (library_handle_) {
|
||||
if (sandbox_context_) {
|
||||
SandboxDestroy(library_handle_, sandbox_context_);
|
||||
}
|
||||
UnloadLibrary(library_handle_);
|
||||
}
|
||||
}
|
||||
|
||||
bool CefScopedSandboxContext::Initialize(int argc, char** argv) {
|
||||
if (!library_handle_) {
|
||||
const std::string& library_path = GetLibraryPath();
|
||||
if (library_path.empty()) {
|
||||
fprintf(stderr, "App does not have the expected bundle structure.\n");
|
||||
return false;
|
||||
}
|
||||
library_handle_ = LoadLibrary(library_path.c_str());
|
||||
}
|
||||
if (!library_handle_ || sandbox_context_) {
|
||||
return false;
|
||||
}
|
||||
sandbox_context_ = SandboxInitialize(library_handle_, argc, argv);
|
||||
return !!sandbox_context_;
|
||||
}
|
@ -757,13 +757,13 @@ parser.add_option(
|
||||
action='store_true',
|
||||
dest='sandboxdistrib',
|
||||
default=False,
|
||||
help='Create a cef_sandbox static library distribution.')
|
||||
help='Create a sandbox distribution.')
|
||||
parser.add_option(
|
||||
'--sandbox-distrib-only',
|
||||
action='store_true',
|
||||
dest='sandboxdistribonly',
|
||||
default=False,
|
||||
help='Create a cef_sandbox static library distribution only.')
|
||||
help='Create a sandbox distribution only.')
|
||||
parser.add_option(
|
||||
'--tools-distrib',
|
||||
action='store_true',
|
||||
@ -911,18 +911,23 @@ if platform == 'mac' and not (options.x64build or options.arm64build):
|
||||
'Add --x64-build or --arm64-build flag to generate a 64-bit build.')
|
||||
sys.exit(1)
|
||||
|
||||
# Platforms that build a cef_sandbox library in a separate output directory.
|
||||
sandbox_lib_platforms = ['mac']
|
||||
# Platforms that build a cef_sandbox static library in a separate output directory.
|
||||
sandbox_static_platforms = []
|
||||
|
||||
# Platforms that build a cef_sandbox shared library in the same output directory.
|
||||
sandbox_shared_platforms = []
|
||||
|
||||
# Platforms that build a bootstrap executable in the same output directory.
|
||||
bootstrap_exe_platforms = []
|
||||
|
||||
if branch_is_7151_or_older:
|
||||
sandbox_lib_platforms.append('windows')
|
||||
sandbox_static_platforms.extend(['windows', 'mac'])
|
||||
else:
|
||||
bootstrap_exe_platforms.append('windows')
|
||||
sandbox_shared_platforms.append('mac')
|
||||
|
||||
if not platform in sandbox_lib_platforms and \
|
||||
if not platform in sandbox_static_platforms and \
|
||||
not platform in sandbox_shared_platforms and \
|
||||
not platform in bootstrap_exe_platforms and \
|
||||
(options.sandboxdistrib or options.sandboxdistribonly):
|
||||
print('The sandbox distribution is not supported on this platform.')
|
||||
@ -1362,7 +1367,7 @@ if not options.nobuild and (chromium_checkout_changed or \
|
||||
os.path.join(download_dir, 'build-%s-debug.log' % (cef_branch)) \
|
||||
if options.buildlogfile else None)
|
||||
|
||||
if platform in sandbox_lib_platforms:
|
||||
if platform in sandbox_static_platforms:
|
||||
# Make the separate cef_sandbox build when GN is_official_build=true.
|
||||
build_path += '_sandbox'
|
||||
if os.path.exists(os.path.join(chromium_src_dir, build_path)):
|
||||
@ -1383,7 +1388,7 @@ if not options.nobuild and (chromium_checkout_changed or \
|
||||
os.path.join(download_dir, 'build-%s-release.log' % (cef_branch)) \
|
||||
if options.buildlogfile else None)
|
||||
|
||||
if platform in sandbox_lib_platforms:
|
||||
if platform in sandbox_static_platforms:
|
||||
# Make the separate cef_sandbox build when GN is_official_build=true.
|
||||
build_path += '_sandbox'
|
||||
if os.path.exists(os.path.join(chromium_src_dir, build_path)):
|
||||
|
@ -1,9 +1,9 @@
|
||||
CONTENTS
|
||||
--------
|
||||
|
||||
Debug Contains the Debug build of cef_sandbox.a.
|
||||
Debug Contains the Debug build of libcef_sandbox.dylib
|
||||
|
||||
Release Contains the Release build of cef_sandbox.a.
|
||||
Release Contains the Release build of libcef_sandbox.dylib
|
||||
|
||||
|
||||
USAGE
|
||||
@ -11,4 +11,4 @@ USAGE
|
||||
|
||||
Please visit the CEF Website for usage information.
|
||||
|
||||
https://bitbucket.org/chromiumembedded/cef/
|
||||
https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md
|
||||
|
@ -518,47 +518,6 @@ def GetConfigArgs(args, is_debug, cpu):
|
||||
return result
|
||||
|
||||
|
||||
def GetConfigArgsSandbox(platform, args, is_debug, cpu):
|
||||
"""
|
||||
Return merged GN args for the cef_sandbox configuration and validate.
|
||||
"""
|
||||
add_args = {
|
||||
# Avoid libucrt.lib linker errors.
|
||||
'use_allocator_shim': False,
|
||||
|
||||
# PartitionAlloc is selected as the default allocator in some cases.
|
||||
# We can't use it because it requires use_allocator_shim=true.
|
||||
'use_partition_alloc_as_malloc': False,
|
||||
'use_partition_alloc': False,
|
||||
|
||||
# These require use_partition_alloc_as_malloc=true, so disable them.
|
||||
'enable_backup_ref_ptr_support': False,
|
||||
'enable_dangling_raw_ptr_checks': False,
|
||||
'enable_dangling_raw_ptr_feature_flag': False,
|
||||
|
||||
# Avoid /LTCG linker warnings and generate smaller lib files.
|
||||
'is_official_build': False,
|
||||
|
||||
# Disable use of thin archives with lld. Thin archives contain just the
|
||||
# symbol table and the path to find the original .o files. They are
|
||||
# generally incompatible with default platform ld/link versions and
|
||||
# shouldn't be distributed due to the external .o file dependencies.
|
||||
'use_thin_archives': False,
|
||||
}
|
||||
|
||||
if not is_debug:
|
||||
# Disable DCHECKs in Release builds.
|
||||
add_args['dcheck_always_on'] = False
|
||||
|
||||
result = MergeDicts(args, add_args, {
|
||||
'is_debug': is_debug,
|
||||
'target_cpu': cpu,
|
||||
})
|
||||
|
||||
ValidateArgs(result, is_debug)
|
||||
return result
|
||||
|
||||
|
||||
def LinuxSysrootExists(cpu):
|
||||
"""
|
||||
Returns true if the sysroot for the specified |cpu| architecture exists.
|
||||
@ -632,14 +591,6 @@ def GetAllPlatformConfigs(build_args, quiet=False):
|
||||
result['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu)
|
||||
result['Release_GN_' + cpu] = GetConfigArgs(args, False, cpu)
|
||||
|
||||
if platform == 'mac' and GetArgValue(args, 'is_official_build'):
|
||||
# Build cef_sandbox.lib with a different configuration.
|
||||
if create_debug:
|
||||
result['Debug_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox(
|
||||
platform, args, True, cpu)
|
||||
result['Release_GN_' + cpu + '_sandbox'] = GetConfigArgsSandbox(
|
||||
platform, args, False, cpu)
|
||||
|
||||
out_configs = os.environ.get('GN_OUT_CONFIGS', None)
|
||||
if not out_configs is None:
|
||||
# Only generate the specified configurations.
|
||||
|
@ -165,7 +165,11 @@ def create_readme():
|
||||
'licensing terms and conditions.'
|
||||
elif mode == 'sandbox':
|
||||
distrib_type = 'Sandbox'
|
||||
distrib_desc = 'This distribution contains only the cef_sandbox static library. Please see\n' \
|
||||
if platform == 'windows':
|
||||
distrib_desc = 'This distribution contains only the bootstrap executables. Please see\n' \
|
||||
'the LICENSING section of this document for licensing terms and conditions.'
|
||||
elif platform == 'mac':
|
||||
distrib_desc = 'This distribution contains only the cef_sandbox dynamic library. Please see\n' \
|
||||
'the LICENSING section of this document for licensing terms and conditions.'
|
||||
elif mode == 'tools':
|
||||
distrib_type = 'Tools'
|
||||
@ -520,113 +524,6 @@ def copy_files_list(build_dir, dst_dir, paths):
|
||||
raise Exception('Missing required path: %s' % source_path)
|
||||
|
||||
|
||||
def get_exported_symbols(file):
|
||||
""" Returns the global symbols exported by |file|. """
|
||||
symbols = []
|
||||
|
||||
# Each symbol line has a value like:
|
||||
# 0000000000000000 T _cef_sandbox_initialize
|
||||
cmdline = 'nm -g -U %s' % file
|
||||
result = exec_cmd(cmdline, os.path.join(cef_dir, 'tools'))
|
||||
if len(result['err']) > 0:
|
||||
raise Exception('ERROR: nm failed: %s' % result['err'])
|
||||
for line in result['out'].split('\n'):
|
||||
if line.find(' T ') < 0:
|
||||
continue
|
||||
symbol = line[line.rfind(' ') + 1:]
|
||||
symbols.append(symbol)
|
||||
|
||||
return symbols
|
||||
|
||||
|
||||
def get_undefined_symbols(file):
|
||||
""" Returns the undefined symbols imported by |file|. """
|
||||
symbols = []
|
||||
|
||||
# Each symbol line has a value like:
|
||||
# cef_sandbox.a:cef_sandbox.o: _memcpy
|
||||
cmdline = 'nm -u -A %s' % file
|
||||
result = exec_cmd(cmdline, os.path.join(cef_dir, 'tools'))
|
||||
if len(result['err']) > 0:
|
||||
raise Exception('ERROR: nm failed: %s' % result['err'])
|
||||
for line in result['out'].split('\n'):
|
||||
if line.find(': ') < 0:
|
||||
continue
|
||||
symbol = line[line.rfind(': ') + 2:]
|
||||
symbols.append(symbol)
|
||||
|
||||
return symbols
|
||||
|
||||
|
||||
def combine_libs(platform, build_dir, libs, dest_lib):
|
||||
""" Combine multiple static libraries into a single static library. """
|
||||
intermediate_obj = None
|
||||
if platform == 'mac':
|
||||
# Find CEF_EXPORT symbols from libcef_sandbox.a (include/cef_sandbox_mac.h)
|
||||
# Export only symbols that include these strings.
|
||||
symbol_match = [
|
||||
'_cef_', # C symbols
|
||||
'Cef', # C++ symbols
|
||||
]
|
||||
|
||||
print('Finding exported symbols...')
|
||||
assert 'libcef_sandbox.a' in libs[0], libs[0]
|
||||
symbols = []
|
||||
for symbol in get_exported_symbols(os.path.join(build_dir, libs[0])):
|
||||
for match in symbol_match:
|
||||
if symbol.find(match) >= 0:
|
||||
symbols.append(symbol)
|
||||
break
|
||||
assert len(symbols) > 0
|
||||
|
||||
# Create an intermediate object file that combines all other object files.
|
||||
# Symbols not identified above will be made private (local).
|
||||
intermediate_obj = os.path.splitext(dest_lib)[0] + '.o'
|
||||
arch = 'arm64' if options.arm64build else 'x86_64'
|
||||
cmdline = 'ld -arch %s -r -o "%s"' % (arch, intermediate_obj)
|
||||
for symbol in symbols:
|
||||
cmdline += ' -exported_symbol %s' % symbol
|
||||
else:
|
||||
raise Exception('Unsupported platform for combine_libs: %s' % platform)
|
||||
|
||||
for lib in libs:
|
||||
lib_path = os.path.join(build_dir, lib)
|
||||
for path in get_files(lib_path): # Expand wildcards in |lib_path|.
|
||||
if not path_exists(path):
|
||||
raise Exception('File not found: ' + path)
|
||||
cmdline += ' "%s"' % path
|
||||
run(cmdline, os.path.join(cef_dir, 'tools'))
|
||||
|
||||
if not intermediate_obj is None:
|
||||
# Create an archive file containing the new object file.
|
||||
cmdline = 'libtool -static -o "%s" "%s"' % (dest_lib, intermediate_obj)
|
||||
run(cmdline, os.path.join(cef_dir, 'tools'))
|
||||
remove_file(intermediate_obj)
|
||||
|
||||
# Verify that only the expected symbols are exported from the archive file.
|
||||
print('Verifying exported symbols...')
|
||||
result_symbols = get_exported_symbols(dest_lib)
|
||||
if set(symbols) != set(result_symbols):
|
||||
print('Expected', symbols)
|
||||
print('Got', result_symbols)
|
||||
raise Exception('Failure verifying exported symbols')
|
||||
|
||||
# Verify that no C++ symbols are imported by the archive file. If the
|
||||
# archive imports C++ symbols and the client app links an incompatible C++
|
||||
# library, the result will be undefined behavior.
|
||||
# For example, to avoid importing libc++ symbols the cef_sandbox target
|
||||
# should have a dependency on libc++abi. This dependency can be verified
|
||||
# with the following command:
|
||||
# gn path out/[config] //cef:cef_sandbox //buildtools/third_party/libc++abi
|
||||
print('Verifying imported (undefined) symbols...')
|
||||
undefined_symbols = get_undefined_symbols(dest_lib)
|
||||
cpp_symbols = list(
|
||||
filter(lambda symbol: symbol.startswith('__Z'), undefined_symbols))
|
||||
if cpp_symbols:
|
||||
print('Found C++ symbols:', cpp_symbols)
|
||||
raise Exception('Failure verifying imported (undefined) symbols')
|
||||
|
||||
|
||||
def run(command_line, working_dir):
|
||||
""" Run a command. """
|
||||
sys.stdout.write('-------- Running "'+command_line+'" in "'+\
|
||||
@ -1255,15 +1152,6 @@ elif platform == 'mac':
|
||||
framework_name = 'Chromium Embedded Framework'
|
||||
cefclient_app = 'cefclient.app'
|
||||
|
||||
cef_sandbox_lib = 'obj/cef/libcef_sandbox.a'
|
||||
sandbox_libs = [
|
||||
cef_sandbox_lib,
|
||||
'obj/sandbox/mac/libseatbelt.a',
|
||||
'obj/sandbox/mac/libseatbelt_proto.a',
|
||||
'obj/third_party/protobuf/libprotobuf_lite.a',
|
||||
'obj/buildtools/third_party/libc++/libc++/*.o',
|
||||
'obj/buildtools/third_party/libc++abi/libc++abi/*.o',
|
||||
]
|
||||
dsym_dirs = [
|
||||
'%s.dSYM' % framework_name,
|
||||
'libEGL.dylib.dSYM',
|
||||
@ -1271,25 +1159,15 @@ elif platform == 'mac':
|
||||
'libvk_swiftshader.dylib.dSYM',
|
||||
]
|
||||
|
||||
# Generate the cef_sandbox.a merged library. A separate *_sandbox build
|
||||
# should exist when GN is_official_build=true.
|
||||
if mode in ('standard', 'minimal', 'sandbox') and not options.nosandbox:
|
||||
dirs = {
|
||||
'Debug': (build_dir_debug + '_sandbox', build_dir_debug),
|
||||
'Release': (build_dir_release + '_sandbox', build_dir_release)
|
||||
}
|
||||
for dir_name in dirs.keys():
|
||||
for src_dir in dirs[dir_name]:
|
||||
if path_exists(os.path.join(src_dir, cef_sandbox_lib)):
|
||||
dst_dir = os.path.join(output_dir, dir_name)
|
||||
make_dir(dst_dir, options.quiet)
|
||||
combine_libs(platform, src_dir, sandbox_libs,
|
||||
os.path.join(dst_dir, 'cef_sandbox.a'))
|
||||
break
|
||||
sandbox_lib = 'libcef_sandbox.dylib'
|
||||
if mode == 'sandbox':
|
||||
# Only transfer the sandbox dSYM.
|
||||
dsym_dirs = []
|
||||
dsym_dirs.append('%s.dSYM' % sandbox_lib)
|
||||
|
||||
valid_build_dir = None
|
||||
|
||||
if mode == 'standard':
|
||||
if mode == 'standard' or mode == 'sandbox':
|
||||
# transfer Debug files
|
||||
build_dir = build_dir_debug
|
||||
if not options.allowpartial or path_exists(
|
||||
@ -1300,7 +1178,15 @@ elif platform == 'mac':
|
||||
framework_src_dir = os.path.join(
|
||||
build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' %
|
||||
(cefclient_app, framework_name))
|
||||
framework_dst_dir = os.path.join(dst_dir, '%s.framework' % framework_name)
|
||||
|
||||
if mode == 'sandbox':
|
||||
# Only transfer the sandbox library.
|
||||
copy_file(
|
||||
os.path.join(framework_src_dir, 'Libraries', sandbox_lib), dst_dir,
|
||||
options.quiet)
|
||||
else:
|
||||
framework_dst_dir = os.path.join(dst_dir,
|
||||
'%s.framework' % framework_name)
|
||||
copy_dir(framework_src_dir, framework_dst_dir, options.quiet)
|
||||
|
||||
if not options.nosymbols:
|
||||
@ -1318,7 +1204,6 @@ elif platform == 'mac':
|
||||
else:
|
||||
sys.stdout.write("No Debug build files.\n")
|
||||
|
||||
if mode != 'sandbox':
|
||||
# transfer Release files
|
||||
build_dir = build_dir_release
|
||||
if not options.allowpartial or path_exists(
|
||||
@ -1329,6 +1214,13 @@ elif platform == 'mac':
|
||||
framework_src_dir = os.path.join(
|
||||
build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' %
|
||||
(cefclient_app, framework_name))
|
||||
|
||||
if mode == 'sandbox':
|
||||
# Only transfer the sandbox library.
|
||||
copy_file(
|
||||
os.path.join(framework_src_dir, 'Libraries', sandbox_lib), dst_dir,
|
||||
options.quiet)
|
||||
else:
|
||||
if mode != 'client':
|
||||
framework_dst_dir = os.path.join(dst_dir,
|
||||
'%s.framework' % framework_name)
|
||||
|
Reference in New Issue
Block a user