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 :wikipedia:`GNU 15Autotools-based <GNU_Build_System>` workflow, which is outside of the 16: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 :width: 70% 23 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 34#. *Create a Working Directory and Populate It:* Create a clean 35 directory for your project and then make that directory your working 36 location:: 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 77#. *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 90 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 95#. *Create the configure Script:* Use the ``autoreconf`` command to 96 generate the ``configure`` script:: 97 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 106 If you get errors from ``configure.ac``, which ``autoreconf`` 107 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 111#. *Cross-Compile the Project:* This command compiles the project using 112 the cross-compiler. The 113 :term:`CONFIGURE_FLAGS` 114 environment variable provides the minimal arguments for GNU 115 configure:: 116 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 128 the appropriate cross-toolchain tools:: 129 130 $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=sysroot_dir 131 132#. *Make and Install the Project:* These two commands generate and 133 install the project into the destination directory:: 134 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 142 overridden by the Makefile, see the 143 :ref:`sdk-manual/working-projects:makefile-based projects` section. 144 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 148 architecture that the installed cross-toolchain supports:: 149 150 $ file ./tmp/usr/local/bin/hello 151 152#. *Execute Your Project:* To execute the project, you would need to run 153 it on your target hardware. If your target hardware happens to be 154 your build host, you could run the project as follows:: 155 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 174 :width: 70% 175 176The main point of this section is to explain the following three cases 177regarding variable behavior: 178 179- *Case 1 --- No Variables Set in the Makefile Map to Equivalent 180 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 184- *Case 2 --- Variables Are Set in the Makefile that Map to Equivalent 185 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 191- *Case 3 --- Variables Are Set Using the Command Line that Map to 192 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 200 with ``make``, the variables from the SDK setup script take precedence:: 201 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. 211:term:`CC`):: 212 213 $ echo ${CC} 214 215 $ 216 217Running the 218SDK setup script for a 64-bit build host and an i586-tuned target 219architecture for a ``core-image-sato`` image using the current &DISTRO; 220Yocto Project release and then echoing that variable shows the value 221established through the script:: 222 223 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux 224 $ echo ${CC} 225 i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux 226 227To illustrate variable use, work through this simple "Hello World!" 228example: 229 230#. *Create a Working Directory and Populate It:* Create a clean 231 directory for your project and then make that directory your working 232 location:: 233 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 245 - ``main.c``:: 246 247 #include "module.h" 248 void sample_func(); 249 int main() 250 { 251 sample_func(); 252 return 0; 253 } 254 255 - ``module.h``:: 256 257 #include <stdio.h> 258 void sample_func(); 259 260 - ``module.c``:: 261 262 #include "module.h" 263 void sample_func() 264 { 265 printf("Hello World!"); 266 printf("\n"); 267 } 268 269#. *Source the Cross-Toolchain Environment Setup File:* As described 270 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 277 that uses the 32-bit Intel x86 Architecture and the &DISTRO_NAME; Yocto 278 Project release:: 279 280 $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux 281 282 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 287#. *Create the Makefile:* For this example, the Makefile contains 288 two lines that can be used to set the :term:`CC` variable. One line is 289 identical to the value that is set when you run the SDK environment 290 setup script, and the other line sets :term:`CC` to "gcc", the default 291 GNU compiler on the build host:: 292 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 296 ${CC} main.o module.o -o target_bin 297 main.o: main.c module.h 298 ${CC} -I . -c main.c 299 module.o: module.c module.h 300 ${CC} -I . -c module.c 301 clean: 302 rm -rf *.o 303 rm target_bin 304 305#. *Make the Project:* Use the ``make`` command to create the binary 306 output file. Because variables are commented out in the Makefile, the 307 value used for :term:`CC` is the value set when the SDK environment setup 308 file was run:: 309 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 316 the compiler used was the compiler established through the :term:`CC` 317 variable defined in the setup script. 318 319 You can override the :term:`CC` environment variable with the same 320 variable as set from the Makefile by uncommenting the line in the 321 Makefile and running ``make`` again:: 322 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 342 command-line argument to set :term:`CC` to "gcc":: 343 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 366 then use the "-e" option on the ``make`` command line:: 367 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 390#. *Execute Your Project:* To execute the project (i.e. ``target_bin``), 391 use the following command:: 392 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. 404