Skip to content

Instantly share code, notes, and snippets.

@heetbeet
Created August 22, 2019 11:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save heetbeet/3ddc2bc6841e4c61431809f392dac859 to your computer and use it in GitHub Desktop.
Save heetbeet/3ddc2bc6841e4c61431809f392dac859 to your computer and use it in GitHub Desktop.
Download inkscape and all its dependancies into your current folder, and create a portable wrapper entry point.
import os
import subprocess
def sh(*params, strip=True):
p = subprocess.Popen(params,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
universal_newlines=True)
outstr, errstr = p.communicate()
retstr = outstr + errstr
if strip:
return retstr.strip()
else:
return retstr
def single_sep(path):
N = -1
while(N!=len(path)):
N = len(path)
path = path.replace('//', '/')
return path
def get_linkdirs():
linkdirs = []
for line in sh('ld', '--verbose').split('SEARCH')[1:]:
linkdir = line.split('"')[1].split('"')[0]
if linkdir[:1] == '=':
linkdir = linkdir[1:]
return linkdirs
_linkdirs = get_linkdirs()
def get_so_path(f):
for searchpth in _linkdirs:
if os.path.isfile(searchpth+'/'+f):
return(searchpth+'/'+f)
inkbin = sh('which', 'inkscape')
inkhome = os.path.split(inkbin)[0]
lines = set()
libfiles = set([inkbin])
donezo = set()
N = -1
while(N != len(libfiles)):
N = len(libfiles)
for file in libfiles.difference(donezo):
donezo.add(file)
try:
for line in sh('ldd', file).split('\n'):
fnext = None
for i in line.split():
if os.path.isfile(i):
fnext = i
break
if not fnext:
fnext = get_so_path(
line.split('.so')[0].split()[-1].split('/')[-1]+'.so'
)
if fnext:
libfiles.add(single_sep(fnext))
except Exception as e:
print(e)
print('\n'.join(lines))
os.makedirs('files', exist_ok=True)
linkerpaths = set()
for file in libfiles:
print(file)
try:
linkpath = single_sep('./'+os.path.split(file)[0])
linkerpaths.add(linkpath)
os.makedirs(linkpath, exist_ok=True)
sh('cp', file, './'+file)
except Exception as e:
print(e)
import os
for path in sh('dpkg', '-L', 'inkscape').split('\n'):
if os.path.isfile(path):
if not os.path.isfile('./'+path):
os.makedirs(os.path.split('./'+path)[0], exist_ok=True)
sh('cp', path, './'+path)
else:
pass
from textwrap import dedent
lpathtxt = ':'.join(['$DIR/'+i[2:] for i in linkerpaths])
binpathtxt = '$DIR/'+inkbin
binwrap_template = dedent(r'''
#!/bin/bash
#--------------------------------------------------
# I might be a symlink, so here is my root dwelling
#--------------------------------------------------
#From https://stackoverflow.com/a/246128
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
SOURCE="$(readlink "$SOURCE")"
# if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
[[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
DIR="$( cd -P "$( dirname "$SOURCE" )" && pwd )"
#--------------------------------------------------
# Hey linker, also look here for .so files
#--------------------------------------------------
#From https://stackoverflow.com/a/37558191
export LD_LIBRARY_PATH=%s:$LD_LIBRARY_PATH
#--------------------------------------------------
# Finally, hey Linux, run this binary please
#--------------------------------------------------
"%s" "$@"
''').strip()%(lpathtxt,
binpathtxt)
open(os.path.split(binpathtxt)[-1], 'w').write(binwrap_template)
sh('chmod', '+x', os.path.split(binpathtxt)[-1])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment