blob: 521271d54cc74b009b442d53aea657ed955a24d1 [file] [log] [blame]
Patrick Williamsc0f7c042017-02-23 20:41:17 -06001<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
2"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
3[<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
4
5<chapter id='sdk-working-projects'>
6
7 <title>Using the SDK Toolchain Directly</title>
8
9 <para>
Brad Bishopc342db32019-05-15 21:57:59 -040010 You can use the SDK toolchain directly with Makefile and
11 Autotools-based projects.
Patrick Williamsc0f7c042017-02-23 20:41:17 -060012 </para>
13
14 <section id='autotools-based-projects'>
15 <title>Autotools-Based Projects</title>
16
17 <para>
Brad Bishop316dfdd2018-06-25 12:45:53 -040018 Once you have a suitable
19 <ulink url='&YOCTO_DOCS_REF_URL;#cross-development-toolchain'>cross-development toolchain</ulink>
20 installed, it is very easy to develop a project using the
21 <ulink url='https://en.wikipedia.org/wiki/GNU_Build_System'>GNU Autotools-based</ulink>
22 workflow, which is outside of the
23 <ulink url='&YOCTO_DOCS_REF_URL;#build-system-term'>OpenEmbedded build system</ulink>.
Patrick Williamsc0f7c042017-02-23 20:41:17 -060024 </para>
25
Brad Bishop316dfdd2018-06-25 12:45:53 -040026 <para>
27 The following figure presents a simple Autotools workflow.
28 <imagedata fileref="figures/sdk-autotools-flow.png" width="7in" height="8in" align="center" />
29 </para>
Patrick Williamsc0f7c042017-02-23 20:41:17 -060030
Brad Bishop316dfdd2018-06-25 12:45:53 -040031 <para>
32 Follow these steps to create a simple Autotools-based
33 "Hello World" project:
34 <note>
35 For more information on the GNU Autotools workflow,
36 see the same example on the
37 <ulink url='https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en'>GNOME Developer</ulink>
38 site.
39 </note>
40 <orderedlist>
41 <listitem><para>
42 <emphasis>Create a Working Directory and Populate It:</emphasis>
43 Create a clean directory for your project and then make
44 that directory your working location.
45 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -060046 $ mkdir $HOME/helloworld
47 $ cd $HOME/helloworld
Brad Bishop316dfdd2018-06-25 12:45:53 -040048 </literallayout>
49 After setting up the directory, populate it with files
50 needed for the flow.
51 You need a project source file, a file to help with
52 configuration, and a file to help create the Makefile,
53 and a README file:
54 <filename>hello.c</filename>,
55 <filename>configure.ac</filename>,
56 <filename>Makefile.am</filename>, and
57 <filename>README</filename>, respectively.</para>
58
59 <para> Use the following command to create an empty README
60 file, which is required by GNU Coding Standards:
61 <literallayout class='monospaced'>
62 $ touch README
63 </literallayout>
64 Create the remaining three files as follows:
65 <itemizedlist>
66 <listitem><para>
67 <emphasis><filename>hello.c</filename>:</emphasis>
68 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -060069 #include &lt;stdio.h&gt;
70
71 main()
72 {
73 printf("Hello World!\n");
74 }
Brad Bishop316dfdd2018-06-25 12:45:53 -040075 </literallayout>
76 </para></listitem>
77 <listitem><para>
78 <emphasis><filename>configure.ac</filename>:</emphasis>
79 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -060080 AC_INIT(hello,0.1)
81 AM_INIT_AUTOMAKE([foreign])
82 AC_PROG_CC
Brad Bishop316dfdd2018-06-25 12:45:53 -040083 AC_CONFIG_FILES(Makefile)
84 AC_OUTPUT
85 </literallayout>
86 </para></listitem>
87 <listitem><para>
88 <emphasis><filename>Makefile.am</filename>:</emphasis>
89 <literallayout class='monospaced'>
90 bin_PROGRAMS = hello
91 hello_SOURCES = hello.c
92 </literallayout>
93 </para></listitem>
94 </itemizedlist>
95 </para></listitem>
96 <listitem><para>
97 <emphasis>Source the Cross-Toolchain
98 Environment Setup File:</emphasis>
99 As described earlier in the manual, installing the
100 cross-toolchain creates a cross-toolchain
101 environment setup script in the directory that the SDK
102 was installed.
103 Before you can use the tools to develop your project,
104 you must source this setup script.
105 The script begins with the string "environment-setup"
106 and contains the machine architecture, which is
107 followed by the string "poky-linux".
108 For this example, the command sources a script from the
109 default SDK installation directory that uses the
110 32-bit Intel x86 Architecture and the
111 &DISTRO_NAME; Yocto Project release:
112 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600113 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Brad Bishop316dfdd2018-06-25 12:45:53 -0400114 </literallayout>
115 </para></listitem>
116 <listitem><para>
117 <emphasis>Create the <filename>configure</filename> Script:</emphasis>
118 Use the <filename>autoreconf</filename> command to
119 generate the <filename>configure</filename> script.
120 <literallayout class='monospaced'>
121 $ autoreconf
122 </literallayout>
123 The <filename>autoreconf</filename> tool takes care
124 of running the other Autotools such as
125 <filename>aclocal</filename>,
126 <filename>autoconf</filename>, and
127 <filename>automake</filename>.
128 <note>
129 If you get errors from
130 <filename>configure.ac</filename>, which
131 <filename>autoreconf</filename> runs, that indicate
132 missing files, you can use the "-i" option, which
133 ensures missing auxiliary files are copied to the build
134 host.
135 </note>
136 </para></listitem>
137 <listitem><para>
138 <emphasis>Cross-Compile the Project:</emphasis>
139 This command compiles the project using the
140 cross-compiler.
141 The
142 <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIGURE_FLAGS'><filename>CONFIGURE_FLAGS</filename></ulink>
143 environment variable provides the minimal arguments for
144 GNU configure:
145 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600146 $ ./configure ${CONFIGURE_FLAGS}
Brad Bishop316dfdd2018-06-25 12:45:53 -0400147 </literallayout>
148 For an Autotools-based project, you can use the
149 cross-toolchain by just passing the appropriate host
150 option to <filename>configure.sh</filename>.
151 The host option you use is derived from the name of the
152 environment setup script found in the directory in which
153 you installed the cross-toolchain.
154 For example, the host option for an ARM-based target that
155 uses the GNU EABI is
156 <filename>armv5te-poky-linux-gnueabi</filename>.
157 You will notice that the name of the script is
158 <filename>environment-setup-armv5te-poky-linux-gnueabi</filename>.
159 Thus, the following command works to update your project
160 and rebuild it using the appropriate cross-toolchain tools:
161 <literallayout class='monospaced'>
162 $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=<replaceable>sysroot_dir</replaceable>
163 </literallayout>
164 </para></listitem>
165 <listitem><para>
166 <emphasis>Make and Install the Project:</emphasis>
167 These two commands generate and install the project
168 into the destination directory:
169 <literallayout class='monospaced'>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600170 $ make
171 $ make install DESTDIR=./tmp
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600172 </literallayout>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400173 <note>
174 To learn about environment variables established
175 when you run the cross-toolchain environment setup
176 script and how they are used or overridden when
177 the Makefile, see the
178 "<link linkend='makefile-based-projects'>Makefile-Based Projects</link>"
179 section.
180 </note>
181 This next command is a simple way to verify the
182 installation of your project.
183 Running the command prints the architecture on which
184 the binary file can run.
185 This architecture should be the same architecture that
186 the installed cross-toolchain supports.
187 <literallayout class='monospaced'>
188 $ file ./tmp/usr/local/bin/hello
189 </literallayout>
190 </para></listitem>
191 <listitem><para>
192 <emphasis>Execute Your Project:</emphasis>
193 To execute the project, you would need to run it on your
194 target hardware.
195 If your target hardware happens to be your build host,
196 you could run the project as follows:
197 <literallayout class='monospaced'>
198 $ ./tmp/usr/local/bin/hello
199 </literallayout>
200 As expected, the project displays the "Hello World!"
201 message.
202 </para></listitem>
203 </orderedlist>
204 </para>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600205 </section>
206
207 <section id='makefile-based-projects'>
208 <title>Makefile-Based Projects</title>
209
210 <para>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400211 Simple Makefile-based projects use and interact with the
212 cross-toolchain environment variables established when you run
213 the cross-toolchain environment setup script.
214 The environment variables are subject to general
215 <filename>make</filename> rules.
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600216 </para>
217
218 <para>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400219 This section presents a simple Makefile development flow and
220 provides an example that lets you see how you can use
221 cross-toolchain environment variables and Makefile variables
222 during development.
223 <imagedata fileref="figures/sdk-makefile-flow.png" width="6in" height="7in" align="center" />
224 </para>
225
226 <para>
227 The main point of this section is to explain the following three
228 cases regarding variable behavior:
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600229 <itemizedlist>
230 <listitem><para>
231 <emphasis>Case 1 - No Variables Set in the
Brad Bishop316dfdd2018-06-25 12:45:53 -0400232 <filename>Makefile</filename> Map to Equivalent
233 Environment Variables Set in the SDK Setup Script:</emphasis>
234 Because matching variables are not specifically set in the
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600235 <filename>Makefile</filename>, the variables retain their
Brad Bishop316dfdd2018-06-25 12:45:53 -0400236 values based on the environment setup script.
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600237 </para></listitem>
238 <listitem><para>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400239 <emphasis>Case 2 - Variables Are Set in the Makefile that
240 Map to Equivalent Environment Variables from the SDK
241 Setup Script:</emphasis>
242 Specifically setting matching variables in the
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600243 <filename>Makefile</filename> during the build results in
244 the environment settings of the variables being
245 overwritten.
Brad Bishop316dfdd2018-06-25 12:45:53 -0400246 In this case, the variables you set in the
247 <filename>Makefile</filename> are used.
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600248 </para></listitem>
249 <listitem><para>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400250 <emphasis>Case 3 - Variables Are Set Using the Command Line
251 that Map to Equivalent Environment Variables from the
252 SDK Setup Script:</emphasis>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600253 Executing the <filename>Makefile</filename> from the
Brad Bishop316dfdd2018-06-25 12:45:53 -0400254 command line results in the environment variables being
255 overwritten.
256 In this case, the command-line content is used.
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600257 </para></listitem>
258 </itemizedlist>
259 <note>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400260 Regardless of how you set your variables, if you use
261 the "-e" option with <filename>make</filename>, the
262 variables from the SDK setup script take precedence:
263 <literallayout class='monospaced'>
264 $ make -e <replaceable>target</replaceable>
265 </literallayout>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600266 </note>
267 </para>
Brad Bishop316dfdd2018-06-25 12:45:53 -0400268
269 <para>
270 The remainder of this section presents a simple Makefile example
271 that demonstrates these variable behaviors.
272 </para>
273
274 <para>
275 In a new shell environment variables are not established for the
276 SDK until you run the setup script.
277 For example, the following commands show a null value for the
278 compiler variable (i.e.
279 <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'><filename>CC</filename></ulink>).
280 <literallayout class='monospaced'>
281 $ echo ${CC}
282
283 $
284 </literallayout>
285 Running the SDK setup script for a 64-bit build host and an
286 i586-tuned target architecture for a
287 <filename>core-image-sato</filename> image using the current
288 &DISTRO; Yocto Project release and then echoing that variable
289 shows the value established through the script:
290 <literallayout class='monospaced'>
291 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
292 $ echo ${CC}
293 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
294 </literallayout>
295 </para>
296
297 <para>
298 To illustrate variable use, work through this simple "Hello World!"
299 example:
300 <orderedlist>
301 <listitem><para>
302 <emphasis>Create a Working Directory and Populate It:</emphasis>
303 Create a clean directory for your project and then make
304 that directory your working location.
305 <literallayout class='monospaced'>
306 $ mkdir $HOME/helloworld
307 $ cd $HOME/helloworld
308 </literallayout>
309 After setting up the directory, populate it with files
310 needed for the flow.
311 You need a <filename>main.c</filename> file from which you
312 call your function, a <filename>module.h</filename> file
313 to contain headers, and a <filename>module.c</filename>
314 that defines your function.
315 </para>
316
317 <para>Create the three files as follows:
318 <itemizedlist>
319 <listitem><para>
320 <emphasis><filename>main.c</filename>:</emphasis>
321 <literallayout class='monospaced'>
322 #include "module.h"
323 void sample_func();
324 int main()
325 {
326 sample_func();
327 return 0;
328 }
329 </literallayout>
330 </para></listitem>
331 <listitem><para>
332 <emphasis><filename>module.h</filename>:</emphasis>
333 <literallayout class='monospaced'>
334 #include &lt;stdio.h&gt;
335 void sample_func();
336 </literallayout>
337 </para></listitem>
338 <listitem><para>
339 <emphasis><filename>module.c</filename>:</emphasis>
340 <literallayout class='monospaced'>
341 #include "module.h"
342 void sample_func()
343 {
344 printf("Hello World!");
345 printf("\n");
346 }
347 </literallayout>
348 </para></listitem>
349 </itemizedlist>
350 </para></listitem>
351 <listitem><para>
352 <emphasis>Source the Cross-Toolchain Environment Setup File:</emphasis>
353 As described earlier in the manual, installing the
354 cross-toolchain creates a cross-toolchain environment setup
355 script in the directory that the SDK was installed.
356 Before you can use the tools to develop your project,
357 you must source this setup script.
358 The script begins with the string "environment-setup"
359 and contains the machine architecture, which is
360 followed by the string "poky-linux".
361 For this example, the command sources a script from the
362 default SDK installation directory that uses the
363 32-bit Intel x86 Architecture and the
364 &DISTRO_NAME; Yocto Project release:
365 <literallayout class='monospaced'>
366 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
367 </literallayout>
368 </para></listitem>
369 <listitem><para>
370 <emphasis>Create the <filename>Makefile</filename>:</emphasis>
371 For this example, the Makefile contains two lines that
372 can be used to set the <filename>CC</filename> variable.
373 One line is identical to the value that is set when you
374 run the SDK environment setup script, and the other line
375 sets <filename>CC</filename> to "gcc", the default GNU
376 compiler on the build host:
377 <literallayout class='monospaced'>
378 # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
379 # CC="gcc"
380 all: main.o module.o
381 ${CC} main.o module.o -o target_bin
382 main.o: main.c module.h
383 ${CC} -I . -c main.c
384 module.o: module.c module.h
385 ${CC} -I . -c module.c
386 clean:
387 rm -rf *.o
388 rm target_bin
389 </literallayout>
390 </para></listitem>
391 <listitem><para>
392 <emphasis>Make the Project:</emphasis>
393 Use the <filename>make</filename> command to create the
394 binary output file.
395 Because variables are commented out in the Makefile,
396 the value used for <filename>CC</filename> is the value
397 set when the SDK environment setup file was run:
398 <literallayout class='monospaced'>
399 $ make
400 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
401 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
402 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
403 </literallayout>
404 From the results of the previous command, you can see that
405 the compiler used was the compiler established through
406 the <filename>CC</filename> variable defined in the
407 setup script.</para>
408
409 <para>You can override the <filename>CC</filename>
410 environment variable with the same variable as set from
411 the Makefile by uncommenting the line in the Makefile
412 and running <filename>make</filename> again.
413 <literallayout class='monospaced'>
414 $ make clean
415 rm -rf *.o
416 rm target_bin
417 #
418 # Edit the Makefile by uncommenting the line that sets CC to "gcc"
419 #
420 $ make
421 gcc -I . -c main.c
422 gcc -I . -c module.c
423 gcc main.o module.o -o target_bin
424 </literallayout>
425 As shown in the previous example, the cross-toolchain
426 compiler is not used.
427 Rather, the default compiler is used.</para>
428
429 <para>This next case shows how to override a variable
430 by providing the variable as part of the command line.
431 Go into the Makefile and re-insert the comment character
432 so that running <filename>make</filename> uses
433 the established SDK compiler.
434 However, when you run <filename>make</filename>, use a
435 command-line argument to set <filename>CC</filename>
436 to "gcc":
437 <literallayout class='monospaced'>
438 $ make clean
439 rm -rf *.o
440 rm target_bin
441 #
442 # Edit the Makefile to comment out the line setting CC to "gcc"
443 #
444 $ make
445 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
446 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
447 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
448 $ make clean
449 rm -rf *.o
450 rm target_bin
451 $ make CC="gcc"
452 gcc -I . -c main.c
453 gcc -I . -c module.c
454 gcc main.o module.o -o target_bin
455 </literallayout>
456 In the previous case, the command-line argument overrides
457 the SDK environment variable.</para>
458
459 <para>In this last case, edit Makefile again to use the
460 "gcc" compiler but then use the "-e" option on the
461 <filename>make</filename> command line:
462 <literallayout class='monospaced'>
463 $ make clean
464 rm -rf *.o
465 rm target_bin
466 #
467 # Edit the Makefile to use "gcc"
468 #
469 $ make
470 gcc -I . -c main.c
471 gcc -I . -c module.c
472 gcc main.o module.o -o target_bin
473 $ make clean
474 rm -rf *.o
475 rm target_bin
476 $ make -e
477 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
478 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
479 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
480 </literallayout>
481 In the previous case, the "-e" option forces
482 <filename>make</filename> to use the SDK environment
483 variables regardless of the values in the Makefile.
484 </para></listitem>
485 <listitem><para>
486 <emphasis>Execute Your Project:</emphasis>
487 To execute the project (i.e.
488 <filename>target_bin</filename>), use the following
489 command:
490 <literallayout class='monospaced'>
491 $ ./target_bin
492 Hello World!
493 </literallayout>
494 <note>
495 If you used the cross-toolchain compiler to build
496 <filename>target_bin</filename> and your build host
497 differs in architecture from that of the target
498 machine, you need to run your project on the target
499 device.
500 </note>
501 As expected, the project displays the "Hello World!"
502 message.
503 </para></listitem>
504 </orderedlist>
505 </para>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600506 </section>
Patrick Williamsc0f7c042017-02-23 20:41:17 -0600507</chapter>
508<!--
509vim: expandtab tw=80 ts=4
510-->