GetModuleFilename()
to obtain their full path.
GetModuleFilename()
. For executables, you can still find your full location by resolving the symlink /proc/self/exe
, but that won't work for libraries.
KStandardDirs
class. If your application uses KStandardDirs
to lookup data files, your application will be automatically relocatable, so using BinReloc is not necessary. Libraries however will not benefit from this, and must use BinReloc directly.
binreloc-2.0
appears.
[joe@localhost /home/joe]$ tar xzf binreloc-2.0.tar.gz [joe@localhost /home/joe]$ cd binreloc-2.0</div>
[joe@localhost /home/joe/binreloc-2.0]$ ./generate.pl normal Source code written to 'binreloc.c' Header written to 'binreloc.h' [joe@localhost /home/joe/binreloc-2.0]$ mkdir ~/helloworld [joe@localhost /home/joe/binreloc-2.0]$ mv binreloc.c binreloc.h ~/helloworld/</div>
#include <stdio.h> #include "binreloc.h" #ifndef NULL #define NULL ((void *) 0) #endif int main () { BrInitError error; if (br_init (&error) == 0 && error != BR_INIT_ERROR_DISABLED) { printf ("Warning: BinReloc failed to initialize (error code %d)\n", error); printf ("Will fallback to hardcoded default path.\n"); } printf ("The full path of this application is: %s\n", br_find_exe ("default fallback path")); return 0; }
/home/joe/helloworld/hello.c
.
[joe@localhost /home/joe/helloworld]$ gcc -DENABLE_BINRELOC hello.c binreloc.c -o hello
[joe@localhost /home/joe/helloworld]$ ./hello
The full path of this application is: /home/joe/helloworld/hello
-DENABLE_BINRELOC
argument enables BinReloc support. BinReloc is only enabled if this macro is defined. Let's take a look at what happens if the macro is not defined:
[joe@localhost /home/joe/helloworld]$ gcc hello.c binreloc.c -o hello
[joe@localhost /home/joe/helloworld]$ ./hello
The full path of this application is: default fallback path
br_init()
. The definition is:
int br_init (BrInitError *error);
error
. The following error codes are available:
typedef enum { /* Cannot allocate memory. */ BR_INIT_ERROR_NOMEM, /* Unable to open /proc/self/maps; see errno for details. */ BR_INIT_ERROR_OPEN_MAPS, /* Unable to read from /proc/self/maps; see errno for details. */ BR_INIT_ERROR_READ_MAPS, /* The file format of /proc/self/maps is invalid; kernel bug? */ BR_INIT_ERROR_INVALID_MAPS, /* BinReloc is disabled. */ BR_INIT_ERROR_DISABLED } BrInitError;
br_init_lib()
. The definition is: int br_init_lib (BrInitError *error);
ENABLE_BINRELOC
is not defined), or because the application is running on a platform which doesn't support relocating executables (non-Linux platforms).
br_find_exe()
. Here is a list of all relocation functions:
Function | Returns |
---|---|
br_find_exe()
|
The full path of your application or library.
|
br_find_exe_dir()
|
The folder in which your application or library is located.
|
br_find_prefix()
|
The prefix in which your application or library is located. This function assumes that your binary is located inside an FHS-compatible directory structure (
$prefix/bin/ or $prefix/lib/ ). Examples:
So basically, it returns dirname(executable_filename) + "/.."
|
br_find_bin_dir()
|
PREFIX + "/bin"
|
br_find_sbin_dir()
|
PREFIX + "/sbin"
|
br_find_data_dir()
|
PREFIX + "/share"
|
br_find_locale_dir()
|
PREFIX + "/locale"
|
br_find_lib_dir()
|
PREFIX + "/lib"
|
br_find_libexec_dir()
|
PREFIX + "/libexec"
|
br_find_etc_dir()
|
PREFIX + "/etc"
|
char *br_find_something (const char *default_path);
default_path
is used as fallback: if the BinReloc isn't initialized, or failed to initialize, then a copy of default_path will be returned. Or if the default_path is NULL, NULL will be returned.
binreloc.c
if you need more info about a certain function.
[joe@localhost /home/joe/binreloc-2.0]$ ./generate.pl glib Source code written to 'binreloc.c' Header written to 'binreloc.h'
char *br_strcat (const char *str1, const char *str2);
char *datafile; datafile = br_strcat ("/usr", "/foo/mydata.txt"); load_data_file (datafile); free (datafile);</pre>
Makefile.am
:
INCLUDES = $(LIBGLADE_CFLAGS) \ -DDATADIR=\"$(datadir)\" bin_PROGRAMS = foo foo_SOURCES = main.c
main.c
:
xml = glade_xml_new (DATADIR "/foobar/glade/main.glade", NULL, NULL);
binreloc.m4
). This file can be found in the BinReloc SDK.
binreloc.m4
to acinclude.m4
(which is in the same folder as configure.in
). Create acinclude.m4
if it doesn't exist.
configure.in
, put the command AM_BINRELOC
somewhere.
AM_BINRELOC
macro checks whether BinReloc should be enabled (whether the system supports the feature, whether the user explicitly disabled it, etc). The variable $br_cv_binreloc
will be set to 'yes' if BinReloc is enabled, or 'no' otherwise.
binreloc.c
and binreloc.h
to your source code directory.
BINRELOC_CFLAGS
and binreloc.c/binreloc.h
to Makefile.am
:
AM_CPPFLAGS = $(BINRELOC_CFLAGS) ... foo_SOURCES = main.c <span class="highlight">\ binreloc.h \ binreloc.c
main.c
, add:
#include "binreloc.h"
main.c
:
gchar *dir, *file;
gbr_init (NULL);
dir = br_find_data_dir (DEFAULT_DATA_DIR);
file = g_strdup_printf ("%s/foobar/glade/main.glade", dir);
g_free (dir);
xml = glade_xml_new (file, NULL, NULL);
g_free (file);
/proc/self/maps
is available.
KStandardDirs
class. If your application uses KStandardDirs
to lookup data files, your application will be automatically relocatable, so using BinReloc is not necessary. Libraries however will not benefit from this, and must use BinReloc directly.
KGlobal::dirs()->addPrefix(br_find_prefix(DEFAULT_PREFIX));
KGlobal::dirs()
to lookup data files througout your entire program. If you create new instances of KStandardDirs
, you need the re-add the prefix.
KIconLoader
to load icons from whever your program is installed, add this:
KGlobal::iconLoader()->addAppDir(br_find_data_dir(DEFAULT_DATA_DIR));
contrib/binreloc/tests
folder in the Listaller source tarball contains more examples about how to use BinReloc.