1.. SPDX-License-Identifier: CC-BY-SA-2.0-UK
2
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
13Once you have a suitable :ref:`sdk-manual/intro:the cross-development toolchain`
14installed, 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      $ touch README
51
52   Create the remaining
53   three files as follows:
54
55   -  ``hello.c``::
56
57         #include <stdio.h>
58
59         main()
60             {
61                 printf("Hello World!\n");
62             }
63
64   -  ``configure.ac``::
65
66         AC_INIT(hello,0.1)
67         AM_INIT_AUTOMAKE([foreign])
68         AC_PROG_CC
69         AC_CONFIG_FILES(Makefile)
70         AC_OUTPUT
71
72   -  ``Makefile.am``::
73
74         bin_PROGRAMS = hello
75         hello_SOURCES = hello.c
76
772. *Source the Cross-Toolchain Environment Setup File:* As described
78   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
85   that uses the 32-bit Intel x86 Architecture and the &DISTRO; Yocto
86   Project release::
87
88      $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
89
903. *Create the configure Script:* Use the ``autoreconf`` command to
91   generate the ``configure`` script.
92   ::
93
94      $ autoreconf
95
96   The ``autoreconf``
97   tool takes care of running the other Autotools such as ``aclocal``,
98   ``autoconf``, and ``automake``.
99
100   .. note::
101
102      If you get errors from ``configure.ac``, which ``autoreconf``
103      runs, that indicate missing files, you can use the "-i" option,
104      which ensures missing auxiliary files are copied to the build
105      host.
106
1074. *Cross-Compile the Project:* This command compiles the project using
108   the cross-compiler. The
109   :term:`CONFIGURE_FLAGS`
110   environment variable provides the minimal arguments for GNU
111   configure::
112
113      $ ./configure ${CONFIGURE_FLAGS}
114
115   For an Autotools-based
116   project, you can use the cross-toolchain by just passing the
117   appropriate host option to ``configure.sh``. The host option you use
118   is derived from the name of the environment setup script found in the
119   directory in which you installed the cross-toolchain. For example,
120   the host option for an ARM-based target that uses the GNU EABI is
121   ``armv5te-poky-linux-gnueabi``. You will notice that the name of the
122   script is ``environment-setup-armv5te-poky-linux-gnueabi``. Thus, the
123   following command works to update your project and rebuild it using
124   the appropriate cross-toolchain tools::
125
126     $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=sysroot_dir
127
1285. *Make and Install the Project:* These two commands generate and
129   install the project into the destination directory::
130
131      $ make
132      $ make install DESTDIR=./tmp
133
134   .. note::
135
136      To learn about environment variables established when you run the
137      cross-toolchain environment setup script and how they are used or
138      overridden by the Makefile, see the
139      :ref:`sdk-manual/working-projects:makefile-based projects` section.
140
141   This next command is a simple way to verify the installation of your
142   project. Running the command prints the architecture on which the
143   binary file can run. This architecture should be the same
144   architecture that the installed cross-toolchain supports.
145   ::
146
147      $ file ./tmp/usr/local/bin/hello
148
1496. *Execute Your Project:* To execute the project, you would need to run
150   it on your target hardware. If your target hardware happens to be
151   your build host, you could run the project as follows::
152
153      $ ./tmp/usr/local/bin/hello
154
155   As expected, the project displays the "Hello World!" message.
156
157Makefile-Based Projects
158=======================
159
160Simple Makefile-based projects use and interact with the cross-toolchain
161environment variables established when you run the cross-toolchain
162environment setup script. The environment variables are subject to
163general ``make`` rules.
164
165This section presents a simple Makefile development flow and provides an
166example that lets you see how you can use cross-toolchain environment
167variables and Makefile variables during development.
168
169.. image:: figures/sdk-makefile-flow.png
170   :align: center
171
172The main point of this section is to explain the following three cases
173regarding variable behavior:
174
175-  *Case 1 - No Variables Set in the Makefile Map to Equivalent
176   Environment Variables Set in the SDK Setup Script:* Because matching
177   variables are not specifically set in the ``Makefile``, the variables
178   retain their values based on the environment setup script.
179
180-  *Case 2 - Variables Are Set in the Makefile that Map to Equivalent
181   Environment Variables from the SDK Setup Script:* Specifically
182   setting matching variables in the ``Makefile`` during the build
183   results in the environment settings of the variables being
184   overwritten. In this case, the variables you set in the ``Makefile``
185   are used.
186
187-  *Case 3 - Variables Are Set Using the Command Line that Map to
188   Equivalent Environment Variables from the SDK Setup Script:*
189   Executing the ``Makefile`` from the command line results in the
190   environment variables being overwritten. In this case, the
191   command-line content is used.
192
193.. note::
194
195   Regardless of how you set your variables, if you use the "-e" option
196   with ``make``, the variables from the SDK setup script take precedence::
197
198      $ make -e target
199
200
201The remainder of this section presents a simple Makefile example that
202demonstrates these variable behaviors.
203
204In a new shell environment variables are not established for the SDK
205until you run the setup script. For example, the following commands show
206a null value for the compiler variable (i.e.
207:term:`CC`).
208::
209
210   $ echo ${CC}
211
212   $
213
214Running the
215SDK setup script for a 64-bit build host and an i586-tuned target
216architecture for a ``core-image-sato`` image using the current &DISTRO;
217Yocto Project release and then echoing that variable shows the value
218established through the script::
219
220   $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
221   $ echo ${CC}
222   i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux
223
224To illustrate variable use, work through this simple "Hello World!"
225example:
226
2271. *Create a Working Directory and Populate It:* Create a clean
228   directory for your project and then make that directory your working
229   location.
230   ::
231
232      $ mkdir $HOME/helloworld
233      $ cd $HOME/helloworld
234
235   After
236   setting up the directory, populate it with files needed for the flow.
237   You need a ``main.c`` file from which you call your function, a
238   ``module.h`` file to contain headers, and a ``module.c`` that defines
239   your function.
240
241   Create the three files as follows:
242
243   -  ``main.c``::
244
245         #include "module.h"
246         void sample_func();
247         int main()
248         {
249             sample_func();
250             return 0;
251         }
252
253   -  ``module.h``::
254
255         #include <stdio.h>
256         void sample_func();
257
258   -  ``module.c``::
259
260         #include "module.h"
261         void sample_func()
262         {
263             printf("Hello World!");
264             printf("\n");
265         }
266
2672. *Source the Cross-Toolchain Environment Setup File:* As described
268   earlier in the manual, installing the cross-toolchain creates a
269   cross-toolchain environment setup script in the directory that the
270   SDK was installed. Before you can use the tools to develop your
271   project, you must source this setup script. The script begins with
272   the string "environment-setup" and contains the machine architecture,
273   which is followed by the string "poky-linux". For this example, the
274   command sources a script from the default SDK installation directory
275   that uses the 32-bit Intel x86 Architecture and the &DISTRO_NAME; Yocto
276   Project release::
277
278      $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
279
2803. *Create the Makefile:* For this example, the Makefile contains
281   two lines that can be used to set the :term:`CC` variable. One line is
282   identical to the value that is set when you run the SDK environment
283   setup script, and the other line sets :term:`CC` to "gcc", the default
284   GNU compiler on the build host::
285
286      # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
287      # CC="gcc"
288      all: main.o module.o
289      	${CC} main.o module.o -o target_bin
290      main.o: main.c module.h
291      	${CC} -I . -c main.c
292      module.o: module.c
293      	module.h ${CC} -I . -c module.c
294      clean:
295      	rm -rf *.o
296      	rm target_bin
297
2984. *Make the Project:* Use the ``make`` command to create the binary
299   output file. Because variables are commented out in the Makefile, the
300   value used for :term:`CC` is the value set when the SDK environment setup
301   file was run::
302
303      $ make
304      i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
305      i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
306      i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
307
308   From the results of the previous command, you can see that
309   the compiler used was the compiler established through the :term:`CC`
310   variable defined in the setup script.
311
312   You can override the :term:`CC` environment variable with the same
313   variable as set from the Makefile by uncommenting the line in the
314   Makefile and running ``make`` again.
315   ::
316
317      $ make clean
318      rm -rf *.o
319      rm target_bin
320      #
321      # Edit the Makefile by uncommenting the line that sets CC to "gcc"
322      #
323      $ make
324      gcc -I . -c main.c
325      gcc -I . -c module.c
326      gcc main.o module.o -o target_bin
327
328   As shown in the previous example, the
329   cross-toolchain compiler is not used. Rather, the default compiler is
330   used.
331
332   This next case shows how to override a variable by providing the
333   variable as part of the command line. Go into the Makefile and
334   re-insert the comment character so that running ``make`` uses the
335   established SDK compiler. However, when you run ``make``, use a
336   command-line argument to set :term:`CC` to "gcc"::
337
338      $ make clean
339      rm -rf *.o
340      rm target_bin
341      #
342      # Edit the Makefile to comment out the line setting CC to "gcc"
343      #
344      $ make
345      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
346      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
347      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
348      $ make clean
349      rm -rf *.o
350      rm target_bin
351      $ make CC="gcc"
352      gcc -I . -c main.c
353      gcc -I . -c module.c
354      gcc main.o module.o -o target_bin
355
356   In the previous case, the command-line argument overrides the SDK
357   environment variable.
358
359   In this last case, edit Makefile again to use the "gcc" compiler but
360   then use the "-e" option on the ``make`` command line::
361
362      $ make clean
363      rm -rf *.o
364      rm target_bin
365      #
366      # Edit the Makefile to use "gcc"
367      #
368      $ make
369      gcc -I . -c main.c
370      gcc -I . -c module.c
371      gcc main.o module.o -o target_bin
372      $ make clean
373      rm -rf *.o
374      rm target_bin
375      $ make -e
376      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
377      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
378      i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
379
380   In the previous case, the "-e" option forces ``make`` to
381   use the SDK environment variables regardless of the values in the
382   Makefile.
383
3845. *Execute Your Project:* To execute the project (i.e. ``target_bin``),
385   use the following command::
386
387      $ ./target_bin
388      Hello World!
389
390   .. note::
391
392      If you used the cross-toolchain compiler to build
393      target_bin
394      and your build host differs in architecture from that of the
395      target machine, you need to run your project on the target device.
396
397   As expected, the project displays the "Hello World!" message.
398