Skip to content

Commit

Permalink
Fix printing on Linux (#238) and fix "undefined symbol" error (#230).
Browse files Browse the repository at this point in the history
Fix OnBeforePluginLoad and change args, see docs.

Add -std=gnu++11 flag to catch OVERRIDE errors.

Minor enhancements to makefiles.

Update build instructions - install python dependencies to make sure
that the right version of Cython is installed (must be exactly 0.19.2).
  • Loading branch information
cztomczak committed Jul 2, 2016
1 parent 22ade5c commit 7d47bfe
Show file tree
Hide file tree
Showing 23 changed files with 857 additions and 118 deletions.
14 changes: 9 additions & 5 deletions docs/Build-instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,26 @@ binaries from GH releases.

3) Install packages: `sudo apt-get install python-dev cmake g++`

4) Download 64-bit Linux binaries and libraries from
4) Install python dependencies by executing:
`cd cefpython/tools/ && pip install -r requirements.txt`
(Cython 0.19.2 required - the version must match exactly)

5) Download 64-bit Linux binaries and libraries from
[GH releases](https://github.com/cztomczak/cefpython/releases)
tagged 'v51-upstream'.


5) Copy "bin/*" to "cefpython/src/linux/binaries_64bit/"
6) Copy "bin/*" to "cefpython/src/linux/binaries_64bit/"

6) Copy "lib/*" to "cefpython/src/linux/setup/lib_64bit/" (create dir)
7) Copy "lib/*" to "cefpython/src/linux/setup/lib_64bit/" (create dir)

7) Build cefpython:
8) Build cefpython:
```
cd cefpython/src/linux/
python compile.py 51.0
```

8) As of writing only "pygtk_.py" and "kivy_.py" examples are working
9) As of writing only "pygtk_.py" and "kivy_.py" examples are working


## Requirements
Expand Down
25 changes: 21 additions & 4 deletions docs/api/RequestHandler.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,30 @@ to use [LoadHandler](LoadHandler.md)::OnLoadError() when implementing this on Li
| Parameter | Type |
| --- | --- |
| browser | [Browser](Browser.md) |
| url | string |
| policyUrl | string |
| mime_type | string |
| plugin_url | string |
| top_origin_url | string |
| info | [WebPluginInfo](WebPluginInfo.md) |
| __Return__ | bool |

Called on the browser process IO thread before a plugin is loaded. Return
True to block loading of the plugin.
Description from upstream CEF:
> Called on multiple browser process threads before a plugin instance is
> loaded. |mime_type| is the mime type of the plugin that will be loaded.
> |plugin_url| is the content URL that the plugin will load and may be empty.
> |top_origin_url| is the URL for the top-level frame that contains the
> plugin when loading a specific plugin instance or empty when building the
> initial list of enabled plugins for 'navigator.plugins' JavaScript state.
> |plugin_info| includes additional information about the plugin that will be
> loaded. |plugin_policy| is the recommended policy. Modify |plugin_policy|
> and return true to change the policy. Return false to use the recommended
> policy. The default plugin policy can be set at runtime using the
> `--plugin-policy=[allow|detect|block]` command-line flag. Decisions to mark
> a plugin as disabled by setting |plugin_policy| to PLUGIN_POLICY_DISABLED
> may be cached when |top_origin_url| is empty. To purge the plugin list
> cache and potentially trigger new calls to this method call
> CefRequestContext::PurgePluginListCache.
Return True to block loading of the plugin.

This callback will be executed during browser creation, thus you must call [cefpython](cefpython.md).SetGlobalClientCallback() to use it. The callback name was prefixed with "`_`" to distinguish this special behavior.

Expand Down
42 changes: 27 additions & 15 deletions src/client_handler/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,15 @@

# Cython compiler options:
# -fPIC -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions \
# -Wl,-z,relro
# -Wl,-z,relro

UNAME_S = $(shell uname -s)

