File: chap-Listaller-App-Development.html

package info (click to toggle)
listaller 0.5.9-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 8,096 kB
  • ctags: 1,611
  • sloc: xml: 11,195; ansic: 2,298; sh: 1,648; perl: 1,452; cpp: 1,289; java: 157; makefile: 134; cs: 48; python: 24
file content (298 lines) | stat: -rw-r--r-- 28,802 bytes parent folder | download
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&lt;</span>/div<span class="perl_Operator">&gt;</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">&lt;</span>/div<span class="perl_Operator">&gt;</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 &lt;stdio.h&gt;</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 (&amp;error) == 0 &amp;&amp; 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 &amp; run
				</div><div class="para">
					Now it is time to compile &amp; 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);&lt;/pre&gt;

</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 &lt;span class="highlight"&gt;\
              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()-&gt;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()-&gt;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>