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