Kaydet (Commit) fc6c31a2 authored tarafından Enrico Tröger's avatar Enrico Tröger

Add binary relocation support.


git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@2100 ea778897-0a13-0410-b9d1-a72fbfd435f5
üst 2e8a6e89
......@@ -7,6 +7,9 @@
* src/vte.c: Enable dragging of text into the VTE.
* src/msgwindow.c: Fix crashes when clicking on message window items
introduced with changing rules hints for treeviews.
* configure.in, src/Makefile.am, src/main.c, src/plugins.c,
src/prefix.c, src/prefix.h, src/symbols.c:
Add binary relocation support.
2007-12-09 Enrico Tröger <enrico(dot)troeger(at)uvena(dot)de>
......
......@@ -52,6 +52,61 @@ else
fi
AC_DEFINE_UNQUOTED([REVISION], "$REVISION", [subversion revision number])
dnl Check for binary relocation support
dnl taken from Inkscape (Hongli Lai <h.lai@chello.nl>)
AC_ARG_ENABLE(binreloc,
[ --enable-binreloc compile with binary relocation support],
enable_binreloc=$enableval,enable_binreloc=no)
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)
else
AC_MSG_RESULT(no)
AC_MSG_ERROR(/proc/self/maps is not available. Binary relocation cannot be enabled.)
enable_binreloc="no"
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
AC_MSG_CHECKING(whether everything is installed to the same prefix)
if test "$bindir" = '${exec_prefix}/bin' -a "$sbindir" = '${exec_prefix}/sbin' -a \
"$datadir" = '${prefix}/share' -a "$libdir" = '${exec_prefix}/lib' -a \
"$libexecdir" = '${exec_prefix}/libexec' -a "$sysconfdir" = '${prefix}/etc'
then
AC_MSG_RESULT(yes)
else
AC_MSG_RESULT(no)
AC_MSG_NOTICE(Binary relocation support will be disabled.)
enable_binreloc=no
fi
else
AC_MSG_RESULT(no)
enable_binreloc=no
fi
elif test "$enable_binreloc" = "no"; then
AC_MSG_RESULT(no)
else
AC_MSG_RESULT(no (unknown value "$enable_binreloc"))
enable_binreloc=no
fi
if test "$enable_binreloc" = "yes"; then
AC_DEFINE(ENABLE_BINRELOC,,[Use AutoPackage?])
fi
# GTK checks
gtk_modules="gtk+-2.0 >= 2.6.0"
PKG_CHECK_MODULES(GTK, [$gtk_modules])
......
......@@ -25,6 +25,7 @@ SRCS = \
navqueue.c navqueue.h \
notebook.c notebook.h \
plugins.c plugins.h \
prefix.c prefix.h \
prefs.c prefs.h \
printing.c printing.h \
project.c project.h \
......@@ -75,8 +76,8 @@ nodist_EXTRA_geany_SOURCES = dummy.cxx
geany_LDADD = ../scintilla/libscintilla.a ../tagmanager/libtagmanager.a @GTK_LIBS@ $(INTLLIBS)
INCLUDES = \
-DPACKAGE_DATA_DIR=\""$(datadir)"\" -DPACKAGE_LIB_DIR=\""$(libdir)"\" \
-DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-DDATADIR=\""$(datadir)"\" -DLIBDIR=\""$(libdir)"\" \
-DLOCALEDIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \
-I$(srcdir)/../scintilla/include -I$(srcdir)/../tagmanager/include @GTK_CFLAGS@
clean-local:
......
......@@ -40,6 +40,7 @@
#endif
#include "main.h"
#include "prefix.h"
#include "prefs.h"
#include "interface.h"
#include "support.h"
......@@ -377,8 +378,8 @@ static void setup_paths()
g_free(install_dir);
#else
data_dir = g_strdup(PACKAGE_DATA_DIR "/" PACKAGE "/"); // e.g. /usr/share/geany
doc_dir = g_strdup(PACKAGE_DATA_DIR "/doc/" PACKAGE "/html/");
data_dir = g_strconcat(DATADIR, "/" PACKAGE "/", NULL); // e.g. /usr/share/geany
doc_dir = g_strconcat(DATADIR, "/doc/" PACKAGE "/html/", NULL);
#endif
// convert path names to locale encoding
......@@ -405,7 +406,7 @@ static void locale_init()
locale_dir = g_strconcat(install_dir, "\\lib\\locale", NULL);
g_free(install_dir);
#else
locale_dir = g_strdup(PACKAGE_LOCALE_DIR);
locale_dir = g_strdup(LOCALEDIR);
#endif
bindtextdomain(GETTEXT_PACKAGE, locale_dir);
......
......@@ -33,6 +33,7 @@
#include "Scintilla.h"
#include "ScintillaWidget.h"
#include "prefix.h"
#include "plugins.h"
#include "plugindata.h"
#include "support.h"
......@@ -534,13 +535,13 @@ static void load_plugin_paths()
path = g_strconcat(app->configdir, G_DIR_SEPARATOR_S, "plugins", NULL);
// first load plugins in ~/.geany/plugins/, then in $prefix/lib/geany
load_plugins(path);
#ifdef G_OS_WIN32
g_free(path);
#ifdef G_OS_WIN32
path = get_plugin_path();
load_plugins(path);
#else
load_plugins(PACKAGE_LIB_DIR G_DIR_SEPARATOR_S "geany");
path = g_strconcat(LIBDIR, G_DIR_SEPARATOR_S "geany", NULL);
#endif
load_plugins(path);
g_free(path);
}
......
/*
* BinReloc - a library for creating relocatable executables
* Written by: Mike Hearn <mike@theoretic.com>
* Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* NOTE: if you're using C++ and are getting "undefined reference
* to br_*", try renaming prefix.c to prefix.cpp
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
/*
* enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h,
* this only happens if configure option --enable-binreloc was used
*/
#ifdef ENABLE_BINRELOC
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <string.h>
#include <glib.h>
#include "prefix.h"
#undef NULL
#define NULL ((void *) 0)
#ifdef __GNUC__
#define br_return_val_if_fail(expr,val) if (!(expr)) {fprintf (stderr, "** BinReloc (%s): assertion %s failed\n", __PRETTY_FUNCTION__, #expr); return val;}
#else
#define br_return_val_if_fail(expr,val) if (!(expr)) return val
#endif /* __GNUC__ */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <unistd.h>
static char *br_last_value = (char*)NULL;
static void
br_free_last_value ()
{
if (br_last_value)
free (br_last_value);
}
/**
* br_thread_local_store:
* str: A dynamically allocated string.
* Returns: str. This return value must not be freed.
*
* Store str in a thread-local variable and return str. The next
* you run this function, that variable is freed too.
* This function is created so you don't have to worry about freeing
* strings.
*
* Example:
* char *foo;
* foo = thread_local_store (strdup ("hello")); --> foo == "hello"
* foo = thread_local_store (strdup ("world")); --> foo == "world"; "hello" is now freed.
*/
const char *
br_thread_local_store (char *str)
{
static int initialized = 0;
if (!initialized)
{
atexit (br_free_last_value);
initialized = 1;
}
if (br_last_value)
free (br_last_value);
br_last_value = str;
return (const char *) str;
}
/**
* br_locate:
* symbol: A symbol that belongs to the app/library you want to locate.
* Returns: A newly allocated string containing the full path of the
* app/library that func belongs to, or NULL on error. This
* string should be freed when not when no longer needed.
*
* Finds out to which application or library symbol belongs, then locate
* the full path of that application or library.
* Note that symbol cannot be a pointer to a function. That will not work.
*
* Example:
* --> main.c
* #include "prefix.h"
* #include "libfoo.h"
*
* int main (int argc, char *argv[]) {
* printf ("Full path of this app: %s\n", br_locate (&argc));
* libfoo_start ();
* return 0;
* }
*
* --> libfoo.c starts here
* #include "prefix.h"
*
* void libfoo_start () {
* --> "" is a symbol that belongs to libfoo (because it's called
* --> from libfoo_start()); that's why this works.
* printf ("libfoo is located in: %s\n", br_locate (""));
* }
*/
char *
br_locate (void *symbol)
{
char line[5000];
FILE *f;
char *path;
br_return_val_if_fail (symbol != NULL, NULL);
f = fopen ("/proc/self/maps", "r");
if (!f)
return NULL;
while (!feof (f))
{
unsigned long start, end;
if (!fgets (line, sizeof (line), f))
continue;
if (!strstr (line, " r-xp ") || !strchr (line, '/'))
continue;
sscanf (line, "%lx-%lx ", &start, &end);
if (symbol >= (void *) start && symbol < (void *) end)
{
char *tmp;
size_t len;
/* Extract the filename; it is always an absolute path */
path = strchr (line, '/');
/* Get rid of the newline */
tmp = strrchr (path, '\n');
if (tmp) *tmp = 0;
/* Get rid of "(deleted)" */
len = strlen (path);
if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
{
tmp = path + len - 10;
*tmp = 0;
}
fclose(f);
return strdup (path);
}
}
fclose (f);
return NULL;
}
/**
* br_extract_prefix:
* path: The full path of an executable or library.
* Returns: The prefix, or NULL on error. This string should be freed when no longer needed.
*
* Extracts the prefix from path. This function assumes that your executable
* or library is installed in an LSB-compatible directory structure.
*
* Example:
* br_extract_prefix ("/usr/bin/gnome-panel"); --> Returns "/usr"
* br_extract_prefix ("/usr/local/lib/libfoo.so"); --> Returns "/usr/local"
* br_extract_prefix ("/usr/local/libfoo.so"); --> Returns "/usr"
*/
char *
br_extract_prefix (const char *path)
{
char *end, *tmp, *result;
br_return_val_if_fail (path != (char*)NULL, (char*)NULL);
if (!*path) return strdup ("/");
end = strrchr (path, '/');
if (!end) return strdup (path);
tmp = g_strndup ((char *) path, end - path);
if (!*tmp)
{
free (tmp);
return strdup ("/");
}
end = strrchr (tmp, '/');
if (!end) return tmp;
result = g_strndup (tmp, end - tmp);
free (tmp);
if (!*result)
{
free (result);
result = strdup ("/");
}
return result;
}
/**
* br_locate_prefix:
* symbol: A symbol that belongs to the app/library you want to locate.
* Returns: A prefix. This string should be freed when no longer needed.
*
* Locates the full path of the app/library that symbol belongs to, and return
* the prefix of that path, or NULL on error.
* Note that symbol cannot be a pointer to a function. That will not work.
*
* Example:
* --> This application is located in /usr/bin/foo
* br_locate_prefix (&argc); --> returns: "/usr"
*/
char *
br_locate_prefix (void *symbol)
{
char *path, *prefix;
br_return_val_if_fail (symbol != NULL, NULL);
path = br_locate (symbol);
if (!path) return NULL;
prefix = br_extract_prefix (path);
free (path);
return prefix;
}
/**
* br_prepend_prefix:
* symbol: A symbol that belongs to the app/library you want to locate.
* path: The path that you want to prepend the prefix to.
* Returns: The new path, or NULL on error. This string should be freed when no
* longer needed.
*
* Gets the prefix of the app/library that symbol belongs to. Prepend that prefix to path.
* Note that symbol cannot be a pointer to a function. That will not work.
*
* Example:
* --> The application is /usr/bin/foo
* br_prepend_prefix (&argc, "/share/foo/data.png"); --> Returns "/usr/share/foo/data.png"
*/
char *
br_prepend_prefix (void *symbol, char *path)
{
char *tmp, *newpath;
br_return_val_if_fail (symbol != NULL, NULL);
br_return_val_if_fail (path != NULL, NULL);
tmp = br_locate_prefix (symbol);
if (!tmp) return NULL;
if (strcmp (tmp, "/") == 0)
newpath = strdup (path);
else
newpath = g_strconcat (tmp, path, NULL);
free (tmp);
return newpath;
}
#endif /* ENABLE_BINRELOC */
/*
* BinReloc - a library for creating relocatable executables
* Written by: Mike Hearn <mike@theoretic.com>
* Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*
* NOTE: if you're using C++ and are getting "undefined reference
* to br_*", try renaming prefix.c to prefix.cpp
*/
#ifndef _PREFIX_H_
#define _PREFIX_H_
/*
* enrico - all the code below is only compiled and used if ENABLE_BINRELOC is set in config.h,
* this only happens if configure option --enable-binreloc was used
*/
#ifdef ENABLE_BINRELOC
/* WARNING, BEFORE YOU MODIFY PREFIX.C:
*
* If you make changes to any of the functions in prefix.c, you MUST
* change the BR_NAMESPACE macro.
* This way you can avoid symbol table conflicts with other libraries
* that also happen to use BinReloc.
*
* Example:
* #define BR_NAMESPACE(funcName) foobar_ ## funcName
* --> expands br_locate to foobar_br_locate
*/
#undef BR_NAMESPACE
#define BR_NAMESPACE(funcName) geany_ ## funcName
#define br_thread_local_store BR_NAMESPACE(br_thread_local_store)
#define br_locate BR_NAMESPACE(br_locate)
#define br_locate_prefix BR_NAMESPACE(br_locate_prefix)
#define br_prepend_prefix BR_NAMESPACE(br_prepend_prefix)
#ifndef BR_NO_MACROS
/* These are convience macros that replace the ones usually used
in Autoconf/Automake projects */
#undef SELFPATH
#undef PREFIX
#undef PREFIXDIR
#undef BINDIR
#undef SBINDIR
#undef DATADIR
#undef LIBDIR
#undef LIBEXECDIR
#undef ETCDIR
#undef SYSCONFDIR
#undef CONFDIR
#undef LOCALEDIR
#define SELFPATH (br_thread_local_store (br_locate ((void *) "")))
#define PREFIX (br_thread_local_store (br_locate_prefix ((void *) "")))
#define PREFIXDIR (br_thread_local_store (br_locate_prefix ((void *) "")))
#define BINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/bin")))
#define SBINDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/sbin")))
#define DATADIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share")))
#define LIBDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/lib")))
#define LIBEXECDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/libexec")))
#define ETCDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc")))
#define SYSCONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc")))
#define CONFDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/etc")))
#define LOCALEDIR (br_thread_local_store (br_prepend_prefix ((void *) "", "/share/locale")))
#endif /* BR_NO_MACROS */
/* The following functions are used internally by BinReloc
and shouldn't be used directly in applications. */
const char *br_thread_local_store (char *str);
char *br_locate (void *symbol);
char *br_locate_prefix (void *symbol);
char *br_prepend_prefix (void *symbol, char *path);
#endif /* ENABLE_BINRELOC */
#endif /* _PREFIX_H_ */
......@@ -34,6 +34,7 @@
#include <string.h>
#include <stdlib.h>
#include "prefix.h"
#include "symbols.h"
#include "utils.h"
#include "filetypes.h"
......@@ -463,12 +464,16 @@ tag_list_add_groups(GtkTreeStore *tree_store, ...)
if (icon_theme == NULL)
{
#ifndef G_OS_WIN32
gchar *path = g_strconcat(DATADIR, "/icons", NULL);
#endif
gtk_icon_size_lookup(GTK_ICON_SIZE_MENU, &x, &y);
icon_theme = gtk_icon_theme_get_default();
#ifdef G_OS_WIN32
gtk_icon_theme_append_search_path(icon_theme, "share\\icons");
#else
gtk_icon_theme_append_search_path(icon_theme, PACKAGE_DATA_DIR "/icons");
gtk_icon_theme_append_search_path(icon_theme, path);
g_free(path);
#endif
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment