Linux binary build: Fix worker processes not working on linux systems with bash >= 4.3

This commit is contained in:
Kovid Goyal 2014-03-25 00:36:05 +05:30
parent 462b429071
commit 587e5aba65
2 changed files with 81 additions and 16 deletions

View File

@ -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)

View File

@ -0,0 +1,74 @@
/*
* launcher.c
* Copyright (C) 2014 Kovid Goyal <kovid at kovidgoyal.net>
*
* Distributed under terms of the GPL3 license.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <libgen.h>
#include <stdlib.h>
#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;
}