Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load resources from a location relative to the main executable #111

Open
probonopd opened this issue Jan 26, 2019 · 1 comment
Open

Load resources from a location relative to the main executable #111

probonopd opened this issue Jan 26, 2019 · 1 comment

Comments

@probonopd
Copy link

probonopd commented Jan 26, 2019

Currently Scribus is loading resources (e.g. some of the icons) from a location defined at compile time.

This makes the binary non-relocateable in the filesystem, which means it only works when it is installed to the $PREFIX it was compiled for.

However, for AppImage, we need to make a bundle that can run from any location in the filesystem.
For the past 2 years, we have been doing a crude binary patch as a workaround:

########################################################################
# Patch away absolute paths; it would be nice if they were relative
########################################################################
sed -i -e 's|/usr/share/scribus|././/share/scribus|g' usr/bin/scribus
sed -i -e 's|/usr/lib/scribus|././/lib/scribus|g' usr/bin/scribus
sed -i -e 's|/usr/share/doc/scribus/|././/share/doc/scribus/|g' usr/bin/scribus
# Possibly need to patch additional hardcoded paths away, replace
# "/usr" with "././" which means "usr/ in the AppDir"

At execution time, we change to the usr/ directory inside the AppImage.

This causes considerable pain. One cannot, for example, use relative paths to open documents anymore but needs to do things like

me@host:~$ ./Scribus-*-x86_64.AppImage $(readlink -f my_document.sla)

Even worse, one cannot use relative paths in Python scripts.

Hence, Scribus should be changed to load resources from a location relative to the main executable.

One could use QString QCoreApplication::applicationDirPath() instead and construct a relative path to ../share/... from there. This would have the advantage that for normal installations, nothing would change (all files would stay where they are now) but since they would be referenced relative to the main application, the application would be relocateable.

I wonder what is done for macOS, where the application also needs to be relocateable...

@probonopd
Copy link
Author

probonopd commented Jan 26, 2019

Looks like it has been implemented in

#ifdef Q_OS_LINUX
// Set the application name expliticly.
QCoreApplication::setApplicationName("scribus");
QString pathPtr = QCoreApplication::applicationDirPath() + QString("/..");
m_shareDir = QString("%1/share/scribus/").arg(pathPtr);
m_docDir = QString("%1/share/doc/scribus/").arg(pathPtr);
//m_fontDir = QString("%1/share/scribus/fonts/").arg(pathPtr);
m_iconDir = QString("%1/share/scribus/icons/").arg(pathPtr);
m_sampleScriptDir = QString("%1/share/scribus/samples/").arg(pathPtr);
m_scriptDir = QString("%1/share/scribus/scripts/").arg(pathPtr);
m_templateDir = QString("%1/share/scribus/templates/").arg(pathPtr);
m_libDir = QString("%1/lib/scribus/").arg(pathPtr);
m_pluginDir = QString("%1/lib/scribus/plugins/").arg(pathPtr);
m_qmlDir = QString("%1/share/scribus/qml/").arg(pathPtr);
qDebug() << QString("scpaths: doc dir=%1").arg(m_docDir);
qDebug() << QString("scpaths: icon dir=%1").arg(m_iconDir);
//qDebug() << QString("scpaths: font dir=%1").arg(m_fontDir);
qDebug() << QString("scpaths: sample dir=%1").arg(m_sampleScriptDir);
qDebug() << QString("scpaths: script dir=%1").arg(m_scriptDir);
qDebug() << QString("scpaths: template dir=%1").arg(m_templateDir);
qDebug() << QString("scpaths: lib dir=%1").arg(m_libDir);
qDebug() << QString("scpaths: plugins dir=%1").arg(m_pluginDir);
qDebug() << QString("scpaths: qml dir=%1").arg(m_qmlDir);
#endif

Thanks @LyzardKing.

However, it's not entirely working yet:

me@host:~/digital-handshake-master$ '/home/me/Downloads/Scribus-b5aa26c-x86_64.AppImage'
Run experimental bundle that bundles everything
"scpaths: doc dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/doc/scribus/"
"scpaths: icon dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/scribus/icons/"
"scpaths: sample dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/scribus/samples/"
"scpaths: script dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/scribus/scripts/"
"scpaths: template dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/scribus/templates/"
"scpaths: lib dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../lib/scribus/"
"scpaths: plugins dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../lib/scribus/plugins/"
"scpaths: qml dir=/tmp/.mount_ScribuAitwXX/lib/x86_64-linux-gnu/../share/scribus/qml/"
No icons found :(

Looks like for whatever reason it thinks the application directory applicationDirPath() is not usr/bin but lib/x86_64-linux-gnu/. Thanks to @jghali, we assume the reason is that applicationDirPath() trips over what we are doing in the AppRun:

exec "${HERE}/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2" --inhibit-cache --library-path "${LIBRARY_PATH}" "${MAIN}" "$@"

One can temporarily work around this by symlinking

( cd appdir/lib/ ; ln -s ../usr/share . ; ln -s ../usr/lib . )

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant