On Win32, Gimp is relocatable. It can find out it's own path at runtime
and find out where it's data files are. On Linux, all paths in Gimp are
hardcoded at compile time. This means the app is not relocatable.
I work for the autopackage project (http://autopackage.org/), a new
installation system for Linux. One of the features of autopackage is
that packages can be installed to any prefix (although that's not
recommended), which means the software must be relocatable. Because
there's no real easy way to quickly find out the path of a library or
application.
See also http://autopackage.org/docs/binreloc/ for more info about
BinReloc and the relocation problem.
Anyway, to the point. I'm packaging Gimp 2 currently and I've modified
Gimp to be relocatable on Linux. The patch is mostly finished but there
are still minor issues to take care of. I'd like to know if this patch
is good enough to be able to get accepted, and if not, why.
Please note that adding binary relocation support on Linux will not harm
portability! I wrote a configure check for this, and binary relocation
support will be automatically disabled if the system is not running on
Linux. The user can also explicitly tell configure to disable binreloc
support.
I am aware that app/main.c sets LD_LIBRARY_PATH. This is just temporary
because it's less work than modifying every Makefile for every plugin.
Apart from this obvious hack, how does the rest of the patch look? Is it
good enough to be accepted once I remove the LD_LIBRARY_PATH hack?
--- gimp-2.0.0/app/main.c.old 2004-04-07 19:47:40.0 +0200
+++ gimp-2.0.0/app/main.c 2004-04-07 19:48:21.0 +0200
@@ -41,6 +41,7 @@
#include glib-object.h
#include libgimpbase/gimpbase.h
+#include libgimpbase/prefix.h
#include config/gimpconfig-dump.h
@@ -114,6 +115,9 @@
GimpPDBCompatMode pdb_compat_mode = GIMP_PDB_COMPAT_WARN;
#endif
ginti, j;
+#ifdef ENABLE_BINRELOC
+ gchar *libpath, *tmp;
+#endif
#if 0
g_mem_set_vtable (glib_mem_profiler_table);
@@ -140,6 +144,19 @@
textdomain (GETTEXT_PACKAGE);
+#ifdef ENABLE_BINRELOC
+ tmp = gimp_br_prepend_prefix (, /lib);
+ libpath = (gchar *) g_getenv (LD_LIBRARY_PATH);
+ if (libpath *libpath)
+{
+ libpath = g_strdup_printf (%s:%s, tmp, libpath);
+ setenv (LD_LIBRARY_PATH, libpath, 1);
+ g_free (tmp);
+}
+ else
+setenv (LD_LIBRARY_PATH, tmp, 1);
+#endif
+
/* Check argv[] for --no-interface before trying to initialize gtk+.
* We also check for --help or --version here since those shouldn't
* require gui libs either.
--- gimp-2.0.0/app/Makefile.am.old 2004-04-07 19:47:45.0 +0200
+++ gimp-2.0.0/app/Makefile.am 2004-04-07 19:48:21.0 +0200
@@ -64,7 +64,8 @@
-DG_LOG_DOMAIN=\Gimp\ \
-DGIMP_APP_GLUE_COMPILATION \
@GIMP_THREAD_FLAGS@ \
- @GIMP_MP_FLAGS@
+ @GIMP_MP_FLAGS@ \
+ $(BINRELOC_CFLAGS)
INCLUDES = \
-I$(top_srcdir) \
--- gimp-2.0.0/libgimpbase/gimpenv.c.old 2004-04-07 19:47:54.0 +0200
+++ gimp-2.0.0/libgimpbase/gimpenv.c 2004-04-07 19:48:21.0 +0200
@@ -31,6 +31,8 @@
#include sys/types.h
#include sys/stat.h
+#include prefix.h
+
#ifdef HAVE_UNISTD_H
#include unistd.h
#endif
--- gimp-2.0.0/libgimpbase/Makefile.am.old 2004-04-07 19:47:57.0 +0200
+++ gimp-2.0.0/libgimpbase/Makefile.am 2004-04-07 19:48:21.0 +0200
@@ -47,6 +47,10 @@
-DPLUGINDIR=\$(gimpplugindir)\ \
-DSYSCONFDIR=\$(gimpsysconfdir)\ \
-DG_LOG_DOMAIN=\LibGimpBase\ \
+ -DGIMP_DATA_VERSION=\$(GIMP_DATA_VERSION)\ \
+ -DGIMP_SYSCONF_VERSION=\$(GIMP_SYSCONF_VERSION)\ \
+ -DGIMP_PLUGIN_VERSION=\$(GIMP_PLUGIN_VERSION)\ \
+ $(BINRELOC_CFLAGS) \
@GIMP_THREAD_FLAGS@
INCLUDES = \
@@ -91,7 +95,9 @@
gimputils.h \
gimpwin32-io.h \
gimpwire.c \
- gimpwire.h
+ gimpwire.h \
+ prefix.c \
+ prefix.h
libgimpbaseinclude_HEADERS = \
gimpbase.h \
--- gimp-2.0.0/configure.in.old 2004-04-07 19:48:16.0 +0200
+++ gimp-2.0.0/configure.in 2004-04-07 20:11:27.0 +0200
@@ -376,6 +376,59 @@
AC_CHECK_FUNCS(difftime putenv mmap)
+AC_ARG_ENABLE(binreloc,
+ [ --enable-binreloc compile with binary relocation support
+ (default=enable when available)],
+ enable_binreloc=$enableval,enable_binreloc=auto)
+BINRELOC_CFLAGS=
+
+AC_MSG_CHECKING(whether binary relocation support should be enabled)
+if test $enable_binreloc = yes; then
+ AC_MSG_RESULT(yes)
+ AC_MSG_CHECKING(for linker mappings at /proc/self/maps)
+ if test -e /proc/self/maps; then
+ AC_MSG_RESULT(yes)
+ BINRELOC_CFLAGS=-DENABLE_BINRELOC
+ else
+ AC_MSG_RESULT(no)
+ AC_MSG_ERROR(/proc/self/maps is not available. Binary relocation cannot be enabled.)
+ fi
+
+elif test $enable_binreloc = auto; then
+ AC_MSG_RESULT(yes when available)
+ AC_MSG_CHECKING(for linker mappings at /proc/self/maps)
+ if test -e /proc/self/maps; then
+ AC_MSG_RESULT(yes)
+ enable_binreloc=yes
+
+