1 | RTEMS Waf |
---|
2 | ~~~~~~~~~ |
---|
3 | |
---|
4 | RTEMS Waf is a module that supports the Waf build system and RTEMS. The module |
---|
5 | is integrated into a project or library proividing Waf build support to create |
---|
6 | RTEMS libraries or executables. |
---|
7 | |
---|
8 | RTEMS Waf provides: |
---|
9 | |
---|
10 | * Checking for a valid RTEMS installation of tools and kernel. |
---|
11 | |
---|
12 | * Support for multiple versions of RTEMS. |
---|
13 | |
---|
14 | * Support to build a number of BSPs at once. |
---|
15 | |
---|
16 | * Support for the RTEMS tools and kernel being installed under a shared or |
---|
17 | separate prefixes [2]. |
---|
18 | |
---|
19 | * Flexible integration that allows easy project specific specialization. |
---|
20 | |
---|
21 | * Support to check which features RTEMS is built with. |
---|
22 | |
---|
23 | * Support for BSP compiler and linker flags. The flags are separated into their |
---|
24 | various types to allow flexible options management in a project. |
---|
25 | |
---|
26 | * Support to list the available architectures and BSPs. |
---|
27 | |
---|
28 | * Additional support for creating root file systems for RTEMS targets. |
---|
29 | |
---|
30 | Bugs |
---|
31 | ---- |
---|
32 | |
---|
33 | Please report issues to the RTEMS Users list mailto:users@rtems.org or raise a |
---|
34 | ticket in RTEMS's Trac under https://devel.rtems.org/. |
---|
35 | |
---|
36 | Feedback is always welcome. |
---|
37 | |
---|
38 | Waf |
---|
39 | --- |
---|
40 | |
---|
41 | You can find the Waf project here: |
---|
42 | |
---|
43 | https://waf.io/ |
---|
44 | |
---|
45 | Waf does not come as a package in distrubitions so you need to download and |
---|
46 | install it. |
---|
47 | |
---|
48 | 1. Waf is a Python program so you will also need to have a current Python |
---|
49 | installed and accessible via your environment's path. |
---|
50 | |
---|
51 | 2. Download the latest signed Waf executable file from the Waf website. |
---|
52 | |
---|
53 | 3. Place the waf executable in a personal directory that is in your path, for |
---|
54 | example $HOME/bin. Modify the file's permissions so it can be executed: |
---|
55 | |
---|
56 | $ chmod +x $HOME/bin/waf |
---|
57 | |
---|
58 | Git Submodule |
---|
59 | ------------- |
---|
60 | |
---|
61 | RTEMS Waf can be used as a git submodule. This lets a number of projects share |
---|
62 | the common waf support. |
---|
63 | |
---|
64 | 1. Add RTEMS Waf a git submodule to your project: |
---|
65 | |
---|
66 | $ cd my_project |
---|
67 | $ git submodule add git://git.rtems.org/rtems_waf.git rtems_waf |
---|
68 | |
---|
69 | 2. Initialize the submodule(s) for your project: |
---|
70 | |
---|
71 | $ git submodule init |
---|
72 | |
---|
73 | 3. Update the RTEMS Waf submodule: |
---|
74 | |
---|
75 | $ git submodule update rtems_waf |
---|
76 | |
---|
77 | Note, the `rtems_waf` submodule name is provided as some projects may have |
---|
78 | other submodules you may not wish to update. |
---|
79 | |
---|
80 | 4. When submodules are added they are headless which means they are not on a |
---|
81 | current branch. Switch to a branch: |
---|
82 | |
---|
83 | $ cd rtems_waf |
---|
84 | $ git checkout master |
---|
85 | $ cd .. |
---|
86 | |
---|
87 | Note, you can replace `master` in the `checkout` above with any valid branch |
---|
88 | in the RTEMS Waf repo. |
---|
89 | |
---|
90 | 5. Update the RTEMS Waf submodule to the latest version on the selected branch: |
---|
91 | |
---|
92 | $ cd rtems_waf |
---|
93 | $ git pull |
---|
94 | $ cd .. |
---|
95 | |
---|
96 | 6. Check the new submodule is part of your project and ready to be committed: |
---|
97 | |
---|
98 | $ git status |
---|
99 | |
---|
100 | The `rtems_waf` module will be listed as `modified`. |
---|
101 | |
---|
102 | 7. Commit the change by adding it to your staged files: |
---|
103 | |
---|
104 | $ git add rtems_waf |
---|
105 | |
---|
106 | When ready commit: |
---|
107 | |
---|
108 | $ git commit |
---|
109 | |
---|
110 | Review the changes and if they are correct push them: |
---|
111 | |
---|
112 | $ git log -p |
---|
113 | $ git push |
---|
114 | |
---|
115 | The RTEMS Waf module is updated from time to time as new features are added or |
---|
116 | changes happen in waf. To update a project's existing RTEMS Waf submodule |
---|
117 | perform steps 5. to 7. |
---|
118 | |
---|
119 | Project Instructions |
---|
120 | -------------------- |
---|
121 | |
---|
122 | Create a README.waf file in your project and add the Waf installation section, |
---|
123 | your project specific options and the following steps. These steps are for |
---|
124 | RTEMS 5, change for the specific version of RTEMS your project supports. |
---|
125 | |
---|
126 | 1. Build or install the tools. In this example the path is the personal prefix |
---|
127 | of $HOME/development/rtems/5 [1]. |
---|
128 | |
---|
129 | 2. Build and install the RTEMS Board Support Packages you want to use. In this |
---|
130 | example separate tools and kernel prefixes are used [2]. The kernel path is |
---|
131 | $HOME/development/rtems/bsps/5. |
---|
132 | |
---|
133 | 3. Unpack this package somewhere, anywhere on your disk and change into the top |
---|
134 | level directory. |
---|
135 | |
---|
136 | 4. Populate the git submodule: |
---|
137 | |
---|
138 | $ git submodule init |
---|
139 | $ git submodule update rtems_waf |
---|
140 | |
---|
141 | 5. Configure with your specific settings. In this case the path to the tools |
---|
142 | and the kernel are separate and provided on the command line. Your |
---|
143 | envronment's path variable does not need to changed [3]. We limit the build |
---|
144 | to 'sparc/erc32' BSP: |
---|
145 | |
---|
146 | $ waf configure --rtems=$HOME/development/rtems/bsps/5 \ |
---|
147 | --rtems-tools=$HOME/development/rtems/5 \ |
---|
148 | --rtems-bsps=sparc/erc32 |
---|
149 | |
---|
150 | You can use '--rtems-archs=sparc,i386' or |
---|
151 | '--rtems-bsps=sparc/erc32,i386/pc586' to build more than BSP at a time. |
---|
152 | |
---|
153 | 6. Build: |
---|
154 | |
---|
155 | $ waf |
---|
156 | |
---|
157 | An RTEMS Waf Project |
---|
158 | -------------------- |
---|
159 | |
---|
160 | RTEMS Waf provides a base to build RTEMS application. |
---|
161 | |
---|
162 | Waf provides a build system framework. You can use waf in your project by |
---|
163 | simply prooviding a list of files you wish to build and link to create an |
---|
164 | executable or you can use waf as framework which is integrated into your |
---|
165 | project to become is build system. |
---|
166 | |
---|
167 | Importing RTEMS Waf |
---|
168 | ~~~~~~~~~~~~~~~~~~~ |
---|
169 | |
---|
170 | Using RTEMS Waf as a submodule means it may not be present if the submodules |
---|
171 | have not been initialized and updated. This results in a Python error. The |
---|
172 | following import is recommended so a user friendly error is reported: |
---|
173 | |
---|
174 | from __future__ import print_function |
---|
175 | |
---|
176 | try: |
---|
177 | import rtems_waf.rtems as rtems |
---|
178 | except: |
---|
179 | print('error: no rtems_waf git submodule; see README.waf', file = stderr) |
---|
180 | import sys |
---|
181 | sys.exit(1) |
---|
182 | |
---|
183 | Initialization |
---|
184 | ~~~~~~~~~~~~~~ |
---|
185 | |
---|
186 | The `wscript` `init()` function is called early in waf's processing. The RTEMS |
---|
187 | Waf's `init()` call lets you provide: |
---|
188 | |
---|
189 | 1. Filters |
---|
190 | |
---|
191 | 2. RTEMS Version |
---|
192 | |
---|
193 | 3. Long command line control |
---|
194 | |
---|
195 | 4. Waf BSP initialization hook |
---|
196 | |
---|
197 | A example call to RTEMS Waf's `init()` is: |
---|
198 | |
---|
199 | rtems_version = "5" |
---|
200 | |
---|
201 | def init(ctx): |
---|
202 | rtems.init(ctx, version = rtems_version, long_commands = True) |
---|
203 | |
---|
204 | Filters provide a way to control the tools, architectures and BSPs your project |
---|
205 | supports. RTEMS Waf scans and finds all installed RTEMS tool sets and BSPs and |
---|
206 | your project may only support a limited number of these. Filtering provides a |
---|
207 | way for your project to control what RTEMS Waf accepts and rejects when |
---|
208 | automatically scanning the installed tools and RTEMS kernels. A filter is a |
---|
209 | Python dictionary and the following example will accept `arm` and `sparc` tool |
---|
210 | chains and filtering out the `bfin` tool chain. The filter will only build the |
---|
211 | `arm` acrhitecture and will accept all BSPs except ones starting with `lpc` if |
---|
212 | they are installed: |
---|
213 | |
---|
214 | my_filter = { 'tools': { 'in': ['arm', 'sparc'], 'out': ['bfin'] }, |
---|
215 | 'arch': { 'in': ['arm'], 'out': [] }, |
---|
216 | 'bsps': { 'in': [], 'out': ['lpc.*'] } } |
---|
217 | |
---|
218 | There are three (3) filters the `tools`, `archs` and `bsps` and each of these |
---|
219 | filter types has an `in` and `out` list. The `in` and `out` items are Python |
---|
220 | regular expressions. |
---|
221 | |
---|
222 | The RTEMS Version lets your project provide the default RTEMS version. This can |
---|
223 | be overridden by the configure option `--rtems-version`. |
---|
224 | |
---|
225 | Long commands is specific to Windows and provides support for tool command |
---|
226 | lines that are longer than the standard Windows command shell's limit. The |
---|
227 | support is based on the example available in Waf extra's. |
---|
228 | |
---|
229 | The Waf BSP initialization hook is a function called as part of the RTEMS Waf's |
---|
230 | `init()` call with the Waf environment and list of BSP contexts. This hook can |
---|
231 | be used to provide specialized BSP support. |
---|
232 | |
---|
233 | Options |
---|
234 | ~~~~~~~ |
---|
235 | |
---|
236 | The `wscript` `option()` function is called to collect command line options for |
---|
237 | Waf argument processing. |
---|
238 | |
---|
239 | A example call to RTEMS Waf's `options()` is: |
---|
240 | |
---|
241 | def options(opt): |
---|
242 | rtems.options(opt) |
---|
243 | |
---|
244 | Configure |
---|
245 | ~~~~~~~~~ |
---|
246 | |
---|
247 | The `wscript` `configure()` function is called when Waf is configuring a |
---|
248 | build. The RTEMS Waf's `configure()` lets you provide: |
---|
249 | |
---|
250 | 1. Waf BSP configure hook |
---|
251 | |
---|
252 | A example call to RTEMS Waf's `configure()` is: |
---|
253 | |
---|
254 | def configure(conf): |
---|
255 | rtems.configure(conf) |
---|
256 | |
---|
257 | The BSP configure hook is called at end of a BSP's configuration. The BSP's |
---|
258 | `conf` variable and the `arch/bsp` are passed as arguments. The `arch/bsp` is |
---|
259 | the RTEMS standard for specifing a BSP, for example `sparc/erc32`. The BSP |
---|
260 | configure support can be used to check a BSP for header, check an RTEMS feature |
---|
261 | is present for a specific BSP or add per BSP build variant support: |
---|
262 | |
---|
263 | def bsp_configure(conf, arch_bsp): |
---|
264 | conf.check(header_name = "dlfcn.h", features = "c") |
---|
265 | conf.check(header_name = "rtems/pci.h", features = "c", mandatory = False) |
---|
266 | if not rtems.check_posix(conf): |
---|
267 | conf.fatal("POSIX is disabled; configure RTEMS with --enable-posix") |
---|
268 | env = conf.env.derive() |
---|
269 | for builder in builders: |
---|
270 | ab = conf.env.RTEMS_ARCH_BSP |
---|
271 | variant = ab + "-" + builder |
---|
272 | conf.msg('Configure variant: ', variant) |
---|
273 | conf.setenv(variant, env) |
---|
274 | build_variant_bsp_configure(conf, arch_bsp) |
---|
275 | conf.setenv(ab) |
---|
276 | |
---|
277 | Build |
---|
278 | ~~~~~ |
---|
279 | |
---|
280 | The `wscript` `build()` function is called when Waf is asking what to |
---|
281 | build. |
---|
282 | |
---|
283 | A example call to RTEMS Waf's `build()` is: |
---|
284 | |
---|
285 | def build(bld): |
---|
286 | rtems.build(bld) |
---|
287 | bld(features = 'c cprogram', |
---|
288 | target = 'hello.exe', |
---|
289 | source = ['hello.c']) |
---|
290 | |
---|
291 | In this example the C source file `hello.c` is compiled and linked to create |
---|
292 | the RTEMS executable `hello.exe`. The build is within the context of the BSP. |
---|
293 | |
---|
294 | Example |
---|
295 | ~~~~~~~ |
---|
296 | |
---|
297 | Save the following as `wscript`: |
---|
298 | |
---|
299 | # |
---|
300 | # Example Waf build script for RTEMS |
---|
301 | # |
---|
302 | # To configure, build and run: |
---|
303 | # |
---|
304 | # $ waf configure --rtems=$HOME/development/rtems/build/5 \ |
---|
305 | # --rtems-tools=$HOME/development/rtems/5 \ |
---|
306 | # --rtems-bsps=sparc/erc32 |
---|
307 | # $ waf |
---|
308 | # $ $HOME/development/rtems/5/bin/sparc-rtems5-run \ |
---|
309 | # ./build/sparc-rtems5-erc32/hello.exe |
---|
310 | # |
---|
311 | # You can use '--rtems-archs=sparc,i386' or |
---|
312 | # '--rtems-bsps=sparc/erc32,i386/pc586' to build for more than one BSP at a |
---|
313 | # time. |
---|
314 | # |
---|
315 | |
---|
316 | from __future__ import print_function |
---|
317 | |
---|
318 | rtems_version = "5" |
---|
319 | |
---|
320 | try: |
---|
321 | import rtems_waf.rtems as rtems |
---|
322 | except: |
---|
323 | print('error: no rtems_waf git submodule; see README.waf', file = stderr) |
---|
324 | import sys |
---|
325 | sys.exit(1) |
---|
326 | |
---|
327 | def init(ctx): |
---|
328 | rtems.init(ctx, version = rtems_version, long_commands = True) |
---|
329 | |
---|
330 | def options(opt): |
---|
331 | rtems.options(opt) |
---|
332 | |
---|
333 | def configure(conf): |
---|
334 | rtems.configure(conf) |
---|
335 | |
---|
336 | def build(bld): |
---|
337 | rtems.build(bld) |
---|
338 | bld.env.CFLAGS += ['-O2','-g'] |
---|
339 | bld(features = 'c cprogram', |
---|
340 | target = 'hello.exe', |
---|
341 | source = ['hello.c']) |
---|
342 | |
---|
343 | Save the example C hello world as `hello.c`: |
---|
344 | |
---|
345 | #include <rtems.h> |
---|
346 | #include <stdlib.h> |
---|
347 | #include <stdio.h> |
---|
348 | |
---|
349 | rtems_task Init(rtems_task_argument ignored) { |
---|
350 | printf("Hello World\n"); |
---|
351 | exit(0); |
---|
352 | } |
---|
353 | |
---|
354 | /* configuration information */ |
---|
355 | #include <bsp.h> |
---|
356 | #define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER |
---|
357 | #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER |
---|
358 | #define CONFIGURE_USE_DEVFS_AS_BASE_FILESYSTEM |
---|
359 | #define CONFIGURE_RTEMS_INIT_TASKS_TABLE |
---|
360 | #define CONFIGURE_MAXIMUM_TASKS 1 |
---|
361 | #define CONFIGURE_INIT |
---|
362 | #include <rtems/confdefs.h> |
---|
363 | |
---|
364 | -- |
---|
365 | |
---|
366 | [1] A personal prefix is private to you and located where you have enough disk |
---|
367 | space to complete an RTEMS installation. We often show this as your home |
---|
368 | directory ($HOME) because it works on machines you may not have root access |
---|
369 | to and cannot configure. We recommend you never work as root on a machine |
---|
370 | you control. |
---|
371 | |
---|
372 | [2] RTEMS supports shared or separate tool and kernel prefixes. The prefix is |
---|
373 | the path given to the tools and kernel when building and is the path the |
---|
374 | tools or kernel are installed into when you run the install phase of a |
---|
375 | build. A shared tools and kernel prefix is often used with releases because |
---|
376 | the tools and kernel in a release are matched and do not change. Separate |
---|
377 | tools and kernel paths can be used if you have a common tool set with |
---|
378 | changing kernel versions. This tends to happen when you are testing kernel |
---|
379 | patches or changes. |
---|
380 | |
---|
381 | [3] It is good practice to keep your environment as empty as possible. Using |
---|
382 | the environment to set paths to tools or specific values to configure and |
---|
383 | control builds is dangerous because settings can leak between different |
---|
384 | builds and change what you expect or not been and seen and lost. The waf |
---|
385 | tool used here lets you specify on the command line the tools and RTEMS |
---|
386 | paths and this is embedded in waf's configuration information. If you have |
---|
387 | a few source trees working at any one time with different tool sets or |
---|
388 | configurations you can easly move between them safe in the knowledge that |
---|
389 | one build will not affect another. |
---|