CC = g++
CCFLAGS = -g -fPIC -Wall -Werror $(CEF_CCFLAGS)
CCFLAGS = -fPIC -std=gnu++11 -Wall -Werror $(CEF_CCFLAGS)

SRC = client_handler.cpp cookie_visitor.cpp resource_handler.cpp \
web_request_client.cpp string_visitor.cpp request_context_handler.cpp \
task.cpp x11.cpp
web_request_client.cpp string_visitor.cpp request_context_handler.cpp \
task.cpp x11.cpp

OBJ = $(SRC:.cpp=.o)

Expand All @@ -25,26 +24,39 @@ endif

OUT = libclient_handler.a

INC = -I./../ -I/usr/include/python2.7 -I/usr/include/gtk-2.0 \
-I/usr/include/glib-2.0 -I/usr/lib/i386-linux-gnu/gtk-2.0/include \
-I/usr/lib/i386-linux-gnu/glib-2.0/include -I/usr/include/cairo \
-I/usr/include/pango-1.0 -I/usr/include/gdk-pixbuf-2.0 \
-I/usr/include/atk-1.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include \
INC = -I./../ -I/usr/include/python2.7 \
-I/usr/include/gtk-2.0 \
-I/usr/include/gtk-unix-print-2.0 \
-I/usr/include/glib-2.0 \
-I/usr/include/cairo \
-I/usr/include/pango-1.0 \
-I/usr/include/gdk-pixbuf-2.0 \
-I/usr/include/atk-1.0 \
-I/usr/lib/x86_64-linux-gnu/gtk-2.0/include \
-I/usr/lib64/glib-2.0/include -I/usr/lib64/gtk-2.0/include \
-I/usr/lib/glib-2.0/include -I/usr/lib/gtk-2.0/include
-I/usr/lib/x86_64-linux-gnu/gtk-unix-print-2.0 \
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include \
-I/usr/lib/i386-linux-gnu/gtk-2.0/include \
-I/usr/lib/i386-linux-gnu/gtk-unix-print-2.0 \
-I/usr/lib/i386-linux-gnu/glib-2.0/include \
-I/usr/lib64/gtk-2.0/include \
-I/usr/lib64/gtk-unix-print-2.0 \
-I/usr/lib64/glib-2.0/include \
-I/usr/lib/gtk-2.0/include \
-I/usr/lib/gtk-2.0/gtk-unix-print-2.0 \
-I/usr/lib/glib-2.0/include

.cpp.o:
@echo [Makefile] Building $@ from $<...
@echo [CLIENT HANDLER] Building $@ from $<...
$(CC) $(CCFLAGS) $(INC) -c $< -o $@

$(OUT): $(OBJ)
@echo [Makefile] Creating library $(OUT) from $(OBJ)...
@echo [CLIENT HANDLER] Creating library $(OUT) from $(OBJ)...
ar rcs $(OUT) $(OBJ)

util_mac.o: util_mac.mm
@echo [Makefile] Building $@ from $<...
@echo [CLIENT HANDLER] Building $@ from $<...
$(CC) $(CCFLAGS) $(INC) -c $< -o $@

clean:
@echo [CLIENT HANDLER] Cleaning...
rm *.o *.a
9 changes: 0 additions & 9 deletions src/client_handler/client_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,15 +327,6 @@ void ClientHandler::OnProtocolExecution(CefRefPtr<CefBrowser> browser,
RequestHandler_OnProtocolExecution(browser, url, allow_os_execution);
}

bool ClientHandler::OnBeforePluginLoad(CefRefPtr<CefBrowser> browser,
const CefString& url,
const CefString& policy_url,
CefRefPtr<CefWebPluginInfo> info) {
REQUIRE_IO_THREAD();
return RequestHandler_OnBeforePluginLoad(browser, url, policy_url, info);
// Default: return false;
}

