diff --git a/api/ApplicationSettings.md b/api/ApplicationSettings.md
index b0ec2d08..fba94f94 100644
--- a/api/ApplicationSettings.md
+++ b/api/ApplicationSettings.md
@@ -216,6 +216,8 @@ Custom flags that will be used when initializing the V8 Javascript engine.
The consequences of using custom flags may not be well tested. Also
configurable using the --js-flags switch.
+To enable WebAssembly support set the `--expose-wasm` flag.
+
### locale
diff --git a/docs/Build-instructions.md b/docs/Build-instructions.md
index 1693e39f..b0c4a049 100644
--- a/docs/Build-instructions.md
+++ b/docs/Build-instructions.md
@@ -69,6 +69,9 @@ __Windows__
* Install an appropriate MS compiler for a specific Python version:
https://wiki.python.org/moin/WindowsCompilers
+* When using "Visual C++ compiler for Python 2.7" you have to install
+ "Microsoft Visual C++ 2008 Redistributable Package (x64)" from
+ [here](https://www.microsoft.com/en-us/download/details.aspx?id=15336)
* To build CEF from sources:
* Use Win7 x64 or later. 32-bit OS'es are not supported. For more details
see [here](https://www.chromium.org/developers/how-tos/build-instructions-windows).
diff --git a/examples/resources/back.gif b/examples/resources/back.gif
new file mode 100644
index 00000000..92362f5e
Binary files /dev/null and b/examples/resources/back.gif differ
diff --git a/examples/resources/forward.gif b/examples/resources/forward.gif
new file mode 100644
index 00000000..1032b9be
Binary files /dev/null and b/examples/resources/forward.gif differ
diff --git a/examples/resources/reload.gif b/examples/resources/reload.gif
new file mode 100644
index 00000000..ef96a429
Binary files /dev/null and b/examples/resources/reload.gif differ
diff --git a/examples/resources/tkinter.gif b/examples/resources/tkinter.gif
new file mode 100644
index 00000000..cbd12220
Binary files /dev/null and b/examples/resources/tkinter.gif differ
diff --git a/examples/resources/tkinter.png b/examples/resources/tkinter.png
index 444ec8df..f593cb89 100644
Binary files a/examples/resources/tkinter.png and b/examples/resources/tkinter.png differ
diff --git a/examples/tkinter_.py b/examples/tkinter_.py
index 40acfd0f..c8385992 100644
--- a/examples/tkinter_.py
+++ b/examples/tkinter_.py
@@ -14,10 +14,13 @@
import Tkinter as tk
import sys
import os
+import platform
import logging as _logging
# Globals
logger = _logging.getLogger("tkinter_.py")
+# Python 2.7 on Windows comes with Tk 8.5 which doesn't support PNG images
+IMAGE_EXT = ".gif" if platform.system() == "Windows" else ".png"
def main():
@@ -112,7 +115,7 @@ def get_browser_frame(self):
def setup_icon(self):
resources = os.path.join(os.path.dirname(__file__), "resources")
- icon_path = os.path.join(resources, "tkinter.png")
+ icon_path = os.path.join(resources, "tkinter"+IMAGE_EXT)
if os.path.exists(icon_path):
self.icon = tk.PhotoImage(file=icon_path)
# noinspection PyProtectedMember
@@ -132,7 +135,7 @@ def __init__(self, master):
resources = os.path.join(os.path.dirname(__file__), "resources")
# Back button
- back_png = os.path.join(resources, "back.png")
+ back_png = os.path.join(resources, "back"+IMAGE_EXT)
if os.path.exists(back_png):
self.back_image = tk.PhotoImage(file=back_png)
self.back_button = tk.Button(self, image=self.back_image,
@@ -140,7 +143,7 @@ def __init__(self, master):
self.back_button.grid(row=0, column=0)
# Forward button
- forward_png = os.path.join(resources, "forward.png")
+ forward_png = os.path.join(resources, "forward"+IMAGE_EXT)
if os.path.exists(forward_png):
self.forward_image = tk.PhotoImage(file=forward_png)
self.forward_button = tk.Button(self, image=self.forward_image,
@@ -148,7 +151,7 @@ def __init__(self, master):
self.forward_button.grid(row=0, column=1)
# Reload button
- reload_png = os.path.join(resources, "reload.png")
+ reload_png = os.path.join(resources, "reload"+IMAGE_EXT)
if os.path.exists(reload_png):
self.reload_image = tk.PhotoImage(file=reload_png)
self.reload_button = tk.Button(self, image=self.reload_image,
@@ -255,6 +258,7 @@ def embed_browser(self):
window_info.SetAsChild(self.winfo_id())
self.browser = cef.CreateBrowserSync(window_info,
url="https://www.google.com/")
+ assert self.browser
self.browser.SetClientHandler(LoadHandler(self))
self.browser.SetClientHandler(FocusHandler(self))
self.message_loop_work()
@@ -274,7 +278,11 @@ def on_root_configure(self):
def on_mainframe_configure(self, width, height):
if self.browser:
- self.browser.SetBounds(0, 0, width, height)
+ if platform.system() == "Windows":
+ # noinspection PyUnresolvedReferences
+ cef.WindowUtils.OnSize(self.winfo_id(), 0, 0, 0)
+ elif platform.system() == "Linux":
+ self.browser.SetBounds(0, 0, width, height)
self.browser.NotifyMoveOrResizeStarted()
def on_focus_in(self, _):
diff --git a/examples/wxpython.py b/examples/wxpython.py
index d4a0a5e1..2de7a752 100644
--- a/examples/wxpython.py
+++ b/examples/wxpython.py
@@ -111,6 +111,7 @@ def OnSize(self, _):
(width, height) = self.browser_panel.GetSizeTuple()
# noinspection PyUnresolvedReferences
self.browser.SetBounds(x, y, width, height)
+ self.browser.NotifyMoveOrResizeStarted()
def OnClose(self, event):
# In cefpython3.wx.chromectrl example calling browser.CloseBrowser()
diff --git a/src/client_handler/client_handler_py27_win32.vcproj b/src/client_handler/client_handler_py27_win32.vcproj
index 51670b21..07e4fbb1 100644
--- a/src/client_handler/client_handler_py27_win32.vcproj
+++ b/src/client_handler/client_handler_py27_win32.vcproj
@@ -4,7 +4,7 @@
Version="9.00"
Name="client_handler_py27_win32"
RootNamespace="client_handler_py27_win32"
- ProjectGUID="{15AD928F-FFD0-4FA5-B469-E42ABB0B4196}"
+ ProjectGUID="{15AD928F-FFD0-4FA5-B469-E42AAA0B4196}"
Keyword="Win32Proj"
TargetFrameworkVersion="0"
>
@@ -27,7 +27,7 @@
browser,
diff --git a/src/cpp_utils/cpp_utils_win32.vcproj b/src/cpp_utils/cpp_utils_win32.vcproj
index cc2349da..e0f49c2f 100644
--- a/src/cpp_utils/cpp_utils_win32.vcproj
+++ b/src/cpp_utils/cpp_utils_win32.vcproj
@@ -27,6 +27,7 @@
@@ -27,7 +27,7 @@
+
+
+
+
+
diff --git a/src/subprocess/main.cpp b/src/subprocess/main.cpp
index fbf2d5bf..1192f4a8 100644
--- a/src/subprocess/main.cpp
+++ b/src/subprocess/main.cpp
@@ -8,22 +8,21 @@
#include
int APIENTRY wWinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPTSTR lpCmdLine,
- int nCmdShow)
-
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
CefMainArgs mainArgs(hInstance);
-#else // Mac, Linux
+#else // defined(OS_WIN)
int main(int argc, char **argv)
{
CefMainArgs mainArgs(argc, argv);
-#endif
+#endif // Mac, Linux
CefRefPtr app(new CefPythonApp);
int exitCode = CefExecuteProcess(mainArgs, app.get(), NULL);
diff --git a/src/subprocess/main_message_loop/main_message_loop_external_pump_win.cpp b/src/subprocess/main_message_loop/main_message_loop_external_pump_win.cpp
index 0de7ebf8..4ba8575b 100644
--- a/src/subprocess/main_message_loop/main_message_loop_external_pump_win.cpp
+++ b/src/subprocess/main_message_loop/main_message_loop_external_pump_win.cpp
@@ -1,4 +1,5 @@
// Copied from upstream cefclient with minor modifications.
+// Windows UNICODE API calls were converted to ANSI or commented out.
// Copyright (c) 2016 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
@@ -50,7 +51,7 @@ MainMessageLoopExternalPumpWin::MainMessageLoopExternalPumpWin()
: timer_pending_(false),
main_thread_target_(NULL) {
HINSTANCE hInstance = GetModuleHandle(NULL);
- const wchar_t* const kClassName = L"CEFMainTargetHWND";
+ const char* const kClassName = "CEFMainTargetHWND";
WNDCLASSEX wcex = {};
wcex.cbSize = sizeof(WNDCLASSEX);
@@ -60,7 +61,7 @@ MainMessageLoopExternalPumpWin::MainMessageLoopExternalPumpWin()
RegisterClassEx(&wcex);
// Create the message handling window.
- main_thread_target_ = CreateWindowW(kClassName, NULL, WS_OVERLAPPEDWINDOW,
+ main_thread_target_ = CreateWindowA(kClassName, NULL, WS_OVERLAPPEDWINDOW,
0, 0, 0, 0, HWND_MESSAGE , NULL, hInstance, NULL);
DCHECK(main_thread_target_);
SetUserDataPtr(main_thread_target_, this);
@@ -140,8 +141,8 @@ LRESULT CALLBACK MainMessageLoopExternalPumpWin::WndProc(
} // namespace
// static
-scoped_ptr>MainMessageLoopExternalPump>
+scoped_ptr
MainMessageLoopExternalPump::Create() {
- return scoped_ptr>MainMessageLoopExternalPump>(
+ return scoped_ptr(
new MainMessageLoopExternalPumpWin());
}
diff --git a/src/subprocess/main_message_loop/util_win.cpp b/src/subprocess/main_message_loop/util_win.cpp
index 3dbb4c31..bc1f0965 100644
--- a/src/subprocess/main_message_loop/util_win.cpp
+++ b/src/subprocess/main_message_loop/util_win.cpp
@@ -1,4 +1,5 @@
// Copied from upstream cefclient with minor modifications.
+// Windows UNICODE API calls were converted to ANSI or commented out.
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
@@ -25,12 +26,12 @@ WNDPROC SetWndProcPtr(HWND hWnd, WNDPROC wndProc) {
return old;
}
-std::wstring GetResourceString(UINT id) {
- #define MAX_LOADSTRING 100
- TCHAR buff[MAX_LOADSTRING] = {0};
- LoadString(::GetModuleHandle(NULL), id, buff, MAX_LOADSTRING);
- return buff;
-}
+//std::wstring GetResourceString(UINT id) {
+// #define MAX_LOADSTRING 100
+// TCHAR buff[MAX_LOADSTRING] = {0};
+// LoadString(::GetModuleHandle(NULL), id, buff, MAX_LOADSTRING);
+// return buff;
+//}
int GetCefMouseModifiers(WPARAM wparam) {
int modifiers = 0;
diff --git a/src/subprocess/main_message_loop/util_win.h b/src/subprocess/main_message_loop/util_win.h
index 0f806ba5..39870204 100644
--- a/src/subprocess/main_message_loop/util_win.h
+++ b/src/subprocess/main_message_loop/util_win.h
@@ -1,4 +1,5 @@
// Copied from upstream cefclient with minor modifications.
+// Windows UNICODE API calls were converted to ANSI or commented out.
// Copyright (c) 2015 The Chromium Embedded Framework Authors. All rights
// reserved. Use of this source code is governed by a BSD-style license that
@@ -26,7 +27,7 @@ T GetUserDataPtr(HWND hWnd) {
WNDPROC SetWndProcPtr(HWND hWnd, WNDPROC wndProc);
// Return the resource string with the specified id.
-std::wstring GetResourceString(UINT id);
+//std::wstring GetResourceString(UINT id);
int GetCefMouseModifiers(WPARAM wparam);
int GetCefKeyboardModifiers(WPARAM wparam, LPARAM lparam);
diff --git a/src/subprocess/subprocess_32bit.vcproj b/src/subprocess/subprocess_win32.vcproj
similarity index 88%
rename from src/subprocess/subprocess_32bit.vcproj
rename to src/subprocess/subprocess_win32.vcproj
index d5cf7d4a..18cff5e7 100644
--- a/src/subprocess/subprocess_32bit.vcproj
+++ b/src/subprocess/subprocess_win32.vcproj
@@ -31,8 +31,8 @@
Name="VCCLCompilerTool"
Optimization="2"
EnableIntrinsicFunctions="true"
- AdditionalIncludeDirectories="../"
- PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_WARNINGS;RENDERER_PROCESS;"
+ AdditionalIncludeDirectories="$(INCLUDE);..\;..\common"
+ PreprocessorDefinitions="WIN32;_WIN32;_WINDOWS;WINVER=0x0601;_WIN32_WINNT=0x0601;UNICODE;_UNICODE;NOMINMAX;WIN32_LEAN_AND_MEAN;_HAS_EXCEPTIONS=0;NDEBUG;_NDEBUG;_CRT_SECURE_NO_WARNINGS;RENDERER_PROCESS;"
ExceptionHandling="1"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
@@ -48,9 +48,10 @@
IgnoreImportLibrary="false"
LinkLibraryDependencies="true"
AdditionalDependencies="libcef.lib libcef_dll_wrapper_mt.lib"
+ AdditionalOptions="/MANIFEST:NO /LARGEADDRESSAWARE"
LinkIncremental="1"
- AdditionalLibraryDirectories="../../build/cef_win32/lib"
- GenerateManifest="true"
+ AdditionalLibraryDirectories="$(AdditionalLibraryDirectories);$(LIB)"
+ GenerateManifest="false"
IgnoreAllDefaultLibraries="false"
GenerateDebugInformation="true"
SubSystem="2"
diff --git a/src/window_info.pyx b/src/window_info.pyx
index c3bef322..988c665e 100644
--- a/src/window_info.pyx
+++ b/src/window_info.pyx
@@ -81,7 +81,16 @@ cdef class WindowInfo:
cpdef py_void SetAsChild(self, WindowHandle parentWindowHandle,
list windowRect=None):
- if not WindowUtils.IsWindowHandle(parentWindowHandle):
+ # Allow parent window handle to be 0, in such case CEF will
+ # create top window automatically as in hello_world.py example.
+ IF UNAME_SYSNAME == "Windows":
+ # On Windows when parent window handle is 0 then SetAsPopup()
+ # must be called instead.
+ if parentWindowHandle == 0:
+ self.SetAsPopup(parentWindowHandle, "Popup")
+ return
+ if parentWindowHandle != 0\
+ and not WindowUtils.IsWindowHandle(parentWindowHandle):
raise Exception("Invalid parentWindowHandle: %s"\
% parentWindowHandle)
self.windowType = "child"
@@ -100,7 +109,10 @@ cdef class WindowInfo:
IF UNAME_SYSNAME == "Windows":
cpdef py_void SetAsPopup(self, WindowHandle parentWindowHandle,
py_string windowName):
- if not WindowUtils.IsWindowHandle(parentWindowHandle):
+ # Allow parent window handle to be 0, in such case CEF will
+ # create top window automatically as in hello_world.py example.
+ if parentWindowHandle != 0\
+ and not WindowUtils.IsWindowHandle(parentWindowHandle):
raise Exception("Invalid parentWindowHandle: %s"\
% parentWindowHandle)
self.parentWindowHandle = parentWindowHandle
@@ -109,7 +121,7 @@ cdef class WindowInfo:
cpdef py_void SetAsOffscreen(self,
WindowHandle parentWindowHandle):
- # It is allowed to pass 0 as parentWindowHandle.
+ # It is allowed to pass 0 as parentWindowHandle in OSR mode
if parentWindowHandle and \
not WindowUtils.IsWindowHandle(parentWindowHandle):
raise Exception("Invalid parentWindowHandle: %s" \
diff --git a/src/windows/compile.bat b/src/windows/compile.bat
deleted file mode 100644
index eacaee71..00000000
--- a/src/windows/compile.bat
+++ /dev/null
@@ -1,235 +0,0 @@
-@echo off
-
-:: It's best to always call with a flag that specifies python
-:: version and architecture (eg. --py27-32bit). This will ensure
-:: that PATH contains only minimum set of directories and will
-:: allow to detect possible issues early.
-
-:: Arguments
-if [%1] == [] (
- echo [compile.bat] Version number not provided. Usage: compile.bat 31.0
- echo [compile.bat] Opt: --rebuild --py27-32bit --py27-64bit --py34-32bit
- echo --py34-64bit
- exit /B 1
-)
-
-:: --rebuild flag to rebuild all vcproj builds
-set rebuild_flag=0
-echo.%*|findstr /C:"--rebuild" >nul 2>&1
-if %errorlevel% equ 0 (
- set rebuild_flag=1
-)
-
-:: Add only Python/ to PATH.
-:: --py27-32bit flag
-echo.%*|findstr /C:"--py27-32bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27
-)
-:: --py27-64bit flag
-echo.%*|findstr /C:"--py27-64bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27_x64;C:\Python27_amd64;C:\Python27_64
-)
-:: --py34-32bit flag
-echo.%*|findstr /C:"--py34-32bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34
-)
-:: --py34-64bit flag
-echo.%*|findstr /C:"--py34-64bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34_x64;C:\Python34_amd64;C:\Python34_64
-)
-:: PATH
-echo [compile.bat] PATH: %PATH%
-
-:: Version number
-set version=%1
-echo [compile.bat] Version argument: %version%
-
-:: Python architecture. %bits%=="32bit" or "64bit"
-FOR /F "delims=" %%i IN ('python -c "import struct, sys; sys.stdout.write(str(8 * struct.calcsize('P')) + 'bit');"') do set bits=%%i
-echo [compile.bat] Python architecture: %bits%
-
-:: Cython version
-FOR /F "delims=" %%i IN ('python -c "import sys, Cython; sys.stdout.write(Cython.__version__);"') do set cython_version=%%i
-echo [compile.bat] Cython version: %cython_version%
-
-:: Python version
-for /F %%i in ('python -c "import sys; sys.stdout.write(str(sys.version_info[0])+str(sys.version_info[1]));"') do set pyver=%%i
-echo [compile.bat] Python version: py%pyver%
-
-:: Binaries directory
-set binaries=%~dp0binaries_%bits%
-echo [compile.bat] Binaries directory: %binaries%
-
-:: Setup directory
-set setup=%~dp0setup
-echo [compile.bat] Setup directory: %setup%
-
-:: Delete .pyd files
-echo [compile.bat] Cleaning cython build files from previous run
-del "%binaries%\cefpython_py%pyver%.pyd"
-del "%setup%\cefpython_py%pyver%.pyd"
-for /R %setup% %%f in (*.pyx) do del "%%f"
-rmdir /S /Q "%setup%\build\"
-
-:: Fix cefpython.h
-echo [compile.bat] Fixing cefpython.h
-cd %setup%
-python fix_cefpython_h.py
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: failed to fix cefpython.h
- cd ../
- exit /B 1
-)
-cd ../
-
-:: Compile VS projects: client_handler, libcefpythonapp, subprocess, cpp_utils
-
-:: client_handler paths
-set client_handler_dir=%~dp0..\client_handler
-set client_handler_vcproj=%client_handler_dir%\client_handler_py%pyver%_%bits%.vcproj
-
-set subprocess_dir=%~dp0..\subprocess
-
-:: libcefpythonapp paths
-set libcefpythonapp_vcproj=%subprocess_dir%\libcefpythonapp_py%pyver%_%bits%.vcproj
-
-:: subprocess paths
-set subprocess_vcproj=%subprocess_dir%\subprocess_%bits%.vcproj
-
-:: cpp_utils paths
-set cpp_utils_dir=%~dp0..\..\cpp_utils
-set cpp_utils_vcproj=%cpp_utils_dir%\cpp_utils_%bits%.vcproj
-
-set success=0
-if "%pyver%"=="27" (
- if "%bits%"=="32bit" (
- set "vcbuild=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe"
- set success=1
- )
- if "%bits%"=="64bit" (
- REM :: The same vcbuild.exe 32-bit for building x64
- set "vcbuild=C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\vcpackages\vcbuild.exe"
- set success=1
- )
- set "vcoptions=/nocolor /nologo /nohtmllog"
- if %rebuild_flag% equ 1 (
- set "vcoptions=%vcoptions% /rebuild"
- )
-)
-if "%pyver%"=="34" (
- :: In VS2010 vcbuild was replaced by msbuild.exe.
- :: /clp:disableconsolecolor
- :: msbuild /p:BuildProjectReferences=false project.proj
- :: MSBuild.exe MyProject.proj /t:build
-)
-
-if %success% neq 1 (
- echo [compile.bat] ERROR: failed determining tool to build vcproj files
- exit /B 1
-)
-
-echo [compile.bat] Building client_handler vcproj
-"%vcbuild%" %vcoptions% %client_handler_vcproj%
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: building client_handler vcproj failed
- exit /B 1
-)
-
-echo [compile.bat] Building libcefpythonapp vcproj
-"%vcbuild%" %vcoptions% %libcefpythonapp_vcproj%
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: building libcefpythonapp vcproj failed
- exit /B 1
-)
-
-echo [compile.bat] Building subprocess vcproj
-"%vcbuild%" %vcoptions% %subprocess_vcproj%
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: building subprocess vcproj failed
- exit /B 1
-)
-
-echo [compile.bat] Building cpp_utils vcproj
-"%vcbuild%" %vcoptions% %cpp_utils_vcproj%
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: building cpp_utils vcproj failed
- exit /B 1
-)
-
-:: Do not clean VS build files, as this would slow down the process
-:: of recompiling.
-
-:: Compile .rc file to a .res object.
-echo [compile.bat] Compiling cefpython.rc file to a .res object
-cd %setup%\
-python compile_rc.py -v %version%
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: compiling .rc file failed
- exit /B 1
-)
-
-echo [compile.bat] Entering setup/ directory
-cd %setup%
-
-echo [compile.bat] Copying .pyx files to setup/ directory and fixing includes
-python fix_pyx_files.py
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: running fix_pyx_files.py failed
- exit /B 1
-)
-
-:: __version__.pyx must be generated after running fix_pyx_files.py,
-:: as that script deletes old pyx files before copying new ones.
-echo [compile.bat] Creating __version__.pyx file
-echo __version__ = "%version%">>__version__.pyx
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: writing __version__.pyx failed
- exit /B 1
-)
-
-echo [compile.bat] Running the cython setup.py script
-python setup.py build_ext --inplace
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: the cython setup.py script failed
- :: Clean files from the build that failed
- for /R %setup% %%f in (*.pyx) do del "%%f"
- for /R %setup% %%f in (*.res) do del "%%f"
- rmdir /S /Q "%setup%\build\"
- cd ../
- exit /B 1
-)
-
-echo [compile.bat] Fixing cefpython.h
-python fix_cefpython_h.py
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: failed to fix cefpython.h
- exit /B 1
-)
-
-echo [compile.bat] Cleaning files from the build
-for /R %setup% %%f in (*.pyx) do del "%%f"
-for /R %setup% %%f in (*.res) do del "%%f"
-rmdir /S /Q "%setup%\build\"
-
-echo [compile.bat] Moving the pyd module to the binaries directory
-move "%setup%\cefpython_py%pyver%.pyd" "%binaries%/cefpython_py%pyver%.pyd"
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: Moving the pyd module failed
- exit /B 1
-)
-
-echo [compile.bat] Copying subprocess.exe to the binaries directory
-copy "%~dp0..\subprocess\Release_%bits%\subprocess_%bits%.exe" "%binaries%\subprocess.exe"
-if %errorlevel% neq 0 (
- echo [compile.bat] ERROR: Copying subprocess.exe failed
- exit /B 1
-)
-
-echo [compile.bat] Everything went OK. Running the wxpython.py example..
-
-cd %binaries%
-python wxpython.py & cd ../
diff --git a/src/windows/installer/.gitignore b/src/windows/installer/.gitignore
deleted file mode 100644
index 0dc5ef2a..00000000
--- a/src/windows/installer/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-cefpython3-*/
-Output/
-dist/
diff --git a/src/windows/installer/README.txt b/src/windows/installer/README.txt
deleted file mode 100644
index 2325940f..00000000
--- a/src/windows/installer/README.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-1. To install CEF Python 3 type:
-
- python setup.py install
-
-2. In the same directory that setup.py resides there is
- an examples/ directory, run some example scripts from there:
-
- cd examples/
- python wxpython.py
- python pyqt.py
- python pyside.py
- python pygtk_.py
- python pywin32.py
-
- cd wx/
- python sample1.py
- python sample2.py
- python sample3.py
diff --git a/src/windows/installer/__init__.py.template b/src/windows/installer/__init__.py.template
deleted file mode 100644
index 94ef341b..00000000
--- a/src/windows/installer/__init__.py.template
+++ /dev/null
@@ -1,12 +0,0 @@
-__all__ = ["cefpython", "wx"]
-__version__ = "%(APP_VERSION)s"
-__author__ = "The CEF Python authors"
-
-import sys
-
-if 0x02070000 <= sys.hexversion < 0x03000000:
- from . import cefpython_py27 as cefpython
-elif 0x03000000 <= sys.hexversion < 0x04000000:
- from . import cefpython_py32 as cefpython
-else:
- raise Exception("Unsupported python version: " + sys.version)
diff --git a/src/windows/installer/build_all.bat b/src/windows/installer/build_all.bat
deleted file mode 100644
index 3c2dfdea..00000000
--- a/src/windows/installer/build_all.bat
+++ /dev/null
@@ -1,213 +0,0 @@
-@echo off
-setlocal ENABLEDELAYEDEXPANSION
-
-:: It's best to always call with a flag that specifies python
-:: version and architecture (eg. --py27-32bit). This will ensure
-:: that PATH contains only minimum set of directories and will
-:: allow to detect possible issues early.
-
-if "%1"=="" goto usage
-if "%2"=="" goto usage
-
-set version=%1
-
-:: Add only Python/ and Python/Scripts/ to PATH.
-:: --py27-32bit flag
-echo.%*|findstr /C:"--py27-32bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27;C:\Python27\Scripts
-)
-:: --py27-64bit flag
-echo.%*|findstr /C:"--py27-64bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python27_x64;C:\Python27_amd64;C:\Python27_64;C:\Python27_x64\Scripts;C:\Python27_amd64\Scripts;C:\Python27_64\Scripts
-)
-:: --py34-32bit flag
-echo.%*|findstr /C:"--py34-32bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34;C:\Python34\Scripts
-)
-:: --py34-64bit flag
-echo.%*|findstr /C:"--py34-64bit" >nul 2>&1
-if %errorlevel% equ 0 (
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Python34_x64;C:\Python34_amd64;C:\Python34_64;C:\Python34_x64\Scripts;C:\Python34_amd64\Scripts;C:\Python34_64\Scripts
-)
-:: PATH
-echo [compile.bat] PATH: %PATH%
-
-:: Python architecture. %bits%=="32bit" or "64bit"
-FOR /F "delims=" %%i IN ('python -c "import struct, sys; sys.stdout.write(str(8 * struct.calcsize('P')) + 'bit');"') do set bits=%%i
-echo [compile.bat] Python architecture: %bits%
-set success=0
-if "%bits%"=="32bit" (
- set platform=win32
- set success=1
-)
-if "%bits%"=="64bit" (
- set platform=win-amd64
- set success=1
-)
-if %success% neq 1 (
- echo [build_all.bat] ERROR: invalid architecture: %bits%
- exit /B 1
-)
-
-echo [build_all.bat] PLATFORM: %platform%
-echo [build_all.bat] VERSION: %version%
-
-:: Python version
-for /F %%i in ('python -c "import sys; sys.stdout.write(str(sys.version_info[0]) + '.' + str(sys.version_info[1]));"') do set pyverdot=%%i
-echo [build_all.bat] Python version: py%pyverdot%
-
-:: --disable-inno-setup flag
-set DISABLE_INNO_SETUP=0
-echo.%*|findstr /C:"--disable-inno-setup" >nul 2>&1
-if %errorlevel% equ 0 (
- set DISABLE_INNO_SETUP=1
-)
-
-:: Clean directories from previous run
-rmdir /s /q Output
-for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do rmdir /s /q %%f
-rmdir /s /q dist
-
-mkdir dist
-
-echo [build_all.bat] Installing setuptools and wheel
-pip install setuptools wheel
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: pip install setuptools wheel
- exit /B 1
-)
-
-if %DISABLE_INNO_SETUP% equ 0 (
- echo [build_all.bat] Creating Inno Setup intaller
- python make-installer.py -v %version%
- if !errorlevel! equ 0 (
- for /f "tokens=*" %%f in ('dir .\Output\*.exe /b') do (
- move .\Output\%%f dist/%%f
- if !errorlevel! neq 0 (
- echo [build_all.bat] ERROR: moving inno setup installer failed
- exit /B 1
- )
- )
- rmdir Output
- if !errorlevel! neq 0 (
- echo [build_all.bat] ERROR: deleting Output/ directory failed
- exit /B 1
- )
- )
- if !errorlevel! neq 0 (
- echo [build_all.bat] ERROR: creating Inno Setup installer failed
- exit /B 1
- )
-)
-
-echo [build_all.bat] Creating Distutils setup
-python make-setup.py -v %version%
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating Distutils setup
- exit /B 1
-)
-
-:: Enter the setup directory
-for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do cd %%f
-
-echo [build_all.bat] Creating Distutils source package
-python setup.py sdist
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating Distutils source package
- exit /B 1
-)
-
-echo [build_all.bat] Creating Python Egg
-python setup.py bdist_egg
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating Python Egg failed
- exit /B 1
-)
-
-echo [build_all.bat] Creating Python Wheel
-python setup.py bdist_wheel
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating Python Wheel failed
- exit /B 1
-)
-
-echo [build_all.bat] Creating MSI installer
-python setup.py bdist_msi
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating MSI installer failed
- exit /B 1
-)
-
-echo [build_all.bat] Creating EXE installer
-python setup.py bdist_wininst
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: creating EXE installer failed
- exit /B 1
-)
-
-echo [build_all.bat] Moving all packages to the dist/ directory
-set success=0
-for /f "tokens=*" %%f in ('dir .\dist\*.* /b') do (
- move .\dist\%%f .\..\dist\%%f
- if !errorlevel! neq 0 (
- echo [build_all.bat] ERROR: moving setup dist/ packages failed
- exit /B 1
- )
- if !errorlevel! equ 0 (
- set success=1
- )
-)
-if %success% neq 1 (
- echo [build_all.bat] ERROR: moving setup dist/ packages failed
- exit /B 1
-)
-
-:: Up to the installer/ directory
-cd ../
-
-echo [build_all.bat] Deleting the Distutils setup directory
-for /f "tokens=*" %%f in ('dir .\cefpython3*setup /ad/b') do rmdir /s /q %%f
-if %errorlevel% neq 0 (
- echo [build_all.bat] ERROR: failed deleting the Distutils setup directory
- exit /B 1
-)
-
-cd dist/
-
-echo [build_all.bat] Renaming some of the packages to include platform tag
-for /R %%i in (*) do (
- set oldfile=%%i
- set newfile=!oldfile:.egg=-%platform%.egg!
- if "!oldfile!" neq "!newfile!" (
- move !oldfile! !newfile!
- )
- set oldfile=%%i
- set newfile=!oldfile:.zip=-py%pyverdot%-%platform%.zip!
- if "!oldfile!" neq "!newfile!" (
- move !oldfile! !newfile!
- )
- set oldfile=%%i
- set newfile=!oldfile:%platform%.exe=py%pyverdot%-%platform%.exe!
- if "!oldfile!" neq "!newfile!" (
- move !oldfile! !newfile!
- )
- set oldfile=%%i
- set newfile=!oldfile:%platform%.msi=py%pyverdot%-%platform%.msi!
- if "!oldfile!" neq "!newfile!" (
- move !oldfile! !newfile!
- )
-)
-
-echo [build_all.bat] Packages in the dist/ directory:
-dir
-
-echo OK
-
-goto :eof
-:usage
-@echo [build_all.bat] ERROR: platform or version arguments missing or invalid
-@echo [build_all.bat] ERROR: example usage: build_all.bat win32 31.2
-exit /B 1
diff --git a/src/windows/installer/innosetup.template b/src/windows/installer/innosetup.template
deleted file mode 100644
index e3a9a51e..00000000
--- a/src/windows/installer/innosetup.template
+++ /dev/null
@@ -1,165 +0,0 @@
-; Parts of this code was taken from wxPython/distrib/make_installer.py
-
-[Setup]
-
-AppName = CEF Python 3 for Python %(PYTHON_VERSION)s %(APP_NAME_BITS)s
-AppVersion = %(APP_VERSION)s
-AppVerName = CEF Python 3 version %(APP_VERSION)s for Python %(PYTHON_VERSION)s %(PYTHON_ARCHITECTURE)s
-
-AppPublisher = Czarek Tomczak
-AppPublisherURL = http://code.google.com/cefpython/
-AppSupportURL = https://groups.google.com/group/cefpython?hl=en
-AppUpdatesURL = http://code.google.com/cefpython/
-AppCopyright = Copyright 2012-2013 Czarek Tomczak
-
-DefaultDirName = {code:GetInstallDir|c:\Python}
-
-DefaultGroupName = CEF Python 3 for Python %(PYTHON_VERSION)s %(APP_NAME_BITS)s
-PrivilegesRequired = none
-DisableStartupPrompt = yes
-Compression = zip
-DirExistsWarning = no
-DisableReadyMemo = yes
-DisableReadyPage = yes
-DisableDirPage = no
-DisableProgramGroupPage = no
-UsePreviousAppDir = yes
-UsePreviousGroup = yes
-
-SourceDir = %(BINARIES_DIR)s
-OutputDir = %(INSTALLER_DIR)s\Output
-OutputBaseFilename = %(PACKAGE_NAME)s-%(APP_VERSION)s.%(PLATFORM)s-py%(PYTHON_VERSION)s-innosetup
-
-UninstallFilesDir = {app}\%(PACKAGE_NAME)s
-LicenseFile = %(BINARIES_DIR)s\LICENSE.txt
-
-[Icons]
-
-Name: "{group}\Examples"; Filename: "{app}\%(PACKAGE_NAME)s\examples";
-Name: "{group}\Uninstall Package"; Filename: "{uninstallexe}";
-
-[Run]
-
-Filename: "{app}\%(PACKAGE_NAME)s\examples"; Flags: postinstall skipifsilent shellexec;
-
-[Files]
-
-Source: "*.dll"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "locales\*.pak"; DestDir: "{app}\%(PACKAGE_NAME)s\locales"; Flags: ignoreversion;
-Source: "%(INSTALLER_DIR)s\__init__.py.generated"; DestDir: "{app}\%(PACKAGE_NAME)s"; DestName: "__init__.py"; Flags: ignoreversion;
-Source: "cefclient.exe"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "cefpython_py%(PYTHON_VERSION_NODOT)s.pyd"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "LICENSE.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "README.txt"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-Source: "subprocess.exe"; DestDir: "{app}\%(PACKAGE_NAME)s"; Flags: ignoreversion;
-
-; ------------------------------------------------------------------------------
-; wx subpackage
-; ------------------------------------------------------------------------------
-
-Source: "%(WX_SUBPACKAGE_DIR)s\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion;
-Source: "%(WX_SUBPACKAGE_DIR)s\*.txt"; DestDir: "{app}\%(PACKAGE_NAME)s\wx"; Flags: ignoreversion;
-Source: "%(WX_SUBPACKAGE_DIR)s\images\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\wx\images"; Flags: ignoreversion;
-
-; ------------------------------------------------------------------------------
-; wx examples
-; ------------------------------------------------------------------------------
-
-Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion;
-Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion;
-Source: "%(WX_SUBPACKAGE_DIR)s\examples\*.png"; DestDir: "{app}\%(PACKAGE_NAME)s\examples\wx"; Flags: ignoreversion;
-
-; ------------------------------------------------------------------------------
-; examples
-; ------------------------------------------------------------------------------
-
-Source: "*.py"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion;
-Source: "*.html"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion;
-Source: "*.css"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion;
-Source: "*.js"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion;
-Source: "*.ico"; DestDir: "{app}\%(PACKAGE_NAME)s\examples"; Flags: ignoreversion;
-
-[UninstallDelete]
-
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\*.pyc";
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\*.log";
-Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\__pycache__"
-
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.pyc";
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\*.log";
-Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\examples\__pycache__"
-
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.pyc";
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\*.log";
-Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\examples\wx\__pycache__"
-
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.pyc";
-Type: files; Name: "{app}\%(PACKAGE_NAME)s\wx\*.log";
-Type: filesandordirs; Name: "{app}\%(PACKAGE_NAME)s\wx\__pycache__"
-
-[Code]
-
-program Setup;
-var
- PythonDir : String;
- InstallDir : String;
-
-function InitializeSetup(): Boolean;
-begin
-
- if not RegQueryStringValue(%(HKEY_CURRENT_USER)s,
- 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath',
- '', PythonDir) then begin
-
- if not RegQueryStringValue(%(HKEY_LOCAL_MACHINE)s,
- 'Software\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath',
- '', PythonDir) then begin
-
- if not RegQueryStringValue(%(HKEY_CURRENT_USER)s,
- 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath',
- '', PythonDir) then begin
-
- if not RegQueryStringValue(%(HKEY_LOCAL_MACHINE)s,
- 'Software\Wow6432Node\Python\PythonCore\%(PYTHON_VERSION)s\InstallPath',
- '', PythonDir) then begin
-
- MsgBox('No installation of Python %(PYTHON_VERSION)s '
- + 'found in registry.' + #13 + 'Be sure to enter '
- + 'a pathname that places Python on the '
- + 'PYTHONPATH',
- mbConfirmation, MB_OK);
- PythonDir := 'C:\Python';
- end;
- end;
- end;
- end;
-
- InstallDir := PythonDir + '\Lib\site-packages';
- Result := True;
-end;
-
-function GetInstallDir(Default: String): String;
-begin
- Result := InstallDir;
-end;
-
-function UninstallOld(FileName: String): Boolean;
-var
- ResultCode: Integer;
-begin
- Result := False;
- if FileExists(FileName) then begin
- Result := True;
- Exec(FileName, '/SILENT', WizardDirValue(), SW_SHOWNORMAL,
- ewWaitUntilTerminated, ResultCode);
- end;
-end;
-
-function NextButtonClick(CurPage: Integer): Boolean;
-begin
- Result := True;
- if CurPage <> wpSelectDir then Exit;
- UninstallOld(WizardDirValue() + '\%(PACKAGE_NAME)s\unins001.exe')
- UninstallOld(WizardDirValue() + '\%(PACKAGE_NAME)s\unins000.exe')
-end;
diff --git a/src/windows/installer/make-installer.py b/src/windows/installer/make-installer.py
deleted file mode 100644
index ab31d536..00000000
--- a/src/windows/installer/make-installer.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
-# License: New BSD License.
-# Website: http://code.google.com/p/cefpython/
-
-# Create a Windows package installer.
-
-import sys
-import os
-import platform
-import argparse
-import re
-import struct
-import sysconfig
-
-BITS = str(8 * struct.calcsize('P')) + 'bit'
-assert (BITS == "32bit" or BITS == "64bit")
-
-ISCC = r"c:\Program Files (x86)\Inno Setup 5\ISCC.exe"
-if "INNO5" in os.environ:
- ISCC = os.environ["INNO5"]
-
-TEMPLATE_FILE = os.getcwd()+r"\innosetup.template"
-ISS_FILE = os.getcwd()+r"\innosetup.generated"
-
-def main():
- parser = argparse.ArgumentParser(usage="%(prog)s [options]")
- parser.add_argument("-v", "--version", help="cefpython version",
- required=True)
- args = parser.parse_args()
- assert re.search(r"^\d+\.\d+$", args.version), "Invalid version string"
-
- vars = {}
- vars["PACKAGE_NAME"] = "cefpython3"
- vars["APP_VERSION"] = args.version
- vars["PYTHON_VERSION"] = (str(sys.version_info.major) + "."
- + str(sys.version_info.minor))
- vars["PYTHON_VERSION_NODOT"] = (str(sys.version_info.major) + ""
- + str(sys.version_info.minor))
- vars["PYTHON_ARCHITECTURE"] = platform.architecture()[0]
- vars["BINARIES_DIR"] = os.path.realpath(
- os.getcwd() + r"\..\binaries_%s" % BITS)
- vars["PYD_FILE"] = (vars["BINARIES_DIR"]+r"\cefpython_py"
- + str(sys.version_info.major) + str(sys.version_info.minor)
- + ".pyd")
- vars["INSTALLER_DIR"] = os.getcwd()
- vars["WX_SUBPACKAGE_DIR"] = os.path.realpath(os.getcwd()+r"\..\..\wx")
- vars["PLATFORM"] = sysconfig.get_platform()
-
- if BITS == "32bit":
- # We must keep compatibility, 32bit installers didn't contain
- # architecture information in AppName. So make it an empty string.
- vars["APP_NAME_BITS"] = ""
- vars["HKEY_CURRENT_USER"] = "HKEY_CURRENT_USER"
- vars["HKEY_LOCAL_MACHINE"] = "HKEY_LOCAL_MACHINE"
- elif BITS == "64bit":
- vars["APP_NAME_BITS"] = "64bit"
- # Inno setup installer is a 32bit application. To query 64bit
- # registry from within 32bit application you need to add _64
- # postfix.
- vars["HKEY_CURRENT_USER"] = "HKEY_CURRENT_USER_64"
- vars["HKEY_LOCAL_MACHINE"] = "HKEY_LOCAL_MACHINE_64"
-
- print("Reading template: %s" % TEMPLATE_FILE)
-
- f = open(TEMPLATE_FILE)
- template = f.read()
- f.close()
-
- f = open(ISS_FILE, "w")
- f.write(template % vars)
- f.close()
-
- print("Saved: %s" % ISS_FILE)
-
- initPyTemplate = os.getcwd()+r"\__init__.py.template"
- initPyInstall = os.getcwd()+r"\__init__.py.generated"
-
- f = open(initPyTemplate)
- initPyTemplateCode = f.read()
- f.close()
-
- f = open(initPyInstall, "w")
- f.write(initPyTemplateCode % vars)
- f.close()
- print("Saved: %s" % initPyInstall)
-
- iscc_command = '"'+ ISCC + '" ' + ISS_FILE
- print("Running ISCC: %s" % iscc_command)
- exit_code = os.system(iscc_command)
- sys.exit(exit_code)
-
-if __name__ == "__main__":
- main()
diff --git a/src/windows/installer/make-setup.py b/src/windows/installer/make-setup.py
deleted file mode 100644
index 27d521e3..00000000
--- a/src/windows/installer/make-setup.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# Copyright (c) 2012-2014 The CEF Python authors. All rights reserved.
-# License: New BSD License.
-# Website: http://code.google.com/p/cefpython/
-
-# Create a setup package.
-
-import sys
-import os
-import platform
-import argparse
-import re
-import platform
-import shutil
-import glob
-import shutil
-import sysconfig
-
-BITS = platform.architecture()[0]
-assert (BITS == "32bit" or BITS == "64bit")
-
-PACKAGE_NAME = "cefpython3"
-
-README_FILE = os.getcwd()+r"/README.txt"
-INIT_TEMPLATE = os.getcwd()+r"/__init__.py.template"
-SETUP_TEMPLATE = os.getcwd()+r"/setup.py.template"
-SETUP_CFG_TEMPLATE = os.getcwd()+r"/setup.cfg.template"
-
-def glob_remove(pathname):
- filelist = glob.glob(pathname)
- for f in filelist:
- os.remove(f)
-
-def glob_copy(src_glob, dst_folder):
- for fname in glob.iglob(src_glob):
- print("Copying %s to %s" % (fname, dst_folder))
- if os.path.isdir(fname):
- shutil.copytree(fname,
- os.path.join(dst_folder, os.path.basename(fname)))
- else:
- shutil.copy(fname,
- os.path.join(dst_folder, os.path.basename(fname)))
-
-def glob_move(src_glob, dst_folder):
- if not os.path.exists(dst_folder):
- os.mkdir(dst_folder)
- for fname in glob.iglob(src_glob):
- shutil.move(fname,
- os.path.join(dst_folder, os.path.basename(fname)))
-
-def str_format(string, dictionary):
- orig_string = string
- for key, value in dictionary.iteritems():
- string = string.replace("%("+key+")s", value)
- if string == orig_string:
- raise Exception("Nothing to format")
- if re.search(r"%\([a-zA-Z0-9_]+\)s", string):
- raise Exception("Not all strings formatted")
- return string
-
-def main():
- parser = argparse.ArgumentParser(usage="%(prog)s [options]")
- parser.add_argument("-v", "--version", help="cefpython version",
- required=True)
- args = parser.parse_args()
- assert re.search(r"^\d+\.\d+$", args.version), (
- "Invalid version string")
-
- vars = {}
- vars["APP_VERSION"] = args.version
- vars["PLATFORM"] = sysconfig.get_platform()
- vars["PY_VERSION_DIGITS_ONLY"] = (str(sys.version_info.major) + ""
- + str(sys.version_info.minor)) # "27" or "34"
-
- print("Reading template: %s" % README_FILE)
- f = open(README_FILE)
- README_CONTENT = f.read()
- f.close()
-
- print("Reading template: %s" % INIT_TEMPLATE)
- f = open(INIT_TEMPLATE)
- INIT_CONTENT = str_format(f.read(), vars)
- f.close()
-
- print("Reading template: %s" % SETUP_TEMPLATE)
- f = open(SETUP_TEMPLATE)
- SETUP_CONTENT = str_format(f.read(), vars)
- f.close()
-
- print("Reading template: %s" % SETUP_CFG_TEMPLATE)
- f = open(SETUP_CFG_TEMPLATE)
- SETUP_CFG_CONTENT = str_format(f.read(), vars)
- f.close()
-
- installer_dir = os.path.dirname(os.path.abspath(__file__))
-
- pyVersion = str(sys.version_info.major) +"."+ str(sys.version_info.minor)
- setup_dir = installer_dir+"/"+PACKAGE_NAME+"-"+vars["APP_VERSION"]\
- +"."+BITS+"-py"+pyVersion+"-setup"
- print("Creating setup dir: "+setup_dir)
- os.mkdir(setup_dir)
-
- package_dir = setup_dir+"/"+PACKAGE_NAME
- #print("Creating package dir")
- #os.mkdir(package_dir)
-
- print("Creating README.txt from template")
- with open(setup_dir+"/README.txt", "w") as f:
- f.write(README_CONTENT)
-
- print("Creating setup.py from template")
- with open(setup_dir+"/setup.py", "w") as f:
- f.write(SETUP_CONTENT)
-
- print("Creating setup.cfg from template")
- with open(setup_dir+"/setup.cfg", "w") as f:
- f.write(SETUP_CFG_CONTENT)
-
- binaries_dir = os.path.abspath(installer_dir+"/../binaries_"+BITS+"/")
- print("Copying binaries to package dir")
- shutil.copytree(binaries_dir, package_dir)
-
- os.chdir(package_dir)
- print("Removing .log .pyc .pdb files from the package dir")
- glob_remove("*.log")
- glob_remove("*.pyc")
- glob_remove("*.pdb")
-
- os.chdir(installer_dir)
-
- print("Creating __init__.py from template")
- with open(package_dir+"/__init__.py", "w") as f:
- f.write(INIT_CONTENT)
-
- print("Creating examples dir in package dir")
- os.mkdir(package_dir+"/examples/")
-
- print("Creating wx dir in package dir")
- os.mkdir(package_dir+"/wx/")
-
- print("Moving example scripts from package dir to examples dir")
- examples = glob.glob(package_dir+"/*.py")
- for example in examples:
- # Ignore: cefpython_py27.py - dummy API script
- if os.path.basename(example).startswith("cefpython_"):
- continue
- # Ignore: __init__.py
- if os.path.basename(example).startswith("__"):
- continue
- os.rename(example, package_dir+"/examples/"+os.path.basename(example))
- glob_move(package_dir+"/*.html", package_dir+"/examples/")
- glob_move(package_dir+"/*.css", package_dir+"/examples/")
- glob_move(package_dir+"/*.js", package_dir+"/examples/")
-
- print("Copying wx/ to package dir")
- wx_subpackage_dir = os.path.abspath(installer_dir+"/../../wx/")
- glob_copy(wx_subpackage_dir+"/*", package_dir+"/wx/")
-
- print("Moving wx examples from wx/examples to examples/wx")
- glob_move(package_dir+"/wx/examples/*", package_dir+"/examples/wx/")
- os.rmdir(package_dir+"/wx/examples/")
-
- print("Copying package dir examples to setup dir")
- glob_copy(package_dir+"/examples/", setup_dir+"/examples/")
-
- # Create empty debug.log files so that package uninstalls cleanly
- # in case examples were launched. Issue 149.
- debug_log_dirs = [package_dir,
- package_dir+"/examples/",
- package_dir+"/examples/wx/"]
- for dir in debug_log_dirs:
- print("Creating empty debug.log in %s" % dir)
- with open(dir+"/debug.log", "w") as f:
- f.write("")
-
- print("Setup Package created successfully.")
-
-if __name__ == "__main__":
- main()
diff --git a/src/windows/installer/setup.cfg.template b/src/windows/installer/setup.cfg.template
deleted file mode 100644
index 067dcbfd..00000000
--- a/src/windows/installer/setup.cfg.template
+++ /dev/null
@@ -1,2 +0,0 @@
-[bdist_wheel]
-python-tag=cp%(PY_VERSION_DIGITS_ONLY)s
diff --git a/src/windows/installer/setup.py.template b/src/windows/installer/setup.py.template
deleted file mode 100644
index 36fb2809..00000000
--- a/src/windows/installer/setup.py.template
+++ /dev/null
@@ -1,68 +0,0 @@
-try:
- # The setuptools package is not installed by default
- # on a clean Ubuntu. Might be also a case on Windows.
- # Python Eggs and Wheels can be created only with setuptools.
- from setuptools import setup
- from setuptools.command.install import install as _install
- from setuptools.dist import Distribution
- print("[setup.py] Using setuptools")
-except:
- from distutils.core import setup
- from distutils.command.install import install as _install
- from distutils.dist import Distribution
- print("[setup.py] Using distutils")
-
-import sys
-import os
-import subprocess
-
-def post_install():
- """ Post install tasks """
- print("[setup.py] post_install()")
- # Nothing extra is required to do on Windows.
-
-class install(_install):
- def run(self):
- _install.run(self)
- post_install()
-
-class BinaryDistribution(Distribution):
- def is_pure(self):
- return False
-
-setup(
- distclass=BinaryDistribution,
- cmdclass={'install': install},
- name='cefpython3', # No spaces here, so that it works with deb packages.
- version='%(APP_VERSION)s',
- description='Python bindings for the Chromium Embedded Framework',
- license='BSD 3-Clause',
- author='Czarek Tomczak',
- author_email='czarek.tomczak@gmail.com',
- url='http://code.google.com/p/cefpython/',
- platforms=['%(PLATFORM)s'],
- packages=['cefpython3', 'cefpython3.wx'],
- package_data={'cefpython3': [
- 'examples/*.py',
- 'examples/*.html',
- 'examples/*.js',
- 'examples/*.css',
- 'examples/wx/*.py',
- 'examples/wx/*.html',
- 'examples/wx/*.js',
- 'examples/wx/*.css',
- 'examples/wx/*.png',
- 'locales/*.pak',
- 'wx/*.txt',
- 'wx/images/*.png',
- '*.txt',
- 'cefclient.exe',
- 'subprocess.exe',
- '*.pyd',
- '*.dll',
- '*.pak',
- 'debug.log',
- 'examples/debug.log',
- 'examples/wx/debug.log',
- ]}
-)
diff --git a/tools/automate.py b/tools/automate.py
index 4da35108..0d966067 100644
--- a/tools/automate.py
+++ b/tools/automate.py
@@ -1,6 +1,22 @@
# Copyright (c) 2016 CEF Python, see the Authors file. All rights reserved.
-"""Automates building CEF from sources with CEF Python patches applied.
+"""
+Prepares CEF binaries and libraries for work with the build.py tool.
+
+Option 1 is to build CEF from sources with the CEF Python patches applied
+using the --build-cef flag.
+
+Option 2 is to use CEF binaries from Spotify Automated Builds using
+the --prebuilt-cef flag. In such case check the cefpython/src/version/
+directory to know which version of CEF to download from Spotify:
+http://opensource.spotify.com/cefbuilds/index.html
+Download and extract it so that for example you have such a directory:
+cefpython/build/cef_binary_3.2883.1553.g80bd606_windows32/ .
+
+This tool generates CEF binaries and libraries that are ready for work
+with cefpython, with the build.py script. When automate.py tool completes
+job you should see a new subdirectory in the build/ directory, for example:
+cefpython/build/cef55_3.2883.1553.g80bd606_win32/ .
Usage:
automate.py (--prebuilt-cef | --build-cef)
@@ -50,24 +66,6 @@
CEF_GIT_URL = "https://bitbucket.org/chromiumembedded/cef.git"
-VS2015_VCVARS = "\"C:\Program Files (x86)\\Microsoft Visual Studio 14.0" \
- "\\VC\\vcvarsall.bat\" x86" \
- if ARCH32 else \
- "\"C:\Program Files (x86)\\Microsoft Visual Studio 14.0" \
- "\\VC\\vcvarsall.bat\" amd64"
-
-VS2013_VCVARS = "\"C:\Program Files (x86)\\Microsoft Visual Studio 12.0" \
- "\\VC\\vcvarsall.bat\" x86" \
- if ARCH32 else \
- "\"C:\Program Files (x86)\\Microsoft Visual Studio 12.0" \
- "\\VC\\cvarsall.bat\" amd64"
-
-VS2008_VCVARS = "\"%LocalAppData%\\Programs\\Common\\Microsoft" \
- "\\Visual C++ for Python\\9.0\\vcvarsall.bat\" x86" \
- if ARCH32 else \
- "\"%LocalAppData%\\Programs\\Common\\Microsoft" \
- "\\Visual C++ for Python\\9.0\\vcvarsall.bat\" amd64"
-
class Options(object):
"""Options from command-line and internal options."""
@@ -94,6 +92,9 @@ class Options(object):
release_build = True
build_type = "" # Will be set according to "release_build" value
cef_binary = ""
+ build_cefclient_dir = ""
+ build_wrapper_mt_dir = ""
+ build_wrapper_md_dir = ""
def main():
@@ -104,6 +105,10 @@ def main():
print(" automate-git.py works only with that version.")
sys.exit(1)
+ if len(sys.argv) <= 1:
+ print(__doc__)
+ sys.exit(1)
+
setup_options(docopt.docopt(__doc__))
if Options.build_cef:
@@ -303,7 +308,7 @@ def build_cef_projects():
fix_cef_include_files()
- # Find cef_binary directories and create the cef_binary/build/ dir
+ # Find cef_binary directory
if not Options.cef_binary:
if platform.system() == "Windows":
files = glob.glob(os.path.join(Options.binary_distrib,
@@ -324,127 +329,224 @@ def build_cef_projects():
assert os.path.exists(cef_binary)
Options.cef_binary = cef_binary
+ # Set build directory
+ Options.build_cefclient_dir = os.path.join(Options.cef_binary,
+ "build_cefclient")
+
print("[automate.py] Creating build_cefclient dir in cef_binary dir")
- build_cefclient = os.path.join(Options.cef_binary, "build_cefclient")
+
+ # Check whether already built
already_built = False
- if os.path.exists(build_cefclient):
+ if build_cefclient_succeeded():
already_built = True
+ elif os.path.exists(Options.build_cefclient_dir):
+ # Last build failed, clean directory
+ assert Options.build_cefclient_dir
+ shutil.rmtree(Options.build_cefclient_dir)
+ os.makedirs(Options.build_cefclient_dir)
else:
- os.makedirs(build_cefclient)
+ os.makedirs(Options.build_cefclient_dir)
# Build cefclient, cefsimple, ceftests
if already_built:
print("[automate.py] Already built: cefclient, cefsimple, ceftests")
else:
- print("[automate.py] Building cefclient, cefsimple, ceftests ...")
+ print("[automate.py] Build cefclient, cefsimple, ceftests")
+ # Cmake
command = prepare_build_command()
- command += "cmake -G \"Ninja\" -DCMAKE_BUILD_TYPE=%s .." \
- % Options.build_type
- run_command(command, build_cefclient)
+ command.extend(["cmake", "-G", "Ninja",
+ "-DCMAKE_BUILD_TYPE="+Options.build_type, ".."])
+ run_command(command, Options.build_cefclient_dir)
print("[automate.py] OK")
- # On Linux cannot pass "&&" and run two commands using run_command()
+ # Ninja
command = prepare_build_command()
- command += "ninja cefclient cefsimple ceftests"
- run_command(command, build_cefclient)
+ command.extend(["ninja", "cefclient", "cefsimple", "ceftests"])
+ run_command(command, Options.build_cefclient_dir)
print("[automate.py] OK")
- if platform.system() == "Windows":
- assert(os.path.exists(os.path.join(build_cefclient,
- "tests",
- "cefclient",
- Options.build_type,
- "cefclient.exe")))
- else:
- assert (os.path.exists(os.path.join(build_cefclient,
- "tests",
- "cefclient",
- Options.build_type,
- "cefclient")))
+ assert build_cefclient_succeeded()
# Build libcef_dll_wrapper libs
if platform.system() == "Windows":
- build_wrapper_windows(Options.cef_binary)
+ build_wrapper_windows()
-def prepare_build_command(build_lib=False):
- """On Windows VS env variables must be set up by calling vcvarsall.bat"""
- command = ""
- if platform.system() == "Windows":
- if build_lib:
- msvs = get_msvs_for_python()
- command = globals()["VS"+msvs+"_VCVARS"] + " && "
- else:
- if int(Options.cef_branch) >= 2704:
- command = VS2015_VCVARS + " && "
- else:
- command = VS2013_VCVARS + " && "
- return command
+def build_wrapper_windows():
+ # When building library cmake variables file is being modified
+ # for the /MD build. If the build fails and variables aren't
+ # restored then the next /MT build would be broken. Make sure
+ # that original contents of cmake variables files is always
+ # restored.
+ fix_cmake_variables_for_md_library(try_undo=True)
-
-def build_wrapper_windows(cef_binary):
# Command to build libcef_dll_wrapper
- wrapper_cmake = prepare_build_command(build_lib=True)
- wrapper_cmake += "cmake -G \"Ninja\" -DCMAKE_BUILD_TYPE=%s .." \
- % Options.build_type
+ cmake_wrapper = prepare_build_command(build_lib=True)
+ cmake_wrapper.extend(["cmake", "-G", "Ninja",
+ "-DCMAKE_BUILD_TYPE="+Options.build_type, ".."])
+
+ # Set build directory for /MT lib.
+ Options.build_wrapper_mt_dir = os.path.join(Options.cef_binary,
+ "build_wrapper_mt")
- # Build libcef_dll_wrapper_mt.lib
- build_wrapper_mt = os.path.join(cef_binary, "build_wrapper_mt")
+ # Check whether already built
mt_already_built = False
- if os.path.exists(build_wrapper_mt):
+ if build_wrapper_mt_succeeded():
mt_already_built = True
+ elif os.path.exists(Options.build_wrapper_mt_dir):
+ # Last build failed, clean directory
+ assert Options.build_wrapper_mt_dir
+ shutil.rmtree(Options.build_wrapper_mt_dir)
+ os.makedirs(Options.build_wrapper_mt_dir)
else:
- os.makedirs(build_wrapper_mt)
+ os.makedirs(Options.build_wrapper_mt_dir)
+
+ # Build /MT lib.
if mt_already_built:
print("[automate.py] Already built: libcef_dll_wrapper /MT")
else:
- print("[automate.py] Building libcef_dll_wrapper /MT")
+ print("[automate.py] Build libcef_dll_wrapper /MT")
old_gyp_msvs_version = Options.gyp_msvs_version
Options.gyp_msvs_version = get_msvs_for_python()
- run_command(wrapper_cmake, build_wrapper_mt)
+ # Cmake
+ run_command(cmake_wrapper, Options.build_wrapper_mt_dir)
Options.gyp_msvs_version = old_gyp_msvs_version
print("[automate.py] cmake OK")
+ # Ninja
ninja_wrapper = prepare_build_command(build_lib=True)
- ninja_wrapper += "ninja libcef_dll_wrapper"
- run_command(ninja_wrapper, build_wrapper_mt)
+ ninja_wrapper.extend(["ninja", "libcef_dll_wrapper"])
+ run_command(ninja_wrapper, Options.build_wrapper_mt_dir)
print("[automate.py] ninja OK")
- assert(os.path.exists(os.path.join(build_wrapper_mt,
- "libcef_dll_wrapper",
- "libcef_dll_wrapper.lib")))
+ assert build_wrapper_mt_succeeded()
- # Build libcef_dll_wrapper_md.lib
- build_wrapper_md = os.path.join(cef_binary, "build_wrapper_md")
+ # Set build directory for /MD lib.
+ Options.build_wrapper_md_dir = os.path.join(Options.cef_binary,
+ "build_wrapper_md")
+
+ # Check whether already built
md_already_built = False
- if os.path.exists(build_wrapper_md):
+ if build_wrapper_md_succeeded():
md_already_built = True
+ elif os.path.exists(Options.build_wrapper_md_dir):
+ # Last build failed, clean directory
+ assert Options.build_wrapper_md_dir
+ shutil.rmtree(Options.build_wrapper_md_dir)
+ os.makedirs(Options.build_wrapper_md_dir)
else:
- os.makedirs(build_wrapper_md)
+ os.makedirs(Options.build_wrapper_md_dir)
+
+ # Build /MD lib.
if md_already_built:
print("[automate.py] Already built: libcef_dll_wrapper /MD")
else:
- print("[automate.py] Building libcef_dll_wrapper /MD")
+ print("[automate.py] Build libcef_dll_wrapper /MD")
old_gyp_msvs_version = Options.gyp_msvs_version
Options.gyp_msvs_version = get_msvs_for_python()
- # Replace /MT with /MD /wd\"4275\" in CMakeLists.txt
- # Warnings are treated as errors so this needs to be ignored:
- # >> warning C4275: non dll-interface class 'stdext::exception'
- # >> used as base for dll-interface class 'std::bad_cast'
- # This warning occurs only in VS2008, in VS2013 not.
- cmakelists = os.path.join(cef_binary, "CMakeLists.txt")
- with open(cmakelists, "rb") as fp:
- contents = fp.read()
- contents = contents.replace(r"/MT ", r"/MD /wd\"4275\" ")
- contents = contents.replace(r"/MTd ", r"/MDd /wd\"4275\" ")
- with open(cmakelists, "wb") as fp:
- fp.write(contents)
- run_command(wrapper_cmake, build_wrapper_md)
+ # Fix cmake variables
+ # Cmake
+ fix_cmake_variables_for_md_library()
+ run_command(cmake_wrapper, Options.build_wrapper_md_dir)
Options.gyp_msvs_version = old_gyp_msvs_version
+ fix_cmake_variables_for_md_library(undo=True)
print("[automate.py] cmake OK")
+ # Ninja
ninja_wrapper = prepare_build_command(build_lib=True)
- ninja_wrapper += "ninja libcef_dll_wrapper"
- run_command(ninja_wrapper, build_wrapper_md)
+ ninja_wrapper.extend(["ninja", "libcef_dll_wrapper"])
+ run_command(ninja_wrapper, Options.build_wrapper_md_dir)
print("[automate.py] ninja OK")
- assert(os.path.exists(os.path.join(build_wrapper_md,
- "libcef_dll_wrapper",
- "libcef_dll_wrapper.lib")))
+ assert build_wrapper_md_succeeded()
+
+
+def fix_cmake_variables_for_md_library(undo=False, try_undo=False):
+ """Fix cmake variables or undo it. The try_undo param is
+ for a case when want to be sure that the file wasn't modified,
+ for example in case the last build failed."""
+
+ # Replace /MT with /MD /wd4275 in cef/cmake/cef_variables.cmake
+ # Warnings are treated as errors so this needs to be ignored:
+ # >> warning C4275: non dll-interface class 'stdext::exception'
+ # >> used as base for dll-interface class 'std::bad_cast'
+ # This warning occurs only in VS2008, in VS2013 not.
+ # This replacements must be unique for the undo operation
+ # to be reliable.
+
+ mt_find = r"/MT "
+ mt_replace = r"/MD /wd4275 "
+
+ mtd_find = r"/MTd "
+ mtd_replace = r"/MDd /wd4275 "
+
+ cmake_variables = os.path.join(Options.cef_binary, "cmake",
+ "cef_variables.cmake")
+ with open(cmake_variables, "rb") as fp:
+ contents = fp.read()
+
+ if try_undo:
+ matches1 = re.findall(re.escape(mt_replace), contents)
+ matches2 = re.findall(re.escape(mtd_replace), contents)
+ if len(matches1) or len(matches2):
+ undo = True
+ else:
+ return
+
+ if undo:
+ (contents, count) = re.subn(re.escape(mt_replace), mt_find,
+ contents)
+ assert count == 2
+ (contents, count) = re.subn(re.escape(mtd_replace), mtd_find,
+ contents)
+ assert count == 1
+ else:
+ (contents, count) = re.subn(re.escape(mt_find), mt_replace,
+ contents)
+ assert count == 2
+ (contents, count) = re.subn(re.escape(mtd_find), mtd_replace,
+ contents)
+ assert count == 1
+
+ with open(cmake_variables, "wb") as fp:
+ fp.write(contents)
+
+
+def build_cefclient_succeeded():
+ """Whether building cefclient/cefsimple/ceftests succeeded."""
+ assert Options.build_cefclient_dir
+ cefclient_exe = "cefclient.exe" if WINDOWS else "cefclient"
+ return os.path.exists(os.path.join(Options.build_cefclient_dir,
+ "tests",
+ "cefclient",
+ Options.build_type,
+ cefclient_exe))
+
+
+def build_wrapper_mt_succeeded():
+ """Whether building /MT library succeeded (Windows-only)."""
+ assert Options.build_wrapper_mt_dir
+ return os.path.exists(os.path.join(Options.build_wrapper_mt_dir,
+ "libcef_dll_wrapper",
+ "libcef_dll_wrapper.lib"))
+
+
+def build_wrapper_md_succeeded():
+ """Whether building /MD library succeeded (Windows-only)."""
+ assert Options.build_wrapper_md_dir
+ return os.path.exists(os.path.join(Options.build_wrapper_md_dir,
+ "libcef_dll_wrapper",
+ "libcef_dll_wrapper.lib"))
+
+
+def prepare_build_command(build_lib=False):
+ """On Windows VS env variables must be set up by calling vcvarsall.bat"""
+ command = list()
+ if platform.system() == "Windows":
+ if build_lib:
+ msvs = get_msvs_for_python()
+ command.append(globals()["VS"+msvs+"_VCVARS"])
+ else:
+ if int(Options.cef_branch) >= 2704:
+ command.append(VS2015_VCVARS)
+ else:
+ command.append(VS2013_VCVARS)
+ command.append("&&")
+ return command
def fix_cef_include_files():
@@ -600,13 +702,16 @@ def getenv():
return env
-def run_command(command_line, working_dir):
+def run_command(command, working_dir):
"""Run command in a given directory with env variables set.
On Linux multiple commands on one line with the use of && are not allowed.
"""
- print("[automate.py] Running '"+command_line+"' in '" +
+ print("[automate.py] Running '"+" ".join(command)+"' in '" +
working_dir+"'...")
- args = shlex.split(command_line.replace("\\", "\\\\"))
+ if isinstance(command, str):
+ args = shlex.split(command.replace("\\", "\\\\"))
+ else:
+ args = command
return subprocess.check_call(args, cwd=working_dir, env=getenv(),
shell=(platform.system() == "Windows"))
diff --git a/tools/build.py b/tools/build.py
index 48c13874..6c424a78 100644
--- a/tools/build.py
+++ b/tools/build.py
@@ -1,16 +1,29 @@
+# Copyright (c) 2017 The CEF Python authors. All rights reserved.
+# Licensed under the BSD 3-clause license.
+
"""
Build the cefpython module, install package and run example.
+Before running you must first put cefpython ready CEF binaries and
+libraries in the cefpython/build/ directory (create if doesn't exist).
+You have two options for obtaining these binaries and libraries.
+
+Option 1: Download upstream CEF binaries and libraries from cefpython
+GitHub Releases page. These binaries are tagged eg. "v55-upstream".
+Extract the archive so that for example you have such a directory:
+cefpython/build/cef55_3.2883.1553.g80bd606_win32/ .
+
+Option 2: Use the automate.py tool. With this tool you can build CEF
+from sources or use ready binaries from Spotify Automated Builds.
+
Usage:
- build.py VERSION [--debug] [--fast]
+ build.py VERSION [--rebuild-cpp] [--fast] [--kivy]
Options:
- VERSION Version in format xx.xx
- --debug Debug mode
- --fast Fast mode, don't delete C++ .o .a files, nor the setup/build/
- directory, and disable optimization flags when building
- the so/pyd module.
- --kivy Run Kivy example
+ VERSION Version in format xx.xx
+ --rebuild-cpp Force rebuild of C++ projects
+ --fast Fast mode
+ --kivy Run only Kivy example
"""
# How to debug on Linux:
@@ -56,21 +69,18 @@
else:
MODULE_EXT = "so"
-# Compiler options
-if MAC:
- os.environ["PATH"] = "/usr/local/bin:"+os.environ["PATH"]
- os.environ["CC"] = "gcc"
- os.environ["CXX"] = "g++"
- os.environ["CEF_CCFLAGS"] = "-arch x86_64"
- os.environ["ARCHFLAGS"] = "-arch x86_64"
- if ARCH32:
- raise Exception("Python 32bit is not supported on Mac")
+# First run
+FIRST_RUN = False
+CEFPYTHON_H = os.path.join(BUILD_CEFPYTHON, "cefpython.h")
def main():
+ if len(sys.argv) <= 1:
+ print(__doc__)
+ sys.exit(1)
print("[build.py] PYVERSION = %s" % PYVERSION)
print("[build.py] OS_POSTFIX2 = %s" % OS_POSTFIX2)
- setup_environ_path()
+ setup_environ()
check_cython_version()
command_line_args()
check_directories()
@@ -87,28 +97,57 @@ def main():
install_and_run()
-def setup_environ_path():
- print("[build.py] Setup environment PATH")
+def setup_environ():
+ """Set environment variables. Set PATH so that it contains only
+ minimum set of directories,to avoid any possible issues. Set Python
+ include path. Set Mac compiler options. Etc."""
+ print("[build.py] Setup environment variables")
+
if not WINDOWS:
return
- if ARCH32:
- os.environ["PATH"] = ("C:\\Windows\\system32;C:\\Windows;"
- "C:\\Windows\\System32\\Wbem;C:\\Python27")
- else:
- raise Exception("Only 32-bit is currently supported")
- print("[build.py] PATH: {path}".format(path=os.environ["PATH"]))
+ # PATH
+ if WINDOWS:
+ path = [
+ "C:\\Windows\\system32",
+ "C:\\Windows",
+ "C:\\Windows\\System32\\Wbem",
+ get_python_path(),
+ ]
+ os.environ["PATH"] = os.pathsep.join(path)
+ print("[build.py] environ PATH: {path}"
+ .format(path=os.environ["PATH"]))
+
+ # INCLUDE env for vcproj build
+ if WINDOWS:
+ if "INCLUDE" not in os.environ:
+ os.environ["INCLUDE"] = ""
+ os.environ["INCLUDE"] += os.pathsep + os.path.join(get_python_path(),
+ "include")
+ print("[build.py] environ INCLUDE: {include}"
+ .format(include=os.environ["INCLUDE"]))
+
+ # LIB env for vcproj build
+ if WINDOWS:
+ os.environ["AdditionalLibraryDirectories"] = os.path.join(
+ CEF_BINARIES_LIBRARIES, "lib")
+ print("[build.py] environ AdditionalLibraryDirectories: {lib}"
+ .format(lib=os.environ["AdditionalLibraryDirectories"]))
- """
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;
- C:\Python27_x64;C:\Python27_amd64;C:\Python27_64
+ # Mac compiler options
+ if MAC:
+ os.environ["PATH"] = "/usr/local/bin:"+os.environ["PATH"]
+ os.environ["CC"] = "gcc"
+ os.environ["CXX"] = "g++"
+ os.environ["CEF_CCFLAGS"] = "-arch x86_64"
+ os.environ["ARCHFLAGS"] = "-arch x86_64"
+ if ARCH32:
+ raise Exception("Python 32-bit is not supported on Mac")
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;
- C:\Python34
- set PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;
- C:\Python34_x64;C:\Python34_amd64;C:\Python34_64
- """
+def get_python_path():
+ """Get Python path."""
+ return os.path.dirname(sys.executable)
def check_cython_version():
@@ -185,7 +224,7 @@ def check_directories():
# Check directories exist
assert os.path.exists(BUILD_DIR)
assert os.path.exists(BUILD_CEFPYTHON)
- assert os.path.exists(CEF_BINARY)
+ assert os.path.exists(CEF_BINARIES_LIBRARIES)
assert os.path.exists(CEFPYTHON_BINARY)
@@ -204,31 +243,44 @@ def fix_cefpython_h():
content = ("%s\n\n" % pragma) + content
with open("cefpython.h", "w") as fo:
fo.write(content)
- print("[build.py] Saved cefpython.h")
+ print("[build.py] Save build_cefpython/cefpython.h")
def compile_cpp_projects_windows():
print("[build.py] Compile C++ projects")
- print("[build.py] Build client_handler vcproj")
+ print("[build.py] ~~ Build CLIENT_HANDLER vcproj")
vcproj = ("client_handler_py{pyver}_{os}.vcproj"
.format(pyver=PYVERSION, os=OS_POSTFIX2))
vcproj = os.path.join(SRC_DIR, "client_handler", vcproj)
build_vcproj(vcproj)
- print("[build.py] Build libcefpythonapp vcproj")
+ print("[build.py] ~~ Build LIBCEFPYTHONAPP vcproj")
vcproj = ("libcefpythonapp_py{pyver}_{os}.vcproj"
.format(pyver=PYVERSION, os=OS_POSTFIX2))
vcproj = os.path.join(SRC_DIR, "subprocess", vcproj)
build_vcproj(vcproj)
- print("[build.py] Build subprocess vcproj")
+ print("[build.py] ~~ Build SUBPROCESS vcproj")
vcproj = ("subprocess_{os}.vcproj"
.format(os=OS_POSTFIX2))
vcproj = os.path.join(SRC_DIR, "subprocess", vcproj)
- build_vcproj(vcproj)
-
- print("[build.py] Build cpp_utils vcproj")
+ ret = build_vcproj(vcproj)
+
+ # Copy subprocess executable
+ subprocess_from = os.path.join(
+ SUBPROCESS_DIR,
+ "Release_{os}".format(os=OS_POSTFIX2),
+ "subprocess_{os}.exe".format(os=OS_POSTFIX2))
+ subprocess_to = os.path.join(CEFPYTHON_BINARY, "subprocess.exe")
+ if os.path.exists(subprocess_to):
+ os.remove(subprocess_to)
+ if ret == 0:
+ print("[build.py] Copy subprocess executable")
+ # shutil.copy() will also copy Permission bits
+ shutil.copy(subprocess_from, subprocess_to)
+
+ print("[build.py] ~~ Build CPP_UTILS vcproj")
vcproj = ("cpp_utils_{os}.vcproj"
.format(os=OS_POSTFIX2))
vcproj = os.path.join(SRC_DIR, "cpp_utils", vcproj)
@@ -236,11 +288,19 @@ def compile_cpp_projects_windows():
def build_vcproj(vcproj):
+ if not os.path.exists(CEFPYTHON_H):
+ print("[build.py] INFO: Looks like first run, as cefpython.h"
+ " is missing. Skip building C++ project.")
+ global FIRST_RUN
+ FIRST_RUN = True
+ return
+
if PYVERSION == "27":
args = list()
- args.append("%LocalAppData%\\Programs\\Common\\"
- "Microsoft\\Visual C++ for Python\\9.0\\"
- "VC\\bin\\amd64\\vcbuild.exe")
+ args.append(VS2008_VCVARS)
+ args.append(VS_PLATFORM_ARG)
+ args.append("&&")
+ args.append(VS2008_BUILD)
args.append("/nocolor")
args.append("/nologo")
args.append("/nohtmllog")
@@ -250,20 +310,17 @@ def build_vcproj(vcproj):
ret = subprocess.call(args, shell=True)
if ret != 0:
compile_ask_to_continue()
+ return ret
else:
raise Exception("Only Python 2.7 32-bit is currently supported")
- """
- In VS2010 vcbuild was replaced by msbuild.exe.
- /clp:disableconsolecolor
- msbuild /p:BuildProjectReferences=false project.proj
- MSBuild.exe MyProject.proj /t:build
- """
+ # In VS2010 vcbuild was replaced by msbuild.exe.
+ # /clp:disableconsolecolor
+ # msbuild /p:BuildProjectReferences=false project.proj
+ # MSBuild.exe MyProject.proj /t:build
def compile_ask_to_continue():
- print("[build.py] **INFO**: On first run you should continue despite"
- " errors and after completion re-run the build.py script again")
# noinspection PyUnboundLocalVariable
what = input("[build.py] make failed, 'y' to continue, Enter to stop: ")
if what != "y":
@@ -280,17 +337,8 @@ def compile_cpp_projects_unix():
# fails and then run the compile.py script again and this time
# make should succeed.
- # -------- CPP_UTILS_DIR
-
- os.chdir(CPP_UTILS_DIR)
- if not FAST_FLAG:
- subprocess.call("rm -f *.o *.a", shell=True)
-
- ret = subprocess.call("make -f Makefile", shell=True)
- if ret != 0:
- compile_ask_to_continue()
-
- # -------- CLIENT_HANDLER_DIR
+ # -- CLIENT_HANDLER
+ print("[build.py] ~~ Build CLIENT_HANDLER project")
os.chdir(CLIENT_HANDLER_DIR)
if not FAST_FLAG:
@@ -300,7 +348,8 @@ def compile_cpp_projects_unix():
if ret != 0:
compile_ask_to_continue()
- # -------- SUBPROCESS_DIR
+ # -- LIBCEFPYTHONAPP
+ print("[build.py] ~~ Build LIBCEFPYTHONAPP project")
os.chdir(SUBPROCESS_DIR)
if not FAST_FLAG:
@@ -311,14 +360,29 @@ def compile_cpp_projects_unix():
if ret != 0:
compile_ask_to_continue()
+ # -- SUBPROCESS
+ print("[build.py] ~~ Build SUBPROCESS project")
ret = subprocess.call("make -f Makefile", shell=True)
if ret != 0:
compile_ask_to_continue()
- subprocess_exe = os.path.join(CEFPYTHON_BINARY, "subprocess")
- if os.path.exists("./subprocess"):
- # .copy() will also copy Permission bits
- shutil.copy("./subprocess", subprocess_exe)
+ # Copy subprocess executable
+ subprocess_from = os.path.join(SUBPROCESS_DIR, "subprocess")
+ subprocess_to = os.path.join(CEFPYTHON_BINARY, "subprocess")
+ if os.path.exists(subprocess_from):
+ # shutil.copy() will also copy Permission bits
+ shutil.copy(subprocess_from, subprocess_to)
+
+ # -- CPP_UTILS
+ print("[build.py] ~~ Build CPP_UTILS project")
+
+ os.chdir(CPP_UTILS_DIR)
+ if not FAST_FLAG:
+ subprocess.call("rm -f *.o *.a", shell=True)
+
+ ret = subprocess.call("make -f Makefile", shell=True)
+ if ret != 0:
+ compile_ask_to_continue()
def clear_cache():
@@ -510,7 +574,19 @@ def build_cefpython_module():
# Check if built succeeded after pyx files were removed
if ret != 0:
- print("[build.py] FAILED to build the cefpython module")
+ if FIRST_RUN and os.path.exists(CEFPYTHON_H):
+ print("[build.py] INFO: looks like this was first run and"
+ " linking is expected to fail in such case. Will re-run"
+ " the build.py script programmatically now.")
+ args = list()
+ args.append(sys.executable)
+ args.append(os.path.join(TOOLS_DIR, os.path.basename(__file__)))
+ assert __file__ in sys.argv[0]
+ args.extend(sys.argv[1:])
+ ret = subprocess.call(args, shell=True)
+ sys.exit(ret)
+ else:
+ print("[build.py] ERROR: failed to build the cefpython module")
sys.exit(1)
# Move the cefpython module
@@ -521,7 +597,7 @@ def build_cefpython_module():
.format(pyver=PYVERSION,
ext=MODULE_EXT)))
- print("[build.py] Done building the cefpython module")
+ print("[build.py] DONE building the cefpython module")
def move_file_by_pattern(pattern, move_to):
@@ -553,60 +629,44 @@ def delete_directories_by_pattern(pattern):
def install_and_run():
- os.chdir(BUILD_CEFPYTHON)
-
# if DEBUG_FLAG:
# os.chdir("./binaries_%s" % BITS)
# subprocess.call("cygdb . --args python-dbg wxpython.py", shell=True)
print("[build.py] Install and run...")
+ os.chdir(BUILD_DIR)
- # Clean installer directory from previous run
- try:
- delete_directories_by_pattern("./cefpython3-{ver}-*-setup/"
- .format(ver=VERSION))
- except:
- if LINUX:
- os.system("sudo rm -rf ./cefpython3-{ver}-*-setup/"
- .format(ver=VERSION))
- else:
- raise
+ # Setup installer directory
+ setup_installer_dir = ("./cefpython3-{version}-{os}-setup/"
+ .format(version=VERSION, os=OS_POSTFIX2))
+ setup_installer_dir = os.path.join(BUILD_DIR, setup_installer_dir)
- # System python requires sudo when installing package
- if sys.executable in ["/usr/bin/python", "/usr/bin/python3"]:
- sudo = "sudo"
- else:
- sudo = ""
-
- os.chdir(BUILD_CEFPYTHON)
+ # Delete setup installer directory if exists
+ if os.path.exists(setup_installer_dir):
+ delete_directory_reliably(setup_installer_dir)
# Make setup installer
print("[build.py] Make setup installer")
- os.system("{python} ../../tools/setup/make.py --version {ver}"
- .format(python=sys.executable, ver=VERSION))
-
- # Enter setup installer directory
- os.chdir("cefpython3-{ver}-{os_postfix2}-setup/"
- .format(ver=VERSION, os_postfix2=OS_POSTFIX2))
+ make_tool = os.path.join(TOOLS_DIR, "make_installer.py")
+ os.system("{python} {make_tool} --version {version}"
+ .format(python=sys.executable,
+ make_tool=make_tool,
+ version=VERSION))
# Install
print("[build.py] Install the cefpython package")
+ os.chdir(setup_installer_dir)
os.system("{sudo} {python} setup.py install"
- .format(sudo=sudo, python=sys.executable))
-
- # Delete setup installer directory
- print("[build.py] Delete the setup installer directory")
- if WINDOWS:
- shutil.rmtree("./cefpython3-{ver}-{os_postfix2}-setup/"
- .format(ver=VERSION, os_postfix2=OS_POSTFIX2))
- else:
- os.system("{sudo} rm -rf ./cefpython3-{ver}-*-setup/"
- .format(sudo=sudo, ver=VERSION))
+ .format(sudo=get_sudo(), python=sys.executable))
+ os.chdir(BUILD_DIR)
# Run unittests
print("[build.py] Run unittests")
- os.system("cd {unittests_dir} && {python} _test_runner.py"
- .format(unittests_dir=UNITTESTS_DIR, python=sys.executable))
+ test_runner = os.path.join(UNITTESTS_DIR, "_test_runner.py")
+ ret = os.system("{python} {test_runner}"
+ .format(python=sys.executable, test_runner=test_runner))
+ if ret != 0:
+ sys.exit(ret)
# Run examples
print("[build.py] Run examples")
@@ -625,14 +685,38 @@ def install_and_run():
if LINUX:
run_examples += (" && {python}"
" {linux_dir}/deprecated_64bit/kivy_.py")
- run_examples.format(linux_dir=LINUX_DIR, examples_dir=EXAMPLES_DIR)
+ run_examples.format(
+ python=sys.executable,
+ linux_dir=LINUX_DIR,
+ examples_dir=EXAMPLES_DIR)
os.system(run_examples)
- # Enter tools dir
- os.system("cd {tools_dir}".format(tools_dir=TOOLS_DIR))
-
print("[build.py] DONE")
+def get_sudo():
+ # System Python requires sudo when installing package
+ if sys.executable in ["/usr/bin/python", "/usr/bin/python3"]:
+ sudo = "sudo"
+ else:
+ sudo = ""
+ return sudo
+
+
+def delete_directory_reliably(adir):
+ assert len(adir) > 2
+ assert os.path.isdir(adir)
+ print("[build.py] Delete directory: {dir}"
+ .format(dir=adir.replace(ROOT_DIR, "")))
+ if WINDOWS:
+ shutil.rmtree(adir)
+ else:
+ # On Linux sudo might be required to delete directory, as this
+ # might be a setup installer directory with package installed
+ # using sudo and in such case files were created with sudo.
+ os.system("{sudo} rm -rf {dir}"
+ .format(sudo=get_sudo(), dir=adir))
+
+
if __name__ == "__main__":
main()
diff --git a/tools/build_module.py b/tools/build_module.py
index bb99eb2f..0d1524df 100644
--- a/tools/build_module.py
+++ b/tools/build_module.py
@@ -1,5 +1,10 @@
-# For internal use only - called by build.py.
-# This is Cython's setup for building the cefpython module.
+# Copyright (c) 2017 The CEF Python authors. All rights reserved.
+# Licensed under the BSD 3-clause license.
+
+"""
+build_module.py is for internal use only - called by build.py.
+This is Cython's setup for building the cefpython module
+"""
# Use setuptools so that "Visual C++ compiler for Python 2.7" tools
# can be used. Otherwise "Unable to find vcvarsall.bat" error occurs.
@@ -171,7 +176,7 @@ def get_include_dirs():
def get_library_dirs():
print("[build_module.py] Prepare library directories")
library_dirs = [
- os.path.join(CEF_BINARY, "lib"),
+ os.path.join(CEF_BINARIES_LIBRARIES, "lib"),
]
if WINDOWS:
library_dirs.extend([
@@ -182,8 +187,11 @@ def get_library_dirs():
os.path.join(SRC_DIR, "subprocess",
"Release_{os}"
.format(os=OS_POSTFIX2)),
+ os.path.join(SRC_DIR, "subprocess",
+ "Release_py{pyver}_{os}"
+ .format(pyver=PYVERSION, os=OS_POSTFIX2)),
os.path.join(SRC_DIR, "cpp_utils",
- "Release_py{os}"
+ "Release_{os}"
.format(os=OS_POSTFIX2))
])
if MAC or LINUX:
@@ -280,6 +288,9 @@ def compile_time_constants():
def main():
+ if len(sys.argv) <= 1:
+ print(__doc__)
+ sys.exit(1)
print("[build_module.py] Cython version: %s" % Cython.__version__)
compile_time_constants()
options = dict()
diff --git a/tools/common.py b/tools/common.py
index f42a2667..fb0a733b 100644
--- a/tools/common.py
+++ b/tools/common.py
@@ -29,32 +29,55 @@
# Python version eg. 27
PYVERSION = str(sys.version_info[0])+str(sys.version_info[1])
-# Directories
-TOOLS_DIR = os.path.abspath(os.path.dirname(__file__))
-SRC_DIR = os.path.abspath(os.path.join(TOOLS_DIR, "../src"))
-WINDOWS_DIR = os.path.abspath(os.path.join(SRC_DIR, "windows"))
-MAC_DIR = os.path.abspath(os.path.join(SRC_DIR, "mac"))
-LINUX_DIR = os.path.abspath(os.path.join(SRC_DIR, "linux"))
-CPP_UTILS_DIR = os.path.abspath(os.path.join(SRC_DIR, "cpp_utils"))
-CLIENT_HANDLER_DIR = os.path.abspath(os.path.join(SRC_DIR, "client_handler"))
-SUBPROCESS_DIR = os.path.abspath(os.path.join(SRC_DIR, "subprocess"))
-CEFPYTHON_DIR = os.path.abspath(os.path.join(SRC_DIR, ".."))
-EXAMPLES_DIR = os.path.abspath(os.path.join(CEFPYTHON_DIR, "examples"))
-UNITTESTS_DIR = os.path.abspath(os.path.join(CEFPYTHON_DIR, "unittests"))
-BUILD_DIR = os.path.abspath(os.path.join(CEFPYTHON_DIR, "build"))
-BUILD_CEFPYTHON = os.path.abspath(os.path.join(BUILD_DIR, "build_cefpython"))
-# CEF_BINARY may be auto-overwritten through detect_cef_binary_directory()
-CEF_BINARY = os.path.abspath(os.path.join(BUILD_DIR, "cef_"+OS_POSTFIX2))
-CEFPYTHON_BINARY = os.path.abspath(os.path.join(BUILD_DIR,
- "cefpython_"+OS_POSTFIX2))
-
-
-def detect_cef_binary_directory():
- # Detect cef binary directory created by automate.py
- # eg. build/cef55_3.2883.1553.g80bd606_win32/
- # and set CEF_BINARY to it. Otherwise CEF_BINARY will
- # indicate to build/cef_{os_postfix2}/.
- if not os.path.exists(CEF_BINARY):
+# Root directory
+assert __file__
+ROOT_DIR = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
+
+# Other directories
+BUILD_DIR = os.path.join(ROOT_DIR, "build")
+if BUILD_DIR:
+ BUILD_CEFPYTHON = os.path.join(BUILD_DIR, "build_cefpython")
+ # -- Auto-detected directories.
+ # May be auto-overwritten through detect_cef_binaries_libraries_dir()
+ CEF_BINARIES_LIBRARIES = os.path.join(BUILD_DIR, "cef_"+OS_POSTFIX2)
+ # Will be overwritten through detect_cefpython_binary_dir()
+ CEFPYTHON_BINARY = "CEFPYTHON_BINARY"
+EXAMPLES_DIR = os.path.join(ROOT_DIR, "examples")
+SRC_DIR = os.path.join(ROOT_DIR, "src")
+if SRC_DIR:
+ CLIENT_HANDLER_DIR = os.path.join(SRC_DIR, "client_handler")
+ CPP_UTILS_DIR = os.path.join(SRC_DIR, "cpp_utils")
+ LINUX_DIR = os.path.join(SRC_DIR, "linux")
+ MAC_DIR = os.path.join(SRC_DIR, "mac")
+ SUBPROCESS_DIR = os.path.join(SRC_DIR, "subprocess")
+ WINDOWS_DIR = os.path.abspath(os.path.join(SRC_DIR, "windows"))
+TOOLS_DIR = os.path.join(ROOT_DIR, "tools")
+if TOOLS_DIR:
+ INSTALLER_DIR = os.path.join(TOOLS_DIR, "installer")
+UNITTESTS_DIR = os.path.abspath(os.path.join(ROOT_DIR, "unittests"))
+
+# Visual Studio constants
+VS_PLATFORM_ARG = "x86" if ARCH32 else "amd64"
+VS2015_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0"
+ "\\VC\\vcvarsall.bat")
+VS2015_BUILD = "" # TODO
+VS2013_VCVARS = ("C:\\Program Files (x86)\\Microsoft Visual Studio 12.0"
+ "\\VC\\vcvarsall.bat")
+VS2013_BUILD = "" # TODO
+VS2008_VCVARS = ("%LocalAppData%\\Programs\\Common\\Microsoft"
+ "\\Visual C++ for Python\\9.0\\vcvarsall.bat")
+VS2008_BUILD = ("%LocalAppData%\\Programs\\Common\\"
+ "Microsoft\\Visual C++ for Python\\9.0\\"
+ "VC\\bin\\amd64\\vcbuild.exe")
+
+
+def detect_cef_binaries_libraries_dir():
+ """Detect cef binary directory created by automate.py
+ eg. build/cef55_3.2883.1553.g80bd606_win32/
+ and set CEF_BINARIES_LIBRARIES to it, otherwise it will
+ point to eg. build/cef_win32/ ."""
+ global CEF_BINARIES_LIBRARIES
+ if not os.path.exists(CEF_BINARIES_LIBRARIES):
version = get_cefpython_version()
dirs = glob.glob(os.path.join(
BUILD_DIR,
@@ -64,10 +87,19 @@ def detect_cef_binary_directory():
os=OS_POSTFIX2,
sep=os.sep)))
if len(dirs) == 1:
- print("[common.py] Auto detected CEF_BINARY directory: {dir}"
- .format(dir=dirs[0]))
- global CEF_BINARY
- CEF_BINARY = dirs[0]
+ CEF_BINARIES_LIBRARIES = os.path.normpath(dirs[0])
+
+
+def detect_cefpython_binary_dir():
+ """Detect cefpython binary directory where cefpython modules
+ will be put. Eg. buil/cefpython55_win32/."""
+ version = get_cefpython_version()
+ binary_dir = "cefpython{major}_{os}".format(
+ major=version["CHROME_VERSION_MAJOR"],
+ os=OS_POSTFIX2)
+ binary_dir = os.path.join(BUILD_DIR, binary_dir)
+ global CEFPYTHON_BINARY
+ CEFPYTHON_BINARY = binary_dir
def get_cefpython_version():
@@ -88,4 +120,5 @@ def get_version_from_file(header_file):
return ret
-detect_cef_binary_directory()
+detect_cef_binaries_libraries_dir()
+detect_cefpython_binary_dir()
diff --git a/tools/installer/cefpython3.README.txt b/tools/installer/cefpython3.README.txt
new file mode 100644
index 00000000..d23dea09
--- /dev/null
+++ b/tools/installer/cefpython3.README.txt
@@ -0,0 +1,13 @@
+1. To install CEF Python 3 package type:
+
+ python setup.py install
+
+ On Linux/Mac if using system Python then you need to add sudo:
+
+ sudo python setup.py install
+
+2. To run examples enter the examples/ directory,
+ start with the hello_world.py example:
+
+ cd examples/
+ python hello_world.py
diff --git a/tools/installer/cefpython3.__init__.py b/tools/installer/cefpython3.__init__.py
new file mode 100644
index 00000000..ca54b44b
--- /dev/null
+++ b/tools/installer/cefpython3.__init__.py
@@ -0,0 +1,62 @@
+# Copyright (c) 2017 The CEF Python authors. All rights reserved.
+# Licensed under BSD 3-clause license.
+
+# NOTE: Template variables like {{VERSION}} are replaced with actual
+# values when make.py tool generates this package installer.
+
+import os
+import sys
+import ctypes
+import platform
+
+__all__ = ["cefpython", "wx"]
+__version__ = "{{VERSION}}"
+__author__ = "The CEF Python authors"
+
+# If package was installed using PIP or setup.py then package
+# dir is here:
+# /usr/local/lib/python2.7/dist-packages/cefpython3/
+
+# If this is a debian package then package_dir returns:
+# /usr/lib/pymodules/python2.7/cefpython3
+# The above path consists of symbolic links to the real directory:
+# /usr/share/pyshared/cefpython3
+
+package_dir = os.path.dirname(os.path.abspath(__file__))
+
+# This loads the libcef.so library for the subprocess executable.
+# On Mac it works without setting library paths, but let's set it
+# just to be sure.
+os.environ["LD_LIBRARY_PATH"] = package_dir
+os.environ["DYLD_LIBRARY_PATH"] = package_dir
+
+# This env variable will be returned by cefpython.GetModuleDirectory().
+os.environ["CEFPYTHON3_PATH"] = package_dir
+
+# This loads the libcef library for the main python executable.
+# This is required only on linux and Mac.
+# The libffmpegsumo.so library does not need to be loaded here,
+# it may cause issues to load it here in the browser process.
+libcef = None
+if platform.system() == "Darwin":
+ libcef = os.path.join(package_dir, "libcef.dylib")
+elif platform.system() == "Linux":
+ libcef = os.path.join(package_dir, "libcef.so")
+if libcef:
+ ctypes.CDLL(libcef, ctypes.RTLD_GLOBAL)
+
+# Load the cefpython module for proper Python version
+if (2, 7) <= sys.version_info < (2, 8):
+ # noinspection PyUnresolvedReferences
+ from . import cefpython_py27 as cefpython
+elif (3, 4) <= sys.version_info < (3, 5):
+ # noinspection PyUnresolvedReferences
+ from . import cefpython_py34 as cefpython
+elif (3, 5) <= sys.version_info < (3, 6):
+ # noinspection PyUnresolvedReferences
+ from . import cefpython_py35 as cefpython
+elif (3, 6) <= sys.version_info < (3, 7):
+ # noinspection PyUnresolvedReferences
+ from . import cefpython_py36 as cefpython
+else:
+ raise Exception("Python version not supported: " + sys.version)
diff --git a/tools/installer/cefpython3.setup.py b/tools/installer/cefpython3.setup.py
new file mode 100644
index 00000000..646c5fb3
--- /dev/null
+++ b/tools/installer/cefpython3.setup.py
@@ -0,0 +1,225 @@
+# Copyright (c) 2017 The CEF Python authors. All rights reserved.
+# Licensed under BSD 3-clause license.
+
+"""
+cefpython3 package setup.py file.
+
+Usage:
+ setup.py install
+ setup.py bdist_wheel [--universal]
+
+Options:
+ install Install package
+ bdist_wheel Generate wheel package. Use the --universal flag when
+ you have built cefpython modules for multiple Python
+ versions.
+"""
+
+# NOTE: Template variables like {{VERSION}} are replaced with actual
+# values when make.py tool generates this package installer.
+
+import copy
+import os
+import platform
+import subprocess
+import sys
+
+# The setuptools package is not installed by default on a clean
+# Ubuntu. Might be also a case on Windows. Also Python Eggs
+# and Wheels can be created only with setuptools.
+try:
+ from setuptools import setup
+ from setuptools.command.install import install
+ from setuptools.dist import Distribution
+ print("[setup.py] Using setuptools")
+except ImportError:
+ from distutils.core import setup
+ from distutils.command.install import install
+ from distutils.dist import Distribution
+ print("[setup.py] Using distutils")
+ if "bdist_wheel" in sys.argv:
+ print("[setup.py] ERROR: You must install setuptools package using"
+ " pip tool to be able to create a wheel package. Type"
+ " 'pip install setuptools'.")
+ sys.exit(1)
+
+
+# Need to know which files are executables to set appropriate execute
+# permissions during post_install_hook. On Windows .exe postfix will
+# be added to these automatically.
+EXECUTABLES_NOEXT = [
+ "cefclient",
+ "cefsimple",
+ "ceftests",
+ "subprocess",
+]
+
+
+class custom_install(install):
+ def __init__(self, *args, **kwargs):
+ install.__init__(self, *args, **kwargs)
+
+ def run(self):
+ install.run(self)
+ post_install_hook()
+
+
+class BinaryDistribution(Distribution):
+ def is_pure(self):
+ return False
+
+
+# Provide a custom install command
+print("[setup.py] Overload install command to enable execution of"
+ " post install hook")
+cmdclass = {"install": custom_install}
+
+# Set custom platform tags on Mac when generating wheel package. See:
+# http://lepture.com/en/2014/python-on-a-hard-wheel
+if platform.system() == "Darwin" and "bdist_wheel" in sys.argv:
+ print("[setup.py] Overload bdist_wheel command to add custom"
+ " platform tags")
+ from wheel.bdist_wheel import bdist_wheel
+
+ class custom_bdist_wheel(bdist_wheel):
+ def get_tag(self):
+ tag = bdist_wheel.get_tag(self)
+ platform_tag = ("macosx_10_6_intel"
+ ".macosx_10_9_intel.macosx_10_9_x86_64"
+ ".macosx_10_10_intel.macosx_10_10_x86_64")
+ tag = (tag[0], tag[1], platform_tag)
+ return tag
+
+ cmdclass["bdist_wheel"] = custom_bdist_wheel
+
+
+def main():
+ setup(
+ distclass=BinaryDistribution,
+ cmdclass=cmdclass,
+ name="cefpython3", # No spaces here, so that it works with deb pkg
+ version="{{VERSION}}",
+ description="GUI toolkit for embedding a Chromium widget"
+ " in desktop applications",
+ license="BSD 3-clause",
+ author="Czarek Tomczak",
+ author_email="czarek.tomczak@@gmail.com",
+ url="https://github.com/cztomczak/cefpython",
+ download_url="https://github.com/cztomczak/cefpython/releases",
+ platforms=["{{SYSCONFIG_PLATFORM}}"],
+ packages=["cefpython3"], # Disabled: "cefpython3.wx"
+ package_data=get_package_data(),
+ classifiers=[
+ "Development Status :: 6 - Mature",
+ "Intended Audience :: Developers",
+ "License :: OSI Approved :: BSD License",
+ "Natural Language :: English",
+ "Operating System :: MacOS :: MacOS X",
+ "Operating System :: Microsoft :: Windows",
+ "Operating System :: POSIX :: Linux",
+ "Programming Language :: Python :: 2.7",
+ "Programming Language :: Python :: 3.4",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Topic :: Desktop Environment",
+ "Topic :: Internet",
+ "Topic :: Internet :: WWW/HTTP",
+ "Topic :: Internet :: WWW/HTTP :: Browsers",
+ "Topic :: Multimedia",
+ ("Topic :: Software Development :: Libraries"
+ ":: Application Frameworks"),
+ "Topic :: Software Development :: User Interfaces",
+ ],
+ )
+ print("[setup.py] OK installed")
+
+
+def get_package_data():
+ package_data = {"cefpython3": get_package_files()}
+ return package_data
+
+
+def get_package_files(relative_dir=".", recursive=False):
+ """Finds files recursively in the cefpython3/ local directory.
+ Includes only files and their paths are relative to the cefpython3/
+ local directory. Empty directories are not included."""
+ old_dir = None
+ if not recursive:
+ old_dir = os.getcwd()
+ setup_dir = os.path.abspath(os.path.dirname(__file__))
+ local_pkg_dir = os.path.join(setup_dir, "cefpython3")
+ os.chdir(local_pkg_dir)
+ files = os.listdir(relative_dir)
+ ret = list()
+ for fpath in files:
+ fpath = os.path.join(relative_dir, fpath)
+ if os.path.isdir(fpath):
+ ret.extend(get_package_files(relative_dir=fpath, recursive=True))
+ else:
+ ret.append(fpath)
+ if not recursive:
+ os.chdir(old_dir)
+ return ret
+
+
+def get_executables():
+ data = copy.copy(EXECUTABLES_NOEXT)
+ if platform.system() == "Windows":
+ for key, executable in enumerate(data):
+ data[key] += ".exe"
+ return data
+
+
+def post_install_hook():
+ """Post install hook to chmod files on Linux and Mac."""
+
+ # Nothing extra required to do on Windows
+ if platform.system() == "Windows":
+ print("[setup.py] post_install_hook is ignored on Windows")
+ return
+
+ # If this a wheel package generation then do not execute the hook
+ if "bdist_wheel" in sys.argv:
+ print("[setup.py] Ignoring post_install_hook as this is bdist_wheel")
+ return
+
+ print("[setup.py] Execute post_install_hook")
+
+ # Find the installed package directory. Do not import from
+ # the local cefpython3/ directory.
+ print("[setup.py] Overload sys.path to facilitate finding correct"
+ " directory for the installed package")
+ del sys.path[0]
+ sys.path.append("")
+ import cefpython3
+ installed_package_dir = os.path.dirname(cefpython3.__file__)
+
+ # Make sure that the imported package wasn't the local cefptyhon3/
+ # directory.
+ print("[setup.py] Installed package directory: {dir}"
+ .format(dir=installed_package_dir))
+ assert not installed_package_dir.startswith(
+ os.path.dirname(os.path.abspath(__file__)))
+
+ # Set permissions on executables
+ print("[setup.py] Set execute permissions on executables")
+ for executable in get_executables():
+ executable = os.path.join(installed_package_dir, executable)
+ command = "chmod +x {executable}".format(executable=executable)
+ print("[setup.py] {command}".format(command=command))
+ subprocess.call(command, shell=True)
+
+ # Set write permissions on log files
+ print("[setup.py] Set write permissions on log files")
+ package_data = get_package_data()
+ for pkgfile in package_data:
+ if not pkgfile.endswith(".log"):
+ continue
+ logfile = os.path.join(installed_package_dir, pkgfile)
+ command = "chmod 666 {logfile}".format(logfile=logfile)
+ print("[setup.py] {command}".format(command=command))
+ subprocess.call(command, shell=True)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/make_installer.py b/tools/make_installer.py
new file mode 100644
index 00000000..87f1a12d
--- /dev/null
+++ b/tools/make_installer.py
@@ -0,0 +1,309 @@
+# Copyright (c) 2017 The CEF Python authors. All rights reserved.
+# Licensed under BSD 3-clause license.
+
+"""
+Create setup.py package installer.
+
+Usage:
+ make.py VERSION
+
+Options:
+ VERSION Version number eg. 50.0
+"""
+
+from common import *
+
+import glob
+import os
+import re
+import shutil
+import subprocess
+import sys
+import sysconfig
+
+# Command line args
+VERSION = ""
+
+# Globals
+SETUP_DIR = ""
+PKG_DIR = ""
+
+# Config
+IGNORE_EXT = [".log", ".pyc", ".pdb", ]
+IGNORE_DIRS = ["__pycache__"]
+
+
+def main():
+ command_line_args()
+
+ # Setup and package directories
+ global SETUP_DIR, PKG_DIR
+ setup_dir_name = ("cefpython3-{version}-{os}-setup"
+ .format(version=VERSION, os=OS_POSTFIX2))
+ SETUP_DIR = os.path.join(BUILD_DIR, setup_dir_name)
+ PKG_DIR = os.path.join(SETUP_DIR, "cefpython3")
+
+ # Print src and dest for file operations
+ print("[make_installer.py] Src: {src}".format(src=ROOT_DIR))
+ print("[make_installer.py] Dst: {dst}".format(dst=SETUP_DIR))
+
+ # Make directories
+ if os.path.exists(SETUP_DIR):
+ print("[make_installer.py] Delete: {dir}"
+ .format(dir=SETUP_DIR.replace(ROOT_DIR, "")))
+ shutil.rmtree(SETUP_DIR)
+ os.makedirs(SETUP_DIR)
+ os.makedirs(os.path.join(SETUP_DIR, "examples/"))
+ os.makedirs(PKG_DIR)
+ os.makedirs(os.path.join(PKG_DIR, "examples/"))
+
+ # Copy files from tools/installer/
+ copy_tools_installer_files(SETUP_DIR, PKG_DIR)
+
+ # Multiple copy operations using glob patterns
+ copy_operations = [
+ (ROOT_DIR, "License"), (PKG_DIR,),
+ (CEF_BINARIES_LIBRARIES, "*.txt"), (PKG_DIR,),
+ (CEF_BINARIES_LIBRARIES, "bin/*"), (PKG_DIR,),
+ (CEFPYTHON_BINARY, "*"), (PKG_DIR,),
+ (EXAMPLES_DIR, "*"), (PKG_DIR, "examples/"),
+ (EXAMPLES_DIR, "*"), (SETUP_DIR, "examples/"),
+ ]
+ perform_copy_operations(copy_operations)
+
+ # Linux only operations
+ if LINUX:
+ copy_operations_linux = [
+ (LINUX_DIR, "binaries_64bit/kivy_.py"),
+ (PKG_DIR, "examples/"),
+ (LINUX_DIR, "binaries_64bit/kivy-select-boxes/*"),
+ (PKG_DIR, "examples/")
+ ]
+ perform_copy_operations(copy_operations_linux)
+
+ # Create empty debug.log files so that package uninstalls cleanly
+ # in case examples or CEF tests were launched. See Issue #149.
+ create_empty_log_file(os.path.join(PKG_DIR, "debug.log"))
+ create_empty_log_file(os.path.join(PKG_DIR, "examples/debug.log"))
+
+ print("[make_installer.py] DONE. Installer package created: {setup_dir}"
+ .format(setup_dir=SETUP_DIR))
+
+
+def command_line_args():
+ args = " ".join(sys.argv)
+ match = re.search(r"\d+\.\d+", args)
+ if match:
+ global VERSION
+ VERSION = match.group(0)
+ else:
+ print(__doc__)
+ sys.exit(1)
+
+
+def copy_tools_installer_files(setup_dir, pkg_dir):
+ variables = dict()
+ variables["VERSION"] = VERSION
+ variables["SYSCONFIG_PLATFORM"] = sysconfig.get_platform()
+
+ shutil.copy(
+ os.path.join(INSTALLER_DIR, "cefpython3.README.txt"),
+ os.path.join(setup_dir, "README.txt"))
+
+ copy_template_file(
+ os.path.join(INSTALLER_DIR, "cefpython3.setup.py"),
+ os.path.join(setup_dir, "setup.py"),
+ variables)
+
+ copy_template_file(
+ os.path.join(INSTALLER_DIR, "cefpython3.__init__.py"),
+ os.path.join(pkg_dir, "__init__.py"),
+ variables)
+
+
+def copy_template_file(src, dst, variables):
+ """Copy file and replaces template variables in that file."""
+ print("[make_installer.py] Copy_t: {src} ==> {dst}"
+ .format(src=short_src_path(src), dst=short_dst_path(dst)))
+ with open(src, "rb") as fo:
+ contents = fo.read()
+ contents = replace_template_vars(contents, variables)
+ with open(dst, "wb") as fo:
+ fo.write(contents)
+ return contents
+
+
+def replace_template_vars(string, dictionary):
+ """Replaces template variables like {{SOME}} in the string
+ using the dictionary values."""
+ orig_string = string
+ for key, value in dictionary.items():
+ string = string.replace("{{"+key+"}}", value)
+ if string == orig_string:
+ raise Exception("Nothing to format")
+ if re.search(r"\{\{[a-zA-Z0-9_]+\}\}", string):
+ raise Exception("Not all strings were formatted")
+ return string
+
+
+def perform_copy_operations(operations):
+ assert len(operations) % 2 == 0
+ count_ops = int(len(operations) / 2)
+ for op_i in range(count_ops):
+ # Refer to values by index
+ pattern = operations[op_i*2]
+ dst_dir = operations[op_i*2+1]
+ # Convert tuples to lists
+ pattern = list(pattern)
+ dst_dir = list(dst_dir)
+ # Join paths
+ pattern = os.path.join(*pattern)
+ dst_dir = os.path.join(*dst_dir)
+ dst_dir = os.path.abspath(dst_dir)
+ # Normalize unix slashes on Windows
+ pattern = pattern.replace("/", os.path.sep)
+ # dst_dir must be a directory
+ if not os.path.isdir(dst_dir):
+ raise Exception("Not a directory: {dst_dir}"
+ .format(dst_dir=dst_dir))
+ # Is pattern a file or a directory
+ if os.path.isfile(pattern):
+ if is_ignored_path(pattern):
+ raise Exception("Copy operation pattern is in ignore list:"
+ " {pattern}".format(pattern=pattern))
+ print("[make_installer.py] Copy: {file} ==> {dir}"
+ .format(file=short_src_path(pattern),
+ dir=short_dst_path(dst_dir)))
+ # Destination file must not exist
+ assert not os.path.exists(os.path.join(dst_dir,
+ os.path.basename(pattern)))
+ shutil.copy(pattern, dst_dir)
+ else:
+ # pattern is a glob pattern
+ base_dir = os.path.dirname(pattern)
+ assert base_dir
+ assert base_dir == os.path.abspath(base_dir)
+ paths = glob.glob(pattern)
+ if not len(paths):
+ raise Exception("No paths found in: {pattern}"
+ .format(pattern=pattern))
+ for path in paths:
+ # "path" variable contains absolute path
+ assert path == os.path.abspath(path)
+ if os.path.isfile(path):
+ if is_ignored_path(path):
+ continue
+ print("[make_installer.py] Copy: {file} ==> {dir}"
+ .format(file=short_src_path(path),
+ dir=short_dst_path(dst_dir)))
+ # Destination file must not exist
+ assert not os.path.exists(
+ os.path.join(dst_dir, os.path.basename(path)))
+ shutil.copy(path, dst_dir)
+ elif os.path.isdir(path):
+ if is_ignored_path(path):
+ continue
+ relative_dir = path.replace(base_dir, "")
+ assert relative_dir[0] == os.path.sep
+ relative_dir = relative_dir[1:]
+ perform_copy_recursively(base_dir, relative_dir, dst_dir)
+ else:
+ raise Exception("Unknown path: {path}".format(path=path))
+
+
+def perform_copy_recursively(base_dir, relative_dir, new_dir):
+ real_dir = os.path.join(base_dir, relative_dir)
+ assert os.path.exists(real_dir) and os.path.isdir(real_dir)
+ assert os.path.exists(new_dir) and os.path.isdir(new_dir)
+
+ # Create subdirectory
+ new_subdir = os.path.join(new_dir, relative_dir)
+ if not os.path.exists(new_subdir):
+ print("[make_installer.py] Create: {dir}"
+ .format(dir=short_dst_path(new_subdir)))
+ os.makedirs(new_subdir)
+
+ # List directory
+ paths = os.listdir(real_dir)
+ for path in paths:
+ # "path" variable contains relative path
+ real_path = os.path.join(real_dir, path)
+ path = os.path.join(relative_dir, path)
+ if os.path.isdir(real_path):
+ if is_ignored_path(real_path):
+ continue
+ perform_copy_recursively(base_dir, path, new_dir)
+ elif os.path.isfile(real_path):
+ if is_ignored_path(real_path):
+ continue
+ new_file = os.path.join(new_dir, path)
+ new_subdir = os.path.dirname(new_file)
+ if os.path.exists(new_file):
+ raise Exception("Path aready exists: {new_file}"
+ .format(new_file=short_dst_path(new_file)))
+ print("[make_installer.py] Copy: {file} ==> {dir}"
+ .format(file=short_src_path(real_path),
+ dir=short_dst_path(new_subdir)))
+ shutil.copy(real_path, new_subdir)
+ else:
+ raise Exception("Unknown path: {path}".format(path=real_path))
+
+
+def is_ignored_path(path):
+ basename = os.path.basename(path)
+ if basename in IGNORE_DIRS:
+ print("[make_installer.py] Ignore: {dir}"
+ .format(dir=short_src_path(path)))
+ return True
+ for ext in IGNORE_EXT:
+ if path.endswith(ext):
+ print("[make_installer.py] Ignore: {file}"
+ .format(file=short_src_path(path)))
+ return True
+ return False
+
+
+def delete_files_by_pattern(pattern):
+ assert len(pattern) > 2
+ # Normalize unix slashes on Windows
+ pattern = pattern.replace("/", os.path.sep)
+ print("[make_installer.py] Delete: {pattern}"
+ .format(pattern=short_dst_path(pattern)))
+ files = glob.glob(pattern)
+ for f in files:
+ os.remove(f)
+
+
+def create_empty_log_file(log_file):
+ # Normalize unix slashes on Windows
+ log_file = log_file.replace("/", os.path.sep)
+ print("[make_installer.py] Create: {file}"
+ .format(file=short_dst_path(log_file)))
+ with open(log_file, "wb") as fo:
+ fo.write("")
+ # On Linux and Mac chmod so that for cases when package is
+ # installed using sudo. When wheel package is created it
+ # will remember file permissions set.
+ if LINUX or MAC:
+ command = "chmod 666 {file}".format(file=log_file)
+ print("[make_installer.py] {command}"
+ .format(command=command.replace(SETUP_DIR, "")))
+ subprocess.call(command, shell=True)
+
+
+def short_src_path(path):
+ # Very long: \build\cef55_3.2883.1553.g80bd606_win32\
+ find = os.path.basename(CEF_BINARIES_LIBRARIES)
+ if len(find) > 12:
+ path = path.replace(find, find[:12] + "*")
+ path = path.replace(ROOT_DIR, "")
+ return path
+
+
+def short_dst_path(path):
+ path = path.replace(SETUP_DIR, "")
+ return path
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tools/requirements.txt b/tools/requirements.txt
index c5ba053d..abdc1828 100644
--- a/tools/requirements.txt
+++ b/tools/requirements.txt
@@ -1,2 +1,4 @@
-cython == 0.25.2
+Cython == 0.25.2
docopt >= 0.6.2
+setuptools
+wheel
diff --git a/unittests/_test_runner.py b/unittests/_test_runner.py
index f25f48cb..8b970aca 100644
--- a/unittests/_test_runner.py
+++ b/unittests/_test_runner.py
@@ -3,9 +3,10 @@
"""Run unit tests. With no arguments all tests are run. Read notes below.
Usage:
- _test_runner.py [FILE | _TESTCASE]
+ _test_runner.py [--debug] [FILE | _TESTCASE]
Options:
+ --debug Enable debug info
FILE Run tests from single file
_TESTCASE Test cases matching pattern to run eg "file.TestCase".
Calling with this argument is for internal use only.
@@ -27,6 +28,9 @@
import re
import subprocess
+# Command line args
+CUSTOM_CMDLINE_ARG = ""
+
def main(file_arg=""):
# type: (str) -> None
@@ -37,7 +41,12 @@ def main(file_arg=""):
# Script arguments
testcase_arg = ""
- if len(sys.argv) > 1:
+ if len(sys.argv) > 1 and sys.argv[1].startswith("--"):
+ # Will allow to pass custom args like --debug to isolated tests
+ # (main_test.py for example).
+ global CUSTOM_CMDLINE_ARG
+ CUSTOM_CMDLINE_ARG = sys.argv[1]
+ elif len(sys.argv) > 1:
if ".py" in sys.argv[1]:
file_arg = sys.argv[1]
else:
@@ -141,7 +150,8 @@ def _run_suites_in_isolation(self, suites):
# Run test using new instance of Python interpreter
try:
output = subprocess.check_output(
- [sys.executable, "_test_runner.py", testcase_id],
+ [sys.executable, "_test_runner.py", testcase_id,
+ CUSTOM_CMDLINE_ARG],
stderr=subprocess.STDOUT)
exit_code = 0
except subprocess.CalledProcessError as exc:
diff --git a/unittests/main_test.py b/unittests/main_test.py
index a20af1da..05f34158 100644
--- a/unittests/main_test.py
+++ b/unittests/main_test.py
@@ -101,11 +101,15 @@ def test_main(self):
print("Python {ver}".format(ver=sys.version[:6]))
# Test initialization of CEF
- cef.Initialize({
+ settings = {
"debug": False,
"log_severity": cef.LOGSEVERITY_ERROR,
"log_file": "",
- })
+ }
+ if "--debug" in sys.argv:
+ settings["debug"] = True
+ settings["log_severity"] = cef.LOGSEVERITY_INFO
+ cef.Initialize(settings)
subtest_message("cef.Initialize() ok")
# Test global handler