mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Work on getting windows running
This commit is contained in:
parent
994befe846
commit
be471a8cbe
@ -28,6 +28,7 @@ dlls = [
|
||||
# 'WebSockets',
|
||||
# 'WebView',
|
||||
'Positioning',
|
||||
'PositioningQuick',
|
||||
'Sensors',
|
||||
'Sql',
|
||||
'Svg',
|
||||
@ -178,10 +179,11 @@ def build_c_extensions(ext_dir):
|
||||
|
||||
|
||||
def run_tests(path_to_calibre_debug, cwd_on_failure):
|
||||
if run(path_to_calibre_debug, '--test-build') != 0:
|
||||
ret = run(path_to_calibre_debug, '--test-build')
|
||||
if ret != 0:
|
||||
os.chdir(cwd_on_failure)
|
||||
print(
|
||||
'running calibre build tests failed with:', path_to_calibre_debug, file=sys.stderr)
|
||||
'running calibre build tests failed with return code:', ret, 'and exe:', path_to_calibre_debug, file=sys.stderr)
|
||||
run_shell()
|
||||
raise SystemExit('running calibre build tests failed')
|
||||
|
||||
|
@ -103,7 +103,7 @@ class Env(object):
|
||||
self.py_ver = '.'.join(map(str, python_major_minor_version()))
|
||||
self.lib_dir = j(self.app_base, 'Lib')
|
||||
self.pylib = j(self.app_base, 'pylib.zip')
|
||||
self.dll_dir = j(self.app_base, 'DLLs')
|
||||
self.dll_dir = j(self.app_base, 'bin')
|
||||
self.portable_base = j(d(self.base), 'Calibre Portable')
|
||||
self.obj_dir = j(build_dir, 'launcher')
|
||||
self.installer_dir = j(build_dir, 'wix')
|
||||
@ -165,10 +165,11 @@ def freeze(env, ext_dir):
|
||||
printf('Adding Qt...')
|
||||
for x in QT_DLLS:
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', 'QtWebEngineProcess.exe'))
|
||||
for x in 'libGLESv2 libEGL'.split():
|
||||
copybin(os.path.join(QT_PREFIX, 'bin', x + '.dll'))
|
||||
plugdir = j(QT_PREFIX, 'plugins')
|
||||
tdir = j(env.app_base, 'qt_plugins')
|
||||
tdir = j(env.app_base, 'plugins')
|
||||
for d in QT_PLUGINS:
|
||||
imfd = os.path.join(plugdir, d)
|
||||
tg = os.path.join(tdir, d)
|
||||
@ -178,6 +179,9 @@ def freeze(env, ext_dir):
|
||||
for f in walk(tdir):
|
||||
if not f.lower().endswith('.dll'):
|
||||
os.remove(f)
|
||||
for data_file in os.listdir(j(QT_PREFIX, 'resources')):
|
||||
shutil.copy2(j(QT_PREFIX, 'resources', data_file), j(env.app_base, 'resources'))
|
||||
shutil.copytree(j(QT_PREFIX, 'translations'), j(env.app_base, 'translations'))
|
||||
|
||||
printf('Adding python...')
|
||||
|
||||
@ -205,6 +209,12 @@ def freeze(env, ext_dir):
|
||||
for x in {x for x in os.listdir(pyqt) if x.endswith('.pyd')}:
|
||||
if x.partition('.')[0] not in PYQT_MODULES and x != 'sip.pyd':
|
||||
os.remove(j(pyqt, x))
|
||||
with open(j(pyqt, '__init__.py') , 'r+b') as f:
|
||||
raw = f.read()
|
||||
nraw = raw.replace(b'def find_qt():', b'def find_qt():\n return # disabled for calibre')
|
||||
if nraw == raw:
|
||||
raise Exception('Failed to patch PyQt to disable dll directory manipulation')
|
||||
f.seek(0), f.truncate(), f.write(nraw)
|
||||
|
||||
printf('Adding calibre sources...')
|
||||
for x in glob.glob(j(CALIBRE_DIR, 'src', '*')):
|
||||
@ -636,8 +646,8 @@ def archive_lib_dir(env):
|
||||
shutil.rmtree(env.lib_dir)
|
||||
|
||||
|
||||
def copy_crt(env):
|
||||
printf('Copying CRT...')
|
||||
def copy_crt_and_d3d(env):
|
||||
printf('Copying CRT and D3D...')
|
||||
plat = ('x64' if is64bit else 'x86')
|
||||
for key, val in worker_env.items():
|
||||
if 'COMNTOOLS' in key.upper():
|
||||
@ -653,17 +663,27 @@ def copy_crt(env):
|
||||
'ucrt', 'DLLs', plat)
|
||||
if not os.path.exists(sdk_path):
|
||||
raise SystemExit('Windows 10 Universal CRT redistributable not found at: %r' % sdk_path)
|
||||
for dll in glob.glob(os.path.join(sdk_path, '*.dll')):
|
||||
d3d_path = os.path.join(
|
||||
worker_env['WINDOWSSDKDIR'], 'Redist', 'D3D', plat)
|
||||
if not os.path.exists(d3d_path):
|
||||
raise SystemExit('Windows 10 D3D redistributable not found at: %r' % d3d_path)
|
||||
|
||||
def copy_dll(dll):
|
||||
shutil.copy2(dll, env.dll_dir)
|
||||
os.chmod(os.path.join(env.dll_dir, b(dll)), stat.S_IRWXU)
|
||||
|
||||
for dll in glob.glob(os.path.join(d3d_path, '*.dll')):
|
||||
if os.path.basename(dll).lower().startswith('d3dcompiler_'):
|
||||
copy_dll(dll)
|
||||
for dll in glob.glob(os.path.join(sdk_path, '*.dll')):
|
||||
copy_dll(dll)
|
||||
for dll in glob.glob(os.path.join(vc_path, '*.dll')):
|
||||
bname = os.path.basename(dll)
|
||||
if not bname.startswith('vccorlib') and not bname.startswith('concrt'):
|
||||
# Those two DLLs are not required vccorlib is for the CORE CLR
|
||||
# I think concrt is the concurrency runtime for C++ which I believe
|
||||
# nothing in calibre currently uses
|
||||
shutil.copy(dll, env.dll_dir)
|
||||
os.chmod(os.path.join(env.dll_dir, bname), stat.S_IRWXU)
|
||||
copy_dll(dll)
|
||||
|
||||
|
||||
def sign_executables(env):
|
||||
@ -685,7 +705,7 @@ def main():
|
||||
build_utils(env)
|
||||
freeze(env, ext_dir)
|
||||
embed_manifests(env)
|
||||
copy_crt(env)
|
||||
copy_crt_and_d3d(env)
|
||||
archive_lib_dir(env)
|
||||
if not args.skip_tests:
|
||||
run_tests(os.path.join(env.base, 'calibre-debug.exe'), env.base)
|
||||
|
@ -53,18 +53,22 @@ static int show_last_error(wchar_t *preamble) {
|
||||
}
|
||||
|
||||
typedef int (__cdecl *ENTRYPROC)(const char*, const char*, const char*, int);
|
||||
typedef void (__cdecl *SIMPLEPRINT)(const wchar_t*);
|
||||
typedef BOOL (*SETDEFAULTDIRS)(DWORD);
|
||||
static ENTRYPROC entrypoint = NULL;
|
||||
static SIMPLEPRINT simple_print = NULL;
|
||||
static HMODULE dll = 0;
|
||||
|
||||
static ENTRYPROC load_launcher_dll() {
|
||||
wchar_t buf[MAX_PATH]; // Cannot use a zero initializer for the array as it generates an implicit call to memset()
|
||||
static void
|
||||
load_launcher_dll() {
|
||||
static wchar_t buf[MAX_PATH]; // Cannot use a zero initializer for the array as it generates an implicit call to memset()
|
||||
wchar_t *dll_point = NULL;
|
||||
int i = 0;
|
||||
DWORD sz = 0;
|
||||
HMODULE dll = 0;
|
||||
ENTRYPROC entrypoint = NULL;
|
||||
|
||||
if ((sz = GetModuleFileNameW(NULL, buf, MAX_PATH)) >= MAX_PATH - 30) {
|
||||
show_error(L"Installation directory path too long", L"", 1);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
while (sz > 0) {
|
||||
@ -73,33 +77,36 @@ static ENTRYPROC load_launcher_dll() {
|
||||
}
|
||||
if (dll_point == NULL) {
|
||||
show_error(L"Executable path has no path separators", L"", 1);
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
wsprintf(dll_point, L"%s\0\0", L"app\\DLLs");
|
||||
wsprintf(dll_point, L"%s\0\0", L"app\\bin");
|
||||
// Restrict the directories from which DLLs can be loaded
|
||||
SETDEFAULTDIRS SetDefaultDllDirectories = (SETDEFAULTDIRS)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories");
|
||||
if (SetDefaultDllDirectories) SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
|
||||
if (SetDllDirectoryW(buf) == 0) {
|
||||
show_last_error(L"Failed to set DLL directory");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
// Have to load ucrtbase manually first, otherwise loading fails on systems where the
|
||||
// Universal CRT is not installed.
|
||||
if (!LoadLibraryW(L"ucrtbase.dll")) {
|
||||
show_last_error(L"Unable to find ucrtbase.dll. You should install all Windows updates on your computer to get this file.");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
if (!(dll = LoadLibraryW(L"calibre-launcher.dll"))) {
|
||||
show_last_error(L"Failed to load: calibre-launcher.dll");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
if (!(entrypoint = (ENTRYPROC) GetProcAddress(dll, "execute_python_entrypoint"))) {
|
||||
show_last_error(L"Failed to get the calibre-launcher dll entry point");
|
||||
return NULL;
|
||||
return;
|
||||
}
|
||||
return entrypoint;
|
||||
simple_print = (SIMPLEPRINT) GetProcAddress(dll, "simple_print");
|
||||
}
|
||||
|
||||
int __stdcall start_here() {
|
||||
int ret = 0;
|
||||
ENTRYPROC entrypoint = load_launcher_dll();
|
||||
load_launcher_dll();
|
||||
if (entrypoint) {
|
||||
#ifdef GUI_APP
|
||||
// This should really be returning the value set in the WM_QUIT message, but I cannot be bothered figuring out how to get that.
|
||||
@ -108,6 +115,10 @@ int __stdcall start_here() {
|
||||
ret = entrypoint(BASENAME, MODULE, FUNCTION, 0);
|
||||
#endif
|
||||
} else ret = 1;
|
||||
if (dll != 0) {
|
||||
FreeLibrary(dll);
|
||||
dll = 0;
|
||||
}
|
||||
ExitProcess(ret);
|
||||
return ret;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
#!/usr/bin/env python2
|
||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||
|
||||
__license__ = 'GPL v3'
|
||||
__license__ = 'GPL v3'
|
||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
@ -9,6 +9,7 @@ import sys
|
||||
import os
|
||||
import imp
|
||||
|
||||
|
||||
class PydImporter(object):
|
||||
|
||||
__slots__ = ('items', 'description')
|
||||
@ -19,7 +20,7 @@ class PydImporter(object):
|
||||
|
||||
def find_module(self, fullname, path=None):
|
||||
if self.items is None:
|
||||
dlls_dir = os.path.join(sys.app_dir, 'app', 'DLLs')
|
||||
dlls_dir = os.path.join(sys.app_dir, 'app', 'bin')
|
||||
items = self.items = {}
|
||||
for x in os.listdir(dlls_dir):
|
||||
lx = x.lower()
|
||||
@ -34,27 +35,34 @@ class PydImporter(object):
|
||||
try:
|
||||
path = self.items[fullname.lower()]
|
||||
except KeyError:
|
||||
raise ImportError('The native code module %s seems to have disappeared from self.items' % fullname)
|
||||
raise ImportError(
|
||||
'The native code module %s seems to have disappeared from self.items'
|
||||
% fullname
|
||||
)
|
||||
package, name = fullname.rpartition(b'.')[::2]
|
||||
m = imp.load_module(fullname, None, path, self.description) # This inserts the module into sys.modules itself
|
||||
m = imp.load_module(
|
||||
fullname, None, path, self.description
|
||||
) # This inserts the module into sys.modules itself
|
||||
m.__loader__ = self
|
||||
m.__package__ = package or None
|
||||
return m
|
||||
|
||||
|
||||
def abs__file__():
|
||||
"""Set all module __file__ attribute to an absolute path"""
|
||||
for m in sys.modules.values():
|
||||
if hasattr(m, '__loader__'):
|
||||
continue # don't mess with a PEP 302-supplied __file__
|
||||
continue # don't mess with a PEP 302-supplied __file__
|
||||
try:
|
||||
m.__file__ = os.path.abspath(m.__file__)
|
||||
except AttributeError:
|
||||
continue
|
||||
|
||||
|
||||
def aliasmbcs():
|
||||
import locale, codecs
|
||||
enc = locale.getdefaultlocale()[1]
|
||||
if enc.startswith('cp'): # "cp***" ?
|
||||
if enc.startswith('cp'): # "cp***" ?
|
||||
try:
|
||||
codecs.lookup(enc)
|
||||
except LookupError:
|
||||
@ -62,21 +70,24 @@ def aliasmbcs():
|
||||
encodings._cache[enc] = encodings._unknown
|
||||
encodings.aliases.aliases[enc] = 'mbcs'
|
||||
|
||||
|
||||
def add_calibre_vars():
|
||||
sys.new_app_layout = 1
|
||||
sys.resources_location = os.path.join(sys.app_dir, 'app', 'resources')
|
||||
sys.extensions_location = os.path.join(sys.app_dir, 'app', 'DLLs')
|
||||
sys.extensions_location = os.path.join(sys.app_dir, 'app', 'bin')
|
||||
|
||||
dv = os.environ.get('CALIBRE_DEVELOP_FROM', None)
|
||||
if dv and os.path.exists(dv):
|
||||
sys.path.insert(0, os.path.abspath(dv))
|
||||
|
||||
|
||||
def run_entry_point():
|
||||
bname, mod, func = sys.calibre_basename, sys.calibre_module, sys.calibre_function
|
||||
sys.argv[0] = bname+'.exe'
|
||||
sys.argv[0] = bname + '.exe'
|
||||
pmod = __import__(mod, fromlist=[1], level=0)
|
||||
return getattr(pmod, func)()
|
||||
|
||||
|
||||
def main():
|
||||
sys.frozen = 'windows_exe'
|
||||
sys.setdefaultencoding('utf-8')
|
||||
@ -86,8 +97,10 @@ def main():
|
||||
sys.path_importer_cache.clear()
|
||||
|
||||
import linecache
|
||||
|
||||
def fake_getline(filename, lineno, module_globals=None):
|
||||
return ''
|
||||
|
||||
linecache.orig_getline = linecache.getline
|
||||
linecache.getline = fake_getline
|
||||
|
||||
@ -95,7 +108,7 @@ def main():
|
||||
|
||||
add_calibre_vars()
|
||||
|
||||
# Needed for pywintypes to be able to load its DLL
|
||||
sys.path.append(os.path.join(sys.app_dir, 'app', 'DLLs'))
|
||||
# Needed to bypass meaningless check in pywintypes.py
|
||||
sys.path.append(os.path.join(sys.app_dir, 'app', 'bin'))
|
||||
|
||||
return run_entry_point()
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define arraysz(x) (sizeof((x))/sizeof((x)[0]))
|
||||
|
||||
static int GUI_APP = 0;
|
||||
static char python_dll[] = PYDLL;
|
||||
@ -25,29 +26,16 @@ void set_gui_app(int yes) { GUI_APP = yes; }
|
||||
int calibre_show_python_error(const wchar_t *preamble, int code);
|
||||
|
||||
static int _show_error(const wchar_t *preamble, const wchar_t *msg, const int code) {
|
||||
wchar_t *buf;
|
||||
char *cbuf;
|
||||
buf = (wchar_t*)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)*
|
||||
(wcslen(msg) + wcslen(preamble) + 80));
|
||||
static wchar_t buf[4096];
|
||||
|
||||
_snwprintf_s(buf,
|
||||
LocalSize(buf) / sizeof(wchar_t), _TRUNCATE,
|
||||
L"%s\r\n %s (Error Code: %d)\r\n",
|
||||
preamble, msg, code);
|
||||
fwprintf(stderr, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code);
|
||||
fflush(stderr);
|
||||
|
||||
if (GUI_APP) {
|
||||
_snwprintf_s(buf, arraysz(buf), _TRUNCATE, L"%s\r\n %s (Error Code: %d)\r\n", preamble, msg, code);
|
||||
MessageBeep(MB_ICONERROR);
|
||||
MessageBox(NULL, buf, NULL, MB_OK|MB_ICONERROR);
|
||||
}
|
||||
else {
|
||||
cbuf = (char*) calloc(10+(wcslen(buf)*4), sizeof(char));
|
||||
if (cbuf) {
|
||||
if (WideCharToMultiByte(CP_UTF8, 0, buf, -1, cbuf, (int)(10+(wcslen(buf)*4)), NULL, NULL) != 0) printf_s(cbuf);
|
||||
free(cbuf);
|
||||
}
|
||||
}
|
||||
|
||||
LocalFree(buf);
|
||||
return code;
|
||||
}
|
||||
|
||||
@ -83,72 +71,72 @@ int show_last_error(wchar_t *preamble) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
char* get_app_dir() {
|
||||
char *buf, *buf2, *buf3;
|
||||
static char app_dir[MAX_PATH] = {0};
|
||||
static wchar_t dll_dir[MAX_PATH] = {0};
|
||||
static wchar_t qt_prefix_dir[MAX_PATH] = {0};
|
||||
static char program_name[MAX_PATH] = {0};
|
||||
static wchar_t w_program_name[MAX_PATH] = {0};
|
||||
static wchar_t w_app_dir[MAX_PATH] = {0};
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
static wchar_t python_path[MAX_PATH] = {0};
|
||||
#else
|
||||
static char python_path[MAX_PATH] = {0};
|
||||
#endif
|
||||
|
||||
static void
|
||||
get_app_dir(void) {
|
||||
char drive[4] = "\0\0\0";
|
||||
DWORD sz; errno_t err;
|
||||
char buf[MAX_PATH] = {0};
|
||||
|
||||
buf = (char*)calloc(MAX_PATH, sizeof(char));
|
||||
buf2 = (char*)calloc(MAX_PATH, sizeof(char));
|
||||
buf3 = (char*)calloc(MAX_PATH, sizeof(char));
|
||||
if (!buf || !buf2 || !buf3) ExitProcess(_show_error(L"Out of memory", L"", 1));
|
||||
sz = GetModuleFileNameA(NULL, buf, MAX_PATH);
|
||||
sz = GetModuleFileNameA(NULL, program_name, MAX_PATH);
|
||||
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
||||
err = _splitpath_s(buf, drive, 4, buf2, MAX_PATH, NULL, 0, NULL, 0);
|
||||
err = _splitpath_s(program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0);
|
||||
if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory"));
|
||||
_snprintf_s(buf3, MAX_PATH, _TRUNCATE, "%s%s", drive, buf2);
|
||||
free(buf); free(buf2);
|
||||
return buf3;
|
||||
_snprintf_s(app_dir, MAX_PATH, _TRUNCATE, "%s%s", drive, buf);
|
||||
}
|
||||
|
||||
wchar_t* get_app_dirw() {
|
||||
wchar_t *buf, *buf2, *buf3;
|
||||
static void
|
||||
get_app_dirw(void) {
|
||||
wchar_t buf[MAX_PATH] = {0};
|
||||
wchar_t drive[4] = L"\0\0\0";
|
||||
DWORD sz; errno_t err;
|
||||
|
||||
buf = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t));
|
||||
buf2 = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t));
|
||||
buf3 = (wchar_t*)calloc(MAX_PATH, sizeof(wchar_t));
|
||||
if (!buf || !buf2 || !buf3) ExitProcess(_show_error(L"Out of memory", L"", 1));
|
||||
sz = GetModuleFileNameW(NULL, buf, MAX_PATH);
|
||||
sz = GetModuleFileNameW(NULL, w_program_name, MAX_PATH);
|
||||
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
||||
err = _wsplitpath_s(buf, drive, 4, buf2, MAX_PATH, NULL, 0, NULL, 0);
|
||||
err = _wsplitpath_s(w_program_name, drive, 4, buf, MAX_PATH, NULL, 0, NULL, 0);
|
||||
if (err != 0) ExitProcess(show_last_error_crt(L"Failed to find application directory"));
|
||||
_snwprintf_s(buf3, MAX_PATH, _TRUNCATE, L"%s%s", drive, buf2);
|
||||
free(buf); free(buf2);
|
||||
return buf3;
|
||||
_snwprintf_s(w_app_dir, MAX_PATH, _TRUNCATE, L"%s%s", drive, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
get_install_locations(void) {
|
||||
get_app_dir();
|
||||
get_app_dirw();
|
||||
_snwprintf_s(qt_prefix_dir, MAX_PATH-1, _TRUNCATE, L"%s\\app", w_app_dir);
|
||||
_wputenv_s(L"CALIBRE_QT_PREFIX", qt_prefix_dir);
|
||||
_snwprintf_s(dll_dir, MAX_PATH-1, _TRUNCATE, L"%s\\app\\bin", w_app_dir);
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
_snwprintf_s(python_path, MAX_PATH-1, _TRUNCATE, L"%s\\app\\pylib.zip", w_app_dir);
|
||||
#else
|
||||
_snprintf_s(python_path, MAX_PATH-1, _TRUNCATE, "%s\\app\\pylib.zip", app_dir);
|
||||
#endif
|
||||
|
||||
void load_python_dll() {
|
||||
char *app_dir, *dll_dir, *qt_plugin_dir;
|
||||
size_t l;
|
||||
}
|
||||
|
||||
app_dir = get_app_dir();
|
||||
l = strlen(app_dir)+25;
|
||||
dll_dir = (char*) calloc(l, sizeof(char));
|
||||
qt_plugin_dir = (char*) calloc(l, sizeof(char));
|
||||
if (!dll_dir || !qt_plugin_dir) ExitProcess(_show_error(L"Out of memory", L"", 1));
|
||||
_snprintf_s(dll_dir, l, _TRUNCATE, "%s\\app\\DLLs", app_dir);
|
||||
_snprintf_s(qt_plugin_dir, l, _TRUNCATE, "%s\\app\\qt_plugins", app_dir);
|
||||
free(app_dir);
|
||||
|
||||
_putenv_s("QT_PLUGIN_PATH", qt_plugin_dir);
|
||||
|
||||
if (!SetDllDirectoryA(dll_dir)) ExitProcess(show_last_error(L"Failed to set DLL directory."));
|
||||
static void
|
||||
load_python_dll() {
|
||||
get_install_locations();
|
||||
if (FAILED(__HrLoadAllImportsForDll(python_dll)))
|
||||
ExitProcess(_show_error(L"Failed to delay load the python dll", L"", 1));
|
||||
}
|
||||
|
||||
static char program_name[MAX_PATH];
|
||||
static char python_home[MAX_PATH];
|
||||
const static wchar_t out_of_memory[] = L"Out of memory";
|
||||
|
||||
static wchar_t out_of_memory[] = L"Out of memory";
|
||||
|
||||
void setup_stream(const char *name, const char *errors, UINT cp) {
|
||||
static void
|
||||
setup_stream(const char *name, const char *errors, UINT cp) {
|
||||
PyObject *stream;
|
||||
char *buf = (char *)calloc(100, sizeof(char));
|
||||
if (!buf) ExitProcess(_show_error(out_of_memory, L"", 1));
|
||||
char buf[128] = {0};
|
||||
|
||||
if (cp == CP_UTF8) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-8");
|
||||
else if (cp == CP_UTF7) _snprintf_s(buf, 100, _TRUNCATE, "%s", "utf-7");
|
||||
@ -158,9 +146,6 @@ void setup_stream(const char *name, const char *errors, UINT cp) {
|
||||
|
||||
if (!PyFile_SetEncodingAndErrors(stream, buf, (char*)errors))
|
||||
ExitProcess(calibre_show_python_error(L"Failed to set stream encoding", 1));
|
||||
|
||||
free(buf);
|
||||
|
||||
}
|
||||
|
||||
UINT
|
||||
@ -187,30 +172,12 @@ setup_streams() {
|
||||
|
||||
UINT
|
||||
initialize_interpreter(const char *basename, const char *module, const char *function) {
|
||||
DWORD sz; char *buf, *path; HMODULE dll;
|
||||
DWORD sz; HMODULE dll;
|
||||
int *flag, i, argc;
|
||||
wchar_t *app_dir, **wargv;
|
||||
wchar_t **wargv;
|
||||
PyObject *argv, *v;
|
||||
char *dummy_argv[1] = {""};
|
||||
|
||||
buf = (char*)calloc(MAX_PATH, sizeof(char));
|
||||
path = (char*)calloc(MAX_PATH, sizeof(char));
|
||||
if (!buf || !path) ExitProcess(_show_error(L"Out of memory", L"", 1));
|
||||
|
||||
sz = GetModuleFileNameA(NULL, buf, MAX_PATH);
|
||||
if (sz >= MAX_PATH-1) ExitProcess(_show_error(L"Installation directory path too long", L"", 1));
|
||||
|
||||
_snprintf_s(program_name, MAX_PATH, _TRUNCATE, "%s", buf);
|
||||
free(buf);
|
||||
|
||||
buf = get_app_dir();
|
||||
buf[strlen(buf)-1] = '\0';
|
||||
|
||||
_snprintf_s(python_home, MAX_PATH, _TRUNCATE, "%s", buf);
|
||||
_snprintf_s(path, MAX_PATH, _TRUNCATE, "%s\\app\\pylib.zip", buf);
|
||||
free(buf);
|
||||
|
||||
|
||||
dll = GetModuleHandleA(python_dll);
|
||||
if (!dll) ExitProcess(show_last_error(L"Failed to get python dll handle"));
|
||||
flag = (int*)GetProcAddress(dll, "Py_OptimizeFlag");
|
||||
@ -238,8 +205,13 @@ initialize_interpreter(const char *basename, const char *module, const char *fun
|
||||
if (!flag) ExitProcess(_show_error(L"Failed to get debug flag", L"", 1));
|
||||
//*flag = 1;
|
||||
|
||||
#if PY_VERSION_MAJOR >= 3
|
||||
Py_SetProgramName(w_program_name);
|
||||
Py_SetPythonHome(w_app_dir);
|
||||
#else
|
||||
Py_SetProgramName(program_name);
|
||||
Py_SetPythonHome(python_home);
|
||||
Py_SetPythonHome(app_dir);
|
||||
#endif
|
||||
|
||||
//printf("Path before Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
Py_Initialize();
|
||||
@ -247,11 +219,10 @@ initialize_interpreter(const char *basename, const char *module, const char *fun
|
||||
|
||||
PySys_SetArgv(1, dummy_argv);
|
||||
//printf("Path after Py_Initialize(): %s\r\n\n", Py_GetPath());
|
||||
PySys_SetPath(path);
|
||||
PySys_SetPath(python_path);
|
||||
//printf("Path set by me: %s\r\n\n", path);
|
||||
PySys_SetObject("gui_app", PyBool_FromLong((long)GUI_APP));
|
||||
app_dir = get_app_dirw();
|
||||
PySys_SetObject("app_dir", PyUnicode_FromWideChar(app_dir, wcslen(app_dir)));
|
||||
PySys_SetObject("app_dir", PyUnicode_FromWideChar(w_app_dir, wcslen(w_app_dir)));
|
||||
|
||||
PySys_SetObject("calibre_basename", PyBytes_FromString(basename));
|
||||
PySys_SetObject("calibre_module", PyBytes_FromString(module));
|
||||
@ -271,22 +242,21 @@ initialize_interpreter(const char *basename, const char *module, const char *fun
|
||||
}
|
||||
|
||||
|
||||
wchar_t* pyobject_to_wchar(PyObject *o) {
|
||||
PyUnicodeObject *t;
|
||||
static const wchar_t*
|
||||
pyobject_to_wchar(PyObject *o) {
|
||||
PyObject *t = NULL;
|
||||
size_t s;
|
||||
wchar_t *ans;
|
||||
static wchar_t ans[4096];
|
||||
|
||||
if (!PyUnicode_Check(o)) {
|
||||
t = (PyUnicodeObject*)PyUnicode_FromEncodedObject(o, NULL, "replace");
|
||||
t = PyUnicode_FromEncodedObject(o, NULL, "replace");
|
||||
if (t == NULL) return NULL;
|
||||
} else t = (PyUnicodeObject*)o;
|
||||
}
|
||||
|
||||
|
||||
s = 2*PyUnicode_GET_SIZE(t) +1;
|
||||
ans = (wchar_t*)calloc(s, sizeof(wchar_t));
|
||||
if (ans == NULL) return NULL;
|
||||
s = PyUnicode_AsWideChar(t, ans, s-1);
|
||||
ans[s] = L'\0';
|
||||
s = PyUnicode_AsWideChar(t ? t : o, ans, arraysz(ans)-1);
|
||||
Py_XDECREF(t);
|
||||
if (s >= 0) ans[s] = 0;
|
||||
else ans[s] = 0;
|
||||
|
||||
return ans;
|
||||
}
|
||||
@ -315,7 +285,7 @@ int handle_sysexit(PyObject *e) {
|
||||
int calibre_show_python_error(const wchar_t *preamble, int code) {
|
||||
PyObject *exc, *val, *tb, *str, **system_exit;
|
||||
HMODULE dll;
|
||||
int ret, issysexit = 0; wchar_t *i;
|
||||
int ret, issysexit = 0; const wchar_t *i;
|
||||
|
||||
if (!PyErr_Occurred()) return code;
|
||||
dll = GetModuleHandleA(python_dll);
|
||||
@ -340,7 +310,6 @@ int calibre_show_python_error(const wchar_t *preamble, int code) {
|
||||
}
|
||||
i = pyobject_to_wchar(str);
|
||||
ret = _show_error(preamble, (i==NULL)?out_of_memory:i, code);
|
||||
if (i) free(i);
|
||||
if (tb != NULL) {
|
||||
PyErr_Restore(exc, val, tb);
|
||||
PyErr_Print();
|
||||
@ -373,6 +342,10 @@ null_invalid_parameter_handler(
|
||||
// to return errors instead of aborting the program. So get the windows CRT
|
||||
// to do that.
|
||||
}
|
||||
__declspec(dllexport) int __cdecl
|
||||
simple_print(const wchar_t *msg) {
|
||||
wprintf(L"%s", msg); fflush(stdout);
|
||||
}
|
||||
|
||||
__declspec(dllexport) int __cdecl
|
||||
execute_python_entrypoint(const char *basename, const char *module, const char *function, int is_gui_app) {
|
||||
@ -398,51 +371,35 @@ execute_python_entrypoint(const char *basename, const char *module, const char *
|
||||
if (site == NULL)
|
||||
ret = calibre_show_python_error(L"Failed to import site module", 1);
|
||||
else {
|
||||
Py_XINCREF(site);
|
||||
Py_INCREF(site);
|
||||
|
||||
main = PyObject_GetAttrString(site, "main");
|
||||
if (main == NULL || !PyCallable_Check(main))
|
||||
ret = calibre_show_python_error(L"site module has no main function", 1);
|
||||
else {
|
||||
Py_XINCREF(main);
|
||||
Py_INCREF(main);
|
||||
res = PyObject_CallObject(main, NULL);
|
||||
|
||||
if (res == NULL)
|
||||
ret = calibre_show_python_error(L"Python function terminated unexpectedly", 1);
|
||||
else {
|
||||
#if PY_VERSION_MAJOR < 3
|
||||
if (PyInt_Check(res)) {
|
||||
ret = PyInt_AS_LONG(res);
|
||||
}
|
||||
#else
|
||||
if (PyLong_Check(res)) {
|
||||
ret = PyLong_AsLong(res);
|
||||
}
|
||||
#endif
|
||||
Py_DECREF(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
PyErr_Clear();
|
||||
Py_Finalize();
|
||||
if (code_page != CP_UTF8) SetConsoleOutputCP(code_page);
|
||||
/* printf("111111111111 returning: %d\r\n", ret); */
|
||||
|
||||
//printf("11111 Returning: %d\r\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
wchar_t* get_temp_filename(const wchar_t *prefix) {
|
||||
DWORD dwRetVal;
|
||||
UINT uRetVal;
|
||||
|
||||
wchar_t *szTempName;
|
||||
wchar_t lpPathBuffer[MAX_PATH];
|
||||
szTempName = (wchar_t *)LocalAlloc(LMEM_ZEROINIT, sizeof(wchar_t)*MAX_PATH);
|
||||
|
||||
dwRetVal = GetTempPath(MAX_PATH, lpPathBuffer);
|
||||
|
||||
if (dwRetVal > MAX_PATH || (dwRetVal == 0)) {
|
||||
ExitProcess(show_last_error(L"Failed to get temp path."));
|
||||
}
|
||||
|
||||
uRetVal = GetTempFileName(lpPathBuffer, // directory for tmp files
|
||||
prefix, // temp file name prefix
|
||||
0, // create unique name
|
||||
szTempName); // buffer for name
|
||||
|
||||
if (uRetVal == 0) {
|
||||
ExitProcess(show_last_error(L"Failed to get temp file name"));
|
||||
}
|
||||
return szTempName;
|
||||
}
|
||||
|
@ -194,7 +194,7 @@ def sanitize_path():
|
||||
needed_paths.append(p)
|
||||
executables.remove(x)
|
||||
sw = os.environ['SW']
|
||||
paths = r'{0}\private\python\DLLs {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format(
|
||||
paths = r'{0}\private\python\bin {0}\private\python\Lib\site-packages\pywin32_system32 {0}\bin {0}\qt\bin C:\Windows\System32'.format(
|
||||
sw
|
||||
).split() + needed_paths
|
||||
os.environ['PATH'] = os.pathsep.join(paths)
|
||||
|
Loading…
x
Reference in New Issue
Block a user