diff --git a/setup/installer/linux/freeze2.py b/setup/installer/linux/freeze2.py index 13da77f8db..daae99cafb 100644 --- a/setup/installer/linux/freeze2.py +++ b/setup/installer/linux/freeze2.py @@ -279,6 +279,12 @@ class LinuxFreeze(Command): modules['console'].append('calibre.linux') basenames['console'].append('calibre_postinstall') functions['console'].append('main') + c_launcher = '/tmp/calibre-c-launcher' + lsrc = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'launcher.c') + cmd = ['gcc', '-O2', '-DMAGICK_BASE="%s"' % self.magick_base, '-o', c_launcher, lsrc, ] + self.info('Compiling launcher') + self.run_builder(cmd, verbose=False) + for typ in ('console', 'gui', ): self.info('Processing %s launchers'%typ) for mod, bname, func in zip(modules[typ], basenames[typ], @@ -288,20 +294,6 @@ class LinuxFreeze(Command): xflags += ['-DMODULE="%s"'%mod, '-DBASENAME="%s"'%bname, '-DFUNCTION="%s"'%func] - launcher = textwrap.dedent('''\ - #!/bin/sh - path=`readlink -f $0` - base=`dirname $path` - lib=$base/lib - export QT_ACCESSIBILITY=0 # qt-at-spi causes crashes and performance issues in various distros, so disable it - export LD_LIBRARY_PATH=$lib:$LD_LIBRARY_PATH - export MAGICK_HOME=$base - export MAGICK_CONFIGURE_PATH=$lib/{1}/config - export MAGICK_CODER_MODULE_PATH=$lib/{1}/modules-Q16/coders - export MAGICK_CODER_FILTER_PATH=$lib/{1}/modules-Q16/filters - exec $base/bin/{0} "$@" - ''') - dest = self.j(self.obj_dir, bname+'.o') if self.newer(dest, [src, __file__]+headers): self.info('Compiling', bname) @@ -309,8 +301,7 @@ class LinuxFreeze(Command): self.run_builder(cmd, verbose=False) exe = self.j(self.bin_dir, bname) sh = self.j(self.base, bname) - with open(sh, 'wb') as f: - f.write(launcher.format(bname, self.magick_base)) + shutil.copy2(c_launcher, sh) os.chmod(sh, stat.S_IREAD|stat.S_IEXEC|stat.S_IWRITE|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH) diff --git a/setup/installer/linux/launcher.c b/setup/installer/linux/launcher.c new file mode 100644 index 0000000000..7e501b1dea --- /dev/null +++ b/setup/installer/linux/launcher.c @@ -0,0 +1,74 @@ +/* + * launcher.c + * Copyright (C) 2014 Kovid Goyal + * + * Distributed under terms of the GPL3 license. + */ + +#include +#include +#include +#include +#include + +#define PATHLEN 1023 + +int main(int argc, char **argv) { + static char buf[PATHLEN+1] = {0}, lib[PATHLEN+1] = {0}, base[PATHLEN+1] = {0}, exe[PATHLEN+1] = {0}, *ldp = NULL; + + if (readlink("/proc/self/exe", buf, PATHLEN) == -1) { + fprintf(stderr, "Failed to read path of executable with error: %s\n", strerror(errno)); + return 1; + } + strncpy(lib, buf, PATHLEN); + strncpy(base, dirname(lib), PATHLEN); + snprintf(exe, PATHLEN, "%s/bin/%s", base, basename(buf)); + memset(lib, 0, PATHLEN); + snprintf(lib, PATHLEN, "%s/lib", base); + + /* qt-at-spi causes crashes and performance issues in various distros, so disable it */ + if (setenv("QT_ACCESSIBILITY", "0", 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + + if (setenv("MAGICK_HOME", base, 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + memset(buf, 0, PATHLEN); snprintf(buf, PATHLEN, "%s/%s/config", lib, MAGICK_BASE); + if (setenv("MAGICK_CONFIGURE_PATH", buf, 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + memset(buf, 0, PATHLEN); snprintf(buf, PATHLEN, "%s/%s/modules-Q16/coders", lib, MAGICK_BASE); + if (setenv("MAGICK_CODER_MODULE_PATH", buf, 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + memset(buf, 0, PATHLEN); snprintf(buf, PATHLEN, "%s/%s/modules-Q16/filters", lib, MAGICK_BASE); + if (setenv("MAGICK_CODER_FILTER_PATH", buf, 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + + memset(buf, 0, PATHLEN); + ldp = getenv("LD_LIBRARY_PATH"); + if (ldp == NULL) strncpy(buf, lib, PATHLEN); + else snprintf(buf, PATHLEN, "%s:%s", lib, ldp); + if (setenv("LD_LIBRARY_PATH", buf, 1) != 0) { + fprintf(stderr, "Failed to set environment variable with error: %s\n", strerror(errno)); + return 1; + } + + argv[0] = exe; + if (execv(exe, argv) == -1) { + fprintf(stderr, "Failed to execute binary: %s with error: %s\n", exe, strerror(errno)); + return 1; + } + + return 0; +} + + +