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) {
|
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)) {
|
||||||
|
@ -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': [
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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_); }
|
||||||
|
@ -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;
|
||||||
|
@ -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_;
|
|
||||||
}
|
|
||||||
|
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',
|
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)):
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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)
|
||||||
|
Reference in New Issue
Block a user