diff --git a/__main__.py b/__main__.py index 8abf28c0b..c54ee3847 100644 --- a/__main__.py +++ b/__main__.py @@ -3,6 +3,7 @@ # License: GPL v3 Copyright: 2015, Kovid Goyal import sys +import os def icat(args): @@ -57,7 +58,21 @@ entry_points = { namespaced_entry_points = {k: v for k, v in entry_points.items() if k[0] not in '+@'} +def setup_openssl_environment(): + # Workaround for Linux distros that have still failed to get their heads + # out of their asses and implement a common location for SSL certificates. + # It's not that hard people, there exists a wonderful tool called the symlink + # See http://www.mobileread.com/forums/showthread.php?t=256095 + if 'SSL_CERT_FILE' not in os.environ and 'SSL_CERT_DIR' not in os.environ: + if os.access('/etc/pki/tls/certs/ca-bundle.crt', os.R_OK): + os.environ['SSL_CERT_FILE'] = '/etc/pki/tls/certs/ca-bundle.crt' + elif os.path.isdir('/etc/ssl/certs'): + os.environ['SSL_CERT_DIR'] = '/etc/ssl/certs' + + def main(): + if getattr(sys, 'frozen', False) and 'darwin' not in sys.platform.lower(): + setup_openssl_environment() first_arg = '' if len(sys.argv) < 2 else sys.argv[1] func = entry_points.get(first_arg) if func is None: diff --git a/linux-launcher.c b/linux-launcher.c index 1c8497af0..f34c8f5da 100644 --- a/linux-launcher.c +++ b/linux-launcher.c @@ -39,15 +39,28 @@ static int run_embedded(const char* exe_dir_, int argc, wchar_t **argv) { if (exe_dir == NULL) { fprintf(stderr, "Fatal error: cannot decode exe_dir\n"); return 1; } PyObject *ed = PyUnicode_FromWideChar(exe_dir, -1); wchar_t stdlib[PATH_MAX+1] = {0}; - num = swprintf(stdlib, PATH_MAX, L"%ls/../Resources/Python/lib/python%s:%ls/../Resources/Python/lib/python%s/lib-dynload", exe_dir, PYVER, exe_dir, PYVER); +#ifdef __APPLE__ + const char *python_relpath = "../Resources/Python/lib"; +#else + const char *python_relpath = "../lib"; +#endif + num = swprintf(stdlib, PATH_MAX, L"%ls/%s/python%s:%ls/%s/python%s/lib-dynload:%ls/%s/python%s/site-packages", + exe_dir, python_relpath, PYVER, + exe_dir, python_relpath, PYVER, + exe_dir, python_relpath, PYVER + ); if (num < 0 || num >= PATH_MAX) { fprintf(stderr, "Failed to create path to python stdlib\n"); return 1; } Py_SetPath(stdlib); +#ifdef __APPLE__ num = swprintf(stdlib, PATH_MAX, L"%ls/../Frameworks/kitty", exe_dir); +#else + num = swprintf(stdlib, PATH_MAX, L"%ls/../lib/kitty", exe_dir); +#endif PyMem_RawFree(exe_dir); if (num < 0 || num >= PATH_MAX) { fprintf(stderr, "Failed to create path to kitty lib\n"); return 1; } Py_Initialize(); PySys_SetArgvEx(argc - 1, argv + 1, 0); - PySys_SetObject("frozen", Py_True); // dont care if this fails + PySys_SetObject("frozen", Py_True); if (ed) { PySys_SetObject("bundle_exe_dir", ed); Py_CLEAR(ed); } PyObject *kitty = PyUnicode_FromWideChar(stdlib, -1); if (kitty == NULL) { fprintf(stderr, "Failed to allocate python kitty lib object\n"); goto end; } diff --git a/setup.py b/setup.py index 3aac49780..894a6e478 100755 --- a/setup.py +++ b/setup.py @@ -507,7 +507,7 @@ def build_asan_launcher(args): run_tool(cmd, desc='Creating {} ...'.format(emphasis('asan-launcher'))) -def build_linux_launcher(args, launcher_dir='.', for_bundle=False, sh_launcher=False): +def build_linux_launcher(args, launcher_dir='.', for_bundle=False, sh_launcher=False, for_freeze=False): cflags = '-Wall -Werror -fpie'.split() cppflags = [] libs = [] @@ -516,7 +516,7 @@ def build_linux_launcher(args, launcher_dir='.', for_bundle=False, sh_launcher=F libs.append('-lprofiler') else: cflags.append('-O3') - if for_bundle: + if for_bundle or for_freeze: cppflags.append('-DFOR_BUNDLE') cppflags.append('-DPYVER="{}"'.format(sysconfig.get_python_version())) elif sh_launcher: @@ -527,6 +527,8 @@ def build_linux_launcher(args, launcher_dir='.', for_bundle=False, sh_launcher=F cppflags += shlex.split(os.environ.get('CPPFLAGS', '')) cflags += shlex.split(os.environ.get('CFLAGS', '')) ldflags = shlex.split(os.environ.get('LDFLAGS', '')) + if for_freeze: + ldflags += ['-Wl,-rpath,$ORIGIN/../lib'] cmd = [env.cc] + cppflags + cflags + [ 'linux-launcher.c', '-o', os.path.join(launcher_dir, exe) @@ -567,7 +569,7 @@ def package(args, for_bundle=False, sh_launcher=False): # {{{ shutil.copy2('kitty/launcher/kitty', os.path.join(libdir, 'kitty', 'launcher')) launcher_dir = os.path.join(ddir, 'bin') safe_makedirs(launcher_dir) - build_linux_launcher(args, launcher_dir, for_bundle, sh_launcher) + build_linux_launcher(args, launcher_dir, for_bundle, sh_launcher, args.for_freeze) if not is_macos: # {{{ linux desktop gunk icdir = os.path.join(ddir, 'share', 'icons', 'hicolor', '256x256', 'apps') safe_makedirs(icdir) @@ -668,7 +670,7 @@ def clean(): os.unlink(x) -def option_parser(): +def option_parser(): # {{{ p = argparse.ArgumentParser() p.add_argument( 'action', @@ -716,12 +718,19 @@ def option_parser(): action='store_true', help='Use the -pg compile flag to add profiling information' ) + p.add_argument( + '--for-freeze', + default=False, + action='store_true', + help='Internal use' + ) p.add_argument( '--libdir-name', default='lib', help='The name of the directory inside --prefix in which to store compiled files. Defaults to "lib"' ) return p +# }}} def main():