blob: 4236bcec24c63cc7b39f86b22b87e186bd961eb8 [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`
Patrick Williams7784c422022-11-17 07:29:11 -060014installed, it is very easy to develop a project using the :wikipedia:`GNU
15Autotools-based <GNU_Build_System>` workflow, which is outside of the
16:term:`OpenEmbedded Build System`.
Andrew Geisslerc9f78652020-09-18 14:11:35 -050017
18The following figure presents a simple Autotools workflow.
19
20.. image:: figures/sdk-autotools-flow.png
21 :align: center
Andrew Geisslerd5838332022-05-27 11:33:10 -050022 :width: 70%
Andrew Geisslerc9f78652020-09-18 14:11:35 -050023
24Follow these steps to create a simple Autotools-based "Hello World"
25project:
26
27.. note::
28
29 For more information on the GNU Autotools workflow, see the same
30 example on the
31 GNOME Developer
32 site.
33
Andrew Geissler517393d2023-01-13 08:55:19 -060034#. *Create a Working Directory and Populate It:* Create a clean
Andrew Geisslerc9f78652020-09-18 14:11:35 -050035 directory for your project and then make that directory your working
Andrew Geissler517393d2023-01-13 08:55:19 -060036 location::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050037
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
Andrew Geisslerc926e172021-05-07 16:11:35 -050048 required by GNU Coding Standards::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050049
50 $ touch README
51
52 Create the remaining
53 three files as follows:
54
Andrew Geisslerc926e172021-05-07 16:11:35 -050055 - ``hello.c``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050056
57 #include <stdio.h>
58
59 main()
60 {
61 printf("Hello World!\n");
62 }
63
Andrew Geisslerc926e172021-05-07 16:11:35 -050064 - ``configure.ac``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050065
66 AC_INIT(hello,0.1)
67 AM_INIT_AUTOMAKE([foreign])
68 AC_PROG_CC
69 AC_CONFIG_FILES(Makefile)
70 AC_OUTPUT
71
Andrew Geisslerc926e172021-05-07 16:11:35 -050072 - ``Makefile.am``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050073
74 bin_PROGRAMS = hello
75 hello_SOURCES = hello.c
76
Andrew Geissler517393d2023-01-13 08:55:19 -060077#. *Source the Cross-Toolchain Environment Setup File:* As described
Andrew Geisslerc9f78652020-09-18 14:11:35 -050078 earlier in the manual, installing the cross-toolchain creates a
79 cross-toolchain environment setup script in the directory that the
80 SDK was installed. Before you can use the tools to develop your
81 project, you must source this setup script. The script begins with
82 the string "environment-setup" and contains the machine architecture,
83 which is followed by the string "poky-linux". For this example, the
84 command sources a script from the default SDK installation directory
Andrew Geissler09209ee2020-12-13 08:44:15 -060085 that uses the 32-bit Intel x86 Architecture and the &DISTRO; Yocto
Andrew Geisslerc926e172021-05-07 16:11:35 -050086 Project release::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050087
Andrew Geissler09209ee2020-12-13 08:44:15 -060088 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -050089
Patrick Williams92b42cb2022-09-03 06:53:57 -050090 Another example is sourcing the environment setup directly in a Yocto
91 build::
92
93 $ source tmp/deploy/images/qemux86-64/environment-setup-core2-64-poky-linux
94
Andrew Geissler517393d2023-01-13 08:55:19 -060095#. *Create the configure Script:* Use the ``autoreconf`` command to
Patrick Williams92b42cb2022-09-03 06:53:57 -050096 generate the ``configure`` script::
Andrew Geisslerc9f78652020-09-18 14:11:35 -050097
98 $ autoreconf
99
100 The ``autoreconf``
101 tool takes care of running the other Autotools such as ``aclocal``,
102 ``autoconf``, and ``automake``.
103
104 .. note::
105
Andrew Geissler3b8a17c2021-04-15 15:55:55 -0500106 If you get errors from ``configure.ac``, which ``autoreconf``
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500107 runs, that indicate missing files, you can use the "-i" option,
108 which ensures missing auxiliary files are copied to the build
109 host.
110
Andrew Geissler517393d2023-01-13 08:55:19 -0600111#. *Cross-Compile the Project:* This command compiles the project using
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500112 the cross-compiler. The
113 :term:`CONFIGURE_FLAGS`
114 environment variable provides the minimal arguments for GNU
Andrew Geisslerc926e172021-05-07 16:11:35 -0500115 configure::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500116
117 $ ./configure ${CONFIGURE_FLAGS}
118
119 For an Autotools-based
120 project, you can use the cross-toolchain by just passing the
121 appropriate host option to ``configure.sh``. The host option you use
122 is derived from the name of the environment setup script found in the
123 directory in which you installed the cross-toolchain. For example,
124 the host option for an ARM-based target that uses the GNU EABI is
125 ``armv5te-poky-linux-gnueabi``. You will notice that the name of the
126 script is ``environment-setup-armv5te-poky-linux-gnueabi``. Thus, the
127 following command works to update your project and rebuild it using
Andrew Geisslerc926e172021-05-07 16:11:35 -0500128 the appropriate cross-toolchain tools::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500129
130 $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=sysroot_dir
131
Andrew Geissler517393d2023-01-13 08:55:19 -0600132#. *Make and Install the Project:* These two commands generate and
Andrew Geisslerc926e172021-05-07 16:11:35 -0500133 install the project into the destination directory::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500134
135 $ make
136 $ make install DESTDIR=./tmp
137
138 .. note::
139
140 To learn about environment variables established when you run the
141 cross-toolchain environment setup script and how they are used or
Andrew Geissler09036742021-06-25 14:25:14 -0500142 overridden by the Makefile, see the
143 :ref:`sdk-manual/working-projects:makefile-based projects` section.
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500144
145 This next command is a simple way to verify the installation of your
146 project. Running the command prints the architecture on which the
147 binary file can run. This architecture should be the same
Andrew Geissler517393d2023-01-13 08:55:19 -0600148 architecture that the installed cross-toolchain supports::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500149
150 $ file ./tmp/usr/local/bin/hello
151
Andrew Geissler517393d2023-01-13 08:55:19 -0600152#. *Execute Your Project:* To execute the project, you would need to run
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500153 it on your target hardware. If your target hardware happens to be
Andrew Geisslerc926e172021-05-07 16:11:35 -0500154 your build host, you could run the project as follows::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500155
156 $ ./tmp/usr/local/bin/hello
157
158 As expected, the project displays the "Hello World!" message.
159
160Makefile-Based Projects
161=======================
162
163Simple Makefile-based projects use and interact with the cross-toolchain
164environment variables established when you run the cross-toolchain
165environment setup script. The environment variables are subject to
166general ``make`` rules.
167
168This section presents a simple Makefile development flow and provides an
169example that lets you see how you can use cross-toolchain environment
170variables and Makefile variables during development.
171
172.. image:: figures/sdk-makefile-flow.png
173 :align: center
Andrew Geisslerd5838332022-05-27 11:33:10 -0500174 :width: 70%
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500175
176The main point of this section is to explain the following three cases
177regarding variable behavior:
178
Andrew Geissler615f2f12022-07-15 14:00:58 -0500179- *Case 1 --- No Variables Set in the Makefile Map to Equivalent
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500180 Environment Variables Set in the SDK Setup Script:* Because matching
181 variables are not specifically set in the ``Makefile``, the variables
182 retain their values based on the environment setup script.
183
Andrew Geissler615f2f12022-07-15 14:00:58 -0500184- *Case 2 --- Variables Are Set in the Makefile that Map to Equivalent
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500185 Environment Variables from the SDK Setup Script:* Specifically
186 setting matching variables in the ``Makefile`` during the build
187 results in the environment settings of the variables being
188 overwritten. In this case, the variables you set in the ``Makefile``
189 are used.
190
Andrew Geissler615f2f12022-07-15 14:00:58 -0500191- *Case 3 --- Variables Are Set Using the Command Line that Map to
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500192 Equivalent Environment Variables from the SDK Setup Script:*
193 Executing the ``Makefile`` from the command line results in the
194 environment variables being overwritten. In this case, the
195 command-line content is used.
196
197.. note::
198
199 Regardless of how you set your variables, if you use the "-e" option
Andrew Geisslerc926e172021-05-07 16:11:35 -0500200 with ``make``, the variables from the SDK setup script take precedence::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500201
202 $ make -e target
203
204
205The remainder of this section presents a simple Makefile example that
206demonstrates these variable behaviors.
207
208In a new shell environment variables are not established for the SDK
209until you run the setup script. For example, the following commands show
210a null value for the compiler variable (i.e.
Andrew Geissler517393d2023-01-13 08:55:19 -0600211:term:`CC`)::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500212
213 $ echo ${CC}
214
215 $
216
217Running the
218SDK setup script for a 64-bit build host and an i586-tuned target
Andrew Geissler09209ee2020-12-13 08:44:15 -0600219architecture for a ``core-image-sato`` image using the current &DISTRO;
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500220Yocto Project release and then echoing that variable shows the value
Andrew Geisslerc926e172021-05-07 16:11:35 -0500221established through the script::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500222
Andrew Geissler09209ee2020-12-13 08:44:15 -0600223 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500224 $ echo ${CC}
Andrew Geissler09209ee2020-12-13 08:44:15 -0600225 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500226
227To illustrate variable use, work through this simple "Hello World!"
228example:
229
Andrew Geissler517393d2023-01-13 08:55:19 -0600230#. *Create a Working Directory and Populate It:* Create a clean
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500231 directory for your project and then make that directory your working
Andrew Geissler517393d2023-01-13 08:55:19 -0600232 location::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500233
234 $ mkdir $HOME/helloworld
235 $ cd $HOME/helloworld
236
237 After
238 setting up the directory, populate it with files needed for the flow.
239 You need a ``main.c`` file from which you call your function, a
240 ``module.h`` file to contain headers, and a ``module.c`` that defines
241 your function.
242
243 Create the three files as follows:
244
Andrew Geisslerc926e172021-05-07 16:11:35 -0500245 - ``main.c``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500246
247 #include "module.h"
248 void sample_func();
249 int main()
250 {
251 sample_func();
252 return 0;
253 }
254
Andrew Geisslerc926e172021-05-07 16:11:35 -0500255 - ``module.h``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500256
257 #include <stdio.h>
258 void sample_func();
259
Andrew Geisslerc926e172021-05-07 16:11:35 -0500260 - ``module.c``::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500261
262 #include "module.h"
263 void sample_func()
264 {
265 printf("Hello World!");
266 printf("\n");
267 }
268
Andrew Geissler517393d2023-01-13 08:55:19 -0600269#. *Source the Cross-Toolchain Environment Setup File:* As described
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500270 earlier in the manual, installing the cross-toolchain creates a
271 cross-toolchain environment setup script in the directory that the
272 SDK was installed. Before you can use the tools to develop your
273 project, you must source this setup script. The script begins with
274 the string "environment-setup" and contains the machine architecture,
275 which is followed by the string "poky-linux". For this example, the
276 command sources a script from the default SDK installation directory
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600277 that uses the 32-bit Intel x86 Architecture and the &DISTRO_NAME; Yocto
Andrew Geisslerc926e172021-05-07 16:11:35 -0500278 Project release::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500279
Andrew Geisslerd1e89492021-02-12 15:35:20 -0600280 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500281
Patrick Williams92b42cb2022-09-03 06:53:57 -0500282 Another example is sourcing the environment setup directly in a Yocto
283 build::
284
285 $ source tmp/deploy/images/qemux86-64/environment-setup-core2-64-poky-linux
286
Andrew Geissler517393d2023-01-13 08:55:19 -0600287#. *Create the Makefile:* For this example, the Makefile contains
Andrew Geissler09036742021-06-25 14:25:14 -0500288 two lines that can be used to set the :term:`CC` variable. One line is
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500289 identical to the value that is set when you run the SDK environment
Andrew Geissler09036742021-06-25 14:25:14 -0500290 setup script, and the other line sets :term:`CC` to "gcc", the default
Andrew Geisslerc926e172021-05-07 16:11:35 -0500291 GNU compiler on the build host::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500292
293 # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
294 # CC="gcc"
295 all: main.o module.o
Patrick Williamsb542dec2023-06-09 01:26:37 -0500296 ${CC} main.o module.o -o target_bin
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500297 main.o: main.c module.h
Patrick Williams44b3caf2024-04-12 16:51:14 -0500298 ${CC} -I . -c main.c
Patrick Williamsb542dec2023-06-09 01:26:37 -0500299 module.o: module.c module.h
300 ${CC} -I . -c module.c
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500301 clean:
Patrick Williams44b3caf2024-04-12 16:51:14 -0500302 rm -rf *.o
303 rm target_bin
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500304
Andrew Geissler517393d2023-01-13 08:55:19 -0600305#. *Make the Project:* Use the ``make`` command to create the binary
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500306 output file. Because variables are commented out in the Makefile, the
Andrew Geissler09036742021-06-25 14:25:14 -0500307 value used for :term:`CC` is the value set when the SDK environment setup
Andrew Geisslerc926e172021-05-07 16:11:35 -0500308 file was run::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500309
310 $ make
311 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
312 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
313 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
314
315 From the results of the previous command, you can see that
Andrew Geissler09036742021-06-25 14:25:14 -0500316 the compiler used was the compiler established through the :term:`CC`
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500317 variable defined in the setup script.
318
Andrew Geissler09036742021-06-25 14:25:14 -0500319 You can override the :term:`CC` environment variable with the same
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500320 variable as set from the Makefile by uncommenting the line in the
Andrew Geissler517393d2023-01-13 08:55:19 -0600321 Makefile and running ``make`` again::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500322
323 $ make clean
324 rm -rf *.o
325 rm target_bin
326 #
327 # Edit the Makefile by uncommenting the line that sets CC to "gcc"
328 #
329 $ make
330 gcc -I . -c main.c
331 gcc -I . -c module.c
332 gcc main.o module.o -o target_bin
333
334 As shown in the previous example, the
335 cross-toolchain compiler is not used. Rather, the default compiler is
336 used.
337
338 This next case shows how to override a variable by providing the
339 variable as part of the command line. Go into the Makefile and
340 re-insert the comment character so that running ``make`` uses the
341 established SDK compiler. However, when you run ``make``, use a
Andrew Geissler09036742021-06-25 14:25:14 -0500342 command-line argument to set :term:`CC` to "gcc"::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500343
344 $ make clean
345 rm -rf *.o
346 rm target_bin
347 #
348 # Edit the Makefile to comment out the line setting CC to "gcc"
349 #
350 $ make
351 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
352 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
353 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
354 $ make clean
355 rm -rf *.o
356 rm target_bin
357 $ make CC="gcc"
358 gcc -I . -c main.c
359 gcc -I . -c module.c
360 gcc main.o module.o -o target_bin
361
362 In the previous case, the command-line argument overrides the SDK
363 environment variable.
364
365 In this last case, edit Makefile again to use the "gcc" compiler but
Andrew Geisslerc926e172021-05-07 16:11:35 -0500366 then use the "-e" option on the ``make`` command line::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500367
368 $ make clean
369 rm -rf *.o
370 rm target_bin
371 #
372 # Edit the Makefile to use "gcc"
373 #
374 $ make
375 gcc -I . -c main.c
376 gcc -I . -c module.c
377 gcc main.o module.o -o target_bin
378 $ make clean
379 rm -rf *.o
380 rm target_bin
381 $ make -e
382 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
383 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
384 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
385
386 In the previous case, the "-e" option forces ``make`` to
387 use the SDK environment variables regardless of the values in the
388 Makefile.
389
Andrew Geissler517393d2023-01-13 08:55:19 -0600390#. *Execute Your Project:* To execute the project (i.e. ``target_bin``),
Andrew Geisslerc926e172021-05-07 16:11:35 -0500391 use the following command::
Andrew Geisslerc9f78652020-09-18 14:11:35 -0500392
393 $ ./target_bin
394 Hello World!
395
396 .. note::
397
398 If you used the cross-toolchain compiler to build
399 target_bin
400 and your build host differs in architecture from that of the
401 target machine, you need to run your project on the target device.
402
403 As expected, the project displays the "Hello World!" message.