Add sandbox support (issue #524).

- The sandbox is now enabled by default on all platforms. Use the CefSettings.no_sandbox option or the "no-sandbox" command-line flag to disable sandbox support.
- Windows: See cef_sandbox_win.h for requirements to enable sandbox support.
- Windows: If Visual Studio isn't installed in the standard location set the CEF_VCVARS environment variable before running make_distrib.py or automate.py (see msvs_env.bat).
- Linux: For binary distributions a new chrome-sandbox executable with SUID permissions must be placed next to the CEF executable. See https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment for details on setting up the development environment when building CEF from source code.

git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1518 5089003a-bbd8-11dd-ad1f-f1f9622dbc98
This commit is contained in:
Marshall Greenblatt 2013-11-15 18:47:02 +00:00
parent 395f443215
commit f5bc72b234
24 changed files with 485 additions and 52 deletions

32
cef.gyp
View File

@ -59,6 +59,9 @@
},
'conditions': [
['OS=="win"', {
'dependencies': [
'cef_sandbox',
],
'configurations': {
'Debug_Base': {
'msvs_settings': {
@ -72,7 +75,6 @@
'VCLinkerTool': {
# Set /SUBSYSTEM:WINDOWS.
'SubSystem': '2',
'EntryPointSymbol' : 'wWinMainCRTStartup',
},
'VCManifestTool': {
'AdditionalManifestFiles': [
@ -94,7 +96,7 @@
'<@(cefclient_sources_win)',
],
}],
['OS == "win"', {
[ 'toolkit_uses_gtk == 1', {
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
@ -304,6 +306,9 @@
],
'conditions': [
[ 'OS=="win"', {
'dependencies': [
'cef_sandbox',
],
'sources': [
'tests/cefclient/cefclient.rc',
'tests/cefclient/resource_util_win.cpp',
@ -316,6 +321,11 @@
},
},
}],
[ 'toolkit_uses_gtk == 1', {
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
}],
[ 'OS=="mac"', {
'product_name': 'cef_unittests',
'dependencies': [
@ -1383,5 +1393,23 @@
},
],
}], # OS=="linux" or OS=="freebsd" or OS=="openbsd"
[ 'OS=="win"', {
'targets': [
{
'target_name': 'cef_sandbox',
'type': 'static_library',
'msvs_guid': 'C90B9CA2-2BD2-4140-9DB8-4474785FF360',
'dependencies': [
'<(DEPTH)/sandbox/sandbox.gyp:sandbox',
],
'include_dirs': [
'.',
],
'sources': [
'libcef_dll/sandbox/sandbox_win.cc',
],
},
],
}], # OS=="win"
],
}

View File

@ -41,6 +41,7 @@
'include/wrapper/cef_zip_archive.h',
],
'includes_win': [
'include/cef_sandbox_win.h',
'include/internal/cef_types_win.h',
'include/internal/cef_win.h',
],

View File

@ -53,19 +53,23 @@ extern "C" {
// called for the browser process (identified by no "type" command-line value)
// it will return immediately with a value of -1. If called for a recognized
// secondary process it will block until the process should exit and then return
// the process exit code. The |application| parameter may be NULL.
// the process exit code. The |application| parameter may be NULL. The
// |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
// cef_sandbox_win.h for details).
///
CEF_EXPORT int cef_execute_process(const struct _cef_main_args_t* args,
struct _cef_app_t* application);
struct _cef_app_t* application, void* windows_sandbox_info);
///
// This function should be called on the main application thread to initialize
// the CEF browser process. The |application| parameter may be NULL. A return
// value of true (1) indicates that it succeeded and false (0) indicates that it
// failed.
// failed. The |windows_sandbox_info| parameter is only used on Windows and may
// be NULL (see cef_sandbox_win.h for details).
///
CEF_EXPORT int cef_initialize(const struct _cef_main_args_t* args,
const struct _cef_settings_t* settings, struct _cef_app_t* application);
const struct _cef_settings_t* settings, struct _cef_app_t* application,
void* windows_sandbox_info);
///
// This function should be called on the main application thread to shut down

View File

@ -56,19 +56,29 @@ class CefApp;
// called for the browser process (identified by no "type" command-line value)
// it will return immediately with a value of -1. If called for a recognized
// secondary process it will block until the process should exit and then return
// the process exit code. The |application| parameter may be empty.
// the process exit code. The |application| parameter may be empty. The
// |windows_sandbox_info| parameter is only used on Windows and may be NULL (see
// cef_sandbox_win.h for details).
///
/*--cef(api_hash_check,optional_param=application)--*/
int CefExecuteProcess(const CefMainArgs& args, CefRefPtr<CefApp> application);
/*--cef(api_hash_check,optional_param=application,
optional_param=windows_sandbox_info)--*/
int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application,
void* windows_sandbox_info);
///
// This function should be called on the main application thread to initialize
// the CEF browser process. The |application| parameter may be empty. A return
// value of true indicates that it succeeded and false indicates that it failed.
// The |windows_sandbox_info| parameter is only used on Windows and may be NULL
// (see cef_sandbox_win.h for details).
///
/*--cef(api_hash_check,optional_param=application)--*/
bool CefInitialize(const CefMainArgs& args, const CefSettings& settings,
CefRefPtr<CefApp> application);
/*--cef(api_hash_check,optional_param=application,
optional_param=windows_sandbox_info)--*/
bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application,
void* windows_sandbox_info);
///
// This function should be called on the main application thread to shut down

92
include/cef_sandbox_win.h Normal file
View File

@ -0,0 +1,92 @@
// Copyright (c) 2013 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_CEF_SANDBOX_WIN_H_
#define CEF_INCLUDE_CEF_SANDBOX_WIN_H_
#pragma once
#include "include/cef_base.h"
#if defined(OS_WIN)
#ifdef __cplusplus
extern "C" {
#endif
// The sandbox is used to restrict sub-processes (renderer, plugin, GPU, etc)
// from directly accessing system resources. This helps to protect the user
// from untrusted and potentially malicious Web content.
// See http://www.chromium.org/developers/design-documents/sandbox for
// complete details.
//
// To enable the sandbox on Windows the following requirements must be met:
// 1. Use the same executable for the browser process and all sub-processes.
// 2. Link the executable with the cef_sandbox static library.
// 3. Call the cef_sandbox_info_create() function from within the executable
// (not from a separate DLL) and pass the resulting pointer into both the
// CefExecutProcess() and CefInitialize() functions via the
// |windows_sandbox_info| parameter.
///
// Create the sandbox information object for this process. It is safe to create
// multiple of this object and to destroy the object immediately after passing
// into the CefExecutProcess() and/or CefInitialize() functions.
///
void* cef_sandbox_info_create();
///
// Destroy the specified sandbox information object.
///
void cef_sandbox_info_destroy(void* sandbox_info);
#ifdef __cplusplus
}
///
// Manages the life span of a sandbox information object.
///
class CefScopedSandboxInfo {
public:
CefScopedSandboxInfo() {
sandbox_info_ = cef_sandbox_info_create();
}
~CefScopedSandboxInfo() {
cef_sandbox_info_destroy(sandbox_info_);
}
void* sandbox_info() const { return sandbox_info_; }
private:
void* sandbox_info_;
};
#endif // __cplusplus
#endif // defined(OS_WIN)
#endif // CEF_INCLUDE_CEF_SANDBOX_WIN_H_

View File

@ -167,6 +167,13 @@ typedef struct _cef_settings_t {
///
bool single_process;
///
// Set to true (1) to disable the sandbox for sub-processes. See
// cef_sandbox_win.h for requirements to enable the sandbox on Windows. Also
// configurable using the "no-sandbox" command-line switch.
///
bool no_sandbox;
///
// The path to a separate executable that will be launched for sub-processes.
// By default the browser process executable is used. See the comments on

View File

@ -344,6 +344,7 @@ struct CefSettingsTraits {
static inline void set(const struct_type* src, struct_type* target,
bool copy) {
target->single_process = src->single_process;
target->no_sandbox = src->no_sandbox;
cef_string_set(src->browser_subprocess_path.str,
src->browser_subprocess_path.length,
&target->browser_subprocess_path, copy);

View File

@ -60,7 +60,8 @@ class CefForceShutdown {
} // namespace
int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application) {
CefRefPtr<CefApp> application,
void* windows_sandbox_info) {
CommandLine command_line(CommandLine::NO_PROGRAM);
#if defined(OS_WIN)
command_line.ParseFromString(::GetCommandLineW());
@ -89,9 +90,14 @@ int CefExecuteProcess(const CefMainArgs& args,
// Execute the secondary process.
#if defined(OS_WIN)
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
if (windows_sandbox_info == NULL) {
content::InitializeSandboxInfo(&sandbox_info);
windows_sandbox_info = &sandbox_info;
}
return content::ContentMain(args.instance, &sandbox_info, &main_delegate);
return content::ContentMain(args.instance,
static_cast<sandbox::SandboxInterfaceInfo*>(windows_sandbox_info),
&main_delegate);
#else
return content::ContentMain(args.argc, const_cast<const char**>(args.argv),
&main_delegate);
@ -100,7 +106,8 @@ int CefExecuteProcess(const CefMainArgs& args,
bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application) {
CefRefPtr<CefApp> application,
void* windows_sandbox_info) {
// Return true if the global context already exists.
if (g_context)
return true;
@ -116,7 +123,8 @@ bool CefInitialize(const CefMainArgs& args,
g_context = new CefContext();
// Initialize the global context.
return g_context->Initialize(args, settings, application);
return g_context->Initialize(args, settings, application,
windows_sandbox_info);
}
void CefShutdown() {
@ -222,7 +230,8 @@ CefContext* CefContext::Get() {
bool CefContext::Initialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application) {
CefRefPtr<CefApp> application,
void* windows_sandbox_info) {
init_thread_id_ = base::PlatformThread::CurrentId();
settings_ = settings;
@ -257,10 +266,15 @@ bool CefContext::Initialize(const CefMainArgs& args,
// Initialize the content runner.
#if defined(OS_WIN)
sandbox::SandboxInterfaceInfo sandbox_info = {0};
content::InitializeSandboxInfo(&sandbox_info);
if (windows_sandbox_info == NULL) {
content::InitializeSandboxInfo(&sandbox_info);
windows_sandbox_info = &sandbox_info;
settings_.no_sandbox = true;
}
exit_code = main_runner_->Initialize(args.instance, &sandbox_info,
main_delegate_.get());
exit_code = main_runner_->Initialize(args.instance,
static_cast<sandbox::SandboxInterfaceInfo*>(windows_sandbox_info),
main_delegate_.get());
#else
exit_code = main_runner_->Initialize(args.argc,
const_cast<const char**>(args.argv),

View File

@ -48,7 +48,8 @@ class CefContext : public content::NotificationObserver {
// These methods will be called on the main application thread.
bool Initialize(const CefMainArgs& args,
const CefSettings& settings,
CefRefPtr<CefApp> application);
CefRefPtr<CefApp> application,
void* windows_sandbox_info);
void Shutdown();
// Returns true if the current thread is the initialization thread.

View File

@ -166,15 +166,26 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
if (settings.single_process)
command_line->AppendSwitch(switches::kSingleProcess);
bool no_sandbox = settings.no_sandbox;
if (settings.browser_subprocess_path.length > 0) {
base::FilePath file_path =
base::FilePath(CefString(&settings.browser_subprocess_path));
if (!file_path.empty()) {
command_line->AppendSwitchPath(switches::kBrowserSubprocessPath,
file_path);
#if defined(OS_WIN)
// The sandbox is not supported when using a separate subprocess
// executable on Windows.
no_sandbox = true;
#endif
}
}
if (no_sandbox)
command_line->AppendSwitch(switches::kNoSandbox);
if (settings.user_agent.length > 0) {
command_line->AppendSwitchASCII(switches::kUserAgent,
CefString(&settings.user_agent));
@ -267,10 +278,6 @@ bool CefMainDelegate::BasicStartupComplete(int* exit_code) {
command_line->AppendSwitchASCII(switches::kContextSafetyImplementation,
base::IntToString(settings.context_safety_implementation));
}
// TODO(cef): Figure out how to support the sandbox.
if (!command_line->HasSwitch(switches::kNoSandbox))
command_line->AppendSwitch(switches::kNoSandbox);
}
if (content_client_.application().get()) {

View File

@ -109,14 +109,14 @@
// GLOBAL FUNCTIONS - Body may be edited by hand.
CEF_EXPORT int cef_execute_process(const struct _cef_main_args_t* args,
struct _cef_app_t* application) {
struct _cef_app_t* application, void* windows_sandbox_info) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: args; type: struct_byref_const
DCHECK(args);
if (!args)
return 0;
// Unverified params: application
// Unverified params: application, windows_sandbox_info
// Translate param: args; type: struct_byref_const
CefMainArgs argsObj;
@ -126,14 +126,16 @@ CEF_EXPORT int cef_execute_process(const struct _cef_main_args_t* args,
// Execute
int _retval = CefExecuteProcess(
argsObj,
CefAppCToCpp::Wrap(application));
CefAppCToCpp::Wrap(application),
windows_sandbox_info);
// Return type: simple
return _retval;
}
CEF_EXPORT int cef_initialize(const struct _cef_main_args_t* args,
const struct _cef_settings_t* settings, struct _cef_app_t* application) {
const struct _cef_settings_t* settings, struct _cef_app_t* application,
void* windows_sandbox_info) {
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Verify param: args; type: struct_byref_const
@ -144,7 +146,7 @@ CEF_EXPORT int cef_initialize(const struct _cef_main_args_t* args,
DCHECK(settings);
if (!settings)
return 0;
// Unverified params: application
// Unverified params: application, windows_sandbox_info
// Translate param: args; type: struct_byref_const
CefMainArgs argsObj;
@ -159,7 +161,8 @@ CEF_EXPORT int cef_initialize(const struct _cef_main_args_t* args,
bool _retval = CefInitialize(
argsObj,
settingsObj,
CefAppCToCpp::Wrap(application));
CefAppCToCpp::Wrap(application),
windows_sandbox_info);
// Return type: bool
return _retval;

View File

@ -0,0 +1,36 @@
// Copyright 2013 The Chromium Embedded Framework Authors. Portions Copyright
// 2011 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 "include/cef_sandbox_win.h"
#include "sandbox/win/src/process_mitigations.h"
#include "sandbox/win/src/sandbox_factory.h"
namespace {
// From content/app/startup_helper_win.cc:
void InitializeSandboxInfo(sandbox::SandboxInterfaceInfo* info) {
info->broker_services = sandbox::SandboxFactory::GetBrokerServices();
if (!info->broker_services) {
info->target_services = sandbox::SandboxFactory::GetTargetServices();
} else {
// Ensure the proper mitigations are enforced for the browser process.
sandbox::ApplyProcessMitigationsToCurrentProcess(
sandbox::MITIGATION_DEP |
sandbox::MITIGATION_DEP_NO_ATL_THUNK);
}
}
} // namespace
void* cef_sandbox_info_create() {
sandbox::SandboxInterfaceInfo* info = new sandbox::SandboxInterfaceInfo();
memset(info, 0, sizeof(sandbox::SandboxInterfaceInfo));
InitializeSandboxInfo(info);
return info;
}
void cef_sandbox_info_destroy(void* sandbox_info) {
delete static_cast<sandbox::SandboxInterfaceInfo*>(sandbox_info);
}

View File

@ -113,7 +113,7 @@
// GLOBAL METHODS - Body may be edited by hand.
CEF_GLOBAL int CefExecuteProcess(const CefMainArgs& args,
CefRefPtr<CefApp> application) {
CefRefPtr<CefApp> application, void* windows_sandbox_info) {
const char* api_hash = cef_api_hash(0);
if (strcmp(api_hash, CEF_API_HASH_PLATFORM)) {
// The libcef API hash does not match the current header API hash.
@ -123,19 +123,21 @@ CEF_GLOBAL int CefExecuteProcess(const CefMainArgs& args,
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: application
// Unverified params: application, windows_sandbox_info
// Execute
int _retval = cef_execute_process(
&args,
CefAppCppToC::Wrap(application));
CefAppCppToC::Wrap(application),
windows_sandbox_info);
// Return type: simple
return _retval;
}
CEF_GLOBAL bool CefInitialize(const CefMainArgs& args,
const CefSettings& settings, CefRefPtr<CefApp> application) {
const CefSettings& settings, CefRefPtr<CefApp> application,
void* windows_sandbox_info) {
const char* api_hash = cef_api_hash(0);
if (strcmp(api_hash, CEF_API_HASH_PLATFORM)) {
// The libcef API hash does not match the current header API hash.
@ -145,13 +147,14 @@ CEF_GLOBAL bool CefInitialize(const CefMainArgs& args,
// AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING
// Unverified params: application
// Unverified params: application, windows_sandbox_info
// Execute
int _retval = cef_initialize(
&args,
&settings,
CefAppCppToC::Wrap(application));
CefAppCppToC::Wrap(application),
windows_sandbox_info);
// Return type: bool
return _retval?true:false;

View File

@ -263,7 +263,7 @@ int main(int argc, char* argv[]) {
CefRefPtr<ClientApp> app(new ClientApp);
// Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, app.get());
int exit_code = CefExecuteProcess(main_args, app.get(), NULL);
if (exit_code >= 0)
return exit_code;
@ -286,7 +286,7 @@ int main(int argc, char* argv[]) {
AppGetSettings(settings);
// Initialize CEF.
CefInitialize(main_args, settings, app.get());
CefInitialize(main_args, settings, app.get(), NULL);
// Register the scheme handler.
scheme_test::InitTest();

View File

@ -468,7 +468,7 @@ int main(int argc, char* argv[]) {
CefRefPtr<ClientApp> app(new ClientApp);
// Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, app.get());
int exit_code = CefExecuteProcess(main_args, app.get(), NULL);
if (exit_code >= 0)
return exit_code;
@ -490,7 +490,7 @@ int main(int argc, char* argv[]) {
AppGetSettings(settings);
// Initialize CEF.
CefInitialize(main_args, settings, app.get());
CefInitialize(main_args, settings, app.get(), NULL);
// Register the scheme handler.
scheme_test::InitTest();

View File

@ -13,6 +13,7 @@
#include "include/cef_browser.h"
#include "include/cef_frame.h"
#include "include/cef_runnable.h"
#include "include/cef_sandbox_win.h"
#include "cefclient/cefclient_osr_widget_win.h"
#include "cefclient/client_handler.h"
#include "cefclient/client_switches.h"
@ -66,11 +67,15 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// Manages the life span of the sandbox information object.
CefScopedSandboxInfo scoped_sandbox;
CefMainArgs main_args(hInstance);
CefRefPtr<ClientApp> app(new ClientApp);
// Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, app.get());
int exit_code = CefExecuteProcess(main_args, app.get(),
scoped_sandbox.sandbox_info());
if (exit_code >= 0)
return exit_code;
@ -87,7 +92,7 @@ int APIENTRY wWinMain(HINSTANCE hInstance,
AppGetSettings(settings);
// Initialize CEF.
CefInitialize(main_args, settings, app.get());
CefInitialize(main_args, settings, app.get(), scoped_sandbox.sandbox_info());
// Register the scheme handler.
scheme_test::InitTest();

View File

@ -28,5 +28,5 @@ int main(int argc, char* argv[]) {
CefRefPtr<CefApp> app(new ClientApp);
// Execute the secondary process.
return CefExecuteProcess(main_args, app);
return CefExecuteProcess(main_args, app, NULL);
}

View File

@ -14,6 +14,10 @@
// Include after base/bind.h to avoid name collisions with cef_tuple.h.
#include "include/cef_runnable.h"
#if defined(OS_WIN)
#include "include/cef_sandbox_win.h"
#endif
namespace {
// Thread used to run the test suite.
@ -60,10 +64,18 @@ int main(int argc, char* argv[]) {
CefMainArgs main_args(argc, argv);
#endif
void* windows_sandbox_info = NULL;
#if defined(OS_WIN)
// Manages the life span of the sandbox information object.
CefScopedSandboxInfo scoped_sandbox;
windows_sandbox_info = scoped_sandbox.sandbox_info();
#endif
CefRefPtr<CefApp> app(new ClientApp);
// Execute the secondary process, if any.
int exit_code = CefExecuteProcess(main_args, app);
int exit_code = CefExecuteProcess(main_args, app, windows_sandbox_info);
if (exit_code >= 0)
return exit_code;
@ -80,7 +92,7 @@ int main(int argc, char* argv[]) {
#endif
// Initialize CEF.
CefInitialize(main_args, settings, app);
CefInitialize(main_args, settings, app, windows_sandbox_info);
// Create the test suite object.
CefTestSuite test_suite(argc, argv);

View File

@ -561,7 +561,9 @@ if any_changed or options.forcebuild:
command = 'ninja -v -C'
target = ' cefclient'
if options.buildtests:
target = ' cefclient cef_unittests'
target = target + ' cef_unittests'
if platform == 'linux':
target = target + ' chrome_sandbox'
build_dir_suffix = ''
if platform == 'windows' and options.x64build:
build_dir_suffix = '_x64'

118
tools/combine_libs.py Normal file
View File

@ -0,0 +1,118 @@
#!/usr/bin/env python
# Copyright (c) 2011 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.
# TODO(slightlyoff): move to using shared version of this script.
'''This script makes it easy to combine libs and object files to a new lib,
optionally removing some of the object files in the input libs by regular
expression matching.
For usage information, run the script with a --help argument.
'''
import optparse
import os
import re
import subprocess
import sys
def Shell(*args):
'''Runs the program and args in args, returns the output from the program.'''
process = subprocess.Popen(args,
stdin = None,
stdout = subprocess.PIPE,
stderr = subprocess.STDOUT)
output = process.stdout.readlines()
process.wait()
retcode = process.returncode
if retcode != 0:
raise RuntimeError('%s exited with status %d' % (args[0], retcode))
return output
def CollectRemovals(remove_re, inputs):
'''Returns a list of all object files in inputs that match remove_re.'''
removals = []
for input in inputs:
output = Shell('lib.exe', '/list', input)
for line in output:
line = line.rstrip()
if remove_re.search(line):
removals.append(line)
return removals
def CombineLibraries(output, remove_re, inputs):
'''Combines all the libraries and objects in inputs, while removing any
object files that match remove_re.
'''
removals = []
if remove_re:
removals = CollectRemovals(remove_re, inputs)
if len(removals) > 0:
print 'Removals: ', removals
args = ['lib.exe', '/out:%s' % output]
args += ['/remove:%s' % obj for obj in removals]
args += inputs
Shell(*args)
USAGE = '''usage: %prog [options] <lib or obj>+
Combines input libraries or objects into an output library, while removing
any object file (in the input libraries) that matches a given regular
expression.
'''
def GetOptionParser():
parser = optparse.OptionParser(USAGE)
parser.add_option('-o', '--output', dest = 'output',
help = 'write to this output library')
parser.add_option('-r', '--remove', dest = 'remove',
help = 'object files matching this regexp will be removed '
'from the output library')
return parser
def Main():
'''Main function for this script'''
parser = GetOptionParser()
(opt, args) = parser.parse_args()
output = opt.output
remove = opt.remove
if not output:
parser.error('You must specify an output file')
if not args:
parser.error('You must specify at least one object or library')
output = output.strip()
if remove:
remove = remove.strip()
if remove:
try:
remove_re = re.compile(opt.remove)
except:
parser.error('%s is not a valid regular expression' % opt.remove)
else:
remove_re = None
if sys.platform != 'win32' and sys.platform != 'cygwin':
parser.error('this script only works on Windows for now')
# If this is set, we can't capture lib.exe's output.
if 'VS_UNICODE_OUTPUT' in os.environ:
del os.environ['VS_UNICODE_OUTPUT']
CombineLibraries(output, remove_re, args)
return 0
if __name__ == '__main__':
sys.exit(Main())

View File

@ -97,7 +97,6 @@
'VCLinkerTool': {
# Set /SUBSYSTEM:WINDOWS.
'SubSystem': '2',
'EntryPointSymbol' : 'wWinMainCRTStartup',
},
'VCManifestTool': {
'AdditionalManifestFiles': [
@ -112,7 +111,8 @@
'-lrpcrt4.lib',
'-lopengl32.lib',
'-lglu32.lib',
'-l$(ConfigurationName)/libcef.lib'
'-l$(ConfigurationName)/libcef.lib',
'-l$(ConfigurationName)/cef_sandbox.lib',
],
},
'sources': [
@ -224,6 +224,7 @@
'Resources/cef.pak',
'Resources/devtools_resources.pak',
'Resources/locales/',
'$(BUILDTYPE)/chrome-sandbox',
'$(BUILDTYPE)/libcef.so',
'$(BUILDTYPE)/libffmpegsumo.so',
],

View File

@ -3,6 +3,10 @@ if [ -z "$1" ]; then
echo "ERROR: Please specify a build target: Debug or Release"
else
make -j8 cefclient BUILDTYPE=$1
if [ $? -eq 0 ]; then
echo "Giving SUID permissions to chrome-sandbox..."
echo "(using sudo so you may be asked for your password)"
sudo -- chown root:root "out/$1/chrome-sandbox" &&
sudo -- chmod 4755 "out/$1/chrome-sandbox"
fi
fi

View File

@ -169,6 +169,16 @@ def transfer_files(cef_dir, script_dir, transfer_cfg, output_dir, quiet):
new_path = cfg['new_header_path']
normalize_headers(dst, new_path)
def combine_libs(build_dir, libs, dest_lib):
""" Combine multiple static libraries into a single static library. """
cmdline = 'msvs_env.bat python combine_libs.py -o "%s"' % dest_lib
for lib in libs:
lib_path = os.path.join(build_dir, lib)
if not path_exists(lib_path):
raise Exception('Library not found: ' + lib_path)
cmdline = cmdline + ' "%s"' % lib_path
run(cmdline, os.path.join(cef_dir, 'tools'))
def generate_msvs_projects(version):
""" Generate MSVS projects for the specified version. """
sys.stdout.write('Generating '+version+' project files...')
@ -464,9 +474,23 @@ if platform == 'windows':
if options.ninjabuild:
out_dir = os.path.join(src_dir, 'out')
libcef_dll_file = 'libcef.dll.lib'
sandbox_libs = [
'obj\\base\\base.lib',
'obj\\base\\base_static.lib',
'obj\\cef\\cef_sandbox.lib',
'obj\\base\\third_party\\dynamic_annotations\\dynamic_annotations.lib',
'obj\\sandbox\\sandbox.lib',
]
else:
out_dir = os.path.join(src_dir, 'build')
libcef_dll_file = 'lib/libcef.lib'
sandbox_libs = [
'lib\\base.lib',
'lib\\base_static.lib',
'lib\\cef_sandbox.lib',
'lib\\dynamic_annotations.lib',
'lib\\sandbox.lib',
]
valid_build_dir = None
@ -485,6 +509,7 @@ if platform == 'windows':
copy_files(os.path.join(build_dir, '*.dll'), dst_dir, options.quiet)
copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \
options.quiet)
combine_libs(build_dir, sandbox_libs, os.path.join(dst_dir, 'cef_sandbox.lib'));
if not options.nosymbols:
# create the symbol output directory
@ -506,6 +531,7 @@ if platform == 'windows':
if mode != 'client':
copy_file(os.path.join(build_dir, libcef_dll_file), os.path.join(dst_dir, 'libcef.lib'), \
options.quiet)
combine_libs(build_dir, sandbox_libs, os.path.join(dst_dir, 'cef_sandbox.lib'));
else:
copy_file(os.path.join(build_dir, 'cefclient.exe'), dst_dir, options.quiet)
@ -644,6 +670,7 @@ elif platform == 'linux':
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, 'chrome_sandbox'), os.path.join(dst_dir, 'chrome-sandbox'), options.quiet)
copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet)
copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet)
else:
@ -663,6 +690,7 @@ elif platform == 'linux':
copy_file(os.path.join(build_dir, 'cefclient'), dst_dir, options.quiet)
else:
copy_file(os.path.join(build_dir, lib_dir_name, 'libcef.so'), dst_dir, options.quiet)
copy_file(os.path.join(build_dir, 'chrome_sandbox'), os.path.join(dst_dir, 'chrome-sandbox'), options.quiet)
copy_file(os.path.join(build_dir, 'libffmpegsumo.so'), dst_dir, options.quiet)
else:
sys.stderr.write("No Release build files.\n")

56
tools/msvs_env.bat Normal file
View File

@ -0,0 +1,56 @@
@echo off
:: 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.
:: Set up the environment for use with MSVS tools and then execute whatever
:: was specified on the command-line.
set RC=
setlocal
:: In case it's already provided via the environment.
set vcvars="%CEF_VCVARS%"
if exist %vcvars% goto found_vcvars
:: Hardcoded list of MSVS paths.
:: Alternatively we could 'reg query' this key:
:: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\10.0\Setup\VS;ProductDir
set vcvars="%PROGRAMFILES(X86)%\Microsoft Visual Studio 11.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
set vcvars="%PROGRAMFILES(X86)%\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
set vcvars="%PROGRAMFILES%\Microsoft Visual Studio 11.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
set vcvars="%PROGRAMFILES%\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
:: VS 2008 vcvars isn't standalone, it needs this env var.
set VS90COMNTOOLS=%PROGRAMFILES(X86)%\Microsoft Visual Studio 9.0\Common7\Tools\
set vcvars="%PROGRAMFILES(X86)%\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
set VS90COMNTOOLS=%PROGRAMFILES%\Microsoft Visual Studio 9.0\Common7\Tools\
set vcvars="%PROGRAMFILES%\Microsoft Visual Studio 9.0\VC\bin\vcvars32.bat"
if exist %vcvars% goto found_vcvars
set RC=1
echo Failed to find vcvars
goto end
:found_vcvars
echo vcvars:
echo %vcvars%
call %vcvars%
echo PATH:
echo %PATH%
%*
:end
endlocal & set RC=%ERRORLEVEL%
goto omega
:returncode
exit /B %RC%
:omega
call :returncode %RC%