bool ClientHandler::OnCertificateError(
CefRefPtr<CefBrowser> browser, // not used
cef_errorcode_t cert_error,
Expand Down
6 changes: 0 additions & 6 deletions src/client_handler/client_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,12 +194,6 @@ class ClientHandler :
virtual void OnProtocolExecution(CefRefPtr<CefBrowser> browser,
const CefString& url,
bool& allow_os_execution) OVERRIDE;

virtual bool OnBeforePluginLoad(CefRefPtr<CefBrowser> browser,
const CefString& url,
const CefString& policy_url,
CefRefPtr<CefWebPluginInfo> info) OVERRIDE;

virtual bool OnCertificateError(
CefRefPtr<CefBrowser> browser, // not used
cef_errorcode_t cert_error,
Expand Down
12 changes: 12 additions & 0 deletions src/client_handler/request_context_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,15 @@ CefRefPtr<CefCookieManager> RequestContextHandler::GetCookieManager() {
}
// Default: return NULL.
}

bool RequestContextHandler::OnBeforePluginLoad(
const CefString& mime_type,
const CefString& plugin_url,
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
PluginPolicy* plugin_policy) {
// Called on multiple threads
return RequestHandler_OnBeforePluginLoad(browser_, mime_type, plugin_url,
top_origin_url, plugin_info,
plugin_policy);
}
12 changes: 9 additions & 3 deletions src/client_handler/request_context_handler.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
class RequestContextHandler :
public CefRequestContextHandler
{
private:
CefRefPtr<CefBrowser> browser_;
typedef cef_plugin_policy_t PluginPolicy;

public:
// Browser may be NULL when instantiated from cefpython.CreateBrowserSync.
// In such case SetBrowser will be called after browser creation.
Expand All @@ -26,9 +30,11 @@ class RequestContextHandler :
}

virtual CefRefPtr<CefCookieManager> GetCookieManager() OVERRIDE;

private:
CefRefPtr<CefBrowser> browser_;
virtual bool OnBeforePluginLoad(const CefString& mime_type,
const CefString& plugin_url,
const CefString& top_origin_url,
CefRefPtr<CefWebPluginInfo> plugin_info,
PluginPolicy* plugin_policy) OVERRIDE;

private:
IMPLEMENT_REFCOUNTING(RequestContextHandler);
Expand Down
6 changes: 6 additions & 0 deletions src/cython_includes/cef_types.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -328,3 +328,9 @@ cdef extern from "include/internal/cef_types.h":
PK_LOCAL_APP_DATA,
PK_USER_DATA,
ctypedef cef_path_key_t PathKey

ctypedef enum cef_plugin_policy_t:
PLUGIN_POLICY_ALLOW,
PLUGIN_POLICY_DETECT_IMPORTANT,
PLUGIN_POLICY_BLOCK,
PLUGIN_POLICY_DISABLE,
10 changes: 6 additions & 4 deletions src/linux/binaries_32bit/wxpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -493,15 +493,17 @@ def OnProtocolExecution(self, browser, url, allowExecutionOut):
print("[wxpython.py] Magnet link allowed!")
allowExecutionOut[0] = True

def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
def _OnBeforePluginLoad(self, browser, mimeType, pluginUrl, topOriginUrl,
info):
# This is a global callback set using SetGlobalClientCallback().
# Plugins are loaded on demand, only when website requires it,
# the same plugin may be called multiple times.
# This callback is called on the IO thread, thus print messages
# This callback is called on various threads, thus print messages
# may not be visible.
print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()")
print(" url = %s" % url)
print(" policy url = %s" % policyUrl)
print(" mimeType = %s" % mimeType)
print(" pluginUrl = %s" % pluginUrl)
print(" topOriginUrl = %s" % topOriginUrl)
print(" info.GetName() = %s" % info.GetName())
print(" info.GetPath() = %s" % info.GetPath())
print(" info.GetVersion() = %s" % info.GetVersion())
Expand Down
10 changes: 6 additions & 4 deletions src/linux/binaries_64bit/wxpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,15 +480,17 @@ def OnProtocolExecution(self, browser, url, allowExecutionOut):
print("[wxpython.py] Magnet link allowed!")
allowExecutionOut[0] = True

def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
def _OnBeforePluginLoad(self, browser, mimeType, pluginUrl, topOriginUrl,
info):
# This is a global callback set using SetGlobalClientCallback().
# Plugins are loaded on demand, only when website requires it,
# the same plugin may be called multiple times.
# This callback is called on the IO thread, thus print messages
# This callback is called on various threads, thus print messages
# may not be visible.
print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()")
print(" url = %s" % url)
print(" policy url = %s" % policyUrl)
print(" mimeType = %s" % mimeType)
print(" pluginUrl = %s" % pluginUrl)
print(" topOriginUrl = %s" % topOriginUrl)
print(" info.GetName() = %s" % info.GetName())
print(" info.GetPath() = %s" % info.GetPath())
print(" info.GetVersion() = %s" % info.GetVersion())
Expand Down
2 changes: 1 addition & 1 deletion src/linux/setup/cefpython.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ __PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_GetAuthCredentials(CefRefPtr<CefBr
__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnQuotaRequest(CefRefPtr<CefBrowser>, CefString const &, int64, CefRefPtr<CefRequestCallback>);
__PYX_EXTERN_C DL_IMPORT(CefRefPtr<CefCookieManager>) RequestHandler_GetCookieManager(CefRefPtr<CefBrowser>, CefString const &);
__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnProtocolExecution(CefRefPtr<CefBrowser>, CefString const &, bool &);
__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforePluginLoad(CefRefPtr<CefBrowser>, CefString const &, CefString const &, CefRefPtr<CefWebPluginInfo>);
__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnBeforePluginLoad(CefRefPtr<CefBrowser>, CefString const &, CefString const &, CefString const &, CefRefPtr<CefWebPluginInfo>, cef_plugin_policy_t *);
__PYX_EXTERN_C DL_IMPORT(bool) RequestHandler_OnCertificateError(int, CefString const &, CefRefPtr<CefRequestCallback>);
__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnRendererProcessTerminated(CefRefPtr<CefBrowser>, cef_termination_status_t);
__PYX_EXTERN_C DL_IMPORT(void) RequestHandler_OnPluginCrashed(CefRefPtr<CefBrowser>, CefString const &);
Expand Down
39 changes: 25 additions & 14 deletions src/linux/setup/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,51 +50,62 @@ def CompileTimeConstants():
r'./../../cython_includes/',
'/usr/include/gtk-2.0',
'/usr/include/glib-2.0',
'/usr/include/gtk-unix-print-2.0',
'/usr/include/cairo',
'/usr/include/pango-1.0',
'/usr/include/gdk-pixbuf-2.0',
'/usr/include/atk-1.0',
# Ubuntu
'/usr/lib/x86_64-linux-gnu/glib-2.0/include',
'/usr/lib/x86_64-linux-gnu/gtk-2.0/include',
'/usr/lib/x86_64-linux-gnu/gtk-unix-print-2.0',
'/usr/lib/x86_64-linux-gnu/glib-2.0/include',
'/usr/lib/i386-linux-gnu/gtk-2.0/include',
'/usr/lib/i386-linux-gnu/gtk-unix-print-2.0',
'/usr/lib/i386-linux-gnu/glib-2.0/include',
# Fedora
'/usr/lib64/glib-2.0/include',
'/usr/lib64/gtk-2.0/include',
'/usr/lib/glib-2.0/include',
'/usr/lib64/gtk-unix-print-2.0',
'/usr/lib64/glib-2.0/include',
'/usr/lib/gtk-2.0/include',
'/usr/lib/gtk-2.0/gtk-unix-print-2.0',
'/usr/lib/glib-2.0/include',
],

# http_authentication not implemented on Linux.
library_dirs=[
r'./../binaries_%s' % BITS,
r'./lib_%s' % BITS,
r'./../../client_handler/',
r'./../../subprocess/', # libcefpythonapp
r'./../../cpp_utils/'
],

# Static libraries only. Order is important, if library A depends on B,
# then B must be included before A.
libraries=[
# Feed cefpythonapp before cef/cef_dll_wrapper to the linker,
# otherwise an "undefined symbol" error may occur when importing
# the cefpython .so module (Issue #230).
'X11',
'gobject-2.0',
'glib-2.0',
'gtk-x11-2.0',
# CEF and CEF Python libraries
'cef_dll_wrapper',
'cefpythonapp',
'client_handler',
'cpp_utils',
'cef',
'cef_dll_wrapper',
'gtk-x11-2.0',
],

# Loading libcef.so will only work when running scripts from the same
# directory that libcef.so resides in when you put "./" in here.
# When you put "./" in here, loading of libcef.so will only work when
# running scripts from the same directory that libcef.so resides in.
# runtime_library_dirs=[
# './'
#],

extra_compile_args=[],
extra_link_args=[],
# Fix "ImportError ... undefined symbol ..." caused by CEF's include/base/
# headers by adding the -flto flag (Issue #230). Unfortunately -flto
# prolongs compilation time significantly.
# More on the other flags: https://stackoverflow.com/questions/6687630/
extra_compile_args=['-flto', '-fdata-sections', '-ffunction-sections',
'-std=gnu++11'],
extra_link_args=['-flto', '-Wl,--gc-sections'],

# Defining macros:
# define_macros = [("UNICODE","1"), ("_UNICODE","1"), ]
Expand Down
10 changes: 6 additions & 4 deletions src/mac/binaries_32bit/wxpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,15 +543,17 @@ def OnProtocolExecution(self, browser, url, allowExecutionOut):
print("[wxpython.py] Magnet link allowed!")
allowExecutionOut[0] = True

def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
def _OnBeforePluginLoad(self, browser, mimeType, pluginUrl, topOriginUrl,
info):
# This is a global callback set using SetGlobalClientCallback().
# Plugins are loaded on demand, only when website requires it,
# the same plugin may be called multiple times.
# This callback is called on the IO thread, thus print messages
# This callback is called on various threads, thus print messages
# may not be visible.
print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()")
print(" url = %s" % url)
print(" policy url = %s" % policyUrl)
print(" mimeType = %s" % mimeType)
print(" pluginUrl = %s" % pluginUrl)
print(" topOriginUrl = %s" % topOriginUrl)
print(" info.GetName() = %s" % info.GetName())
print(" info.GetPath() = %s" % info.GetPath())
print(" info.GetVersion() = %s" % info.GetVersion())
Expand Down
10 changes: 6 additions & 4 deletions src/mac/binaries_64bit/wxpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -543,15 +543,17 @@ def OnProtocolExecution(self, browser, url, allowExecutionOut):
print("[wxpython.py] Magnet link allowed!")
allowExecutionOut[0] = True

def _OnBeforePluginLoad(self, browser, url, policyUrl, info):
def _OnBeforePluginLoad(self, browser, mimeType, pluginUrl, topOriginUrl,
info):
# This is a global callback set using SetGlobalClientCallback().
# Plugins are loaded on demand, only when website requires it,
# the same plugin may be called multiple times.
# This callback is called on the IO thread, thus print messages
# This callback is called on various threads, thus print messages
# may not be visible.
print("[wxpython.py] RequestHandler::_OnBeforePluginLoad()")
print(" url = %s" % url)
print(" policy url = %s" % policyUrl)
print(" mimeType = %s" % mimeType)
print(" pluginUrl = %s" % pluginUrl)
print(" topOriginUrl = %s" % topOriginUrl)
print(" info.GetName() = %s" % info.GetName())
print(" info.GetPath() = %s" % info.GetPath())
print(" info.GetVersion() = %s" % info.GetVersion())
Expand Down
Loading

0 comments on commit 7d47bfe

Please sign in to comment.