1 | .. SPDX-License-Identifier: CC-BY-SA-4.0 |
---|
2 | |
---|
3 | .. Copyright (C) 2016 Chris Johns <chrisj@rtems.org> |
---|
4 | |
---|
5 | .. _TraceLinker: |
---|
6 | |
---|
7 | Trace Linker |
---|
8 | ************ |
---|
9 | |
---|
10 | RTEMS trace linker is a post link tool central to the RTEMS trace framework. It |
---|
11 | is installed as a part of the RTEMS Tool Project. The RTEMS Trace Linker is a |
---|
12 | post link tool that performs a re-link of your application to produce a trace |
---|
13 | executable. A trace executable has been instrumented by the RTEMS Trace Linker |
---|
14 | with additional code that implements software tracing. A key requirement of the |
---|
15 | trace process in RTEMS is to take existing code in a compiled format (ELF) and |
---|
16 | instrument it without rebuilding that code from source and without annotating |
---|
17 | that source with trace code. |
---|
18 | |
---|
19 | Command Line |
---|
20 | ============ |
---|
21 | |
---|
22 | A typical command to invoke the trace linker consists of two parts separated by |
---|
23 | ``--``. The first part controls the trace linker and provides the various |
---|
24 | options it needs and the second part is a standard linker command line you would |
---|
25 | use to link an RTEMS application. The current command line for trace linker |
---|
26 | consists of: |
---|
27 | |
---|
28 | .. code-block:: shell |
---|
29 | |
---|
30 | $ rtems-tld -h |
---|
31 | rtems-trace-ld [options] objects |
---|
32 | Options and arguments: |
---|
33 | -h : help (also --help) |
---|
34 | -V : print linker version number and exit (also --version) |
---|
35 | -v : verbose (trace import parts), can supply multiple times |
---|
36 | to increase verbosity (also --verbose) |
---|
37 | -w : generate warnings (also --warn) |
---|
38 | -k : keep temporary files (also --keep) |
---|
39 | -c compiler : target compiler is not standard (also --compiler) |
---|
40 | -l linker : target linker is not standard (also --linker) |
---|
41 | -E prefix : the RTEMS tool prefix (also --exec-prefix) |
---|
42 | -f cflags : C compiler flags (also --cflags) |
---|
43 | -r path : RTEMS path (also --rtems) |
---|
44 | -B bsp : RTEMS arch/bsp (also --rtems-bsp) |
---|
45 | -W wrapper : wrapper file name without ext (also --wrapper) |
---|
46 | -C ini : user configuration INI file (also --config) |
---|
47 | -P path : user configuration INI file search path (also --path) |
---|
48 | |
---|
49 | The trace linker generates code that needs to be compiled and linked to the |
---|
50 | application executable so it needs to know the target compiler and `CFLAGS`. |
---|
51 | There are a couple of ways to do this. The simplest is to provide the path to |
---|
52 | RTEMS using the `-r` option and the architecture and BSP name in the standard |
---|
53 | RTEMS format of arch/bsp. The trace linker will extract the compiler and flags |
---|
54 | used to build RTEMS and will use them. If you require specific options you can |
---|
55 | use the `-f`, `-c`, `-l`, and `-E` options to provide them. If the functions you |
---|
56 | are tracing use types from your code then add the include path to the `CFLAGS`. |
---|
57 | |
---|
58 | The trace linker requires you to provide a user configuration file using the |
---|
59 | `-C` or ``--config`` option. This is an INI format file detailed in the |
---|
60 | Configuration section. You can also provide an INI file search path using the |
---|
61 | `-P` option. |
---|
62 | |
---|
63 | If you are working with new configuration files and you want to view the files |
---|
64 | the trace linker generates, add the `-k` option to keep the temporary files, and |
---|
65 | `-W` to specify an explicit wrapper C file name. If you set the |
---|
66 | ``dump-on-error`` option in the configuration options section you will get a |
---|
67 | dump of the configuration on an error. |
---|
68 | |
---|
69 | Configuration (INI) files |
---|
70 | ========================= |
---|
71 | |
---|
72 | The Trace Linker is controlled using configuration files. Configuration files |
---|
73 | are categorized into 3 types: |
---|
74 | |
---|
75 | - User Configuration: These are specific to the user application to be traced. |
---|
76 | This file initializes the values of the trace generator, triggers, enables, |
---|
77 | and traces. |
---|
78 | |
---|
79 | - Tracer Configuration: These are like a library of common or base trace |
---|
80 | functions that can be referenced by an application. These files tend to hold |
---|
81 | the details needed to wrap a specific set of functions. Examples provided with |
---|
82 | the RTEMS Linker are the RTEMS API and Libc. |
---|
83 | |
---|
84 | - Generator Configuration: This is used to encapsulate a specific method of |
---|
85 | tracing. RTEMS currently provides generators for trace buffering, printk, and |
---|
86 | printf. |
---|
87 | |
---|
88 | The configuration files are in the *INI file format* which is composed of |
---|
89 | `sections`. Each section has a section name and set of *keys* which consist of |
---|
90 | *names* and *values*. A typical key is of the form ``name=value``. Keys can be |
---|
91 | used to include other INI files using the include key name. This is shown in the |
---|
92 | following example where the values indicate rtems and rtld-base configuration |
---|
93 | files: |
---|
94 | |
---|
95 | .. code-block:: ini |
---|
96 | |
---|
97 | include = rtems.ini, rtld-base.ini |
---|
98 | |
---|
99 | The trace linker also uses values in keys to specify other sections. In this |
---|
100 | example the functions name lists `test-trace-funcs` and that section contains a |
---|
101 | headers key that further references a section called `test-headers`: |
---|
102 | |
---|
103 | .. code-block:: ini |
---|
104 | |
---|
105 | functions = test-trace-funcs, rtems-api |
---|
106 | |
---|
107 | [test-trace-funcs] |
---|
108 | ; Parsed via the 'function-set', not parse as a 'trace'. |
---|
109 | headers = test-headers |
---|
110 | |
---|
111 | [test-headers] |
---|
112 | header = '#include "test-trace-1.h"' |
---|
113 | |
---|
114 | The format of a configuration file is explained next. Snippets of the file: |
---|
115 | `test-trace.ini` have been used for explicit understanding. This file can |
---|
116 | be found in the rtems-tools directory of the rtems installation. |
---|
117 | |
---|
118 | Tracer Section |
---|
119 | -------------- |
---|
120 | |
---|
121 | The topmost level section is the ``tracer`` section. It can contains the |
---|
122 | following keys: |
---|
123 | |
---|
124 | - ``name``: The name of trace being linked. |
---|
125 | |
---|
126 | - ``options``: A list of option sections. |
---|
127 | |
---|
128 | - ``defines``: A list of sections containing defines or define record. |
---|
129 | |
---|
130 | - ``define``: A list of define string that are single or double quoted. |
---|
131 | |
---|
132 | - ``enables``: The list of sections containing enabled functions to trace. |
---|
133 | |
---|
134 | - ``triggers``: The list of sections containing enabled functions to trigger |
---|
135 | trace on. |
---|
136 | |
---|
137 | - ``traces``: The list of sections containing function lists to trace. |
---|
138 | |
---|
139 | - ``functions``: The list of sections containing function details. |
---|
140 | |
---|
141 | - ``include``: The list of files to include. |
---|
142 | |
---|
143 | The tracer section of the file:`test-trace.ini` is shown below with explanatory |
---|
144 | comments. |
---|
145 | |
---|
146 | .. code-block:: ini |
---|
147 | |
---|
148 | ; |
---|
149 | ; RTEMS Trace Linker Test Configuration. |
---|
150 | ; |
---|
151 | ; We must provide a top level trace section. |
---|
152 | ; |
---|
153 | [tracer] |
---|
154 | ; |
---|
155 | ; Name of the trace. |
---|
156 | ; |
---|
157 | name = RTEMS Trace Linker Test |
---|
158 | ; |
---|
159 | ; The BSP. |
---|
160 | ; |
---|
161 | bsp = sparc/sis |
---|
162 | ; |
---|
163 | ; Functions to trace. |
---|
164 | ; |
---|
165 | traces = test-trace, test-trace-funcs, rtems-api-task |
---|
166 | ; |
---|
167 | ; Specify the options. |
---|
168 | ; |
---|
169 | options = test-options |
---|
170 | ; |
---|
171 | ; Define the function sets. These are the function's that can be |
---|
172 | ; added to the trace lists. |
---|
173 | ; |
---|
174 | functions = test-trace-funcs, rtems-api |
---|
175 | ; |
---|
176 | ; Include RTEMS Trace support. |
---|
177 | ; |
---|
178 | include = rtems.ini, rtld-base.ini |
---|
179 | |
---|
180 | Options section |
---|
181 | --------------- |
---|
182 | |
---|
183 | The options section in the fileio-trace.ini is called the `fileio-options`. A |
---|
184 | general options section can contain following sets of keys: |
---|
185 | |
---|
186 | - ``dump-on-error``: Dump the parsed configuration data on error. The value can |
---|
187 | be true or false. |
---|
188 | |
---|
189 | - ``verbose``: Set the verbose level. The value can be true or a number value. |
---|
190 | |
---|
191 | - ``prefix``: The prefix for the tools and an install RTEMS if rtems-path is not |
---|
192 | set. |
---|
193 | |
---|
194 | - ``cc``: The compiler used to compile the generated wrapper code. Overrides the |
---|
195 | BSP configuration value if a BSP is specified. |
---|
196 | |
---|
197 | - ``ld``: The linker used to link the application. The default is the cc value |
---|
198 | as read from the BSP configuration if specified. If your application contains |
---|
199 | C++ code use this setting to the change the linker to g++. |
---|
200 | |
---|
201 | - ``cflags``: Set the CFLAGS used to compiler the wrapper. These flags are |
---|
202 | pre-pended to the BSP read flags if a BSP is specified. This option is used |
---|
203 | to provide extra include paths to header files in your application that |
---|
204 | contain types referenced by functions being traced. |
---|
205 | |
---|
206 | - ``rtems-path``: The path to an install RTEMS if not installed under the |
---|
207 | prefix. |
---|
208 | |
---|
209 | - ``rtems-bsp``: The BSP we are building the trace executable for. The is an |
---|
210 | arch and bsp pair. For example sparc/erc32. |
---|
211 | |
---|
212 | The options section of the file: `test-trace.ini` uses two of the aforementioned |
---|
213 | keys as shown below: |
---|
214 | |
---|
215 | .. code-block:: ini |
---|
216 | |
---|
217 | ; |
---|
218 | ; Options can be defined here or on the command line. |
---|
219 | ; |
---|
220 | [test-options] |
---|
221 | prefix = /development/rtems/5 |
---|
222 | verbose = true |
---|
223 | |
---|
224 | Trace Section |
---|
225 | ------------- |
---|
226 | |
---|
227 | A trace section defines how trace wrapper functions are built. To build a trace |
---|
228 | function that wraps an existing function in an ELF object file or library |
---|
229 | archive we need to have the function's signature. A signature is the function's |
---|
230 | declaration with any types used. The signature has specific types and we need |
---|
231 | access to those types which means the wrapper code needs to include header files |
---|
232 | that define those types. There may also be specific defines needed to access |
---|
233 | those types. A trace section can contain the following keys: |
---|
234 | |
---|
235 | - ``generator``: The generator defines the type of tracing being used. |
---|
236 | |
---|
237 | - ``headers``: List of sections that contain header file's keys. |
---|
238 | |
---|
239 | - ``header``: A header key. Typically the include code. |
---|
240 | |
---|
241 | - ``defines``: List of sections that contain defines. |
---|
242 | |
---|
243 | - ``define``: A define key. Typically the define code. |
---|
244 | |
---|
245 | - ``signatures``: List of function signature sections. |
---|
246 | |
---|
247 | - ``trace``: Functions that are instrumented with trace code. |
---|
248 | |
---|
249 | The trace section of the file: `test-trace.ini` is shown below. A trace section |
---|
250 | can reference other trace sections of a specific type. This allows a trace |
---|
251 | sections to build on other trace sections. |
---|
252 | |
---|
253 | .. code-block:: ini |
---|
254 | |
---|
255 | ; User application trace example. |
---|
256 | ; |
---|
257 | [test-trace] |
---|
258 | generator = printf-generator |
---|
259 | ; Just here for testing. |
---|
260 | trace = test_trace_3 |
---|
261 | |
---|
262 | [test-trace-funcs] |
---|
263 | ; Parsed via the 'function-set', not parse as a 'trace'. |
---|
264 | headers = test-headers |
---|
265 | header = '#include "test-trace-2.h"' |
---|
266 | defines = test-defines |
---|
267 | define = "#define TEST_TRACE_2 2" |
---|
268 | signatures = test-signatures |
---|
269 | ; Parsed via the 'trace', not parsed as a function-set |
---|
270 | trace = test_trace_1, test_trace_2 |
---|
271 | |
---|
272 | [test-headers] |
---|
273 | header = '#include "test-trace-1.h"' |
---|
274 | |
---|
275 | [test-defines] |
---|
276 | define = "#define TEST_TRACE_1 1" |
---|
277 | |
---|
278 | [test-signatures] |
---|
279 | test_trace_1 = void, int |
---|
280 | test_trace_2 = test_type_2, test_type_1 |
---|
281 | test_trace_3 = float, float* |
---|
282 | |
---|
283 | Function Section |
---|
284 | ---------------- |
---|
285 | |
---|
286 | Function sections define functions that can be traced. Defining a function so it |
---|
287 | can be traced does not mean it is traced. The function must be added to a trace |
---|
288 | list to be traced. Function sections provide any required defines, header files, |
---|
289 | and the function signatures. |
---|
290 | |
---|
291 | A function signature is the function's declaration. It is the name of the |
---|
292 | function, the return value, and the arguments. Tracing using function wrappers |
---|
293 | requires that we have accurate function signatures and ideally we would like to |
---|
294 | determine the function signature from the data held in ELF files. ELF files can |
---|
295 | contain DWARF data, the ELF debugging data format. In time the trace project |
---|
296 | would like to support libdwarf so the DWARF data can be accessed and used to |
---|
297 | determine a function's signature. This work is planned but not scheduled to be |
---|
298 | done and so in the meantime we explicitly define the function signatures in the |
---|
299 | configuration files. |
---|
300 | |
---|
301 | A function section can consist of the following keys: |
---|
302 | |
---|
303 | - ``headers``: A list of sections containing headers or header records. |
---|
304 | - ``header``: A list of include string that are single or double quoted. |
---|
305 | - ``defines``: A list of sections containing defines or define record. |
---|
306 | - ``defines``: A list of define string that are single or double quoted. |
---|
307 | - ``signatures``: A list of section names of function signatures. |
---|
308 | - ``includes``: A list of files to include. |
---|
309 | |
---|
310 | Function signatures are specified with the function name being the key's name |
---|
311 | and the key's value being the return value and a list of function arguments. You |
---|
312 | need to provide void if the function uses void. Variable argument list are |
---|
313 | currently not supported. There is no way to determine statically a variable |
---|
314 | argument list. The function section in the file: `test-trace.ini` has been |
---|
315 | labeled as `test-trace-funcs`. This can be seen in the file snippet of the |
---|
316 | previous section. |
---|
317 | |
---|
318 | Generators |
---|
319 | ---------- |
---|
320 | |
---|
321 | The trace linker's major role is to wrap functions in the existing executable |
---|
322 | with trace code. The directions on how to wrap application functions is provided |
---|
323 | by the generator configuration. The wrapping function uses a GNU linker option |
---|
324 | called --wrap=symbol. The GNU Ld manual states: |
---|
325 | |
---|
326 | "Use a wrapper function for symbol. Any undefined reference to symbol will be |
---|
327 | resolved to __wrap_symbol. Any undefined reference to __real_symbol will be |
---|
328 | resolved to symbol." |
---|
329 | |
---|
330 | Generator sections specify how to generate trace wrapping code. The trace |
---|
331 | linker and generator section must match to work. The trace linker expects a some |
---|
332 | things to be present when wrapping functions. The section's name specifies the |
---|
333 | generator and can be listed in a generator key in a tracer or trace section. If |
---|
334 | the generator is not interested in a specific phase it does not need to define |
---|
335 | it. Nothing will be generated in regard to this phase. For example code to |
---|
336 | profile specific functions may only provide the entry-trace and exit-trace code |
---|
337 | where a nano-second time stamp is taken. |
---|
338 | |
---|
339 | The generate code will create an entry and exit call and the generator code |
---|
340 | block can be used to allocate buffer space for each with the lock held. The |
---|
341 | entry call and argument copy is performed with the lock released. The buffer |
---|
342 | space having been allocated will cause the trace events to be in order. The same |
---|
343 | goes for the exit call. Space is allocated in separate buffer allocate calls so |
---|
344 | the blocking calls will have the exit event appear in the correct location in |
---|
345 | the buffer. |
---|
346 | |
---|
347 | The following keys can be a part of the generator configuration: |
---|
348 | |
---|
349 | - ``headers``: A list of sections containing headers or header records. |
---|
350 | - ``header``: A list of include string that are single or double quoted. |
---|
351 | - ``defines``: A list of sections containing defines or define record. |
---|
352 | - ``define``: A list of define string that are single or double quoted. |
---|
353 | - ``entry-trace``: The wrapper call made on a function's entry. Returns bool |
---|
354 | where true is the function is being traced. This call is made without the lock |
---|
355 | being held if a lock is defined. |
---|
356 | - ``arg-trace``: The wrapper call made for each argument to the trace function |
---|
357 | if the function is being traced. This call is made without the lock being held |
---|
358 | if a lock is defined. |
---|
359 | - ``exit-trace``: The wrapper call made after a function's exit. Returns bool |
---|
360 | where true is the function is being traced. This call is made without the lock |
---|
361 | being held if a lock is defined. |
---|
362 | - ``ret-trace``: The wrapper call made to log the return value if the function |
---|
363 | is being traced. This call is made without the lock being held if a lock is |
---|
364 | defined. |
---|
365 | - ``lock-local``: The wrapper code to declare a local lock variable. |
---|
366 | - ``lock-acquire``: The wrapper code to acquire the lock. |
---|
367 | - ``lock-release``: The wrapper code to release the lock. |
---|
368 | - ``buffer-local``: The wrapper code to declare a buffer index local variable. |
---|
369 | - ``buffer-alloc``: The wrapper call made with a lock held if defined to |
---|
370 | allocate buffer space to hold the trace data. A suitable 32bit buffer index is |
---|
371 | returned. If there is no space an invalid index is returned. The generator |
---|
372 | must handle any overhead space needed. The generator needs to make sure the |
---|
373 | space is available before making the alloc all. |
---|
374 | - ``code-blocks``: A list of code block section names. |
---|
375 | - ``code``: A code block in <<CODE --- CODE (without the single quote). |
---|
376 | - ``includes``: A list of files to include. |
---|
377 | |
---|
378 | The following macros can be used in wrapper calls: |
---|
379 | |
---|
380 | - ``@FUNC_NAME@``: The trace function name as a quote C string. |
---|
381 | - ``@FUNC_INDEX@``: The trace function index as a held in the sorted list of |
---|
382 | trace functions by the trace linker. It can be used to index the names, |
---|
383 | enables, and triggers data. |
---|
384 | - ``@FUNC_LABEL@``: The trace function name as a C label that can be referenced. |
---|
385 | You can take the address of the label. |
---|
386 | - ``@FUNC_DATA_SIZE@``: The size of the data in bytes. |
---|
387 | - ``@FUNC_DATA_ENTRY_SIZE@``: The size of the entry data in bytes. |
---|
388 | - ``@FUNC_DATA_RET_SIZE@``: The size of the return data in bytes. |
---|
389 | - ``@ARG_NUM@``: The argument number to the trace function. |
---|
390 | - ``@ARG_TYPE@``: The type of the argument as a C string. |
---|
391 | - ``@ARG_SIZE@``: The size of the type of the argument in bytes. |
---|
392 | - ``@ARG_LABEL@``: The argument as a C label that can be referenced. |
---|
393 | - ``@RET_TYPE@``: The type of the return value as a C string. |
---|
394 | - ``@RET_SIZE@``: The size of the type of the return value in bytes. |
---|
395 | - ``@RET_LABEL@``: The return value as a C label that can be referenced. |
---|
396 | |
---|
397 | The `buffer-alloc`, `entry-trace`, and `exit-trace` can be transformed using the |
---|
398 | following macros: |
---|
399 | |
---|
400 | - ``@FUNC_NAME@`` |
---|
401 | - ``@FUNC_INDEX@`` |
---|
402 | - ``@FUNC_LABEL@`` |
---|
403 | - ``@FUNC_DATA_SZIE@`` |
---|
404 | - ``@FUNC_DATA_ENTRY_SZIE@`` |
---|
405 | - ``@FUNC_DATA_EXIT_SZIE@`` |
---|
406 | |
---|
407 | The `arg-trace` can be transformed using the following macros: |
---|
408 | |
---|
409 | - ``@ARG_NUM@`` |
---|
410 | - ``@ARG_TYPE@`` |
---|
411 | - ``@ARG_SIZE@`` |
---|
412 | - ``@ARG_LABEL@`` |
---|
413 | |
---|
414 | The `ret-trace` can be transformed using the following macros: |
---|
415 | |
---|
416 | - ``@RET_TYPE@`` |
---|
417 | - ``@RET_SIZE@`` |
---|
418 | - ``@RET_LABEL@`` |
---|
419 | |
---|
420 | The file: `test-trace.ini` specifies ``printf-generator`` as its generator. This |
---|
421 | section can be found in the file: `rtld-print.ini` in the rtems-tools directory |
---|
422 | and is shown below: |
---|
423 | |
---|
424 | .. code:: ini |
---|
425 | |
---|
426 | ; |
---|
427 | ; A printf generator prints to stdout the trace functions. |
---|
428 | ; |
---|
429 | [printf-generator] |
---|
430 | headers = printf-generator-headers |
---|
431 | entry-trace = "rtld_pg_printf_entry(@FUNC_NAME@, (void*) &@FUNC_LABEL@);" |
---|
432 | arg-trace = "rtld_pg_printf_arg(@ARG_NUM@, @ARG_TYPE@, @ARG_SIZE@, (void*) &@ARG_LABEL@);" |
---|
433 | exit-trace = "rtld_pg_printf_exit(@FUNC_NAME@, (void*) &@FUNC_LABEL@);" |
---|
434 | ret-trace = "rtld_pg_printf_ret(@RET_TYPE@, @RET_SIZE@, (void*) &@RET_LABEL@);" |
---|
435 | code = <<<CODE |
---|
436 | static inline void rtld_pg_printf_entry(const char* func_name, |
---|
437 | void* func_addr) |
---|
438 | { |
---|
439 | printf (">>> %s (0x%08x)\n", func_name, func_addr); |
---|
440 | } |
---|
441 | static inline void rtld_pg_printf_arg(int arg_num, |
---|
442 | const char* arg_type, |
---|
443 | int arg_size, |
---|
444 | void* arg) |
---|
445 | { |
---|
446 | const unsigned char* p = arg; |
---|
447 | int i; |
---|
448 | printf (" %2d] %s(%d) = ", arg_num, arg_type, arg_size); |
---|
449 | for (i = 0; i < arg_size; ++i, ++p) printf ("%02x", (unsigned int) *p); |
---|
450 | printf ("\n"); |
---|
451 | } |
---|
452 | static inline void rtld_pg_printf_exit(const char* func_name, |
---|
453 | void* func_addr) |
---|
454 | { |
---|
455 | printf ("<<< %s (0x%08x)\n", func_name, func_addr); |
---|
456 | } |
---|
457 | static inline void rtld_pg_printf_ret(const char* ret_type, |
---|
458 | int ret_size, |
---|
459 | void* ret) |
---|
460 | { |
---|
461 | const unsigned char* p = ret; |
---|
462 | int i; |
---|
463 | printf (" rt] %s(%d) = ", ret_type, ret_size); |
---|
464 | for (i = 0; i < ret_size; ++i, ++p) printf ("%02x", (unsigned int) *p); |
---|
465 | printf ("\n"); |
---|
466 | } |
---|
467 | CODE |
---|
468 | |
---|
469 | [printf-generator-headers] |
---|
470 | header = "#include <stdio.h>" |
---|
471 | |
---|
472 | The trace linker generates C code with a wrapper for each function to be |
---|
473 | instrumented. The trace code generated is driven by the configuration INI files. |
---|
474 | |
---|
475 | Development |
---|
476 | =========== |
---|
477 | |
---|
478 | The Trace Linker is part of the RTEMS tools git repository available at : |
---|
479 | https://git.rtems.org/rtems-tools |
---|
480 | The RTEMS tools project utilizes the waf build system. Use the following |
---|
481 | commands in the topmost build directory to build the tools project: |
---|
482 | |
---|
483 | First we configure using: |
---|
484 | |
---|
485 | .. code-block:: shell |
---|
486 | |
---|
487 | $./waf configure --prefix=$HOME/development/rtems/5 |
---|
488 | |
---|
489 | Then we build and install using: |
---|
490 | |
---|
491 | .. code-block:: shell |
---|
492 | |
---|
493 | $./waf build install |
---|