sdk-working-projects.xml 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  1. <!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  2. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"
  3. [<!ENTITY % poky SYSTEM "../poky.ent"> %poky; ] >
  4. <chapter id='sdk-working-projects'>
  5. <title>Using the SDK Toolchain Directly</title>
  6. <para>
  7. You can use the SDK toolchain directly with Makefile,
  8. Autotools, and <trademark class='trade'>Eclipse</trademark>-based
  9. projects.
  10. This chapter covers the first two, while the
  11. "<link linkend='sdk-eclipse-project'>Developing Applications Using <trademark class='trade'>Eclipse</trademark></link>"
  12. Chapter covers the latter.
  13. </para>
  14. <section id='autotools-based-projects'>
  15. <title>Autotools-Based Projects</title>
  16. <para>
  17. Once you have a suitable
  18. <ulink url='&YOCTO_DOCS_REF_URL;#cross-development-toolchain'>cross-development toolchain</ulink>
  19. installed, it is very easy to develop a project using the
  20. <ulink url='https://en.wikipedia.org/wiki/GNU_Build_System'>GNU Autotools-based</ulink>
  21. workflow, which is outside of the
  22. <ulink url='&YOCTO_DOCS_REF_URL;#build-system-term'>OpenEmbedded build system</ulink>.
  23. </para>
  24. <para>
  25. The following figure presents a simple Autotools workflow.
  26. <imagedata fileref="figures/sdk-autotools-flow.png" width="7in" height="8in" align="center" />
  27. </para>
  28. <para>
  29. Follow these steps to create a simple Autotools-based
  30. "Hello World" project:
  31. <note>
  32. For more information on the GNU Autotools workflow,
  33. see the same example on the
  34. <ulink url='https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en'>GNOME Developer</ulink>
  35. site.
  36. </note>
  37. <orderedlist>
  38. <listitem><para>
  39. <emphasis>Create a Working Directory and Populate It:</emphasis>
  40. Create a clean directory for your project and then make
  41. that directory your working location.
  42. <literallayout class='monospaced'>
  43. $ mkdir $HOME/helloworld
  44. $ cd $HOME/helloworld
  45. </literallayout>
  46. After setting up the directory, populate it with files
  47. needed for the flow.
  48. You need a project source file, a file to help with
  49. configuration, and a file to help create the Makefile,
  50. and a README file:
  51. <filename>hello.c</filename>,
  52. <filename>configure.ac</filename>,
  53. <filename>Makefile.am</filename>, and
  54. <filename>README</filename>, respectively.</para>
  55. <para> Use the following command to create an empty README
  56. file, which is required by GNU Coding Standards:
  57. <literallayout class='monospaced'>
  58. $ touch README
  59. </literallayout>
  60. Create the remaining three files as follows:
  61. <itemizedlist>
  62. <listitem><para>
  63. <emphasis><filename>hello.c</filename>:</emphasis>
  64. <literallayout class='monospaced'>
  65. #include &lt;stdio.h&gt;
  66. main()
  67. {
  68. printf("Hello World!\n");
  69. }
  70. </literallayout>
  71. </para></listitem>
  72. <listitem><para>
  73. <emphasis><filename>configure.ac</filename>:</emphasis>
  74. <literallayout class='monospaced'>
  75. AC_INIT(hello,0.1)
  76. AM_INIT_AUTOMAKE([foreign])
  77. AC_PROG_CC
  78. AC_CONFIG_FILES(Makefile)
  79. AC_OUTPUT
  80. </literallayout>
  81. </para></listitem>
  82. <listitem><para>
  83. <emphasis><filename>Makefile.am</filename>:</emphasis>
  84. <literallayout class='monospaced'>
  85. bin_PROGRAMS = hello
  86. hello_SOURCES = hello.c
  87. </literallayout>
  88. </para></listitem>
  89. </itemizedlist>
  90. </para></listitem>
  91. <listitem><para>
  92. <emphasis>Source the Cross-Toolchain
  93. Environment Setup File:</emphasis>
  94. As described earlier in the manual, installing the
  95. cross-toolchain creates a cross-toolchain
  96. environment setup script in the directory that the SDK
  97. was installed.
  98. Before you can use the tools to develop your project,
  99. you must source this setup script.
  100. The script begins with the string "environment-setup"
  101. and contains the machine architecture, which is
  102. followed by the string "poky-linux".
  103. For this example, the command sources a script from the
  104. default SDK installation directory that uses the
  105. 32-bit Intel x86 Architecture and the
  106. &DISTRO_NAME; Yocto Project release:
  107. <literallayout class='monospaced'>
  108. $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
  109. </literallayout>
  110. </para></listitem>
  111. <listitem><para>
  112. <emphasis>Create the <filename>configure</filename> Script:</emphasis>
  113. Use the <filename>autoreconf</filename> command to
  114. generate the <filename>configure</filename> script.
  115. <literallayout class='monospaced'>
  116. $ autoreconf
  117. </literallayout>
  118. The <filename>autoreconf</filename> tool takes care
  119. of running the other Autotools such as
  120. <filename>aclocal</filename>,
  121. <filename>autoconf</filename>, and
  122. <filename>automake</filename>.
  123. <note>
  124. If you get errors from
  125. <filename>configure.ac</filename>, which
  126. <filename>autoreconf</filename> runs, that indicate
  127. missing files, you can use the "-i" option, which
  128. ensures missing auxiliary files are copied to the build
  129. host.
  130. </note>
  131. </para></listitem>
  132. <listitem><para>
  133. <emphasis>Cross-Compile the Project:</emphasis>
  134. This command compiles the project using the
  135. cross-compiler.
  136. The
  137. <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIGURE_FLAGS'><filename>CONFIGURE_FLAGS</filename></ulink>
  138. environment variable provides the minimal arguments for
  139. GNU configure:
  140. <literallayout class='monospaced'>
  141. $ ./configure ${CONFIGURE_FLAGS}
  142. </literallayout>
  143. For an Autotools-based project, you can use the
  144. cross-toolchain by just passing the appropriate host
  145. option to <filename>configure.sh</filename>.
  146. The host option you use is derived from the name of the
  147. environment setup script found in the directory in which
  148. you installed the cross-toolchain.
  149. For example, the host option for an ARM-based target that
  150. uses the GNU EABI is
  151. <filename>armv5te-poky-linux-gnueabi</filename>.
  152. You will notice that the name of the script is
  153. <filename>environment-setup-armv5te-poky-linux-gnueabi</filename>.
  154. Thus, the following command works to update your project
  155. and rebuild it using the appropriate cross-toolchain tools:
  156. <literallayout class='monospaced'>
  157. $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=<replaceable>sysroot_dir</replaceable>
  158. </literallayout>
  159. </para></listitem>
  160. <listitem><para>
  161. <emphasis>Make and Install the Project:</emphasis>
  162. These two commands generate and install the project
  163. into the destination directory:
  164. <literallayout class='monospaced'>
  165. $ make
  166. $ make install DESTDIR=./tmp
  167. </literallayout>
  168. <note>
  169. To learn about environment variables established
  170. when you run the cross-toolchain environment setup
  171. script and how they are used or overridden when
  172. the Makefile, see the
  173. "<link linkend='makefile-based-projects'>Makefile-Based Projects</link>"
  174. section.
  175. </note>
  176. This next command is a simple way to verify the
  177. installation of your project.
  178. Running the command prints the architecture on which
  179. the binary file can run.
  180. This architecture should be the same architecture that
  181. the installed cross-toolchain supports.
  182. <literallayout class='monospaced'>
  183. $ file ./tmp/usr/local/bin/hello
  184. </literallayout>
  185. </para></listitem>
  186. <listitem><para>
  187. <emphasis>Execute Your Project:</emphasis>
  188. To execute the project, you would need to run it on your
  189. target hardware.
  190. If your target hardware happens to be your build host,
  191. you could run the project as follows:
  192. <literallayout class='monospaced'>
  193. $ ./tmp/usr/local/bin/hello
  194. </literallayout>
  195. As expected, the project displays the "Hello World!"
  196. message.
  197. </para></listitem>
  198. </orderedlist>
  199. </para>
  200. </section>
  201. <section id='makefile-based-projects'>
  202. <title>Makefile-Based Projects</title>
  203. <para>
  204. Simple Makefile-based projects use and interact with the
  205. cross-toolchain environment variables established when you run
  206. the cross-toolchain environment setup script.
  207. The environment variables are subject to general
  208. <filename>make</filename> rules.
  209. </para>
  210. <para>
  211. This section presents a simple Makefile development flow and
  212. provides an example that lets you see how you can use
  213. cross-toolchain environment variables and Makefile variables
  214. during development.
  215. <imagedata fileref="figures/sdk-makefile-flow.png" width="6in" height="7in" align="center" />
  216. </para>
  217. <para>
  218. The main point of this section is to explain the following three
  219. cases regarding variable behavior:
  220. <itemizedlist>
  221. <listitem><para>
  222. <emphasis>Case 1 - No Variables Set in the
  223. <filename>Makefile</filename> Map to Equivalent
  224. Environment Variables Set in the SDK Setup Script:</emphasis>
  225. Because matching variables are not specifically set in the
  226. <filename>Makefile</filename>, the variables retain their
  227. values based on the environment setup script.
  228. </para></listitem>
  229. <listitem><para>
  230. <emphasis>Case 2 - Variables Are Set in the Makefile that
  231. Map to Equivalent Environment Variables from the SDK
  232. Setup Script:</emphasis>
  233. Specifically setting matching variables in the
  234. <filename>Makefile</filename> during the build results in
  235. the environment settings of the variables being
  236. overwritten.
  237. In this case, the variables you set in the
  238. <filename>Makefile</filename> are used.
  239. </para></listitem>
  240. <listitem><para>
  241. <emphasis>Case 3 - Variables Are Set Using the Command Line
  242. that Map to Equivalent Environment Variables from the
  243. SDK Setup Script:</emphasis>
  244. Executing the <filename>Makefile</filename> from the
  245. command line results in the environment variables being
  246. overwritten.
  247. In this case, the command-line content is used.
  248. </para></listitem>
  249. </itemizedlist>
  250. <note>
  251. Regardless of how you set your variables, if you use
  252. the "-e" option with <filename>make</filename>, the
  253. variables from the SDK setup script take precedence:
  254. <literallayout class='monospaced'>
  255. $ make -e <replaceable>target</replaceable>
  256. </literallayout>
  257. </note>
  258. </para>
  259. <para>
  260. The remainder of this section presents a simple Makefile example
  261. that demonstrates these variable behaviors.
  262. </para>
  263. <para>
  264. In a new shell environment variables are not established for the
  265. SDK until you run the setup script.
  266. For example, the following commands show a null value for the
  267. compiler variable (i.e.
  268. <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'><filename>CC</filename></ulink>).
  269. <literallayout class='monospaced'>
  270. $ echo ${CC}
  271. $
  272. </literallayout>
  273. Running the SDK setup script for a 64-bit build host and an
  274. i586-tuned target architecture for a
  275. <filename>core-image-sato</filename> image using the current
  276. &DISTRO; Yocto Project release and then echoing that variable
  277. shows the value established through the script:
  278. <literallayout class='monospaced'>
  279. $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
  280. $ echo ${CC}
  281. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
  282. </literallayout>
  283. </para>
  284. <para>
  285. To illustrate variable use, work through this simple "Hello World!"
  286. example:
  287. <orderedlist>
  288. <listitem><para>
  289. <emphasis>Create a Working Directory and Populate It:</emphasis>
  290. Create a clean directory for your project and then make
  291. that directory your working location.
  292. <literallayout class='monospaced'>
  293. $ mkdir $HOME/helloworld
  294. $ cd $HOME/helloworld
  295. </literallayout>
  296. After setting up the directory, populate it with files
  297. needed for the flow.
  298. You need a <filename>main.c</filename> file from which you
  299. call your function, a <filename>module.h</filename> file
  300. to contain headers, and a <filename>module.c</filename>
  301. that defines your function.
  302. </para>
  303. <para>Create the three files as follows:
  304. <itemizedlist>
  305. <listitem><para>
  306. <emphasis><filename>main.c</filename>:</emphasis>
  307. <literallayout class='monospaced'>
  308. #include "module.h"
  309. void sample_func();
  310. int main()
  311. {
  312. sample_func();
  313. return 0;
  314. }
  315. </literallayout>
  316. </para></listitem>
  317. <listitem><para>
  318. <emphasis><filename>module.h</filename>:</emphasis>
  319. <literallayout class='monospaced'>
  320. #include &lt;stdio.h&gt;
  321. void sample_func();
  322. </literallayout>
  323. </para></listitem>
  324. <listitem><para>
  325. <emphasis><filename>module.c</filename>:</emphasis>
  326. <literallayout class='monospaced'>
  327. #include "module.h"
  328. void sample_func()
  329. {
  330. printf("Hello World!");
  331. printf("\n");
  332. }
  333. </literallayout>
  334. </para></listitem>
  335. </itemizedlist>
  336. </para></listitem>
  337. <listitem><para>
  338. <emphasis>Source the Cross-Toolchain Environment Setup File:</emphasis>
  339. As described earlier in the manual, installing the
  340. cross-toolchain creates a cross-toolchain environment setup
  341. script in the directory that the SDK was installed.
  342. Before you can use the tools to develop your project,
  343. you must source this setup script.
  344. The script begins with the string "environment-setup"
  345. and contains the machine architecture, which is
  346. followed by the string "poky-linux".
  347. For this example, the command sources a script from the
  348. default SDK installation directory that uses the
  349. 32-bit Intel x86 Architecture and the
  350. &DISTRO_NAME; Yocto Project release:
  351. <literallayout class='monospaced'>
  352. $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
  353. </literallayout>
  354. </para></listitem>
  355. <listitem><para>
  356. <emphasis>Create the <filename>Makefile</filename>:</emphasis>
  357. For this example, the Makefile contains two lines that
  358. can be used to set the <filename>CC</filename> variable.
  359. One line is identical to the value that is set when you
  360. run the SDK environment setup script, and the other line
  361. sets <filename>CC</filename> to "gcc", the default GNU
  362. compiler on the build host:
  363. <literallayout class='monospaced'>
  364. # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux
  365. # CC="gcc"
  366. all: main.o module.o
  367. ${CC} main.o module.o -o target_bin
  368. main.o: main.c module.h
  369. ${CC} -I . -c main.c
  370. module.o: module.c module.h
  371. ${CC} -I . -c module.c
  372. clean:
  373. rm -rf *.o
  374. rm target_bin
  375. </literallayout>
  376. </para></listitem>
  377. <listitem><para>
  378. <emphasis>Make the Project:</emphasis>
  379. Use the <filename>make</filename> command to create the
  380. binary output file.
  381. Because variables are commented out in the Makefile,
  382. the value used for <filename>CC</filename> is the value
  383. set when the SDK environment setup file was run:
  384. <literallayout class='monospaced'>
  385. $ make
  386. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
  387. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
  388. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
  389. </literallayout>
  390. From the results of the previous command, you can see that
  391. the compiler used was the compiler established through
  392. the <filename>CC</filename> variable defined in the
  393. setup script.</para>
  394. <para>You can override the <filename>CC</filename>
  395. environment variable with the same variable as set from
  396. the Makefile by uncommenting the line in the Makefile
  397. and running <filename>make</filename> again.
  398. <literallayout class='monospaced'>
  399. $ make clean
  400. rm -rf *.o
  401. rm target_bin
  402. #
  403. # Edit the Makefile by uncommenting the line that sets CC to "gcc"
  404. #
  405. $ make
  406. gcc -I . -c main.c
  407. gcc -I . -c module.c
  408. gcc main.o module.o -o target_bin
  409. </literallayout>
  410. As shown in the previous example, the cross-toolchain
  411. compiler is not used.
  412. Rather, the default compiler is used.</para>
  413. <para>This next case shows how to override a variable
  414. by providing the variable as part of the command line.
  415. Go into the Makefile and re-insert the comment character
  416. so that running <filename>make</filename> uses
  417. the established SDK compiler.
  418. However, when you run <filename>make</filename>, use a
  419. command-line argument to set <filename>CC</filename>
  420. to "gcc":
  421. <literallayout class='monospaced'>
  422. $ make clean
  423. rm -rf *.o
  424. rm target_bin
  425. #
  426. # Edit the Makefile to comment out the line setting CC to "gcc"
  427. #
  428. $ make
  429. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
  430. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
  431. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
  432. $ make clean
  433. rm -rf *.o
  434. rm target_bin
  435. $ make CC="gcc"
  436. gcc -I . -c main.c
  437. gcc -I . -c module.c
  438. gcc main.o module.o -o target_bin
  439. </literallayout>
  440. In the previous case, the command-line argument overrides
  441. the SDK environment variable.</para>
  442. <para>In this last case, edit Makefile again to use the
  443. "gcc" compiler but then use the "-e" option on the
  444. <filename>make</filename> command line:
  445. <literallayout class='monospaced'>
  446. $ make clean
  447. rm -rf *.o
  448. rm target_bin
  449. #
  450. # Edit the Makefile to use "gcc"
  451. #
  452. $ make
  453. gcc -I . -c main.c
  454. gcc -I . -c module.c
  455. gcc main.o module.o -o target_bin
  456. $ make clean
  457. rm -rf *.o
  458. rm target_bin
  459. $ make -e
  460. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c
  461. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c
  462. i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin
  463. </literallayout>
  464. In the previous case, the "-e" option forces
  465. <filename>make</filename> to use the SDK environment
  466. variables regardless of the values in the Makefile.
  467. </para></listitem>
  468. <listitem><para>
  469. <emphasis>Execute Your Project:</emphasis>
  470. To execute the project (i.e.
  471. <filename>target_bin</filename>), use the following
  472. command:
  473. <literallayout class='monospaced'>
  474. $ ./target_bin
  475. Hello World!
  476. </literallayout>
  477. <note>
  478. If you used the cross-toolchain compiler to build
  479. <filename>target_bin</filename> and your build host
  480. differs in architecture from that of the target
  481. machine, you need to run your project on the target
  482. device.
  483. </note>
  484. As expected, the project displays the "Hello World!"
  485. message.
  486. </para></listitem>
  487. </orderedlist>
  488. </para>
  489. </section>
  490. </chapter>
  491. <!--
  492. vim: expandtab tw=80 ts=4
  493. -->