c++ - CEF - 未调用 OnContextCreated 等渲染过程方法
问题描述
潜伏已久,但很高兴来到这里。我正在尝试将基本的 javascript 绑定绑定到 cefSimple 应用程序。
我正在开发最新的 Macbook 以及最新的 iMac。
无数次搜索导致我犯了一些基本错误——但我似乎已经全部纠正了它们,它仍然可以正常工作。
具体来说,我已经确定让我的 SimpleApp 类从 CefRenderProcessHandler 继承(至少,我认为它是继承的。语法对新的还是有点新)
我也在该类中调用了 GetRenderProcessHandler。
我看到的另一个主要建议是确保将 SimpleApp 实例传递给 CefExecuteProcess——我已经这样做了。
这是我的代码:
simple_app.mm
// Copyright (c) 2013 The Chromium Embedded Framework Authors.
// Portions copyright (c) 2010 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.
#import <Cocoa/Cocoa.h>
#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"
// Receives notifications from the application.
@interface SimpleAppDelegate : NSObject <NSApplicationDelegate>
- (void)createApplication:(id)object;
- (void)tryToTerminateApplication:(NSApplication*)app;
@end
// Provide the CefAppProtocol implementation required by CEF.
@interface SimpleApplication : NSApplication <CefAppProtocol> {
@private
BOOL handlingSendEvent_;
}
@end
@implementation SimpleApplication
- (BOOL)isHandlingSendEvent {
return handlingSendEvent_;
}
- (void)setHandlingSendEvent:(BOOL)handlingSendEvent {
handlingSendEvent_ = handlingSendEvent;
}
- (void)sendEvent:(NSEvent*)event {
CefScopedSendingEvent sendingEventScoper;
[super sendEvent:event];
}
// |-terminate:| is the entry point for orderly "quit" operations in Cocoa. This
// includes the application menu's quit menu item and keyboard equivalent, the
// application's dock icon menu's quit menu item, "quit" (not "force quit") in
// the Activity Monitor, and quits triggered by user logout and system restart
// and shutdown.
//
// The default |-terminate:| implementation ends the process by calling exit(),
// and thus never leaves the main run loop. This is unsuitable for Chromium
// since Chromium depends on leaving the main run loop to perform an orderly
// shutdown. We support the normal |-terminate:| interface by overriding the
// default implementation. Our implementation, which is very specific to the
// needs of Chromium, works by asking the application delegate to terminate
// using its |-tryToTerminateApplication:| method.
//
// |-tryToTerminateApplication:| differs from the standard
// |-applicationShouldTerminate:| in that no special event loop is run in the
// case that immediate termination is not possible (e.g., if dialog boxes
// allowing the user to cancel have to be shown). Instead, this method tries to
// close all browsers by calling CloseBrowser(false) via
// ClientHandler::CloseAllBrowsers. Calling CloseBrowser will result in a call
// to ClientHandler::DoClose and execution of |-performClose:| on the NSWindow.
// DoClose sets a flag that is used to differentiate between new close events
// (e.g., user clicked the window close button) and in-progress close events
// (e.g., user approved the close window dialog). The NSWindowDelegate
// |-windowShouldClose:| method checks this flag and either calls
// CloseBrowser(false) in the case of a new close event or destructs the
// NSWindow in the case of an in-progress close event.
// ClientHandler::OnBeforeClose will be called after the CEF NSView hosted in
// the NSWindow is dealloc'ed.
//
// After the final browser window has closed ClientHandler::OnBeforeClose will
// begin actual tear-down of the application by calling CefQuitMessageLoop.
// This ends the NSApplication event loop and execution then returns to the
// main() function for cleanup before application termination.
//
// The standard |-applicationShouldTerminate:| is not supported, and code paths
// leading to it must be redirected.
- (void)terminate:(id)sender {
SimpleAppDelegate* delegate =
static_cast<SimpleAppDelegate*>([NSApp delegate]);
[delegate tryToTerminateApplication:self];
// Return, don't exit. The application is responsible for exiting on its own.
}
@end
@implementation SimpleAppDelegate
// Create the application on the UI thread.
- (void)createApplication:(id)object {
[NSApplication sharedApplication];
[[NSBundle mainBundle] loadNibNamed:@"MainMenu"
owner:NSApp
topLevelObjects:nil];
// Set the delegate for application events.
[[NSApplication sharedApplication] setDelegate:self];
}
- (void)tryToTerminateApplication:(NSApplication*)app {
SimpleHandler* handler = SimpleHandler::GetInstance();
if (handler && !handler->IsClosing())
handler->CloseAllBrowsers(false);
}
- (NSApplicationTerminateReply)applicationShouldTerminate:
(NSApplication*)sender {
return NSTerminateNow;
}
@end
// 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);
@autoreleasepool {
// Initialize the SimpleApplication instance.
[SimpleApplication sharedApplication];
// Specify CEF global settings here.
CefSettings settings;
// When generating projects with CMake the CEF_USE_SANDBOX value will be
// defined automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line
// to disable use of the sandbox.
#if !defined(CEF_USE_SANDBOX)
settings.no_sandbox = true;
#endif
// SimpleApp implements application-level callbacks for the browser process.
// It will create the first browser instance in OnContextInitialized() after
// CEF has initialized.
CefRefPtr<SimpleApp> app(new SimpleApp);
// CEF applications have multiple sub-processes (render, plugin, GPU, etc)
// that share the same executable. This function checks the command-line and,
// if this is a sub-process, executes the appropriate logic.
CefExecuteProcess(main_args, app, nullptr);
// Initialize CEF for the browser process.
CefInitialize(main_args, settings, app.get(), NULL);
// Create the application delegate.
NSObject* delegate = [[SimpleAppDelegate alloc] init];
[delegate performSelectorOnMainThread:@selector(createApplication:)
withObject:nil
waitUntilDone:NO];
// Run the CEF message loop. This will block until CefQuitMessageLoop() is
// called.
CefRunMessageLoop();
// Shut down CEF.
CefShutdown();
// Release the delegate.
#if !__has_feature(objc_arc)
[delegate release];
#endif // !__has_feature(objc_arc)
delegate = nil;
} // @autoreleasepool
return 0;
}
简单应用程序.h
// Copyright (c) 2013 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.
#ifndef CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#define CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
#include "include/cef_app.h"
// Implement application-level callbacks for the browser process.
class SimpleApp : public CefApp,
public CefBrowserProcessHandler,
public CefRenderProcessHandler {
public:
SimpleApp();
// CefApp methods:
virtual CefRefPtr<CefBrowserProcessHandler> GetBrowserProcessHandler()
OVERRIDE {
return this;
}
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()
OVERRIDE {
return this;
}
// CefBrowserProcessHandler methods:
virtual void OnContextInitialized() OVERRIDE;
virtual void OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(SimpleApp);
};
#endif // CEF_TESTS_CEFSIMPLE_SIMPLE_APP_H_
simple_app.cc
// Copyright (c) 2013 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 "tests/cefsimple/simple_app.h"
#include <string>
#include "include/cef_browser.h"
#include "include/cef_command_line.h"
#include "include/views/cef_browser_view.h"
#include "include/views/cef_window.h"
#include "include/wrapper/cef_helpers.h"
#include "tests/cefsimple/simple_handler.h"
namespace {
// When using the Views framework this object provides the delegate
// implementation for the CefWindow that hosts the Views-based browser.
class SimpleWindowDelegate : public CefWindowDelegate {
public:
explicit SimpleWindowDelegate(CefRefPtr<CefBrowserView> browser_view)
: browser_view_(browser_view) {}
void OnWindowCreated(CefRefPtr<CefWindow> window) OVERRIDE {
// Add the browser view and show the window.
window->AddChildView(browser_view_);
window->Show();
// Give keyboard focus to the browser view.
browser_view_->RequestFocus();
}
void OnWindowDestroyed(CefRefPtr<CefWindow> window) OVERRIDE {
browser_view_ = NULL;
}
bool CanClose(CefRefPtr<CefWindow> window) OVERRIDE {
// Allow the window to close if the browser says it's OK.
CefRefPtr<CefBrowser> browser = browser_view_->GetBrowser();
if (browser)
return browser->GetHost()->TryCloseBrowser();
return true;
}
CefSize GetPreferredSize(CefRefPtr<CefView> view) OVERRIDE {
return CefSize(800, 600);
}
private:
CefRefPtr<CefBrowserView> browser_view_;
IMPLEMENT_REFCOUNTING(SimpleWindowDelegate);
DISALLOW_COPY_AND_ASSIGN(SimpleWindowDelegate);
};
} // namespace
SimpleApp::SimpleApp() {}
void SimpleApp::OnContextInitialized() {
CEF_REQUIRE_UI_THREAD();
CefRefPtr<CefCommandLine> command_line =
CefCommandLine::GetGlobalCommandLine();
#if defined(OS_WIN) || defined(OS_LINUX)
// Create the browser using the Views framework if "--use-views" is specified
// via the command-line. Otherwise, create the browser using the native
// platform framework. The Views framework is currently only supported on
// Windows and Linux.
const bool use_views = command_line->HasSwitch("use-views");
#else
const bool use_views = false;
#endif
// SimpleHandler implements browser-level callbacks.
CefRefPtr<SimpleHandler> handler(new SimpleHandler(use_views));
// Specify CEF browser settings here.
CefBrowserSettings browser_settings;
std::string url;
// Check if a "--url=" value was provided via the command-line. If so, use
// that instead of the default URL.
url = command_line->GetSwitchValue("url");
if (url.empty())
url = "http://www.google.com";
if (use_views) {
// Create the BrowserView.
CefRefPtr<CefBrowserView> browser_view = CefBrowserView::CreateBrowserView(
handler, url, browser_settings, NULL, NULL, NULL);
// Create the Window. It will show itself after creation.
CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view));
} else {
// Information used when creating the native window.
CefWindowInfo window_info;
#if defined(OS_WIN)
// On Windows we need to specify certain flags that will be passed to
// CreateWindowEx().
window_info.SetAsPopup(NULL, "cefsimple");
#endif
// Create the first browser window.
CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings,
NULL, NULL);
}
}
void SimpleApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();
// Create a new V8 string value. See the "Basic JS Types" section below.
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
// Add the string to the window object as "window.myval". See the "JS Objects" section below.
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}
当然,还有用于检查它是否正常工作的 HTML。
CEFTest.html
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<span id="thespan"></span>
<script type="text/javascript">
function SetValue(argument) {
document.getElementById( 'thespan' ).innerHTML = window.myval + 'hello'
}
window.addEventListener( 'load', SetValue )
</script>
</body>
</html>
我对 Cef 的理解才刚刚开始真正形成。看起来我必须做的是将 CefRenderProcessHandler 传递给 SimpleApp 类,以便允许它访问所有 RenderProcessHandler 的方法。然后我不得不用我自己的版本覆盖 OnContextCreated (因为原始版本只是一个占位符函数)
我认为,调用 CefExecuteProcess 可以实际强制进程启动。我可以对此做一些澄清。
解决方案
以下是修改为包含 Javascript 集成的 CefSimple 的工作版本。
所以事实证明问题源于使用 Mac 而不是 Linux 或 PC 机器
我原始帖子中发布的代码应该可以在 PC 上运行。我无法测试它,因为我没有。(如果某个善良的灵魂不介意这样做并发布结果,我将不胜感激)
在 Mac 上,渲染进程有一个单独的入口点。对于 CEFSimple,这是 process_helper_mac.cc 文件。所需要的只是创建一个扩展 CefRenderProcessHandler 的类,覆盖它的 GetRenderProcessHandler 方法以返回自身,然后将子进程包装在该类中,然后再将其发送到 CefExecuteProcess。
为此,您需要在 helper_app.h 和 helper_app.cc 文件中定义这个新类,我称之为 Helper_App。最后,您需要进入 CMakeLists.txt 文件并实际指示构建程序包含我们编写的文件。
TL;DR 创建 helper_app.h 和 helper_app.cc 文件并粘贴以下代码。修改 process_helper_mac.cc 文件如下。修改 CMakeLists.txt 文件如下。
helper_app.h
// Copyright (c) 2013 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.
#ifndef CEF_TESTS_CEFSIMPLE_HELPER_APP_H_
#define CEF_TESTS_CEFSIMPLE_HELPER_APP_H_
#include "include/cef_app.h"
// Implement application-level callbacks for the browser process.
class HelperApp : public CefApp, public CefRenderProcessHandler {
public:
HelperApp();
// CefApp methods:
virtual CefRefPtr<CefRenderProcessHandler> GetRenderProcessHandler()
OVERRIDE {
return this;
}
// CefBrowserProcessHandler methods:
virtual void OnContextCreated( CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context ) OVERRIDE;
private:
// Include the default reference counting implementation.
IMPLEMENT_REFCOUNTING(HelperApp);
};
#endif // CEF_TESTS_CEFSIMPLE_HELPER_APP_H_
helper_app.cc
// Copyright (c) 2013 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 "tests/cefsimple/helper_app.h"
HelperApp::HelperApp() {}
void HelperApp::OnContextCreated(CefRefPtr<CefBrowser> browser,
CefRefPtr<CefFrame> frame,
CefRefPtr<CefV8Context> context) {
// Retrieve the context's window object.
CefRefPtr<CefV8Value> object = context->GetGlobal();
// Create a new V8 string value. See the "Basic JS Types" section below.
CefRefPtr<CefV8Value> str = CefV8Value::CreateString("My Value!");
// Add the string to the window object as "window.myval". See the "JS Objects" section below.
object->SetValue("myval", str, V8_PROPERTY_ATTRIBUTE_NONE);
}
process_helper_mac.cc
// Copyright (c) 2013 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/cef_app.h"
#include "include/wrapper/cef_library_loader.h"
#include "tests/cefsimple/helper_app.h"
// When generating projects with CMake the CEF_USE_SANDBOX value will be defined
// automatically. Pass -DUSE_SANDBOX=OFF to the CMake command-line to disable
// use of the sandbox.
#if defined(CEF_USE_SANDBOX)
#include "include/cef_sandbox_mac.h"
#endif
// Entry point function for sub-processes.
int main(int argc, char* argv[]) {
#if defined(CEF_USE_SANDBOX)
// Initialize the macOS sandbox for this helper process.
CefScopedSandboxContext sandbox_context;
if (!sandbox_context.Initialize(argc, argv))
return 1;
#endif
// 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);
CefRefPtr<HelperApp> app(new HelperApp); // <--- Create an object of the type HelperApp
// Execute the sub-process.
return CefExecuteProcess(main_args, app, NULL); <--- Feed our HelperApp object through to CefExecuteProcess
}
CMakeLists.txt
# Copyright (c) 2014 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.
#
# Source files.
#
# cefsimple sources.
set(CEFSIMPLE_SRCS
simple_app.cc
simple_app.h
simple_handler.cc
simple_handler.h
)
set(CEFSIMPLE_SRCS_LINUX
cefsimple_linux.cc
simple_handler_linux.cc
)
set(CEFSIMPLE_SRCS_MACOSX
cefsimple_mac.mm
simple_handler_mac.mm
)
set(CEFSIMPLE_SRCS_WINDOWS
cefsimple.exe.manifest
cefsimple.rc
cefsimple_win.cc
resource.h
simple_handler_win.cc
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_SRCS)
source_group(cefsimple FILES ${CEFSIMPLE_SRCS})
set(CEFSIMPLE_RES_SRCS_WINDOWS
res/cefsimple.ico
res/small.ico
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_RES_SRCS)
source_group(cefsimple\\\\res FILES ${CEFSIMPLE_RES_SRCS})
set(CEFSIMPLE_SRCS
${CEFSIMPLE_SRCS}
${CEFSIMPLE_RES_SRCS}
)
# cefsimple helper sources.
#### Tell the build program to include helper_app.cc and helper_app.h during the build process
set(CEFSIMPLE_HELPER_SRCS_MACOSX
process_helper_mac.cc
helper_app.cc
helper_app.h
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_HELPER_SRCS)
source_group(cefsimple FILES ${CEFSIMPLE_HELPER_SRCS})
# cefsimple resources.
set(CEFSIMPLE_RESOURCES_MAC_SRCS_MACOSX
mac/Info.plist
mac/cefsimple.icns
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_RESOURCES_MAC_SRCS)
source_group(cefsimple\\\\mac FILES ${CEFSIMPLE_RESOURCES_MAC_SRCS})
set(CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS_MACOSX
mac/English.lproj/InfoPlist.strings
mac/English.lproj/MainMenu.xib
)
APPEND_PLATFORM_SOURCES(CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS)
source_group(cefsimple\\\\mac\\\\English.lproj FILES ${CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS})
set(CEFSIMPLE_RESOURCES_SRCS
${CEFSIMPLE_RESOURCES_MAC_SRCS}
${CEFSIMPLE_RESOURCES_MAC_ENGLISH_LPROJ_SRCS}
)
#
# Shared configuration.
#
# Target executable names.
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()
# Determine the target output directory.
SET_CEF_TARGET_OUT_DIR()
#
# Linux configuration.
#
if(OS_LINUX)
# Executable target.
add_executable(${CEF_TARGET} ${CEFSIMPLE_SRCS})
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper)
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
# Set rpath so that libraries can be placed next to the executable.
set_target_properties(${CEF_TARGET} PROPERTIES INSTALL_RPATH "$ORIGIN")
set_target_properties(${CEF_TARGET} PROPERTIES BUILD_WITH_INSTALL_RPATH TRUE)
set_target_properties(${CEF_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CEF_TARGET_OUT_DIR})
# Copy binary and resource files to the target output directory.
COPY_FILES("${CEF_TARGET}" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
COPY_FILES("${CEF_TARGET}" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CEF_TARGET_OUT_DIR}")
if (EXISTS "${CEF_BINARY_DIR}/libminigbm.so")
COPY_FILES("${CEF_TARGET}" "libminigbm.so" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
endif()
# Set SUID permissions on the chrome-sandbox target.
SET_LINUX_SUID_PERMISSIONS("${CEF_TARGET}" "${CEF_TARGET_OUT_DIR}/chrome-sandbox")
endif()
#
# Mac OS X configuration.
#
if(OS_MACOSX)
option(OPTION_USE_ARC "Build with ARC (automatic Reference Counting) on macOS." ON)
if(OPTION_USE_ARC)
list(APPEND CEF_COMPILER_FLAGS
-fobjc-arc
)
set_target_properties(${target} PROPERTIES
CLANG_ENABLE_OBJC_ARC "YES"
)
endif()
# Output paths for the app bundles.
set(CEF_APP "${CEF_TARGET_OUT_DIR}/${CEF_TARGET}.app")
set(CEF_HELPER_APP "${CEF_TARGET_OUT_DIR}/${CEF_HELPER_OUTPUT_NAME}.app")
# Variable referenced from Info.plist files.
set(PRODUCT_NAME "${CEF_TARGET}")
# Helper executable target.
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_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}
)
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_HELPER_TARGET} cef_sandbox_lib)
endif()
# 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_dll_wrapper ${CEF_STANDARD_LIBS})
set_target_properties(${CEF_TARGET} PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/mac/Info.plist
)
# Copy files into the main app bundle.
add_custom_command(
TARGET ${CEF_TARGET}
POST_BUILD
# Copy the helper app bundle into the Frameworks directory.
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CEF_HELPER_APP}"
"${CEF_APP}/Contents/Frameworks/${CEF_HELPER_OUTPUT_NAME}.app"
# Copy the CEF framework into the Frameworks directory.
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CEF_BINARY_DIR}/Chromium Embedded Framework.framework"
"${CEF_APP}/Contents/Frameworks/Chromium Embedded Framework.framework"
VERBATIM
)
# 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.
# Remove these prefixes from input file paths.
set(PREFIXES "mac/")
COPY_MACOSX_RESOURCES("${CEFSIMPLE_RESOURCES_SRCS}" "${PREFIXES}" "${CEF_TARGET}" "${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_APP}")
endif()
#
# Windows configuration.
#
if(OS_WINDOWS)
# Executable target.
add_executable(${CEF_TARGET} WIN32 ${CEFSIMPLE_SRCS})
add_dependencies(${CEF_TARGET} libcef_dll_wrapper)
SET_EXECUTABLE_TARGET_PROPERTIES(${CEF_TARGET})
target_link_libraries(${CEF_TARGET} libcef_lib libcef_dll_wrapper ${CEF_STANDARD_LIBS})
if(USE_SANDBOX)
# Logical target used to link the cef_sandbox library.
ADD_LOGICAL_TARGET("cef_sandbox_lib" "${CEF_SANDBOX_LIB_DEBUG}" "${CEF_SANDBOX_LIB_RELEASE}")
target_link_libraries(${CEF_TARGET} cef_sandbox_lib ${CEF_SANDBOX_STANDARD_LIBS})
endif()
# Add the custom manifest files to the executable.
ADD_WINDOWS_MANIFEST("${CMAKE_CURRENT_SOURCE_DIR}" "${CEF_TARGET}" "exe")
# Copy binary and resource files to the target output directory.
COPY_FILES("${CEF_TARGET}" "${CEF_BINARY_FILES}" "${CEF_BINARY_DIR}" "${CEF_TARGET_OUT_DIR}")
COPY_FILES("${CEF_TARGET}" "${CEF_RESOURCE_FILES}" "${CEF_RESOURCE_DIR}" "${CEF_TARGET_OUT_DIR}")
endif()
推荐阅读
- ios - 在 App Center 和 App Insights 中设置使用情况分析
- django - 如何使用 /download/ 扩展我的端点?
- amp-html - 如何在 amphtml 的过滤下拉列表中对结果进行排序?
- c++ - 如何在 C++ 中以编程方式显示 macOS 上所有正在运行的进程?
- android - 更改 RecyclerView 项目上的项目背景
- mysql - $scope 在 app.js 文件中不起作用。但是当 HTML 文件包含 app.js 文件的内容时,$scope 有效
- android - Gluon 移动视频服务不适用于本地存储在 android 设备上的媒体文件?
- c++ - 如何通过套接字发送 QMap?
- wpf - 如何为 DateTimeField 的 IsReadOnly 属性使用绑定?
- python-3.x - 库已安装并在 conda 中显示,但在 Jupyter Notebook 中不可用