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:
Marshall Greenblatt
2025-05-16 15:16:15 -04:00
parent 353b6fb138
commit cfaa10a746
11 changed files with 220 additions and 280 deletions

View File

@ -1229,7 +1229,7 @@ if (is_win) {
} }
if (is_mac) { if (is_mac) {
static_library("cef_sandbox") { shared_library("cef_sandbox") {
sources = [ "libcef_dll/sandbox/sandbox_mac.mm" ] sources = [ "libcef_dll/sandbox/sandbox_mac.mm" ]
configs += [ ":libcef_includes_config" ] configs += [ ":libcef_includes_config" ]
deps = [ 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. # Add the SwiftShader .dylibs in the MODULE_DIR of the Framework app bundle.
bundle_data("cef_framework_swiftshader_binaries") { bundle_data("cef_framework_swiftshader_binaries") {
sources = [ sources = [
@ -1664,6 +1691,7 @@ if (is_mac) {
deps = libcef_deps_common + [ deps = libcef_deps_common + [
":cef_framework_angle_binaries", ":cef_framework_angle_binaries",
":cef_framework_cef_binaries",
":cef_framework_resources", ":cef_framework_resources",
":cef_framework_swiftshader_binaries", ":cef_framework_swiftshader_binaries",
] ]
@ -1828,7 +1856,6 @@ if (is_mac) {
deps = [ deps = [
":cef_make_headers", ":cef_make_headers",
":cef_sandbox",
":libcef_dll_wrapper", ":libcef_dll_wrapper",
] ]
if (defined(invoker.helper_deps)) { if (defined(invoker.helper_deps)) {

View File

@ -166,6 +166,7 @@
], ],
'libcef_dll_wrapper_sources_mac': [ 'libcef_dll_wrapper_sources_mac': [
'libcef_dll/wrapper/cef_library_loader_mac.mm', 'libcef_dll/wrapper/cef_library_loader_mac.mm',
'libcef_dll/wrapper/cef_scoped_sandbox_context_mac.mm',
'libcef_dll/wrapper/libcef_dll_dylib.cc', 'libcef_dll/wrapper/libcef_dll_dylib.cc',
], ],
'shared_sources_browser': [ 'shared_sources_browser': [

View File

@ -48,14 +48,8 @@ extern "C" {
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from /// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
/// directly accessing system resources. This helps to protect the user from /// directly accessing system resources. This helps to protect the user from
/// untrusted and potentially malicious Web content. See /// 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. /// details. See include/wrapper/cef_library_loader.h for example usage.
///
/// 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.
/// ///
/// ///
@ -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. /// Scoped helper for managing the life span of a sandbox context handle.
/// ///
class CEF_EXPORT CefScopedSandboxContext { class CefScopedSandboxContext final {
public: public:
CefScopedSandboxContext(); CefScopedSandboxContext();
~CefScopedSandboxContext(); ~CefScopedSandboxContext();
@ -87,7 +81,8 @@ class CEF_EXPORT CefScopedSandboxContext {
bool Initialize(int argc, char** argv); bool Initialize(int argc, char** argv);
private: private:
void* sandbox_context_; void* library_handle_ = nullptr;
void* sandbox_context_ = nullptr;
}; };
#endif // __cplusplus #endif // __cplusplus

View File

@ -50,38 +50,9 @@ extern "C" {
/// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from /// The sandbox is used to restrict sub-processes (renderer, GPU, etc) from
/// directly accessing system resources. This helps to protect the user from /// directly accessing system resources. This helps to protect the user from
/// untrusted and potentially malicious Web content. See /// 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. /// 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 /// 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. /// Manages the life span of a sandbox information object.
/// ///
class CefScopedSandboxInfo { class CefScopedSandboxInfo final {
public: public:
CefScopedSandboxInfo() { sandbox_info_ = cef_sandbox_info_create(); } CefScopedSandboxInfo() { sandbox_info_ = cef_sandbox_info_create(); }
~CefScopedSandboxInfo() { cef_sandbox_info_destroy(sandbox_info_); } ~CefScopedSandboxInfo() { cef_sandbox_info_destroy(sandbox_info_); }

View File

@ -84,7 +84,8 @@ int cef_unload_library(void);
/// #include "include/wrapper/cef_library_loader.h" /// #include "include/wrapper/cef_library_loader.h"
/// ///
/// int main(int argc, char* argv[]) { /// 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; /// CefScopedSandboxContext sandbox_context;
/// if (!sandbox_context.Initialize(argc, argv)) /// if (!sandbox_context.Initialize(argc, argv))
/// return 1; /// return 1;

View File

@ -47,19 +47,3 @@ void cef_sandbox_destroy(void* sandbox_context) {
delete static_cast<sandbox::SeatbeltExecServer::CreateFromArgumentsResult*>( delete static_cast<sandbox::SeatbeltExecServer::CreateFromArgumentsResult*>(
sandbox_context); 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_;
}

View 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_;
}

View File

@ -757,13 +757,13 @@ parser.add_option(
action='store_true', action='store_true',
dest='sandboxdistrib', dest='sandboxdistrib',
default=False, default=False,
help='Create a cef_sandbox static library distribution.') help='Create a sandbox distribution.')
parser.add_option( parser.add_option(
'--sandbox-distrib-only', '--sandbox-distrib-only',
action='store_true', action='store_true',
dest='sandboxdistribonly', dest='sandboxdistribonly',
default=False, default=False,
help='Create a cef_sandbox static library distribution only.') help='Create a sandbox distribution only.')
parser.add_option( parser.add_option(
'--tools-distrib', '--tools-distrib',
action='store_true', 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.') 'Add --x64-build or --arm64-build flag to generate a 64-bit build.')
sys.exit(1) sys.exit(1)
# Platforms that build a cef_sandbox library in a separate output directory. # Platforms that build a cef_sandbox static library in a separate output directory.
sandbox_lib_platforms = ['mac'] 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. # Platforms that build a bootstrap executable in the same output directory.
bootstrap_exe_platforms = [] bootstrap_exe_platforms = []
if branch_is_7151_or_older: if branch_is_7151_or_older:
sandbox_lib_platforms.append('windows') sandbox_static_platforms.extend(['windows', 'mac'])
else: else:
bootstrap_exe_platforms.append('windows') 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 \ not platform in bootstrap_exe_platforms and \
(options.sandboxdistrib or options.sandboxdistribonly): (options.sandboxdistrib or options.sandboxdistribonly):
print('The sandbox distribution is not supported on this platform.') 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)) \ os.path.join(download_dir, 'build-%s-debug.log' % (cef_branch)) \
if options.buildlogfile else None) 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. # Make the separate cef_sandbox build when GN is_official_build=true.
build_path += '_sandbox' build_path += '_sandbox'
if os.path.exists(os.path.join(chromium_src_dir, build_path)): 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)) \ os.path.join(download_dir, 'build-%s-release.log' % (cef_branch)) \
if options.buildlogfile else None) 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. # Make the separate cef_sandbox build when GN is_official_build=true.
build_path += '_sandbox' build_path += '_sandbox'
if os.path.exists(os.path.join(chromium_src_dir, build_path)): if os.path.exists(os.path.join(chromium_src_dir, build_path)):

View File

@ -1,9 +1,9 @@
CONTENTS 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 USAGE
@ -11,4 +11,4 @@ USAGE
Please visit the CEF Website for usage information. Please visit the CEF Website for usage information.
https://bitbucket.org/chromiumembedded/cef/ https://bitbucket.org/chromiumembedded/cef/wiki/SandboxSetup.md

View File

@ -518,47 +518,6 @@ def GetConfigArgs(args, is_debug, cpu):
return result 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): def LinuxSysrootExists(cpu):
""" """
Returns true if the sysroot for the specified |cpu| architecture exists. 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['Debug_GN_' + cpu] = GetConfigArgs(args, True, cpu)
result['Release_GN_' + cpu] = GetConfigArgs(args, False, 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) out_configs = os.environ.get('GN_OUT_CONFIGS', None)
if not out_configs is None: if not out_configs is None:
# Only generate the specified configurations. # Only generate the specified configurations.

View File

@ -165,7 +165,11 @@ def create_readme():
'licensing terms and conditions.' 'licensing terms and conditions.'
elif mode == 'sandbox': elif mode == 'sandbox':
distrib_type = '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.' 'the LICENSING section of this document for licensing terms and conditions.'
elif mode == 'tools': elif mode == 'tools':
distrib_type = '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) 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): def run(command_line, working_dir):
""" Run a command. """ """ Run a command. """
sys.stdout.write('-------- Running "'+command_line+'" in "'+\ sys.stdout.write('-------- Running "'+command_line+'" in "'+\
@ -1255,15 +1152,6 @@ elif platform == 'mac':
framework_name = 'Chromium Embedded Framework' framework_name = 'Chromium Embedded Framework'
cefclient_app = 'cefclient.app' 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 = [ dsym_dirs = [
'%s.dSYM' % framework_name, '%s.dSYM' % framework_name,
'libEGL.dylib.dSYM', 'libEGL.dylib.dSYM',
@ -1271,25 +1159,15 @@ elif platform == 'mac':
'libvk_swiftshader.dylib.dSYM', 'libvk_swiftshader.dylib.dSYM',
] ]
# Generate the cef_sandbox.a merged library. A separate *_sandbox build sandbox_lib = 'libcef_sandbox.dylib'
# should exist when GN is_official_build=true. if mode == 'sandbox':
if mode in ('standard', 'minimal', 'sandbox') and not options.nosandbox: # Only transfer the sandbox dSYM.
dirs = { dsym_dirs = []
'Debug': (build_dir_debug + '_sandbox', build_dir_debug), dsym_dirs.append('%s.dSYM' % sandbox_lib)
'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
valid_build_dir = None valid_build_dir = None
if mode == 'standard': if mode == 'standard' or mode == 'sandbox':
# transfer Debug files # transfer Debug files
build_dir = build_dir_debug build_dir = build_dir_debug
if not options.allowpartial or path_exists( if not options.allowpartial or path_exists(
@ -1300,7 +1178,15 @@ elif platform == 'mac':
framework_src_dir = os.path.join( framework_src_dir = os.path.join(
build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' % build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' %
(cefclient_app, framework_name)) (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) copy_dir(framework_src_dir, framework_dst_dir, options.quiet)
if not options.nosymbols: if not options.nosymbols:
@ -1318,7 +1204,6 @@ elif platform == 'mac':
else: else:
sys.stdout.write("No Debug build files.\n") sys.stdout.write("No Debug build files.\n")
if mode != 'sandbox':
# transfer Release files # transfer Release files
build_dir = build_dir_release build_dir = build_dir_release
if not options.allowpartial or path_exists( if not options.allowpartial or path_exists(
@ -1329,6 +1214,13 @@ elif platform == 'mac':
framework_src_dir = os.path.join( framework_src_dir = os.path.join(
build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' % build_dir, '%s/Contents/Frameworks/%s.framework/Versions/A' %
(cefclient_app, framework_name)) (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': if mode != 'client':
framework_dst_dir = os.path.join(dst_dir, framework_dst_dir = os.path.join(dst_dir,
'%s.framework' % framework_name) '%s.framework' % framework_name)