From ec8b64e88a127cd50bea0c7bc3705143b53de7be Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Thu, 21 Nov 2013 22:43:36 +0000 Subject: [PATCH] Add breakpad support (issue #1131). - General usage instructions are available at https://sites.google.com/a/chromium.org/dev/developers/testing/webkit-layout-tests/using-breakpad-with-content-shell. - Mac: Generate "Chromium Embedded Framework.framework" using a new cef_framework target (the libcef target is now only used on Windows and Linux). Rename "Libraries/libcef.dylib" to "Chromium Embedded Framework". Distribute Release and Debug builds of the "Chromium Embedded Framework.framework" folder as part of the binary distribution. - Mac: Fix the Xcode target compiler setting for the binary distribution so that it no longer needs to be set manually. git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1524 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- cef.gyp | 365 +++++++++++++---------- libcef/browser/content_browser_client.cc | 83 ++++++ libcef/browser/content_browser_client.h | 7 + libcef/common/breakpad_client.cc | 58 ++++ libcef/common/breakpad_client.h | 43 +++ libcef/common/cef_switches.cc | 3 + libcef/common/cef_switches.h | 1 + libcef/common/main_delegate.cc | 41 +++ libcef/common/main_delegate.h | 3 + libcef/resources/framework-Info.plist | 18 ++ tests/cefclient/client_handler.cpp | 2 +- tools/distrib/cefclient.gyp | 33 +- tools/distrib/mac/README.minimal.txt | 9 +- tools/distrib/mac/README.redistrib.txt | 75 ++++- tools/distrib/mac/README.standard.txt | 18 +- tools/make_distrib.py | 36 ++- 16 files changed, 574 insertions(+), 221 deletions(-) create mode 100644 libcef/common/breakpad_client.cc create mode 100644 libcef/common/breakpad_client.h create mode 100644 libcef/resources/framework-Info.plist diff --git a/cef.gyp b/cef.gyp index 3b1b8e806..78d4be7de 100644 --- a/cef.gyp +++ b/cef.gyp @@ -8,7 +8,9 @@ 'chromium_code': 1, 'grit_out_dir': '<(SHARED_INTERMEDIATE_DIR)/cef', 'about_credits_file': '<(SHARED_INTERMEDIATE_DIR)/about_credits.html', + 'framework_name': 'Chromium Embedded Framework', 'revision': 'GetSwitchValuePath( + switches::kCrashDumpsDir); + { + ANNOTATE_SCOPED_MEMORY_LEAK; + breakpad::CrashHandlerHostLinux* crash_handler = + new breakpad::CrashHandlerHostLinux( + process_type, dumps_path, false); + crash_handler->StartUploaderThread(); + return crash_handler; + } +} + +int GetCrashSignalFD(const CommandLine& command_line) { + if (!breakpad::IsCrashReporterEnabled()) + return -1; + + std::string process_type = + command_line.GetSwitchValueASCII(switches::kProcessType); + + if (process_type == switches::kRendererProcess) { + static breakpad::CrashHandlerHostLinux* crash_handler = NULL; + if (!crash_handler) + crash_handler = CreateCrashHandlerHost(process_type); + return crash_handler->GetDeathSignalSocket(); + } + + if (process_type == switches::kPluginProcess) { + static breakpad::CrashHandlerHostLinux* crash_handler = NULL; + if (!crash_handler) + crash_handler = CreateCrashHandlerHost(process_type); + return crash_handler->GetDeathSignalSocket(); + } + + if (process_type == switches::kPpapiPluginProcess) { + static breakpad::CrashHandlerHostLinux* crash_handler = NULL; + if (!crash_handler) + crash_handler = CreateCrashHandlerHost(process_type); + return crash_handler->GetDeathSignalSocket(); + } + + if (process_type == switches::kGpuProcess) { + static breakpad::CrashHandlerHostLinux* crash_handler = NULL; + if (!crash_handler) + crash_handler = CreateCrashHandlerHost(process_type); + return crash_handler->GetDeathSignalSocket(); + } + + return -1; +} +#endif // defined(OS_POSIX) && !defined(OS_MACOSX) + } // namespace @@ -509,6 +573,10 @@ void CefContentBrowserClient::AppendExtraCommandLineSwitches( switches::kEnableReleaseDcheck, switches::kDisablePackLoading, switches::kResourcesDirPath, + switches::kEnableCrashReporter, +#if !defined(OS_WIN) + switches::kCrashDumpsDir, +#endif }; command_line->CopySwitchesFrom(browser_cmd, kSwitchNames, arraysize(kSwitchNames)); @@ -763,6 +831,21 @@ std::string CefContentBrowserClient::GetDefaultDownloadName() { return "download"; } + +#if defined(OS_POSIX) && !defined(OS_MACOSX) +void CefContentBrowserClient::GetAdditionalMappedFilesForChildProcess( + const CommandLine& command_line, + int child_process_id, + std::vector* mappings) { + int crash_signal_fd = GetCrashSignalFD(command_line); + if (crash_signal_fd >= 0) { + mappings->push_back(content::FileDescriptorInfo( + kCrashDumpSignal, base::FileDescriptor(crash_signal_fd, false))); + } +} +#endif // defined(OS_POSIX) && !defined(OS_MACOSX) + + #if defined(OS_WIN) const wchar_t* CefContentBrowserClient::GetResourceDllName() { static wchar_t file_path[MAX_PATH+1] = {0}; diff --git a/libcef/browser/content_browser_client.h b/libcef/browser/content_browser_client.h index e9cabda65..2c4873550 100644 --- a/libcef/browser/content_browser_client.h +++ b/libcef/browser/content_browser_client.h @@ -132,6 +132,13 @@ class CefContentBrowserClient : public content::ContentBrowserClient { content::BrowserURLHandler* handler) OVERRIDE; virtual std::string GetDefaultDownloadName() OVERRIDE; +#if defined(OS_POSIX) && !defined(OS_MACOSX) + virtual void GetAdditionalMappedFilesForChildProcess( + const CommandLine& command_line, + int child_process_id, + std::vector* mappings) OVERRIDE; +#endif + #if defined(OS_WIN) const wchar_t* GetResourceDllName() OVERRIDE; #endif diff --git a/libcef/common/breakpad_client.cc b/libcef/common/breakpad_client.cc new file mode 100644 index 000000000..9c9201a89 --- /dev/null +++ b/libcef/common/breakpad_client.cc @@ -0,0 +1,58 @@ +// Copyright 2013 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 "libcef/common/breakpad_client.h" +#include "libcef/common/cef_switches.h" +#include "include/cef_version.h" + +#include "base/command_line.h" +#include "base/logging.h" +#include "base/files/file_path.h" +#include "base/strings/string16.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" + +CefBreakpadClient::CefBreakpadClient() {} +CefBreakpadClient::~CefBreakpadClient() {} + +#if defined(OS_WIN) +void CefBreakpadClient::GetProductNameAndVersion( + const base::FilePath& exe_path, + base::string16* product_name, + base::string16* version, + base::string16* special_build, + base::string16* channel_name) { + *product_name = ASCIIToUTF16("cef"); + *version = UTF8ToUTF16(base::StringPrintf( + "%d.%d.%d", CEF_VERSION_MAJOR, CHROME_VERSION_BUILD, CEF_REVISION)); + *special_build = string16(); + *channel_name = string16(); +} +#endif + +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) +void CefBreakpadClient::GetProductNameAndVersion(std::string* product_name, + std::string* version) { + *product_name = "cef"; + *version = base::StringPrintf( + "%d.%d.%d", CEF_VERSION_MAJOR, CHROME_VERSION_BUILD, CEF_REVISION); +} + +base::FilePath CefBreakpadClient::GetReporterLogFilename() { + return base::FilePath(FILE_PATH_LITERAL("uploads.log")); +} +#endif + +bool CefBreakpadClient::GetCrashDumpLocation(base::FilePath* crash_dir) { +#if !defined(OS_WIN) + if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kCrashDumpsDir)) + return false; + *crash_dir = CommandLine::ForCurrentProcess()->GetSwitchValuePath( + switches::kCrashDumpsDir); + return true; +#else + NOTREACHED(); + return false; +#endif +} diff --git a/libcef/common/breakpad_client.h b/libcef/common/breakpad_client.h new file mode 100644 index 000000000..964a9ecaa --- /dev/null +++ b/libcef/common/breakpad_client.h @@ -0,0 +1,43 @@ +// Copyright 2013 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. + +#ifndef CEF_LIBCEF_COMMON_BREAKPAD_CLIENT_H_ +#define CEF_LIBCEF_COMMON_BREAKPAD_CLIENT_H_ + +#include "base/compiler_specific.h" +#include "components/breakpad/app/breakpad_client.h" + +class CefBreakpadClient : public breakpad::BreakpadClient { + public: + CefBreakpadClient(); + virtual ~CefBreakpadClient(); + +#if defined(OS_WIN) + // Returns a textual description of the product type and version to include + // in the crash report. + virtual void GetProductNameAndVersion(const base::FilePath& exe_path, + base::string16* product_name, + base::string16* version, + base::string16* special_build, + base::string16* channel_name) OVERRIDE; +#endif + +#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_IOS) + // Returns a textual description of the product type and version to include + // in the crash report. + virtual void GetProductNameAndVersion(std::string* product_name, + std::string* version) OVERRIDE; + + virtual base::FilePath GetReporterLogFilename() OVERRIDE; +#endif + + // The location where minidump files should be written. Returns true if + // |crash_dir| was set. + virtual bool GetCrashDumpLocation(base::FilePath* crash_dir) OVERRIDE; + +private: + DISALLOW_COPY_AND_ASSIGN(CefBreakpadClient); +}; + +#endif // CEF_LIBCEF_COMMON_BREAKPAD_CLIENT_H_ diff --git a/libcef/common/cef_switches.cc b/libcef/common/cef_switches.cc index 7ef72eea9..8fd461570 100644 --- a/libcef/common/cef_switches.cc +++ b/libcef/common/cef_switches.cc @@ -86,4 +86,7 @@ const char kEnableSpeechInput[] = "enable-speech-input"; // Enable the speech input profanity filter. const char kEnableProfanityFilter[] = "enable-profanity-filter"; +// The directory breakpad should store minidumps in. +const char kCrashDumpsDir[] = "crash-dumps-dir"; + } // namespace switches diff --git a/libcef/common/cef_switches.h b/libcef/common/cef_switches.h index 2ca072214..26826d534 100644 --- a/libcef/common/cef_switches.h +++ b/libcef/common/cef_switches.h @@ -39,6 +39,7 @@ extern const char kPersistSessionCookies[]; extern const char kEnableMediaStream[]; extern const char kEnableSpeechInput[]; extern const char kEnableProfanityFilter[]; +extern const char kCrashDumpsDir[]; } // namespace switches diff --git a/libcef/common/main_delegate.cc b/libcef/common/main_delegate.cc index f2a42f1a7..b6496214a 100644 --- a/libcef/common/main_delegate.cc +++ b/libcef/common/main_delegate.cc @@ -5,13 +5,16 @@ #include "libcef/common/main_delegate.h" #include "libcef/browser/content_browser_client.h" #include "libcef/browser/context.h" +#include "libcef/common/breakpad_client.h" #include "libcef/common/cef_switches.h" #include "libcef/common/command_line_impl.h" #include "libcef/renderer/content_renderer_client.h" +#include "base/base_switches.h" #include "base/command_line.h" #include "base/files/file_path.h" #include "base/file_util.h" +#include "base/lazy_instance.h" #include "base/path_service.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" @@ -28,16 +31,26 @@ #if defined(OS_WIN) #include // NOLINT(build/include_order) +#include "components/breakpad/app/breakpad_win.h" #endif #if defined(OS_MACOSX) +#include "base/mac/os_crash_dumps.h" #include "base/mac/bundle_locations.h" #include "base/mac/foundation_util.h" +#include "components/breakpad/app/breakpad_mac.h" #include "content/public/common/content_paths.h" #endif +#if defined(OS_POSIX) && !defined(OS_MACOSX) +#include "components/breakpad/app/breakpad_linux.h" +#endif + namespace { +base::LazyInstance::Leaky g_shell_breakpad_client = + LAZY_INSTANCE_INITIALIZER; + #if defined(OS_MACOSX) base::FilePath GetFrameworksPath() { @@ -345,6 +358,26 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) { void CefMainDelegate::PreSandboxStartup() { const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableCrashReporter)) { + breakpad::SetBreakpadClient(g_shell_breakpad_client.Pointer()); +#if defined(OS_MACOSX) + base::mac::DisableOSCrashDumps(); + breakpad::InitCrashReporter(); + breakpad::InitCrashProcessInfo(); +#elif defined(OS_POSIX) && !defined(OS_MACOSX) + std::string process_type = command_line.GetSwitchValueASCII( + switches::kProcessType); + if (process_type != switches::kZygoteProcess) + breakpad::InitCrashReporter(); +#elif defined(OS_WIN) + UINT new_flags = + SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX; + UINT existing_flags = SetErrorMode(new_flags); + SetErrorMode(existing_flags | new_flags); + breakpad::InitCrashReporter(); +#endif + } + #if defined(OS_MACOSX) if (!command_line.HasSwitch(switches::kProcessType)) { // Only override the child process path when executing the main process. @@ -396,6 +429,14 @@ void CefMainDelegate::ProcessExiting(const std::string& process_type) { ResourceBundle::CleanupSharedInstance(); } +#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) +void CefMainDelegate::ZygoteForked() { + if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableCrashReporter)) { + breakpad::InitCrashReporter(); + } +} +#endif content::ContentBrowserClient* CefMainDelegate::CreateContentBrowserClient() { browser_client_.reset(new CefContentBrowserClient); diff --git a/libcef/common/main_delegate.h b/libcef/common/main_delegate.h index e2181bb9e..440d19201 100644 --- a/libcef/common/main_delegate.h +++ b/libcef/common/main_delegate.h @@ -39,6 +39,9 @@ class CefMainDelegate : public content::ContentMainDelegate { const std::string& process_type, const content::MainFunctionParams& main_function_params) OVERRIDE; virtual void ProcessExiting(const std::string& process_type) OVERRIDE; +#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_MACOSX) + virtual void ZygoteForked() OVERRIDE; +#endif virtual content::ContentBrowserClient* CreateContentBrowserClient() OVERRIDE; virtual content::ContentRendererClient* CreateContentRendererClient() OVERRIDE; diff --git a/libcef/resources/framework-Info.plist b/libcef/resources/framework-Info.plist new file mode 100644 index 000000000..21f1d2058 --- /dev/null +++ b/libcef/resources/framework-Info.plist @@ -0,0 +1,18 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.chromium.ContentShell.framework + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + FMWK + CFBundleSignature + ???? + + diff --git a/tests/cefclient/client_handler.cpp b/tests/cefclient/client_handler.cpp index ef2b4f705..de3cbd267 100644 --- a/tests/cefclient/client_handler.cpp +++ b/tests/cefclient/client_handler.cpp @@ -475,7 +475,7 @@ void ClientHandler::OnRenderProcessTerminated(CefRefPtr browser, std::transform(url.begin(), url.end(), url.begin(), tolower); std::string startupURL = GetStartupURL(); - if (url.find(startupURL) != 0) + if (startupURL != "chrome://crash" && url.find(startupURL) != 0) frame->LoadURL(startupURL); } diff --git a/tools/distrib/cefclient.gyp b/tools/distrib/cefclient.gyp index 43257152a..97252baa4 100644 --- a/tools/distrib/cefclient.gyp +++ b/tools/distrib/cefclient.gyp @@ -5,6 +5,7 @@ { 'variables': { 'chromium_code': 1, + 'framework_name': 'Chromium Embedded Framework', 'linux_use_gold_binary': 0, 'linux_use_gold_flags': 0, 'conditions': [ @@ -147,26 +148,12 @@ ], 'copies': [ { - # Add library dependencies to the bundle. - 'destination': '<(PRODUCT_DIR)/cefclient.app/Contents/Frameworks/Chromium Embedded Framework.framework/Libraries/', - 'files': [ - '$(CONFIGURATION)/libcef.dylib', - '$(CONFIGURATION)/ffmpegsumo.so', - ], - }, - { - # Add other resources to the bundle. - 'destination': '<(PRODUCT_DIR)/cefclient.app/Contents/Frameworks/Chromium Embedded Framework.framework/', - 'files': [ - 'Resources/', - ], - }, - { - # Add the helper app. + # Add the framework and helper app. 'destination': '<(PRODUCT_DIR)/cefclient.app/Contents/Frameworks', 'files': [ - '<(PRODUCT_DIR)/cefclient Helper.app', + '$(CONFIGURATION)/<(framework_name).framework/', '$(CONFIGURATION)/libplugin_carbon_interpose.dylib', + '<(PRODUCT_DIR)/cefclient Helper.app', ], }, ], @@ -176,8 +163,8 @@ 'action': [ 'install_name_tool', '-change', - '@executable_path/libcef.dylib', - '@executable_path/../Frameworks/Chromium Embedded Framework.framework/Libraries/libcef.dylib', + '@executable_path/<(framework_name)', + '@executable_path/../Frameworks/<(framework_name).framework/<(framework_name)', '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' ], }, @@ -202,7 +189,7 @@ 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', '$(SDKROOT)/System/Library/Frameworks/OpenGL.framework', - '$(CONFIGURATION)/libcef.dylib', + '$(CONFIGURATION)/<(framework_name).framework/<(framework_name)', ], }, 'sources': [ @@ -320,7 +307,7 @@ 'link_settings': { 'libraries': [ '$(SDKROOT)/System/Library/Frameworks/AppKit.framework', - '$(CONFIGURATION)/libcef.dylib', + '$(CONFIGURATION)/<(framework_name).framework/<(framework_name)', ], }, 'sources': [ @@ -351,8 +338,8 @@ 'action': [ 'install_name_tool', '-change', - '@executable_path/libcef.dylib', - '@executable_path/../../../../Frameworks/Chromium Embedded Framework.framework/Libraries/libcef.dylib', + '@executable_path/<(framework_name)', + '@executable_path/../../../../Frameworks/<(framework_name).framework/<(framework_name)', '${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}' ], }, diff --git a/tools/distrib/mac/README.minimal.txt b/tools/distrib/mac/README.minimal.txt index ca029178e..0b276f8c1 100644 --- a/tools/distrib/mac/README.minimal.txt +++ b/tools/distrib/mac/README.minimal.txt @@ -1,12 +1,9 @@ CONTENTS -------- -Release Contains libcef.dylib and other components required to run the - release version of CEF-based applications. - -Resources Contains images and resources required by applications using CEF. - The contents of this folder should be transferred to the - Contents/Resources folder in the app bundle. +Release Contains the "Chromium Embedded Framework.framework" and other + components required to run the release version of CEF-based + applications. USAGE diff --git a/tools/distrib/mac/README.redistrib.txt b/tools/distrib/mac/README.redistrib.txt index 1524ee113..f413f9703 100644 --- a/tools/distrib/mac/README.redistrib.txt +++ b/tools/distrib/mac/README.redistrib.txt @@ -6,10 +6,67 @@ the "required" section must be redistributed with all applications using CEF. Components listed under the "optional" section may be excluded if the related features will not be used. +Applications using CEF on OS X must follow a specific app bundle structure. +Replace "cefclient" in the below example with your application name. + +cefclient.app/ + Contents/ + Frameworks/ + Chromium Embedded Framework.framework/ + Chromium Embedded Framework <= main application library + Libraries/ + ffmpegsumo.so <= HTML5 audio/video support library + Resources/ + cef.pak, devtools_resources.pak <= non-localized resources and strings + crash_inspector, crash_report_sender <= breakpad support + en.lproj/, ... <= locale-specific resources and strings + Info.plist + libplugin_carbon_interpose.dylib <= plugin support library + cefclient Helper.app/ + Contents/ + Info.plist + MacOS/ + cefclient Helper <= helper executable + Pkginfo + cefclient Helper EH.app/ + Contents/ + Info.plist + MacOS/ + cefclient Helper EH <= helper executable + Pkginfo + cefclient Helper NP.app/ + Contents/ + Info.plist + MacOS/ + cefclient Helper NP <= helper executable + Pkginfo + Info.plist + MacOS/ + cefclient <= cefclient application executable + Pkginfo + Resources/ + binding.html, ... <= cefclient application resources + +The "Chromium Embedded Framework.framework" is an unversioned framework that +contains CEF binaries and resources. Executables (cefclient, cefclient Helper, +etc) are linked to the "Chromium Embedded Framework" library using +install_name_tool and a path relative to @executable_path. + +The "cefclient Helper" apps are used for executing separate processes +(renderer, plugin, etc) with different characteristics. They need to have +separate app bundles and Info.plist files so that, among other things, they +don't show dock icons. The "EH" helper, which is used when launching plugin +processes, has the MH_NO_HEAP_EXECUTION bit cleared to allow an executable +heap. The "NP" helper, which is used when launching NaCl plugin processes +only, has the MH_PIE bit cleared to disable ASLR. This is set up as part of +the build process using scripts from the tools/ directory. Examine the Xcode +project included with the binary distribution or the originating cefclient.gyp +file for a better idea of the script dependencies. + Required components: -* CEF core library - libcef.dylib +* CEF framework library + Chromium Embedded Framework.framework/Chromium Embedded Framework * Plugin support library libplugin_carbon_interpose.dylib @@ -17,7 +74,7 @@ Required components: Optional components: * Localized resources - Resources/*.lproj/ + Chromium Embedded Framework.framework/Resources/*.lproj/ Note: Contains localized strings for WebKit UI controls. A .pak file is loaded from this folder based on the CefSettings.locale value. Only configured locales need to be distributed. If no locale is configured the default locale @@ -25,12 +82,18 @@ Optional components: CefSettings.pack_loading_disabled. * Other resources - Resources/cef.pak - Resources/devtools_resources.pak + Chromium Embedded Framework.framework/Resources/cef.pak + Chromium Embedded Framework.framework/Resources/devtools_resources.pak Note: Contains WebKit image and inspector resources. Pack file loading can be disabled completely using CefSettings.pack_loading_disabled. The resources directory path can be customized using CefSettings.resources_dir_path. * FFmpeg audio and video support - ffmpegsumo.so + Chromium Embedded Framework.framework/Libraries/ffmpegsumo.so Note: Without this component HTML5 audio and video will not function. + +* Breakpad support + Chromium Embedded Framework.framework/Resources/crash_inspector + Chromium Embedded Framework.framework/Resources/crash_report_sender + Chromium Embedded Framework.framework/Resources/Info.plist + Note: Without these components breakpad support will not function. diff --git a/tools/distrib/mac/README.standard.txt b/tools/distrib/mac/README.standard.txt index a37501cf8..bbfe995fc 100644 --- a/tools/distrib/mac/README.standard.txt +++ b/tools/distrib/mac/README.standard.txt @@ -4,20 +4,18 @@ CONTENTS cefclient Contains the cefclient sample application configured to build using the files in this distribution. -Debug Contains libcef.dylib and other components required to run the debug - version of CEF-based applications. +Debug Contains the "Chromium Embedded Framework.framework" and other + components required to run the debug version of CEF-based + applications. include Contains all required CEF header files. libcef_dll Contains the source code for the libcef_dll_wrapper static library that all applications using the CEF C++ API must link against. -Release Contains libcef.dylib and other components required to run the - release version of CEF-based applications. - -Resources Contains images and resources required by applications using CEF. - The contents of this folder should be transferred to the - Contents/Resources folder in the app bundle. +Release Contains the "Chromium Embedded Framework.framework" and other + components required to run the release version of CEF-based + applications. tools Scripts that perform post-processing on Mac release targets. @@ -27,10 +25,6 @@ USAGE Xcode 3 and 4: Open the cefclient.xcodeproj project and build. -When using Xcode 4.2 or newer you will need to change the "Compiler for -C/C++/Objective-C" setting to "LLVM GCC 4.2" under "Build Settings" for -each target. - Please visit the CEF Website for additional usage information. http://code.google.com/p/chromiumembedded diff --git a/tools/make_distrib.py b/tools/make_distrib.py index 331d1d34f..437fdb640 100644 --- a/tools/make_distrib.py +++ b/tools/make_distrib.py @@ -221,12 +221,22 @@ def create_xcode_projects(): gyper = [ 'python', 'tools/gyp_cef', os.path.relpath(os.path.join(output_dir, 'cefclient.gyp'), cef_dir) ] RunAction(cef_dir, gyper); - # Post-process the Xcode project to fix file paths + # Post-process the Xcode project file. src_file = os.path.join(output_dir, 'cefclient.xcodeproj/project.pbxproj') data = read_file(src_file) + + # Fix file paths. data = data.replace('../../../build/mac/', 'tools/') data = data.replace('../../../build', 'build') data = data.replace('../../../xcodebuild', 'xcodebuild') + + # Fix framework type. + data = data.replace('lastKnownFileType = text; name = "Chromium Embedded Framework";', \ + 'explicitFileType = "compiled.mach-o.dylib"; name = "Chromium Embedded Framework";') + + # Fix target compiler. + data = data.replace('GCC_VERSION = 4.2;', 'GCC_VERSION = com.apple.compilers.llvm.clang.1_0;') + write_file(src_file, data) def create_make_projects(): @@ -588,6 +598,7 @@ elif platform == 'macosx': out_dir = os.path.join(src_dir, 'xcodebuild') valid_build_dir = None + framework_name = 'Chromium Embedded Framework' if mode == 'standard': # transfer Debug files @@ -596,8 +607,8 @@ elif platform == 'macosx': valid_build_dir = build_dir dst_dir = os.path.join(output_dir, 'Debug') make_dir(dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) + copy_dir(os.path.join(build_dir, 'cefclient.app/Contents/Frameworks/%s.framework' % framework_name), \ + os.path.join(dst_dir, '%s.framework' % framework_name), options.quiet) copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) # transfer Release files @@ -607,8 +618,8 @@ elif platform == 'macosx': dst_dir = os.path.join(output_dir, 'Release') make_dir(dst_dir, options.quiet) if mode != 'client': - copy_file(os.path.join(build_dir, 'ffmpegsumo.so'), dst_dir, options.quiet) - copy_file(os.path.join(build_dir, 'libcef.dylib'), dst_dir, options.quiet) + copy_dir(os.path.join(build_dir, 'cefclient.app/Contents/Frameworks/%s.framework' % framework_name), \ + os.path.join(dst_dir, '%s.framework' % framework_name), options.quiet) copy_file(os.path.join(build_dir, 'libplugin_carbon_interpose.dylib'), dst_dir, options.quiet) else: copy_dir(os.path.join(build_dir, 'cefclient.app'), os.path.join(dst_dir, 'cefclient.app'), options.quiet) @@ -619,17 +630,10 @@ elif platform == 'macosx': # create the real dSYM file from the "fake" dSYM file sys.stdout.write("Creating the real dSYM file...\n") - src_path = os.path.join(build_dir, 'libcef.dylib.dSYM/Contents/Resources/DWARF/libcef.dylib') - dst_path = os.path.join(symbol_output_dir, 'libcef.dylib.dSYM') - run('dsymutil '+src_path+' -o '+dst_path, cef_dir) - - if not valid_build_dir is None and mode != 'client': - # transfer resource files - build_dir = valid_build_dir - dst_dir = os.path.join(output_dir, 'Resources') - make_dir(dst_dir, options.quiet) - copy_files(os.path.join(build_dir, 'cefclient.app/Contents/Frameworks/Chromium Embedded Framework.framework/Resources/*.*'), \ - dst_dir, options.quiet) + src_path = os.path.join(build_dir, \ + '%s.framework.dSYM/Contents/Resources/DWARF/%s' % (framework_name, framework_name)) + dst_path = os.path.join(symbol_output_dir, '%s.dSYM' % framework_name) + run('dsymutil "%s" -o "%s"' % (src_path, dst_path), cef_dir) if mode == 'standard': # transfer include files