blob: f880cbe0d57cdc172b3d6dddc6b3636f81a86445 [file] [log] [blame]
Andrew Geisslerf0343792020-11-18 10:42:21 -06001.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
Andrew Geisslerc9f78652020-09-18 14:11:35 -05002
3********************************
4Using the SDK Toolchain Directly
5********************************
6
7You can use the SDK toolchain directly with Makefile and Autotools-based
8projects.
9
10Autotools-Based Projects
11========================
12
Andrew Geissler09209ee2020-12-13 08:44:15 -060013Once you have a suitable :ref:`sdk-manual/intro:the cross-development toolchain`
Andrew Geisslerc9f78652020-09-18 14:11:35 -050014installed, it is very easy to develop a project using the `GNU
15Autotools-based <https://en.wikipedia.org/wiki/GNU_Build_System>`__
16workflow, which is outside of the :term:`OpenEmbedded Build System`.
17
18The following figure presents a simple Autotools workflow.
19
20.. image:: figures/sdk-autotools-flow.png
21 :align: center
22
23Follow these steps to create a simple Autotools-based "Hello World"
24project:
25
26.. note::
27
28 For more information on the GNU Autotools workflow, see the same
29 example on the
30 GNOME Developer
31 site.
32
331. *Create a Working Directory and Populate It:* Create a clean
34 directory for your project and then make that directory your working
35 location.
36 ::
37
38 $ mkdir $HOME/helloworld
39 $ cd $HOME/helloworld
40
41 After setting up the directory, populate it with files needed for the flow.
42 You need a project source file, a file to help with configuration,
43 and a file to help create the Makefile, and a README file:
44 ``hello.c``, ``configure.ac``, ``Makefile.am``, and ``README``,
45 respectively.
46
47 Use the following command to create an empty README file, which is
48 required by GNU Coding Standards:
49 ::
50
51 $ touch README
52
53 Create the remaining
54 three files as follows:
55
56 - ``hello.c``:
57 ::
58
59 #include <stdio.h>
60
61 main()
62 {
63 printf("Hello World!\n");
64 }
65
66 - ``configure.ac``:
67 ::
68
69 AC_INIT(hello,0.1)
70 AM_INIT_AUTOMAKE([foreign])
71 AC_PROG_CC
72 AC_CONFIG_FILES(Makefile)
73 AC_OUTPUT
74
75 - ``Makefile.am``:
76 ::
77
78 bin_PROGRAMS = hello
79 hello_SOURCES = hello.c
80
812. *Source the Cross-Toolchain Environment Setup File:* As described
82 earlier in the manual, installing the cross-toolchain creates a
83 cross-toolchain environment setup script in the directory that the
84 SDK was installed. Before you can use the tools to develop your
85 project, you must source this setup script. The script begins with
86 the string "environment-setup" and contains the machine architecture,
87 which is followed by the string "poky-linux". For this example, the
88 command sources a script from the default SDK installation directory
Andrew Geissler09209ee2020-12-13 08:44:15 -060089 that uses the 32-bit Intel x86 Architecture and the &DISTRO; Yocto
Andrew Geisslerc9f78652020-09-18 14:11:35 -050090 Project release:
91 ::
92
Andrew Geissler09209ee2020-12-13 08:44:15 -060093 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -050094
953. *Create the configure Script:* Use the ``autoreconf`` command to
96 generate the ``configure`` script.
97 ::
98
99 $ autoreconf
100
101 The ``autoreconf``
102 tool takes care of running the other Autotools such as ``aclocal``,
103 ``autoconf``, and ``automake``.
104
105 .. note::
106
Andrew Geissler3b8a17c2021-04-15 15:55:55 -0500107 If you get errors from ``configure.ac``, which ``autoreconf``
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500108 runs, that indicate missing files, you can use the "-i" option,
109 which ensures missing auxiliary files are copied to the build
110 host.
111
1124. *Cross-Compile the Project:* This command compiles the project using
113 the cross-compiler. The
114 :term:`CONFIGURE_FLAGS`
115 environment variable provides the minimal arguments for GNU
116 configure:
117 ::
118
119 $ ./configure ${CONFIGURE_FLAGS}
120
121 For an Autotools-based
122 project, you can use the cross-toolchain by just passing the
123 appropriate host option to ``configure.sh``. The host option you use
124 is derived from the name of the environment setup script found in the
125 directory in which you installed the cross-toolchain. For example,
126 the host option for an ARM-based target that uses the GNU EABI is
127 ``armv5te-poky-linux-gnueabi``. You will notice that the name of the
128 script is ``environment-setup-armv5te-poky-linux-gnueabi``. Thus, the
129 following command works to update your project and rebuild it using
130 the appropriate cross-toolchain tools:
131 ::
132
133 $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=sysroot_dir
134
1355. *Make and Install the Project:* These two commands generate and
136 install the project into the destination directory:
137 ::
138
139 $ make
140 $ make install DESTDIR=./tmp
141
142 .. note::
143
144 To learn about environment variables established when you run the
145 cross-toolchain environment setup script and how they are used or
146 overridden when the Makefile, see the "
147 Makefile-Based Projects
148 " section.
149
150 This next command is a simple way to verify the installation of your
151 project. Running the command prints the architecture on which the
152 binary file can run. This architecture should be the same
153 architecture that the installed cross-toolchain supports.
154 ::
155
156 $ file ./tmp/usr/local/bin/hello
157
1586. *Execute Your Project:* To execute the project, you would need to run
159 it on your target hardware. If your target hardware happens to be
160 your build host, you could run the project as follows:
161 ::
162
163 $ ./tmp/usr/local/bin/hello
164
165 As expected, the project displays the "Hello World!" message.
166
167Makefile-Based Projects
168=======================
169
170Simple Makefile-based projects use and interact with the cross-toolchain
171environment variables established when you run the cross-toolchain
172environment setup script. The environment variables are subject to
173general ``make`` rules.
174
175This section presents a simple Makefile development flow and provides an
176example that lets you see how you can use cross-toolchain environment
177variables and Makefile variables during development.
178
179.. image:: figures/sdk-makefile-flow.png
180 :align: center
181
182The main point of this section is to explain the following three cases
183regarding variable behavior:
184
185- *Case 1 - No Variables Set in the Makefile Map to Equivalent
186 Environment Variables Set in the SDK Setup Script:* Because matching
187 variables are not specifically set in the ``Makefile``, the variables
188 retain their values based on the environment setup script.
189
190- *Case 2 - Variables Are Set in the Makefile that Map to Equivalent
191 Environment Variables from the SDK Setup Script:* Specifically
192 setting matching variables in the ``Makefile`` during the build
193 results in the environment settings of the variables being
194 overwritten. In this case, the variables you set in the ``Makefile``
195 are used.
196
197- *Case 3 - Variables Are Set Using the Command Line that Map to
198 Equivalent Environment Variables from the SDK Setup Script:*
199 Executing the ``Makefile`` from the command line results in the
200 environment variables being overwritten. In this case, the
201 command-line content is used.
202
203.. note::
204
205 Regardless of how you set your variables, if you use the "-e" option
Andrew Geissler3b8a17c2021-04-15 15:55:55 -0500206 with ``make``, the variables from the SDK setup script take precedence:
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500207 ::
208
209 $ make -e target
210
211
212The remainder of this section presents a simple Makefile example that
213demonstrates these variable behaviors.
214
215In a new shell environment variables are not established for the SDK
216until you run the setup script. For example, the following commands show
217a null value for the compiler variable (i.e.
218:term:`CC`).
219::
220
221 $ echo ${CC}
222
223 $
224
225Running the
226SDK setup script for a 64-bit build host and an i586-tuned target
Andrew Geissler09209ee2020-12-13 08:44:15 -0600227architecture for a ``core-image-sato`` image using the current &DISTRO;
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500228Yocto Project release and then echoing that variable shows the value
229established through the script:
230::
231
Andrew Geissler09209ee2020-12-13 08:44:15 -0600232 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500233 $ echo ${CC}
Andrew Geissler09209ee2020-12-13 08:44:15 -0600234 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500235
236To illustrate variable use, work through this simple "Hello World!"
237example:
238
2391. *Create a Working Directory and Populate It:* Create a clean
240 directory for your project and then make that directory your working
241 location.
242 ::
243
244 $ mkdir $HOME/helloworld
245 $ cd $HOME/helloworld
246
247 After
248 setting up the directory, populate it with files needed for the flow.
249 You need a ``main.c`` file from which you call your function, a
250 ``module.h`` file to contain headers, and a ``module.c`` that defines
251 your function.
252
253 Create the three files as follows:
254
255 - ``main.c``:
256 ::
257
258 #include "module.h"
259 void sample_func();
260 int main()
261 {
262 sample_func();
263 return 0;
264 }
265
266 - ``module.h``:
267 ::
268
269 #include <stdio.h>
270 void sample_func();
271
272 - ``module.c``:
273 ::
274
275 #include "module.h"
276 void sample_func()
277 {
278 printf("Hello World!");
279 printf("\n");
280 }
281
2822. *Source the Cross-Toolchain Environment Setup File:* As described
283 earlier in the manual, installing the cross-toolchain creates a
284 cross-toolchain environment setup script in the directory that the
285 SDK was installed. Before you can use the tools to develop your
286 project, you must source this setup script. The script begins with
287 the string "environment-setup" and contains the machine architecture,
288 which is followed by the string "poky-linux". For this example, the
289 command sources a script from the default SDK installation directory
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600290 that uses the 32-bit Intel x86 Architecture and the &DISTRO_NAME; Yocto
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500291 Project release:
292 ::
293
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600294 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500295
2963. *Create the Makefile:* For this example, the Makefile contains
297 two lines that can be used to set the ``CC`` variable. One line is
298 identical to the value that is set when you run the SDK environment
299 setup script, and the other line sets ``CC`` to "gcc", the default
300 GNU compiler on the build host:
301 ::
302
303 # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
304 # CC="gcc"
305 all: main.o module.o
306 ${CC} main.o module.o -o target_bin
307 main.o: main.c module.h
308 ${CC} -I . -c main.c
309 module.o: module.c
310 module.h ${CC} -I . -c module.c
311 clean:
312 rm -rf *.o
313 rm target_bin
314
3154. *Make the Project:* Use the ``make`` command to create the binary
316 output file. Because variables are commented out in the Makefile, the
317 value used for ``CC`` is the value set when the SDK environment setup
318 file was run:
319 ::
320
321 $ make
322 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
323 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
324 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
325
326 From the results of the previous command, you can see that
327 the compiler used was the compiler established through the ``CC``
328 variable defined in the setup script.
329
330 You can override the ``CC`` environment variable with the same
331 variable as set from the Makefile by uncommenting the line in the
332 Makefile and running ``make`` again.
333 ::
334
335 $ make clean
336 rm -rf *.o
337 rm target_bin
338 #
339 # Edit the Makefile by uncommenting the line that sets CC to "gcc"
340 #
341 $ make
342 gcc -I . -c main.c
343 gcc -I . -c module.c
344 gcc main.o module.o -o target_bin
345
346 As shown in the previous example, the
347 cross-toolchain compiler is not used. Rather, the default compiler is
348 used.
349
350 This next case shows how to override a variable by providing the
351 variable as part of the command line. Go into the Makefile and
352 re-insert the comment character so that running ``make`` uses the
353 established SDK compiler. However, when you run ``make``, use a
354 command-line argument to set ``CC`` to "gcc":
355 ::
356
357 $ make clean
358 rm -rf *.o
359 rm target_bin
360 #
361 # Edit the Makefile to comment out the line setting CC to "gcc"
362 #
363 $ make
364 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
365 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
366 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
367 $ make clean
368 rm -rf *.o
369 rm target_bin
370 $ make CC="gcc"
371 gcc -I . -c main.c
372 gcc -I . -c module.c
373 gcc main.o module.o -o target_bin
374
375 In the previous case, the command-line argument overrides the SDK
376 environment variable.
377
378 In this last case, edit Makefile again to use the "gcc" compiler but
379 then use the "-e" option on the ``make`` command line:
380 ::
381
382 $ make clean
383 rm -rf *.o
384 rm target_bin
385 #
386 # Edit the Makefile to use "gcc"
387 #
388 $ make
389 gcc -I . -c main.c
390 gcc -I . -c module.c
391 gcc main.o module.o -o target_bin
392 $ make clean
393 rm -rf *.o
394 rm target_bin
395 $ make -e
396 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
397 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
398 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
399
400 In the previous case, the "-e" option forces ``make`` to
401 use the SDK environment variables regardless of the values in the
402 Makefile.
403
4045. *Execute Your Project:* To execute the project (i.e. ``target_bin``),
405 use the following command:
406 ::
407
408 $ ./target_bin
409 Hello World!
410
411 .. note::
412
413 If you used the cross-toolchain compiler to build
414 target_bin
415 and your build host differs in architecture from that of the
416 target machine, you need to run your project on the target device.
417
418 As expected, the project displays the "Hello World!" message.