Commit fcad76b4 authored by Marshall Greenblatt's avatar Marshall Greenblatt
Browse files

macOS: Load the CEF framework using dlopen instead of direct linking (issue #2459)

This is a prerequisite for using the Chromium V2 sandbox.
parent 0fb03e7a
......@@ -1004,6 +1004,10 @@ static_library("libcef_dll_wrapper") {
gypi_paths2.libcef_dll_wrapper_sources_common +
gypi_paths.autogen_client_side
if (is_mac) {
sources += gypi_paths2.libcef_dll_wrapper_sources_mac
}
defines = [ "WRAPPING_CEF_SHARED" ]
configs += [ ":libcef_dll_wrapper_config" ]
......@@ -1463,14 +1467,9 @@ if (is_mac) {
":libcef_static",
]
# Both the main app executable and helper executables need to link the
# framework. Because they are at different directory depths, using
# @executable_path as the install_name would require using install_name_tool
# on one of the executables. However install_name_tool only operates
# in-place, which is problematic to express in GN. Instead, use rpath-based
# loading.
# We don't link the framework so just use the path from the main executable.
ldflags = [
"-Wl,-install_name,@rpath/Frameworks/$output_name.framework/$output_name",
"-Wl,-install_name,@executable_path/../Frameworks/$output_name.framework/$output_name",
"-compatibility_version",
cef_dylib_version,
"-current_version",
......@@ -1569,7 +1568,6 @@ if (is_mac) {
sources = invoker.helper_sources
deps = [
":cef_framework+link",
":libcef_dll_wrapper",
]
if (defined(invoker.helper_deps)) {
......@@ -1578,9 +1576,9 @@ if (is_mac) {
ldflags = [
# The helper is in $app_name.app/Contents/Frameworks/$app_name Helper.app/Contents/MacOS/
# so set rpath up to Contents/ so that the loader can find Frameworks/.
# so set rpath up to the base.
"-rpath",
"@executable_path/../../../..",
"@executable_path/../../../../../..",
]
info_plist_target = ":${app_name}_helper_plist"
......@@ -1594,7 +1592,7 @@ if (is_mac) {
]
public_deps = [
":cef_framework+link",
":cef_framework",
":${app_name}_helper_app",
]
......@@ -1630,13 +1628,6 @@ if (is_mac) {
libs = invoker.libs
}
ldflags = [
# The main app is at $app_name.app/Contents/MacOS/$app_name
# so set rpath up to Contents/ so that the loader can find Frameworks/.
"-rpath",
"@executable_path/../",
]
info_plist_target = ":${app_name}_plist"
}
}
......@@ -1687,6 +1678,7 @@ if (is_mac) {
helper_sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_common +
gypi_paths2.shared_sources_renderer +
gypi_paths2.shared_sources_mac_helper +
......@@ -1700,6 +1692,7 @@ if (is_mac) {
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +
gypi_paths2.shared_sources_mac +
......@@ -1757,6 +1750,7 @@ if (is_mac) {
helper_sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.cefsimple_sources_mac_helper
helper_deps = [
":libcef_dll_wrapper",
......@@ -1766,6 +1760,7 @@ if (is_mac) {
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.cefsimple_sources_common +
gypi_paths2.cefsimple_sources_mac
deps = [
......@@ -1826,6 +1821,7 @@ if (is_mac) {
sources = gypi_paths2.includes_mac +
gypi_paths2.includes_common +
gypi_paths2.includes_wrapper +
gypi_paths2.includes_wrapper_mac +
gypi_paths2.shared_sources_browser +
gypi_paths2.shared_sources_common +
gypi_paths2.shared_sources_mac +
......
......@@ -65,6 +65,9 @@
'include/wrapper/cef_xml_object.h',
'include/wrapper/cef_zip_archive.h',
],
'includes_wrapper_mac': [
'include/wrapper/cef_library_loader.h',
],
'includes_win': [
'include/base/internal/cef_atomicops_x86_msvc.h',
'include/base/internal/cef_bind_internal_win.h',
......@@ -141,6 +144,10 @@
'libcef_dll/wrapper/libcef_dll_wrapper.cc',
'libcef_dll/wrapper/libcef_dll_wrapper2.cc',
],
'libcef_dll_wrapper_sources_mac': [
'libcef_dll/wrapper/cef_library_loader_mac.mm',
'libcef_dll/wrapper/libcef_dll_dylib.cc',
],
'shared_sources_browser': [
'tests/shared/browser/client_app_browser.cc',
'tests/shared/browser/client_app_browser.h',
......
......@@ -185,22 +185,6 @@ endif(OS_LINUX)
if(OS_MACOSX)
# Fix the framework rpath in the helper executable.
macro(FIX_MACOSX_HELPER_FRAMEWORK_RPATH target)
# The helper is in $app_name.app/Contents/Frameworks/$app_name Helper.app/Contents/MacOS/
# so set rpath up to Contents/ so that the loader can find Frameworks/.
set_target_properties(${target} PROPERTIES INSTALL_RPATH "@executable_path/../../../..")
set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
endmacro()
# Fix the framework rpath in the main executable.
macro(FIX_MACOSX_MAIN_FRAMEWORK_RPATH target)
# The main app is at $app_name.app/Contents/MacOS/$app_name
# so set rpath up to Contents/ so that the loader can find Frameworks/.
set_target_properties(${target} PROPERTIES INSTALL_RPATH "@executable_path/..")
set_target_properties(${target} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
endmacro()
# Manually process and copy over resource files.
macro(COPY_MACOSX_RESOURCES resource_list prefix_list target source_dir app_path)
foreach(FILENAME ${resource_list})
......
......@@ -313,10 +313,6 @@ if(OS_MACOSX)
set(CEF_BINARY_DIR "${_CEF_ROOT}/$<CONFIGURATION>")
set(CEF_BINARY_DIR_DEBUG "${_CEF_ROOT}/Debug")
set(CEF_BINARY_DIR_RELEASE "${_CEF_ROOT}/Release")
# CEF library paths.
set(CEF_LIB_DEBUG "${CEF_BINARY_DIR_DEBUG}/Chromium Embedded Framework.framework/Chromium Embedded Framework")
set(CEF_LIB_RELEASE "${CEF_BINARY_DIR_RELEASE}/Chromium Embedded Framework.framework/Chromium Embedded Framework")
endif()
......
// Copyright (c) 2018 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef CEF_INCLUDE_WRAPPER_CEF_LIBRARY_LOADER_H_
#define CEF_INCLUDE_WRAPPER_CEF_LIBRARY_LOADER_H_
#pragma once
#include "include/base/cef_build.h"
#ifdef __cplusplus
#include <string>
#include "include/base/cef_macros.h"
extern "C" {
#endif // __cplusplus
///
// Load the CEF library at the specified |path|. Returns true (1) on
// success and false (0) on failure.
///
int cef_load_library(const char* path);
///
// Unload the CEF library that was previously loaded. Returns true (1)
// on success and false (0) on failure.
///
int cef_unload_library();
#ifdef __cplusplus
}
#if defined(OS_MACOSX)
///
// Scoped helper for loading and unloading the CEF framework library at
// runtime from the expected location in the app bundle. Loading at runtime
// instead of linking directly is a requirement of the macOS sandbox
// implementation.
//
// Example usage in the main process:
//
// int main(int argc, char* argv[]) {
// CefScopedLibraryLoader library_loader;
// if (!library_loader.LoadInMain())
// return 1;
//
// // Rest of the function here...
// }
//
// Example usage in the helper process:
//
// int main(int argc, char* argv[]) {
// CefScopedLibraryLoader library_loader;
// if (!library_loader.LoadInHelper())
// return 1;
//
// // Rest of the function here...
// }
///
class CefScopedLibraryLoader {
public:
CefScopedLibraryLoader();
~CefScopedLibraryLoader();
///
// Load the CEF framework in the main process from the expected app
// bundle location relative to the executable. Returns true if the
// load succeeds.
///
bool LoadInMain() { return Load(false); }
///
// Load the CEF framework in the helper process from the expected app
// bundle location relative to the executable. Returns true if the
// load succeeds.
///
bool LoadInHelper() { return Load(true); }
private:
bool Load(bool helper);
bool loaded_;
DISALLOW_COPY_AND_ASSIGN(CefScopedLibraryLoader);
};
#endif // defined(OS_MACOSX)
#endif // __cplusplus
#endif // CEF_INCLUDE_WRAPPER_CEF_LIBRARY_LOADER_H_
......@@ -27,11 +27,13 @@ set(CEF_TARGET libcef_dll_wrapper)
'includes_capi',
'autogen_capi_includes',
'includes_wrapper',
'includes_wrapper_mac:MACOSX',
'includes_win:WINDOWS',
'includes_mac:MACOSX',
'includes_linux:LINUX',
'libcef_dll_wrapper_sources_base',
'libcef_dll_wrapper_sources_common',
'libcef_dll_wrapper_sources_mac:MACOSX',
'autogen_client_side',
],
}}
......
// Copyright (c) 2018 The Chromium Embedded Framework 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 "include/wrapper/cef_library_loader.h"
#include <libgen.h>
#include <mach-o/dyld.h>
#include <stdio.h>
#include <memory>
#include <sstream>
namespace {
const char kFrameworkPath[] =
"Chromium Embedded Framework.framework/Chromium Embedded Framework";
const char kPathFromHelperExe[] = "../../..";
const char kPathFromMainExe[] = "../Frameworks";
std::string GetFrameworkPath(bool helper) {
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 framework.
std::stringstream ss;
ss << parent_dir << "/" << (helper ? kPathFromHelperExe : kPathFromMainExe)
<< "/" << kFrameworkPath;
return ss.str();
}
} // namespace
CefScopedLibraryLoader::CefScopedLibraryLoader() : loaded_(false) {}
bool CefScopedLibraryLoader::Load(bool helper) {
if (loaded_) {
return false;
}
const std::string& framework_path = GetFrameworkPath(helper);
if (framework_path.empty()) {
fprintf(stderr, "App does not have the expected bundle structure.\n");
return false;
}
// Load the CEF framework library.
if (!cef_load_library(framework_path.c_str())) {
fprintf(stderr, "Failed to load the CEF framework.\n");
return false;
}
loaded_ = true;
return true;
}
CefScopedLibraryLoader::~CefScopedLibraryLoader() {
if (loaded_) {
// Unload the CEF framework library.
cef_unload_library();
}
}
This diff is collapsed.
......@@ -97,11 +97,11 @@ set(CEF_TARGET "cefclient")
if(OS_MACOSX)
set(CEF_HELPER_TARGET "cefclient_Helper")
set(CEF_HELPER_OUTPUT_NAME "cefclient Helper")
else()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
endif()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
# Determine the target output directory.
SET_CEF_TARGET_OUT_DIR()
......@@ -180,20 +180,17 @@ if(OS_MACOSX)
add_executable(${CEF_HELPER_TARGET} MACOSX_BUNDLE ${CEFCLIENT_HELPER_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_HELPER_TARGET})
add_dependencies(${CEF_HELPER_TARGET} libcef_dll_wrapper)
target_link_libraries(${CEF_HELPER_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
target_link_libraries(${CEF_HELPER_TARGET} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_HELPER_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/mac/helper-Info.plist
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
)
# Fix the framework rpath in the helper executable.
FIX_MACOSX_HELPER_FRAMEWORK_RPATH(${CEF_HELPER_TARGET})
# Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFCLIENT_RESOURCES_SRCS} ${CEFCLIENT_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper "${CEF_HELPER_TARGET}")
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS} "-framework OpenGL")
target_link_libraries(${CEF_TARGET} libcef_dll_wrapper ${CEF_STANDARD_LIBS} "-framework OpenGL")
set_target_properties(${CEF_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/mac/Info.plist
)
......@@ -213,9 +210,6 @@ if(OS_MACOSX)
VERBATIM
)
# Fix the framework rpath in the main executable.
FIX_MACOSX_MAIN_FRAMEWORK_RPATH(${CEF_TARGET})
# Manually process and copy over resource files.
# The Xcode generator can support this via the set_target_properties RESOURCE
# directive but that doesn't properly handle nested resource directories.
......
......@@ -476,7 +476,13 @@ void RootWindowMac::CreateRootWindow(const CefBrowserSettings& settings,
NSRect screen_rect = [[NSScreen mainScreen] visibleFrame];
NSRect window_rect =
NSMakeRect(x, screen_rect.size.height - y, width, height);
window_ = [[UnderlayOpenGLHostingWindow alloc]
// The CEF framework library is loaded at runtime so we need to use this
// mechanism for retrieving the class.
Class window_class = NSClassFromString(@"UnderlayOpenGLHostingWindow");
CHECK(window_class);
window_ = [[window_class alloc]
initWithContentRect:window_rect
styleMask:(NSTitledWindowMask | NSClosableWindowMask |
NSMiniaturizableWindowMask | NSResizableWindowMask |
......
......@@ -6,6 +6,7 @@
#import <Cocoa/Cocoa.h>
#include "include/cef_app.h"
#import "include/cef_application_mac.h"
#import "include/wrapper/cef_library_loader.h"
#include "tests/cefclient/browser/main_context_impl.h"
#include "tests/cefclient/browser/resource.h"
#include "tests/cefclient/browser/root_window.h"
......@@ -338,6 +339,12 @@ namespace client {
namespace {
int RunMain(int argc, char* argv[]) {
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInMain())
return 1;
CefMainArgs main_args(argc, argv);
// Initialize the AutoRelease pool.
......@@ -403,7 +410,7 @@ int RunMain(int argc, char* argv[]) {
} // namespace
} // namespace client
// Program entry point function.
// Entry point function for the browser process.
int main(int argc, char* argv[]) {
return client::RunMain(argc, argv);
}
......@@ -45,11 +45,11 @@ set(CEF_TARGET "cefsimple")
if(OS_MACOSX)
set(CEF_HELPER_TARGET "cefsimple_Helper")
set(CEF_HELPER_OUTPUT_NAME "cefsimple Helper")
else()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
endif()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
# Determine the target output directory.
SET_CEF_TARGET_OUT_DIR()
......@@ -95,20 +95,17 @@ if(OS_MACOSX)
add_executable(${CEF_HELPER_TARGET} MACOSX_BUNDLE ${CEFSIMPLE_HELPER_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_HELPER_TARGET})
add_dependencies(${CEF_HELPER_TARGET} libcef_dll_wrapper)
target_link_libraries(${CEF_HELPER_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
target_link_libraries(${CEF_HELPER_TARGET} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_HELPER_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/helper-Info.plist
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
)
# Fix the framework rpath in the helper executable.
FIX_MACOSX_HELPER_FRAMEWORK_RPATH(${CEF_HELPER_TARGET})
# Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${CEFSIMPLE_RESOURCES_SRCS} ${CEFSIMPLE_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper "${CEF_HELPER_TARGET}")
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
target_link_libraries(${CEF_TARGET} libcef_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/Info.plist
)
......@@ -128,9 +125,6 @@ if(OS_MACOSX)
VERBATIM
)
# Fix the framework rpath in the main executable.
FIX_MACOSX_MAIN_FRAMEWORK_RPATH(${CEF_TARGET})
# Manually process and copy over resource files.
# The Xcode generator can support this via the set_target_properties RESOURCE
# directive but that doesn't properly handle nested resource directories.
......
......@@ -7,6 +7,7 @@
#include "include/cef_application_mac.h"
#include "include/wrapper/cef_helpers.h"
#include "include/wrapper/cef_library_loader.h"
#include "tests/cefsimple/simple_app.h"
#include "tests/cefsimple/simple_handler.h"
......@@ -109,6 +110,12 @@
// Entry point function for the browser process.
int main(int argc, char* argv[]) {
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInMain())
return 1;
// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);
......
......@@ -3,9 +3,16 @@
// be found in the LICENSE file.
#include "include/cef_app.h"
#include "include/wrapper/cef_library_loader.h"
// Entry point function for sub-processes.
int main(int argc, char* argv[]) {
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInHelper())
return 1;
// Provide CEF with command-line arguments.
CefMainArgs main_args(argc, argv);
......
......@@ -59,11 +59,11 @@ set(CEF_TARGET "ceftests")
if(OS_MACOSX)
set(CEF_HELPER_TARGET "ceftests_Helper")
set(CEF_HELPER_OUTPUT_NAME "ceftests Helper")
else()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
endif()
# Logical target used to link the libcef library.
ADD_LOGICAL_TARGET("libcef_lib" "${CEF_LIB_DEBUG}" "${CEF_LIB_RELEASE}")
# Determine the target output directory.
SET_CEF_TARGET_OUT_DIR()
......@@ -115,20 +115,17 @@ if(OS_MACOSX)
add_executable(${CEF_HELPER_TARGET} MACOSX_BUNDLE ${UNITTESTS_HELPER_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_HELPER_TARGET})
add_dependencies(${CEF_HELPER_TARGET} libcef_dll_wrapper cef_gtest)
target_link_libraries(${CEF_HELPER_TARGET} libcef_lib libcef_dll_wrapper cef_gtest ${CEF_STANDARD_LIBS})
target_link_libraries(${CEF_HELPER_TARGET} libcef_dll_wrapper cef_gtest ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_HELPER_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/mac/helper-Info.plist
OUTPUT_NAME ${CEF_HELPER_OUTPUT_NAME}
)
# Fix the framework rpath in the helper executable.
FIX_MACOSX_HELPER_FRAMEWORK_RPATH(${CEF_HELPER_TARGET})
# Main executable target.
add_executable(${CEF_TARGET} MACOSX_BUNDLE ${UNITTESTS_RESOURCES_SRCS} ${UNITTESTS_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper cef_gtest "${CEF_HELPER_TARGET}")
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper cef_gtest ${CEF_STANDARD_LIBS})
target_link_libraries(${CEF_TARGET} libcef_dll_wrapper cef_gtest ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/resources/mac/Info.plist
)
......@@ -148,9 +145,6 @@ if(OS_MACOSX)
VERBATIM
)
# Fix the framework rpath in the main executable.
FIX_MACOSX_MAIN_FRAMEWORK_RPATH(${CEF_TARGET})
# Manually process and copy over resource files.
# The Xcode generator can support this via the set_target_properties RESOURCE
# directive but that doesn't properly handle nested resource directories.
......
......@@ -29,6 +29,10 @@
#include "tests/shared/common/client_app_other.h"
#include "tests/shared/renderer/client_app_renderer.h"
#if defined(OS_MACOSX)
#include "include/wrapper/cef_library_loader.h"
#endif
#if defined(OS_WIN)
#include "include/cef_sandbox_win.h"
#endif
......@@ -93,6 +97,14 @@ int XIOErrorHandlerImpl(Display* display) {
} // namespace
int main(int argc, char* argv[]) {
#if defined(OS_MACOSX)
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInMain())
return 1;
#endif
// Create the singleton test suite object.
CefTestSuite test_suite(argc, argv);
......
......@@ -3,6 +3,7 @@
// be found in the LICENSE file.
#include "include/cef_app.h"
#import "include/wrapper/cef_library_loader.h"
#include "tests/shared/common/client_app_other.h"
#include "tests/shared/renderer/client_app_renderer.h"
......@@ -10,6 +11,12 @@
namespace client {
int RunMain(int argc, char* argv[]) {
// Load the CEF framework library at runtime instead of linking directly
// as required by the macOS sandbox implementation.
CefScopedLibraryLoader library_loader;
if (!library_loader.LoadInHelper())