1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>Chapter 3. Developing Listaller-ready applications</title><link rel="stylesheet" type="text/css" href="Common_Content/css/default.css" /><link rel="stylesheet" media="print" href="Common_Content/css/print.css" type="text/css" /><meta name="generator" content="publican 2.8" /><meta name="package" content="Listaller-Listaller-0.5.8-en-US-1-0" /><link rel="home" href="index.html" title="Listaller" /><link rel="up" href="index.html" title="Listaller" /><link rel="prev" href="sect-Listaller-Enduser-AppRemoval.html" title="2.2. Removing IPK packages" /><link rel="next" href="sect-Listaller-App-Development-Ligcc.html" title="3.2. The Ligcc tools" /></head><body><p id="title"><a class="left" href="http://listaller.tenstral.net"><img src="Common_Content/images/image_left.png" alt="Product Site" /></a><a class="right" href="http://listaller.tenstral.net/docs"><img src="Common_Content/images/image_right.png" alt="Documentation Site" /></a></p><ul class="docnav"><li class="previous"><a accesskey="p" href="sect-Listaller-Enduser-AppRemoval.html"><strong>Prev</strong></a></li><li class="next"><a accesskey="n" href="sect-Listaller-App-Development-Ligcc.html"><strong>Next</strong></a></li></ul><div xml:lang="en-US" class="chapter" id="chap-Listaller-App-Development" lang="en-US"><div class="titlepage"><div><div><h2 class="title">Chapter 3. Developing Listaller-ready applications</h2></div></div></div><div class="toc"><dl><dt><span class="section"><a href="chap-Listaller-App-Development.html#sect-Listaller-App-Development-Relocation">3.1. Guide to making relocatable applications</a></span></dt><dd><dl><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-problem">3.1.1. The problem</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-solution">3.1.2. The solution</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-helloworld">3.1.3. Hello World!</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-init">3.1.4. Initialization</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-basic">3.1.5. Basic usage</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-glib">3.1.6. GLib-style API</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-utility">3.1.7. Useful utility functions</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-autoconf">3.1.8. Autoconf/Automake build system integration</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-kde">3.1.9. KDE integration</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-api">3.1.10. Full API reference</a></span></dt><dt><span class="section"><a href="chap-Listaller-App-Development.html#relocation-more">3.1.11. More examples</a></span></dt></dl></dd><dt><span class="section"><a href="sect-Listaller-App-Development-Ligcc.html">3.2. The Ligcc tools</a></span></dt><dd><dl><dt><span class="section"><a href="sect-Listaller-App-Development-Ligcc.html#ligcc-whatis">3.2.1. What is ligcc?</a></span></dt><dt><span class="section"><a href="ligcc-howto.html">3.2.2. How to use ligcc?</a></span></dt></dl></dd><dt><span class="section"><a href="sect-Listaller-App-Development-RelayTool.html">3.3. Relaytool</a></span></dt><dd><dl><dt><span class="section"><a href="sect-Listaller-App-Development-RelayTool.html#relaytool-whatis">3.3.1. What is Relaytool?</a></span></dt><dt><span class="section"><a href="relaytool-howto.html">3.3.2. How to use Relaytool?</a></span></dt></dl></dd></dl></div><div class="para">
We created several standalone tools, the libuild programs, that are designed to help Linux developers write better software that runs on a wider variety of distributions. Most of them are independent of Listaller itself: you can use them even if you don't provide your software using the rest of our software.
</div><div xml:lang="en-US" class="section" id="sect-Listaller-App-Development-Relocation" lang="en-US"><div class="titlepage"><div><div><h2 class="title" id="sect-Listaller-App-Development-Relocation">3.1. Guide to making relocatable applications</h2></div></div></div><div class="section" id="relocation-problem"><div class="titlepage"><div><div><h3 class="title" id="relocation-problem">3.1.1. The problem</h3></div></div></div><div class="para">
Listaller supports relocation. This means that a package can be installed to any location, like how Win32 installers let you choose a directory. However, most applications are not relocatable. The paths where in they search for data files are usually hardd at compile time.
</div><div class="para">
On Win32, applications and libraries are easily relocatable because applications and DLLs can use <code class="code">GetModuleFilename()</code> to obtain their full path.
</div><div class="para">
On Linux however, no easy mechanisms exist. There is no function equivalent to <code class="code">GetModuleFilename()</code>. For executables, you can still find your full location by resolving the symlink <code class="filename">/proc/self/exe</code>, but that won't work for libraries.
</div></div><div class="section" id="relocation-solution"><div class="titlepage"><div><div><h3 class="title" id="relocation-solution">3.1.2. The solution</h3></div></div></div><div class="para">
This is why we have developed <span class="application"><strong>BinReloc</strong></span>. BinReloc provides an easy-to-use API that uses dynamic linker and kernel magic to find out the full path of your application or library.
</div><div class="itemizedlist"><h6>Highlights</h6><ul><li class="listitem"><div class="para">
It can be statically included in your project.
</div></li><li class="listitem"><div class="para">
It's small, only about 20 KB of C source code (I suspect it's only about 10 KB if you remove all the inline documentation comments).
</div></li><li class="listitem"><div class="para">
It has absolutely no dependancies other than libc.
</div></li><li class="listitem"><div class="para">
It's <span class="emphasis"><em>public domain</em></span>, which means you can do anything you want with the code, including relicensing it under a different license.
</div></li><li class="listitem"><div class="para">
Portability to other operating systems will not be affected: BinReloc will fallback to hardcoded paths if it's running on an operating system which has no executable relocation features. You can also completely disable BinReloc with one simple macro, making your program behave exactly like when you were using hardcoded paths.
</div></li><li class="listitem"><div class="para">
There are two versions of BinReloc: a plain C version, and glib version which even has a glib-style API.
</div></li></ul></div><div class="note"><div class="admonition_header"><h2>Tip for KDE developers</h2></div><div class="admonition"><div class="para">
As of April 21 2004, BinReloc-like functionality has been added to the KDE-libs, in the <code class="code">KStandardDirs</code> class. If your application uses <code class="code">KStandardDirs</code> 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.
</div></div></div></div><div class="section" id="relocation-helloworld"><div class="titlepage"><div><div><h3 class="title" id="relocation-helloworld">3.1.3. Hello World!</h3></div></div></div><div class="para">
Let's begin with a BinReloc "Hello World" tutorial. We will use the <span class="emphasis"><em>plain C</em></span> version of BinReloc. The glib version's API is only slightly different from the plain C API, so don't worry about the API differences. In this tutorial, our imaginary developer, Joe, will show you everything he does when writing the <span class="application"><strong>Hello World</strong></span> program.
</div><div class="procedure"><ol class="1"><li class="step"><div class="para">
Generate BinReloc source files
</div><div class="para">
Joe <a href="http://listaller.tenstral.net">downloads the BinReloc SDK</a> from the <span class="emphasis"><em>Listaller Tools</em></span> section of the download page. He extracts the archive in his home folder. A folder called <code class="filename">binreloc-2.0</code> appears.
</div><pre class="programlisting">[joe@localhost /home/joe]$ <span class="perl_BString">tar</span> xzf binreloc-2.0.<span class="perl_BString">tar</span>.gz
[joe@localhost /home/joe]$ <span class="perl_Reserved">cd</span> binreloc-2.<span class="perl_Operator">0<</span>/div<span class="perl_Operator">></span>
</pre><div class="para">
Joe's Hello World program doesn't use glib, so he wants the plain C version of BinReloc. Joe runs the following commands to generate the BinReloc source files:
</div><pre class="programlisting">[joe@localhost /home/joe/binreloc-2.0]$ ./generate.pl normal
<span class="perl_Reserved">Source</span> code written to <span class="perl_String">'binreloc.c'</span>
Header written to <span class="perl_String">'binreloc.h'</span>
[joe@localhost /home/joe/binreloc-2.0]$ <span class="perl_BString">mkdir</span> ~/helloworld
[joe@localhost /home/joe/binreloc-2.0]$ <span class="perl_BString">mv</span> binreloc.c binreloc.h ~/helloworld/<span class="perl_Operator"><</span>/div<span class="perl_Operator">></span>
</pre></li><li class="step"><div class="para">
Write the program
</div><div class="para">
Now that Joe has generated the BinReloc source files, he continues with writing a Hello World program:
</div><pre class="programlisting"><span class="perl_Others">#include <stdio.h></span><span class="perl_Others"></span>
<span class="perl_Others"></span><span class="perl_Others">#include "binreloc.h"</span><span class="perl_Others"></span>
<span class="perl_Others"></span><span class="perl_Others">#ifndef NULL</span><span class="perl_Others"></span>
<span class="perl_Others"></span> <span class="perl_Others">#define NULL ((void *) 0)</span><span class="perl_Others"></span>
<span class="perl_Others"></span><span class="perl_Others">#endif</span><span class="perl_Others"></span>
<span class="perl_Others"></span>
<span class="perl_DataType">int</span> main () {
BrInitError error;
<span class="perl_Keyword">if</span> (br_init (&error) == 0 && error != BR_INIT_ERROR_DISABLED) {
printf (<span class="perl_String">"Warning: BinReloc failed to initialize (error code %d)</span><span class="perl_Char">\n</span><span class="perl_String">"</span>, error);
printf (<span class="perl_String">"Will fallback to hardcoded default path.</span><span class="perl_Char">\n</span><span class="perl_String">"</span>);
}
printf (<span class="perl_String">"The full path of this application is: %s</span><span class="perl_Char">\n</span><span class="perl_String">"</span>, br_find_exe (<span class="perl_String">"default fallback path"</span>));
<span class="perl_Keyword">return</span> 0;
}
</pre><div class="para">
He saves this file as <code class="filename">/home/joe/helloworld/hello.c</code>.
</div></li><li class="step"><div class="para">
Compile & run
</div><div class="para">
Now it is time to compile & run the program:
</div><pre class="programlisting">[joe@localhost /home/joe/helloworld]$ <span class="perl_BString">gcc</span> -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
</pre><div class="para">
Yes, it's this easy!
</div><div class="note"><div class="admonition_header"><h2>How to disable BinReloc</h2></div><div class="admonition"><div class="para">
The <code class="code">-DENABLE_BINRELOC</code> 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:
</div><pre class="programlisting">[joe@localhost /home/joe/helloworld]$ <span class="perl_BString">gcc</span> hello.c binreloc.c -o hello
[joe@localhost /home/joe/helloworld]$ ./hello
The full path of this application is: default fallback path
</pre></div></div></li></ol></div></div><div class="section" id="relocation-init"><div class="titlepage"><div><div><h3 class="title" id="relocation-init">3.1.4. Initialization</h3></div></div></div><div class="para">
BinReloc <span class="emphasis"><em>must</em></span> be initialize by calling one of the BinReloc initialization functions:
</div><div class="para">
If you're using BinReloc in an application, then call <code class="code">br_init()</code>. The definition is:
</div><pre class="programlisting">int br_init <span class="perl_Keyword">(</span>BrInitError *error<span class="perl_Keyword">)</span>;</pre><div class="para">
This function returns 1 on success, and 0 if BinReloc failed to initialize. If BinReloc failed to initialize, then the error code will be stored in <code class="code">error</code>. The following error codes are available:
</div><pre class="programlisting">typedef enum <span class="perl_Keyword">{</span>
/* Cannot allocate memory. */
BR_INIT_ERROR_NOMEM,
/* Unable to open /proc/self/maps; see errno <span class="perl_Keyword">for</span> details. */
BR_INIT_ERROR_OPEN_MAPS,
/* Unable to <span class="perl_Reserved">read</span> <span class="perl_Others">from</span> /proc/self/<span class="perl_Others">maps</span>; see errno <span class="perl_Keyword">for</span> details. */
BR_INIT_ERROR_READ_MAPS,
/* The <span class="perl_BString">file</span> format of /proc/self/maps is invalid; kernel bug? */
BR_INIT_ERROR_INVALID_MAPS,
/* BinReloc is disabled. */
BR_INIT_ERROR_DISABLED
<span class="perl_Keyword">}</span> BrInitError;
</pre><div class="para">
If you're using BinReloc in a library, then call <code class="code">br_init_lib()</code>. The definition is: <code class="code">int br_init_lib (BrInitError *error);</code>
</div><div class="para">
This function returns 1 on success, and 0 if BinReloc failed to initialize.
</div><div class="para">
If you don't initialize BinReloc, or if initialization failed, then all BinReloc functions will return the fallback paths, so even if initialization failed, it's not fatal. Initialization will fail if BinReloc is disabled (because <code class="code">ENABLE_BINRELOC</code> is not defined), or because the application is running on a platform which doesn't support relocating executables (non-Linux platforms).
</div></div><div class="section" id="relocation-basic"><div class="titlepage"><div><div><h3 class="title" id="relocation-basic">3.1.5. Basic usage</h3></div></div></div><div class="para">
There are more functions besides <code class="code">br_find_exe()</code>. Here is a list of all relocation functions:
</div><div class="table"><h6>Table 3.1. Relocation functions</h6><div class="table-contents"><table summary="Relocation functions" border="1"><colgroup><col width="50%" /><col width="50%" /></colgroup><thead><tr><th>
Function
</th><th>
Returns
</th></tr></thead><tbody><tr><td>
<div class="para">
<code class="code">br_find_exe()</code>
</div>
</td><td>
<div class="para">
The full path of your application or library.
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_exe_dir()</code>
</div>
</td><td>
<div class="para">
The folder in which your application or library is located.
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_prefix()</code>
</div>
</td><td>
<div class="para">
The prefix in which your application or library is located. This function assumes that your binary is located inside an FHS-compatible directory structure (<code class="filename">$prefix/bin/</code> or <code class="filename">$prefix/lib/</code>). Examples:
</div>
<div class="itemizedlist"><ul><li class="listitem"><div class="para">
Your binary is <code class="filename">/usr/bin/foo</code>. It will return <code class="filename">/usr</code>.
</div></li><li class="listitem"><div class="para">
Your library is <code class="filename">/usr/local/lib/libfoo.so</code>. It will return <code class="filename">/usr/local</code>.
</div></li><li class="listitem"><div class="para">
Your binary is <code class="filename">/Applications/CoolApp2040XP/CoolApp</code>. It will return <code class="filename">/Applications"</code>.
</div></li></ul></div>
<div class="para">
So basically, it returns <span class="emphasis"><em>dirname(executable_filename) + "/.."</em></span>
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_bin_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/bin"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_sbin_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/sbin"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_data_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/share"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_locale_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/locale"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_lib_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/lib"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_libexec_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/libexec"
</div>
</td></tr><tr><td>
<div class="para">
<code class="code">br_find_etc_dir()</code>
</div>
</td><td>
<div class="para">
PREFIX + "/etc"
</div>
</td></tr></tbody></table></div></div><br class="table-break" /><div class="para">
All functions in the above table are declared like this: <code class="code">char *br_find_something (const char *default_path);</code>
</div><div class="para">
<code class="code">default_path</code> 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.
</div><div class="warning"><div class="admonition_header"><h2>Warning</h2></div><div class="admonition"><div class="para">
Note that the return values of all of the above functions must be freed when no longer necessary, except if the return value is NULL.
</div></div></div><div class="para">
<span class="emphasis"><em>All</em></span> BinReloc functions have inline documentation! So just take a look at <code class="filename">binreloc.c</code> if you need more.metainfo.about a certain function.
</div></div><div class="section" id="relocation-glib"><div class="titlepage"><div><div><h3 class="title" id="relocation-glib">3.1.6. GLib-style API</h3></div></div></div><div class="para">
There's also a BinReloc version with a glib-style API. Generating this version is just like generating the normal version:
</div><pre class="programlisting">[joe@localhost /home/joe/binreloc-2.0]$ ./generate.pl glib
<span class="perl_Reserved">Source</span> code written to <span class="perl_String">'binreloc.c'</span>
Header written to <span class="perl_String">'binreloc.h'</span>
</pre><div class="para">
The API is almost identical to the plain C version, except that it uses glib-style names and glib data types, such as GError. See <a href="http://listaller.tenstral.net">the full API reference</a>.
</div></div><div class="section" id="relocation-utility"><div class="titlepage"><div><div><h3 class="title" id="relocation-utility">3.1.7. Useful utility functions</h3></div></div></div><div class="para">
The plain C version of BinReloc provides some utility functions for modifying strings and paths, because many applications will need such functionality. The GLib version doesn't contain these utility functions because GLib already has its own utility functions. Note that these utility functions are fully portable, and can be used even when BinReloc is not enabled/initialized.
</div><pre class="programlisting"><span class="perl_DataType">char</span> *br_strcat (<span class="perl_DataType">const</span> <span class="perl_DataType">char</span> *str1, <span class="perl_DataType">const</span> <span class="perl_DataType">char</span> *str2);</pre><div class="itemizedlist"><ul><li class="listitem"><div class="para">
str1: A string.
</div></li><li class="listitem"><div class="para">
str2: Another string.
</div></li><li class="listitem"><div class="para">
Returns: A newly-allocated string. This string should be freed when no longer needed.
</div></li></ul></div><div class="para">
Concatenate str1 and str2 to a newly allocated string.
</div><div class="para">
Example:
</div><pre class="programlisting"><span class="perl_DataType">char</span> *datafile;
datafile = br_strcat (<span class="perl_String">"/usr"</span>, <span class="perl_String">"/foo/mydata.txt"</span>);
load_data_file (datafile);
free (datafile);</pre>
</pre></div><div class="section" id="relocation-autoconf"><div class="titlepage"><div><div><h3 class="title" id="relocation-autoconf">3.1.8. Autoconf/Automake build system integration</h3></div></div></div><div class="para">
Most Autoconf/Automake projects use macros that define a hardcoded path. Let's take a look at this piece of code as example.
</div><div class="para">
In <code class="filename">Makefile.am</code>:
</div><pre class="programlisting">INCLUDES = $(LIBGLADE_CFLAGS) \
-DDATADIR=\"$(datadir)\"
bin_PROGRAMS = foo
foo_SOURCES = main.c
</pre><div class="para">
In <code class="filename">main.c</code>:
</div><pre class="programlisting">xml = glade_xml_new (DATADIR <span class="perl_String">"/foobar/glade/main.glade"</span>, NULL, NULL);</pre><div class="para">
How to use BinReloc:
</div><div class="procedure"><ol class="1"><li class="step"><div class="para">
Use the special BinReloc Autoconf Macro (<code class="filename">binreloc.m4</code>). This file can be found in the <a href="http://listaller.tenstral.net">BinReloc SDK</a>.
</div><div class="para">
Append the contents of <code class="filename">binreloc.m4</code> to <code class="filename">acinclude.m4</code> (which is in the same folder as <code class="filename">configure.in</code>). Create <code class="filename">acinclude.m4</code> if it doesn't exist.
</div><div class="para">
In <code class="filename">configure.in</code>, put the command <code class="code">AM_BINRELOC</code> somewhere.
</div><div class="para">
The <code class="literal">AM_BINRELOC</code> macro checks whether BinReloc should be enabled (whether the system supports the feature, whether the user explicitly disabled it, etc). The variable <code class="code">$br_cv_binreloc</code> will be set to 'yes' if BinReloc is enabled, or 'no' otherwise.
</div></li><li class="step"><div class="para">
Copy <code class="filename">binreloc.c</code> and <code class="filename">binreloc.h</code> to your source code directory.
</div></li><li class="step"><div class="para">
Add <code class="code">BINRELOC_CFLAGS</code> and <code class="filename">binreloc.c/binreloc.h</code> to <code class="filename">Makefile.am</code>:
</div><pre class="programlisting">
AM_CPPFLAGS = $(BINRELOC_CFLAGS)
...
foo_SOURCES = main.c <span class="highlight">\
binreloc.h \
binreloc.c
</pre></li><li class="step"><div class="para">
At the beginning of <code class="filename">main.c</code>, add:
</div><pre class="programlisting"><span class="perl_Others">#include "binreloc.h"</span></pre><div class="para">
Somewhere in <code class="filename">main.c</code>:
</div><pre class="programlisting">
gchar *dir, *file;
gbr_init (NULL);
dir = br_find_data_dir (DEFAULT_DATA_DIR);
file = g_strdup_printf (<span class="perl_String">"%s/foobar/glade/main.glade"</span>, dir);
g_free (dir);
xml = glade_xml_new (file, NULL, NULL);
g_free (file);
</pre></li></ol></div><div class="para">
And that was it! Your configure script will now have a <span class="emphasis"><em>--enable-binreloc=[yes/no/auto]</em></span> option. The default value for this option is <span class="emphasis"><em>--enable-binreloc=auto</em></span>, which will automatically check whether BinReloc support is desired. It does so by checking for the following things:
</div><div class="itemizedlist"><ul><li class="listitem"><div class="para">
Whether <code class="filename">/proc/self/maps</code> is available.
</div></li><li class="listitem"><div class="para">
Whether the user told configure to use a different location for a specific directory, such as by passing <span class="emphasis"><em>--bindir=/foo/bin</em></span>.
</div></li></ul></div><div class="para">
Users can always disable BinReloc manually by passing <span class="emphasis"><em>--disable-binreloc</em></span> to the <span class="emphasis"><em>configure</em></span> script.
</div></div><div class="section" id="relocation-kde"><div class="titlepage"><div><div><h3 class="title" id="relocation-kde">3.1.9. KDE integration</h3></div></div></div><div class="note"><div class="admonition_header"><h2>Note to KDE developers</h2></div><div class="admonition"><div class="para">
As of April 21 2004, BinReloc-like functionality has been added to the KDE-libs, in the <code class="code">KStandardDirs</code> class. If your <span class="emphasis"><em>application</em></span> uses <code class="code">KStandardDirs</code> 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.
</div></div></div><div class="para">
In your program's initialization function, add the following code:
</div><pre class="programlisting">KGlobal::dirs()->addPrefix(br_find_prefix(DEFAULT_PREFIX));</pre><div class="para">
Make sure you use <code class="code">KGlobal::dirs()</code> to lookup data files througout your entire program. If you create new instances of <code class="code">KStandardDirs</code>, you need the re-add the prefix.
</div><div class="para">
If you want to use <code class="code">KIconLoader</code> to load icons from whever your program is installed, add this:
</div><pre class="programlisting">KGlobal::iconLoader()->addAppDir(br_find_data_dir(DEFAULT_DATA_DIR));</pre></div><div class="section" id="relocation-api"><div class="titlepage"><div><div><h3 class="title" id="relocation-api">3.1.10. Full API reference</h3></div></div></div><div class="para">
... will be available very soon!
</div></div><div class="section" id="relocation-more"><div class="titlepage"><div><div><h3 class="title" id="relocation-more">3.1.11. More examples</h3></div></div></div><div class="para">
The <code class="filename">contrib/binreloc/tests</code> folder in the Listaller source tarball contains more examples about how to use BinReloc.
</div></div></div></div><ul class="docnav"><li class="previous"><a accesskey="p" href="sect-Listaller-Enduser-AppRemoval.html"><strong>Prev</strong>2.2. Removing IPK packages</a></li><li class="up"><a accesskey="u" href="#"><strong>Up</strong></a></li><li class="home"><a accesskey="h" href="index.html"><strong>Home</strong></a></li><li class="next"><a accesskey="n" href="sect-Listaller-App-Development-Ligcc.html"><strong>Next</strong>3.2. The Ligcc tools</a></li></ul></body></html>
|