macOS: Load the CEF framework using dlopen instead of direct linking (issue #2459)
This is a prerequisite for using the Chromium V2 sandbox.
This commit is contained in:
parent
0fb03e7aa1
commit
fcad76b405
32
BUILD.gn
32
BUILD.gn
|
@ -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()
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
// 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',
|
||||
],
|
||||
}}
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
// 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();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -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())
|
||||
return 1;
|
||||
|
||||
CefMainArgs main_args(argc, argv);
|
||||
|
||||
// Parse command-line arguments.
|
||||
|
@ -30,7 +37,7 @@ int RunMain(int argc, char* argv[]) {
|
|||
|
||||
} // namespace client
|
||||
|
||||
// Process entry point.
|
||||
// Entry point function for sub-processes.
|
||||
int main(int argc, char* argv[]) {
|
||||
return client::RunMain(argc, argv);
|
||||
}
|
||||
|
|
|
@ -386,15 +386,18 @@ _simpletypes = {
|
|||
}
|
||||
|
||||
|
||||
def get_function_impls(content, ident):
|
||||
def get_function_impls(content, ident, has_impl=True):
|
||||
""" Retrieve the function parts from the specified contents as a set of
|
||||
return value, name, arguments and body. Ident must occur somewhere in
|
||||
the value.
|
||||
"""
|
||||
# extract the functions
|
||||
p = re.compile(
|
||||
'\n' + _cre_func + '\((.*?)\)([A-Za-z0-9_\s]{0,})' + '\{(.*?)\n\}',
|
||||
re.MULTILINE | re.DOTALL)
|
||||
find_regex = '\n' + _cre_func + '\((.*?)\)([A-Za-z0-9_\s]{0,})'
|
||||
if has_impl:
|
||||
find_regex += '\{(.*?)\n\}'
|
||||
else:
|
||||
find_regex += '(;)'
|
||||
p = re.compile(find_regex, re.MULTILINE | re.DOTALL)
|
||||
list = p.findall(content)
|
||||
|
||||
# build the function map with the function name as the key
|
||||
|
@ -405,28 +408,31 @@ def get_function_impls(content, ident):
|
|||
continue
|
||||
|
||||
# remove the identifier
|
||||
retval = string.replace(retval, ident, '')
|
||||
retval = string.strip(retval)
|
||||
retval = retval.replace(ident, '')
|
||||
retval = retval.strip()
|
||||
|
||||
# Normalize the delimiter.
|
||||
retval = retval.replace('\n', ' ')
|
||||
|
||||
# retrieve the function name
|
||||
parts = string.split(retval, ' ')
|
||||
parts = retval.split(' ')
|
||||
name = parts[-1]
|
||||
del parts[-1]
|
||||
retval = string.join(parts, ' ')
|
||||
retval = ' '.join(parts)
|
||||
|
||||
# parse the arguments
|
||||
args = []
|
||||
for v in string.split(argval, ','):
|
||||
v = string.strip(v)
|
||||
for v in argval.split(','):
|
||||
v = v.strip()
|
||||
if len(v) > 0:
|
||||
args.append(v)
|
||||
|
||||
result.append({
|
||||
'retval': string.strip(retval),
|
||||
'retval': retval.strip(),
|
||||
'name': name,
|
||||
'args': args,
|
||||
'vfmod': string.strip(vfmod),
|
||||
'body': body
|
||||
'vfmod': vfmod.strip(),
|
||||
'body': body if has_impl else '',
|
||||
})
|
||||
|
||||
return result
|
||||
|
@ -477,6 +483,10 @@ class obj_header:
|
|||
""" Set the root directory. """
|
||||
self.root_directory = root_directory
|
||||
|
||||
def get_root_directory(self):
|
||||
""" Get the root directory. """
|
||||
return self.root_directory
|
||||
|
||||
def add_directory(self, directory, excluded_files=[]):
|
||||
""" Add all header files from the specified directory. """
|
||||
files = get_files(os.path.join(directory, '*.h'))
|
||||
|
|
|
@ -920,6 +920,12 @@ elif platform == 'macosx':
|
|||
# transfer include files
|
||||
transfer_gypi_files(cef_dir, cef_paths2['includes_mac'], \
|
||||
'include/', include_dir, options.quiet)
|
||||
transfer_gypi_files(cef_dir, cef_paths2['includes_wrapper_mac'], \
|
||||
'include/', include_dir, options.quiet)
|
||||
|
||||
# transfer libcef_dll_wrapper files
|
||||
transfer_gypi_files(cef_dir, cef_paths2['libcef_dll_wrapper_sources_mac'], \
|
||||
'libcef_dll/', libcef_dll_dir, options.quiet)
|
||||
|
||||
# transfer additional files, if any
|
||||
transfer_files(cef_dir, script_dir, os.path.join(script_dir, 'distrib', 'mac'), \
|
||||
|
|
|
@ -0,0 +1,214 @@
|
|||
# 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.
|
||||
|
||||
from cef_parser import *
|
||||
from file_util import *
|
||||
import os
|
||||
|
||||
# Other headers that export C API functions.
|
||||
OTHER_HEADERS = [
|
||||
'cef_version.h',
|
||||
'internal/cef_logging_internal.h',
|
||||
'internal/cef_string_list.h',
|
||||
'internal/cef_string_map.h',
|
||||
'internal/cef_string_multimap.h',
|
||||
'internal/cef_string_types.h',
|
||||
'internal/cef_thread_internal.h',
|
||||
'internal/cef_time.h',
|
||||
'internal/cef_trace_event_internal.h',
|
||||
]
|
||||
|
||||
|
||||
def make_libcef_dll_dylib_impl_parts(name, retval, args):
|
||||
# Split arguments into types and names.
|
||||
arg_types = ''
|
||||
arg_names = ''
|
||||
for arg in args:
|
||||
if len(arg_types) > 0:
|
||||
arg_types += ', '
|
||||
arg_names += ', '
|
||||
pos = arg.rfind(' ')
|
||||
arg_types += arg[0:pos]
|
||||
arg_names += arg[pos + 1:]
|
||||
|
||||
typedef = 'typedef %s (*%s_ptr)(%s);\n' % (retval, name, arg_types)
|
||||
|
||||
declare = '%s_ptr %s;\n' % (name, name)
|
||||
|
||||
init = ' INIT_ENTRY(%s);' % name
|
||||
|
||||
impl = """NO_SANITIZE("cfi-icall") %s %s(%s) {
|
||||
%sg_libcef_pointers.%s(%s);
|
||||
}
|
||||
|
||||
""" % (retval, name, ', '.join(args), 'return '
|
||||
if retval != 'void' else '', name, arg_names)
|
||||
|
||||
return (typedef, declare, init, impl)
|
||||
|
||||
|
||||
def make_libcef_dll_dylib_impl_func(func):
|
||||
name = func.get_capi_name()
|
||||
parts = func.get_capi_parts([])
|
||||
retval = parts['retval']
|
||||
args = parts['args']
|
||||
return make_libcef_dll_dylib_impl_parts(name, retval, args)
|
||||
|
||||
|
||||
def make_libcef_dll_dylib_impl(header):
|
||||
filenames = []
|
||||
includes = []
|
||||
ptr_typedef = ''
|
||||
ptr_declare = ''
|
||||
ptr_init = ''
|
||||
ptr_impl = ''
|
||||
|
||||
# Include required headers for global functions.
|
||||
for func in header.get_funcs():
|
||||
typedef, declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
||||
ptr_typedef += typedef
|
||||
ptr_declare += declare
|
||||
ptr_init += init
|
||||
ptr_impl += impl
|
||||
|
||||
filename = func.get_file_name()
|
||||
if not filename in filenames:
|
||||
includes.append('#include "include/capi/%s"' % func.get_capi_file_name())
|
||||
filenames.append(filename)
|
||||
|
||||
# Include required headers for static class functions.
|
||||
allclasses = header.get_classes()
|
||||
for cls in allclasses:
|
||||
funcs = cls.get_static_funcs()
|
||||
for func in funcs:
|
||||
typedef, declare, init, impl = make_libcef_dll_dylib_impl_func(func)
|
||||
ptr_typedef += typedef
|
||||
ptr_declare += declare
|
||||
ptr_init += init
|
||||
ptr_impl += impl
|
||||
|
||||
if len(funcs) > 0:
|
||||
filename = cls.get_file_name()
|
||||
if not filename in filenames:
|
||||
includes.append('#include "include/capi/%s"' % cls.get_capi_file_name())
|
||||
filenames.append(filename)
|
||||
|
||||
# Parse other headers.
|
||||
root_directory = header.get_root_directory()
|
||||
for other in OTHER_HEADERS:
|
||||
path = os.path.join(root_directory, other)
|
||||
content = read_file(path)
|
||||
funcs = get_function_impls(content, 'CEF_EXPORT', False)
|
||||
for func in funcs:
|
||||
typedef, declare, init, impl = make_libcef_dll_dylib_impl_parts(
|
||||
func['name'], func['retval'], func['args'])
|
||||
ptr_typedef += typedef
|
||||
ptr_declare += declare
|
||||
ptr_init += init
|
||||
ptr_impl += impl
|
||||
|
||||
includes.append('#include "include/%s"' % other)
|
||||
|
||||
# Build the final output.
|
||||
result = get_copyright() + """
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
""" + "\n".join(sorted(includes)) + """
|
||||
#include "include/wrapper/cef_library_loader.h"
|
||||
|
||||
// GLOBAL WRAPPER FUNCTIONS - Do not edit by hand.
|
||||
|
||||
namespace {
|
||||
|
||||
void* g_libcef_handle = NULL;
|
||||
|
||||
void* libcef_get_ptr(const char* path, const char* name) {
|
||||
void* ptr = dlsym(g_libcef_handle, name);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "dlsym %s: %s\\n", path, dlerror());
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
""" + ptr_typedef + """
|
||||
|
||||
struct libcef_pointers {
|
||||
""" + ptr_declare + """
|
||||
} g_libcef_pointers = {0};
|
||||
|
||||
#define INIT_ENTRY(name) \
|
||||
g_libcef_pointers.name = (name##_ptr)libcef_get_ptr(path, #name); \
|
||||
if (!g_libcef_pointers.name) { \
|
||||
return 0; \
|
||||
}
|
||||
|
||||
int libcef_init_pointers(const char* path) {
|
||||
""" + ptr_init + """
|
||||
return 1;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
int cef_load_library(const char* path) {
|
||||
if (g_libcef_handle)
|
||||
return 0;
|
||||
|
||||
g_libcef_handle = dlopen(path, RTLD_LAZY | RTLD_LOCAL | RTLD_FIRST);
|
||||
if (!g_libcef_handle) {
|
||||
fprintf(stderr, "dlopen %s: %s\\n", path, dlerror());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!libcef_init_pointers(path)) {
|
||||
cef_unload_library();
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int cef_unload_library() {
|
||||
int result = 0;
|
||||
if (g_libcef_handle) {
|
||||
result = !dlclose(g_libcef_handle);
|
||||
if (!result) {
|
||||
fprintf(stderr, "dlclose: %s\\n", dlerror());
|
||||
}
|
||||
g_libcef_handle = NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
""" + ptr_impl
|
||||
return result
|
||||
|
||||
|
||||
def write_libcef_dll_dylib_impl(header, file):
|
||||
newcontents = make_libcef_dll_dylib_impl(header)
|
||||
return (file, newcontents)
|
||||
|
||||
|
||||
# Test the module.
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
# Verify that the correct number of command-line arguments are provided.
|
||||
if len(sys.argv) < 2:
|
||||
sys.stderr.write('Usage: ' + sys.argv[0] + ' <cpp_header_dir>')
|
||||
sys.exit()
|
||||
|
||||
cpp_header_dir = sys.argv[1]
|
||||
|
||||
# Create the header object. Should match the logic in translator.py.
|
||||
header = obj_header()
|
||||
header.set_root_directory(cpp_header_dir)
|
||||
excluded_files = ['cef_application_mac.h', 'cef_version.h']
|
||||
header.add_directory(cpp_header_dir, excluded_files)
|
||||
header.add_directory(os.path.join(cpp_header_dir, 'test'))
|
||||
header.add_directory(os.path.join(cpp_header_dir, 'views'))
|
||||
|
||||
# Dump the result to stdout.
|
||||
sys.stdout.write(make_libcef_dll_dylib_impl(header))
|
|
@ -13,6 +13,7 @@ from make_cpptoc_impl import *
|
|||
from make_ctocpp_header import *
|
||||
from make_ctocpp_impl import *
|
||||
from make_gypi_file import *
|
||||
from make_libcef_dll_dylib_impl import *
|
||||
from make_views_stub_impl import *
|
||||
from make_wrapper_types_header import *
|
||||
from optparse import OptionParser
|
||||
|
@ -80,6 +81,8 @@ cpptoc_dir = os.path.join(libcef_dll_dir, 'cpptoc')
|
|||
ctocpp_dir = os.path.join(libcef_dll_dir, 'ctocpp')
|
||||
gypi_file = os.path.join(root_dir, 'cef_paths.gypi')
|
||||
views_stub_impl = os.path.join(libcef_dll_dir, 'views_stub.cc')
|
||||
libcef_dll_dylib_impl = os.path.join(libcef_dll_dir, 'wrapper',
|
||||
'libcef_dll_dylib.cc')
|
||||
|
||||
# make sure the header directory exists
|
||||
if not path_exists(cpp_header_dir):
|
||||
|
@ -139,7 +142,7 @@ def update_file(file, newcontents):
|
|||
newcontents = newcontents.replace(hash_token, newhash, 1)
|
||||
|
||||
# Apply clang-format for C/C++ files.
|
||||
if os.path.splitext(file)[1][1:] in ('cc', 'cpp', 'h'):
|
||||
if os.path.splitext(file)[1][1:] in ('c', 'cc', 'cpp', 'h'):
|
||||
result = clang_format(file, newcontents)
|
||||
if result != None:
|
||||
newcontents = result
|
||||
|
@ -228,5 +231,10 @@ if not options.quiet:
|
|||
sys.stdout.write('Generating ' + views_stub_impl + ' file...\n')
|
||||
update_file(*write_views_stub_impl(header, views_stub_impl))
|
||||
|
||||
# output the libcef dll dylib file
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Generating ' + libcef_dll_dylib_impl + ' file...\n')
|
||||
update_file(*write_libcef_dll_dylib_impl(header, libcef_dll_dylib_impl))
|
||||
|
||||
if not options.quiet:
|
||||
sys.stdout.write('Done - Wrote ' + str(writect) + ' files.\n')
|
||||
|
|
Loading…
Reference in New Issue