sdk-extensible.xml 91 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685
  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-extensible'>
  5. <title>Using the Extensible SDK</title>
  6. <para>
  7. This chapter describes the extensible SDK and how to install it.
  8. Information covers the pieces of the SDK, how to install it, and
  9. presents a look at using the <filename>devtool</filename>
  10. functionality.
  11. The extensible SDK makes it easy to add new applications and libraries
  12. to an image, modify the source for an existing component, test
  13. changes on the target hardware, and ease integration into the rest of
  14. the
  15. <ulink url='&YOCTO_DOCS_REF_URL;#build-system-term'>OpenEmbedded build system</ulink>.
  16. <note>
  17. For a side-by-side comparison of main features supported for an
  18. extensible SDK as compared to a standard SDK, see the
  19. "<link linkend='sdk-manual-intro'>Introduction</link>"
  20. section.
  21. </note>
  22. </para>
  23. <para>
  24. In addition to the functionality available through
  25. <filename>devtool</filename>, you can alternatively make use of the
  26. toolchain directly, for example from Makefile, Autotools, and
  27. <trademark class='trade'>Eclipse</trademark>-based projects.
  28. See the
  29. "<link linkend='sdk-working-projects'>Using the SDK Toolchain Directly</link>"
  30. chapter for more information.
  31. </para>
  32. <section id='sdk-extensible-sdk-intro'>
  33. <title>Why use the Extensible SDK and What is in It?</title>
  34. <para>
  35. The extensible SDK provides a cross-development toolchain and
  36. libraries tailored to the contents of a specific image.
  37. You would use the Extensible SDK if you want a toolchain experience
  38. supplemented with the powerful set of <filename>devtool</filename>
  39. commands tailored for the Yocto Project environment.
  40. </para>
  41. <para>
  42. The installed extensible SDK consists of several files and
  43. directories.
  44. Basically, it contains an SDK environment setup script, some
  45. configuration files, an internal build system, and the
  46. <filename>devtool</filename> functionality.
  47. </para>
  48. </section>
  49. <section id='sdk-setting-up-to-use-the-extensible-sdk'>
  50. <title>Setting Up to Use the Extensible SDK</title>
  51. <para>
  52. The first thing you need to do is install the SDK on your host
  53. development machine by running the <filename>*.sh</filename>
  54. installation script.
  55. </para>
  56. <para>
  57. You can download a tarball installer, which includes the
  58. pre-built toolchain, the <filename>runqemu</filename>
  59. script, the internal build system, <filename>devtool</filename>,
  60. and support files from the appropriate directory under
  61. <ulink url='&YOCTO_TOOLCHAIN_DL_URL;'></ulink>.
  62. Toolchains are available for 32-bit and 64-bit x86 development
  63. systems from the <filename>i686</filename> and
  64. <filename>x86_64</filename> directories, respectively.
  65. The toolchains the Yocto Project provides are based off the
  66. <filename>core-image-sato</filename> image and contain
  67. libraries appropriate for developing against that image.
  68. Each type of development system supports five or more target
  69. architectures.
  70. </para>
  71. <para>
  72. The names of the tarball installer scripts are such that a
  73. string representing the host system appears first in the
  74. filename and then is immediately followed by a string
  75. representing the target architecture.
  76. An extensible SDK has the string "-ext" as part of the name.
  77. <literallayout class='monospaced'>
  78. poky-glibc-<replaceable>host_system</replaceable>-<replaceable>image_type</replaceable>-<replaceable>arch</replaceable>-toolchain-ext-<replaceable>release_version</replaceable>.sh
  79. Where:
  80. <replaceable>host_system</replaceable> is a string representing your development system:
  81. i686 or x86_64.
  82. <replaceable>image_type</replaceable> is the image for which the SDK was built.
  83. <replaceable>arch</replaceable> is a string representing the tuned target architecture:
  84. i586, x86_64, powerpc, mips, armv7a or armv5te
  85. <replaceable>release_version</replaceable> is a string representing the release number of the
  86. Yocto Project:
  87. &DISTRO;, &DISTRO;+snapshot
  88. </literallayout>
  89. For example, the following SDK installer is for a 64-bit
  90. development host system and a i586-tuned target architecture
  91. based off the SDK for <filename>core-image-sato</filename> and
  92. using the current &DISTRO; snapshot:
  93. <literallayout class='monospaced'>
  94. poky-glibc-x86_64-core-image-sato-i586-toolchain-ext-&DISTRO;.sh
  95. </literallayout>
  96. <note>
  97. As an alternative to downloading an SDK, you can build the
  98. SDK installer.
  99. For information on building the installer, see the
  100. "<link linkend='sdk-building-an-sdk-installer'>Building an SDK Installer</link>"
  101. section.
  102. Another helpful resource for building an installer is the
  103. <ulink url='https://wiki.yoctoproject.org/wiki/TipsAndTricks/RunningEclipseAgainstBuiltImage'>Cookbook guide to Making an Eclipse Debug Capable Image</ulink>
  104. wiki page.
  105. This wiki page focuses on development when using the Eclipse
  106. IDE.
  107. </note>
  108. </para>
  109. <para>
  110. The SDK and toolchains are self-contained and by default are
  111. installed into the <filename>poky_sdk</filename> folder in your
  112. home directory.
  113. You can choose to install the extensible SDK in any location when
  114. you run the installer.
  115. However, the location you choose needs to be writable for whichever
  116. users need to use the SDK, since files will need to be written
  117. under that directory during the normal course of operation.
  118. </para>
  119. <para>
  120. The following command shows how to run the installer given a
  121. toolchain tarball for a 64-bit x86 development host system and
  122. a 64-bit x86 target architecture.
  123. The example assumes the SDK installer is located in
  124. <filename>~/Downloads/</filename>.
  125. <note>
  126. If you do not have write permissions for the directory
  127. into which you are installing the SDK, the installer
  128. notifies you and exits.
  129. Be sure you have write permissions in the directory and
  130. run the installer again.
  131. </note>
  132. <literallayout class='monospaced'>
  133. $ ./poky-glibc-x86_64-core-image-minimal-core2-64-toolchain-ext-&DISTRO;.sh
  134. Poky (Yocto Project Reference Distro) Extensible SDK installer version &DISTRO;
  135. ===================================================================================
  136. Enter target directory for SDK (default: ~/poky_sdk):
  137. You are about to install the SDK to "/home/scottrif/poky_sdk". Proceed[Y/n]? Y
  138. Extracting SDK......................................................................done
  139. Setting it up...
  140. Extracting buildtools...
  141. Preparing build system...
  142. done
  143. SDK has been successfully set up and is ready to be used.
  144. Each time you wish to use the SDK in a new shell session, you need to source the environment setup script e.g.
  145. $ . /home/scottrif/poky_sdk/environment-setup-core2-64-poky-linux
  146. </literallayout>
  147. </para>
  148. </section>
  149. <section id='sdk-running-the-extensible-sdk-environment-setup-script'>
  150. <title>Running the Extensible SDK Environment Setup Script</title>
  151. <para>
  152. Once you have the SDK installed, you must run the SDK environment
  153. setup script before you can actually use it.
  154. This setup script resides in the directory you chose when you
  155. installed the SDK, which is either the default
  156. <filename>poky_sdk</filename> directory or the directory you
  157. chose during installation.
  158. </para>
  159. <para>
  160. Before running the script, be sure it is the one that matches the
  161. architecture for which you are developing.
  162. Environment setup scripts begin with the string
  163. "<filename>environment-setup</filename>" and include as part of
  164. their name the tuned target architecture.
  165. As an example, the following commands set the working directory
  166. to where the SDK was installed and then source the environment
  167. setup script.
  168. In this example, the setup script is for an IA-based
  169. target machine using i586 tuning:
  170. <literallayout class='monospaced'>
  171. $ cd /home/scottrif/poky_sdk
  172. $ source environment-setup-core2-64-poky-linux
  173. SDK environment now set up; additionally you may now run devtool to perform development tasks.
  174. Run devtool --help for further details.
  175. </literallayout>
  176. When you run the setup script, many environment variables are
  177. defined:
  178. <literallayout class='monospaced'>
  179. <ulink url='&YOCTO_DOCS_REF_URL;#var-SDKTARGETSYSROOT'><filename>SDKTARGETSYSROOT</filename></ulink> - The path to the sysroot used for cross-compilation
  180. <ulink url='&YOCTO_DOCS_REF_URL;#var-PKG_CONFIG_PATH'><filename>PKG_CONFIG_PATH</filename></ulink> - The path to the target pkg-config files
  181. <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIG_SITE'><filename>CONFIG_SITE</filename></ulink> - A GNU autoconf site file preconfigured for the target
  182. <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'><filename>CC</filename></ulink> - The minimal command and arguments to run the C compiler
  183. <ulink url='&YOCTO_DOCS_REF_URL;#var-CXX'><filename>CXX</filename></ulink> - The minimal command and arguments to run the C++ compiler
  184. <ulink url='&YOCTO_DOCS_REF_URL;#var-CPP'><filename>CPP</filename></ulink> - The minimal command and arguments to run the C preprocessor
  185. <ulink url='&YOCTO_DOCS_REF_URL;#var-AS'><filename>AS</filename></ulink> - The minimal command and arguments to run the assembler
  186. <ulink url='&YOCTO_DOCS_REF_URL;#var-LD'><filename>LD</filename></ulink> - The minimal command and arguments to run the linker
  187. <ulink url='&YOCTO_DOCS_REF_URL;#var-GDB'><filename>GDB</filename></ulink> - The minimal command and arguments to run the GNU Debugger
  188. <ulink url='&YOCTO_DOCS_REF_URL;#var-STRIP'><filename>STRIP</filename></ulink> - The minimal command and arguments to run 'strip', which strips symbols
  189. <ulink url='&YOCTO_DOCS_REF_URL;#var-RANLIB'><filename>RANLIB</filename></ulink> - The minimal command and arguments to run 'ranlib'
  190. <ulink url='&YOCTO_DOCS_REF_URL;#var-OBJCOPY'><filename>OBJCOPY</filename></ulink> - The minimal command and arguments to run 'objcopy'
  191. <ulink url='&YOCTO_DOCS_REF_URL;#var-OBJDUMP'><filename>OBJDUMP</filename></ulink> - The minimal command and arguments to run 'objdump'
  192. <ulink url='&YOCTO_DOCS_REF_URL;#var-AR'><filename>AR</filename></ulink> - The minimal command and arguments to run 'ar'
  193. <ulink url='&YOCTO_DOCS_REF_URL;#var-NM'><filename>NM</filename></ulink> - The minimal command and arguments to run 'nm'
  194. <ulink url='&YOCTO_DOCS_REF_URL;#var-TARGET_PREFIX'><filename>TARGET_PREFIX</filename></ulink> - The toolchain binary prefix for the target tools
  195. <ulink url='&YOCTO_DOCS_REF_URL;#var-CROSS_COMPILE'><filename>CROSS_COMPILE</filename></ulink> - The toolchain binary prefix for the target tools
  196. <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIGURE_FLAGS'><filename>CONFIGURE_FLAGS</filename></ulink> - The minimal arguments for GNU configure
  197. <ulink url='&YOCTO_DOCS_REF_URL;#var-CFLAGS'><filename>CFLAGS</filename></ulink> - Suggested C flags
  198. <ulink url='&YOCTO_DOCS_REF_URL;#var-CXXFLAGS'><filename>CXXFLAGS</filename></ulink> - Suggested C++ flags
  199. <ulink url='&YOCTO_DOCS_REF_URL;#var-LDFLAGS'><filename>LDFLAGS</filename></ulink> - Suggested linker flags when you use CC to link
  200. <ulink url='&YOCTO_DOCS_REF_URL;#var-CPPFLAGS'><filename>CPPFLAGS</filename></ulink> - Suggested preprocessor flags
  201. </literallayout>
  202. </para>
  203. </section>
  204. <section id='using-devtool-in-your-sdk-workflow'>
  205. <title>Using <filename>devtool</filename> in Your SDK Workflow</title>
  206. <para>
  207. The cornerstone of the extensible SDK is a command-line tool
  208. called <filename>devtool</filename>.
  209. This tool provides a number of features that help
  210. you build, test and package software within the extensible SDK, and
  211. optionally integrate it into an image built by the OpenEmbedded
  212. build system.
  213. <note><title>Tip</title>
  214. The use of <filename>devtool</filename> is not limited to
  215. the extensible SDK.
  216. You can use <filename>devtool</filename> to help you easily
  217. develop any project whose build output must be part of an
  218. image built using the OpenEmbedded build system.
  219. </note>
  220. </para>
  221. <para>
  222. The <filename>devtool</filename> command line is organized
  223. similarly to
  224. <ulink url='&YOCTO_DOCS_OM_URL;#git'>Git</ulink> in that it
  225. has a number of sub-commands for each function.
  226. You can run <filename>devtool --help</filename> to see all the
  227. commands.
  228. <note>
  229. See the
  230. "<ulink url='&YOCTO_DOCS_REF_URL;#ref-devtool-reference'><filename>devtool</filename>&nbsp;Quick Reference</ulink>"
  231. in the Yocto Project Reference Manual for a
  232. <filename>devtool</filename> quick reference.
  233. </note>
  234. </para>
  235. <para>
  236. Three <filename>devtool</filename> subcommands that provide
  237. entry-points into development are:
  238. <itemizedlist>
  239. <listitem><para>
  240. <emphasis><filename>devtool add</filename></emphasis>:
  241. Assists in adding new software to be built.
  242. </para></listitem>
  243. <listitem><para>
  244. <emphasis><filename>devtool modify</filename></emphasis>:
  245. Sets up an environment to enable you to modify the source of
  246. an existing component.
  247. </para></listitem>
  248. <listitem><para>
  249. <emphasis><filename>devtool upgrade</filename></emphasis>:
  250. Updates an existing recipe so that you can build it for
  251. an updated set of source files.
  252. </para></listitem>
  253. </itemizedlist>
  254. As with the OpenEmbedded build system, "recipes" represent software
  255. packages within <filename>devtool</filename>.
  256. When you use <filename>devtool add</filename>, a recipe is
  257. automatically created.
  258. When you use <filename>devtool modify</filename>, the specified
  259. existing recipe is used in order to determine where to get the source
  260. code and how to patch it.
  261. In both cases, an environment is set up so that when you build the
  262. recipe a source tree that is under your control is used in order to
  263. allow you to make changes to the source as desired.
  264. By default, both new recipes and the source go into a "workspace"
  265. directory under the SDK.
  266. </para>
  267. <para>
  268. The remainder of this section presents the
  269. <filename>devtool add</filename>,
  270. <filename>devtool modify</filename>, and
  271. <filename>devtool upgrade</filename> workflows.
  272. </para>
  273. <section id='sdk-use-devtool-to-add-an-application'>
  274. <title>Use <filename>devtool add</filename> to Add an Application</title>
  275. <para>
  276. The <filename>devtool add</filename> command generates
  277. a new recipe based on existing source code.
  278. This command takes advantage of the
  279. <ulink url='&YOCTO_DOCS_REF_URL;#devtool-the-workspace-layer-structure'>workspace</ulink>
  280. layer that many <filename>devtool</filename> commands
  281. use.
  282. The command is flexible enough to allow you to extract source
  283. code into both the workspace or a separate local Git repository
  284. and to use existing code that does not need to be extracted.
  285. </para>
  286. <para>
  287. Depending on your particular scenario, the arguments and options
  288. you use with <filename>devtool add</filename> form different
  289. combinations.
  290. The following diagram shows common development flows
  291. you would use with the <filename>devtool add</filename>
  292. command:
  293. </para>
  294. <para>
  295. <imagedata fileref="figures/sdk-devtool-add-flow.png" align="center" />
  296. </para>
  297. <para>
  298. <orderedlist>
  299. <listitem><para><emphasis>Generating the New Recipe</emphasis>:
  300. The top part of the flow shows three scenarios by which
  301. you could use <filename>devtool add</filename> to
  302. generate a recipe based on existing source code.</para>
  303. <para>In a shared development environment, it is
  304. typical where other developers are responsible for
  305. various areas of source code.
  306. As a developer, you are probably interested in using
  307. that source code as part of your development using
  308. the Yocto Project.
  309. All you need is access to the code, a recipe, and a
  310. controlled area in which to do your work.</para>
  311. <para>Within the diagram, three possible scenarios
  312. feed into the <filename>devtool add</filename> workflow:
  313. <itemizedlist>
  314. <listitem><para><emphasis>Left</emphasis>:
  315. The left scenario represents a common situation
  316. where the source code does not exist locally
  317. and needs to be extracted.
  318. In this situation, you just let it get
  319. extracted to the default workspace - you do not
  320. want it in some specific location outside of the
  321. workspace.
  322. Thus, everything you need will be located in the
  323. workspace:
  324. <literallayout class='monospaced'>
  325. $ devtool add <replaceable>recipe fetchuri</replaceable>
  326. </literallayout>
  327. With this command, <filename>devtool</filename>
  328. creates a recipe and an append file in the
  329. workspace as well as extracts the upstream
  330. source files into a local Git repository also
  331. within the <filename>sources</filename> folder.
  332. </para></listitem>
  333. <listitem><para><emphasis>Middle</emphasis>:
  334. The middle scenario also represents a situation where
  335. the source code does not exist locally.
  336. In this case, the code is again upstream
  337. and needs to be extracted to some
  338. local area - this time outside of the default
  339. workspace.
  340. If required, <filename>devtool</filename>
  341. always creates
  342. a Git repository locally during the extraction.
  343. Furthermore, the first positional argument
  344. <replaceable>srctree</replaceable> in this case
  345. identifies where the
  346. <filename>devtool add</filename> command
  347. will locate the extracted code outside of the
  348. workspace:
  349. <literallayout class='monospaced'>
  350. $ devtool add <replaceable>recipe srctree fetchuri</replaceable>
  351. </literallayout>
  352. In summary, the source code is pulled from
  353. <replaceable>fetchuri</replaceable> and extracted
  354. into the location defined by
  355. <replaceable>srctree</replaceable> as a local
  356. Git repository.</para>
  357. <para>Within workspace, <filename>devtool</filename>
  358. creates both the recipe and an append file
  359. for the recipe.
  360. </para></listitem>
  361. <listitem><para><emphasis>Right</emphasis>:
  362. The right scenario represents a situation
  363. where the source tree (srctree) has been
  364. previously prepared outside of the
  365. <filename>devtool</filename> workspace.
  366. </para>
  367. <para>The following command names the recipe
  368. and identifies where the existing source tree
  369. is located:
  370. <literallayout class='monospaced'>
  371. $ devtool add <replaceable>recipe srctree</replaceable>
  372. </literallayout>
  373. The command examines the source code and creates
  374. a recipe for it placing the recipe into the
  375. workspace.</para>
  376. <para>Because the extracted source code already exists,
  377. <filename>devtool</filename> does not try to
  378. relocate it into the workspace - just the new
  379. the recipe is placed in the workspace.</para>
  380. <para>Aside from a recipe folder, the command
  381. also creates an append folder and places an initial
  382. <filename>*.bbappend</filename> within.
  383. </para></listitem>
  384. </itemizedlist>
  385. </para></listitem>
  386. <listitem><para><emphasis>Edit the Recipe</emphasis>:
  387. At this point, you can use <filename>devtool edit-recipe</filename>
  388. to open up the editor as defined by the
  389. <filename>$EDITOR</filename> environment variable
  390. and modify the file:
  391. <literallayout class='monospaced'>
  392. $ devtool edit-recipe <replaceable>recipe</replaceable>
  393. </literallayout>
  394. From within the editor, you can make modifications to the
  395. recipe that take affect when you build it later.
  396. </para></listitem>
  397. <listitem><para><emphasis>Build the Recipe or Rebuild the Image</emphasis>:
  398. At this point in the flow, the next step you
  399. take depends on what you are going to do with
  400. the new code.</para>
  401. <para>If you need to take the build output and eventually
  402. move it to the target hardware, you would use
  403. <filename>devtool build</filename>:
  404. <literallayout class='monospaced'>
  405. $ devtool build <replaceable>recipe</replaceable>
  406. </literallayout></para>
  407. <para>On the other hand, if you want an image to
  408. contain the recipe's packages for immediate deployment
  409. onto a device (e.g. for testing purposes), you can use
  410. the <filename>devtool build-image</filename> command:
  411. <literallayout class='monospaced'>
  412. $ devtool build-image <replaceable>image</replaceable>
  413. </literallayout>
  414. </para></listitem>
  415. <listitem><para><emphasis>Deploy the Build Output</emphasis>:
  416. When you use the <filename>devtool build</filename>
  417. command to build out your recipe, you probably want to
  418. see if the resulting build output works as expected on target
  419. hardware.
  420. <note>
  421. This step assumes you have a previously built
  422. image that is already either running in QEMU or
  423. running on actual hardware.
  424. Also, it is assumed that for deployment of the image
  425. to the target, SSH is installed in the image and if
  426. the image is running on real hardware that you have
  427. network access to and from your development machine.
  428. </note>
  429. You can deploy your build output to that target hardware by
  430. using the <filename>devtool deploy-target</filename> command:
  431. <literallayout class='monospaced'>
  432. $ devtool deploy-target <replaceable>recipe target</replaceable>
  433. </literallayout>
  434. The <replaceable>target</replaceable> is a live target machine
  435. running as an SSH server.</para>
  436. <para>You can, of course, also deploy the image you build
  437. using the <filename>devtool build-image</filename> command
  438. to actual hardware.
  439. However, <filename>devtool</filename> does not provide a
  440. specific command that allows you to do this.
  441. </para></listitem>
  442. <listitem><para>
  443. <emphasis>Finish Your Work With the Recipe</emphasis>:
  444. The <filename>devtool finish</filename> command creates
  445. any patches corresponding to commits in the local
  446. Git repository, moves the new recipe to a more permanent
  447. layer, and then resets the recipe so that the recipe is
  448. built normally rather than from the workspace.
  449. <literallayout class='monospaced'>
  450. $ devtool finish <replaceable>recipe layer</replaceable>
  451. </literallayout>
  452. <note>
  453. Any changes you want to turn into patches must be
  454. committed to the Git repository in the source tree.
  455. </note></para>
  456. <para>As mentioned, the <filename>devtool finish</filename>
  457. command moves the final recipe to its permanent layer.
  458. </para>
  459. <para>As a final process of the
  460. <filename>devtool finish</filename> command, the state
  461. of the standard layers and the upstream source is
  462. restored so that you can build the recipe from those
  463. areas rather than the workspace.
  464. <note>
  465. You can use the <filename>devtool reset</filename>
  466. command to put things back should you decide you
  467. do not want to proceed with your work.
  468. If you do use this command, realize that the source
  469. tree is preserved.
  470. </note>
  471. </para></listitem>
  472. </orderedlist>
  473. </para>
  474. </section>
  475. <section id='sdk-devtool-use-devtool-modify-to-modify-the-source-of-an-existing-component'>
  476. <title>Use <filename>devtool modify</filename> to Modify the Source of an Existing Component</title>
  477. <para>
  478. The <filename>devtool modify</filename> command prepares the
  479. way to work on existing code that already has a recipe in
  480. place.
  481. The command is flexible enough to allow you to extract code,
  482. specify the existing recipe, and keep track of and gather any
  483. patch files from other developers that are
  484. associated with the code.
  485. </para>
  486. <para>
  487. Depending on your particular scenario, the arguments and options
  488. you use with <filename>devtool modify</filename> form different
  489. combinations.
  490. The following diagram shows common development flows
  491. you would use with the <filename>devtool modify</filename>
  492. command:
  493. </para>
  494. <para>
  495. <imagedata fileref="figures/sdk-devtool-modify-flow.png" align="center" />
  496. </para>
  497. <para>
  498. <orderedlist>
  499. <listitem><para><emphasis>Preparing to Modify the Code</emphasis>:
  500. The top part of the flow shows three scenarios by which
  501. you could use <filename>devtool modify</filename> to
  502. prepare to work on source files.
  503. Each scenario assumes the following:
  504. <itemizedlist>
  505. <listitem><para>The recipe exists in some layer external
  506. to the <filename>devtool</filename> workspace.
  507. </para></listitem>
  508. <listitem><para>The source files exist upstream in an
  509. un-extracted state or locally in a previously
  510. extracted state.
  511. </para></listitem>
  512. </itemizedlist>
  513. The typical situation is where another developer has
  514. created some layer for use with the Yocto Project and
  515. their recipe already resides in that layer.
  516. Furthermore, their source code is readily available
  517. either upstream or locally.
  518. <itemizedlist>
  519. <listitem><para><emphasis>Left</emphasis>:
  520. The left scenario represents a common situation
  521. where the source code does not exist locally
  522. and needs to be extracted.
  523. In this situation, the source is extracted
  524. into the default workspace location.
  525. The recipe, in this scenario, is in its own
  526. layer outside the workspace
  527. (i.e.
  528. <filename>meta-</filename><replaceable>layername</replaceable>).
  529. </para>
  530. <para>The following command identifies the recipe
  531. and by default extracts the source files:
  532. <literallayout class='monospaced'>
  533. $ devtool modify <replaceable>recipe</replaceable>
  534. </literallayout>
  535. Once <filename>devtool</filename>locates the recipe,
  536. it uses the
  537. <ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
  538. variable to locate the source code and
  539. any local patch files from other developers are
  540. located.
  541. <note>
  542. You cannot provide an URL for
  543. <replaceable>srctree</replaceable> when using the
  544. <filename>devtool modify</filename> command.
  545. </note>
  546. With this scenario, however, since no
  547. <replaceable>srctree</replaceable> argument exists, the
  548. <filename>devtool modify</filename> command by default
  549. extracts the source files to a Git structure.
  550. Furthermore, the location for the extracted source is the
  551. default area within the workspace.
  552. The result is that the command sets up both the source
  553. code and an append file within the workspace with the
  554. recipe remaining in its original location.
  555. </para></listitem>
  556. <listitem><para><emphasis>Middle</emphasis>:
  557. The middle scenario represents a situation where
  558. the source code also does not exist locally.
  559. In this case, the code is again upstream
  560. and needs to be extracted to some
  561. local area as a Git repository.
  562. The recipe, in this scenario, is again in its own
  563. layer outside the workspace.</para>
  564. <para>The following command tells
  565. <filename>devtool</filename> what recipe with
  566. which to work and, in this case, identifies a local
  567. area for the extracted source files that is outside
  568. of the default workspace:
  569. <literallayout class='monospaced'>
  570. $ devtool modify <replaceable>recipe srctree</replaceable>
  571. </literallayout>
  572. As with all extractions, the command uses
  573. the recipe's <filename>SRC_URI</filename> to locate the
  574. source files.
  575. Once the files are located, the command by default
  576. extracts them.
  577. Providing the <replaceable>srctree</replaceable>
  578. argument instructs <filename>devtool</filename> where
  579. to place the extracted source.</para>
  580. <para>Within workspace, <filename>devtool</filename>
  581. creates an append file for the recipe.
  582. The recipe remains in its original location but
  583. the source files are extracted to the location you
  584. provided with <replaceable>srctree</replaceable>.
  585. </para></listitem>
  586. <listitem><para><emphasis>Right</emphasis>:
  587. The right scenario represents a situation
  588. where the source tree
  589. (<replaceable>srctree</replaceable>) exists as a
  590. previously extracted Git structure outside of
  591. the <filename>devtool</filename> workspace.
  592. In this example, the recipe also exists
  593. elsewhere in its own layer.
  594. </para>
  595. <para>The following command tells
  596. <filename>devtool</filename> the recipe
  597. with which to work, uses the "-n" option to indicate
  598. source does not need to be extracted, and uses
  599. <replaceable>srctree</replaceable> to point to the
  600. previously extracted source files:
  601. <literallayout class='monospaced'>
  602. $ devtool modify -n <replaceable>recipe srctree</replaceable>
  603. </literallayout>
  604. </para>
  605. <para>Once the command finishes, it creates only
  606. an append file for the recipe in the workspace.
  607. The recipe and the source code remain in their
  608. original locations.
  609. </para></listitem>
  610. </itemizedlist>
  611. </para></listitem>
  612. <listitem><para><emphasis>Edit the Source</emphasis>:
  613. Once you have used the <filename>devtool modify</filename>
  614. command, you are free to make changes to the source
  615. files.
  616. You can use any editor you like to make and save
  617. your source code modifications.
  618. </para></listitem>
  619. <listitem><para><emphasis>Build the Recipe</emphasis>:
  620. Once you have updated the source files, you can build
  621. the recipe.
  622. </para></listitem>
  623. <listitem><para><emphasis>Deploy the Build Output</emphasis>:
  624. When you use the <filename>devtool build</filename>
  625. command to build out your recipe, you probably want to see
  626. if the resulting build output works as expected on target
  627. hardware.
  628. <note>
  629. This step assumes you have a previously built
  630. image that is already either running in QEMU or
  631. running on actual hardware.
  632. Also, it is assumed that for deployment of the image
  633. to the target, SSH is installed in the image and if
  634. the image is running on real hardware that you have
  635. network access to and from your development machine.
  636. </note>
  637. You can deploy your build output to that target hardware by
  638. using the <filename>devtool deploy-target</filename> command:
  639. <literallayout class='monospaced'>
  640. $ devtool deploy-target <replaceable>recipe target</replaceable>
  641. </literallayout>
  642. The <replaceable>target</replaceable> is a live target machine
  643. running as an SSH server.</para>
  644. <para>You can, of course, also deploy the image you build
  645. using the <filename>devtool build-image</filename> command
  646. to actual hardware.
  647. However, <filename>devtool</filename> does not provide a
  648. specific command that allows you to do this.
  649. </para></listitem>
  650. <listitem><para>
  651. <emphasis>Finish Your Work With the Recipe</emphasis>:
  652. The <filename>devtool finish</filename> command creates
  653. any patches corresponding to commits in the local
  654. Git repository, updates the recipe to point to them
  655. (or creates a <filename>.bbappend</filename> file to do
  656. so, depending on the specified destination layer), and
  657. then resets the recipe so that the recipe is built normally
  658. rather than from the workspace.
  659. <literallayout class='monospaced'>
  660. $ devtool finish <replaceable>recipe layer</replaceable>
  661. </literallayout>
  662. <note>
  663. Any changes you want to turn into patches must be
  664. committed to the Git repository in the source tree.
  665. </note></para>
  666. <para>Because there is no need to move the recipe,
  667. <filename>devtool finish</filename> either updates the
  668. original recipe in the original layer or the command
  669. creates a <filename>.bbappend</filename> in a different
  670. layer as provided by <replaceable>layer</replaceable>.
  671. </para>
  672. <para>As a final process of the
  673. <filename>devtool finish</filename> command, the state
  674. of the standard layers and the upstream source is
  675. restored so that you can build the recipe from those
  676. areas rather than the workspace.
  677. <note>
  678. You can use the <filename>devtool reset</filename>
  679. command to put things back should you decide you
  680. do not want to proceed with your work.
  681. If you do use this command, realize that the source
  682. tree is preserved.
  683. </note>
  684. </para></listitem>
  685. </orderedlist>
  686. </para>
  687. </section>
  688. <section id='sdk-devtool-use-devtool-upgrade-to-create-a-version-of-the-recipe-that-supports-a-newer-version-of-the-software'>
  689. <title>Use <filename>devtool upgrade</filename> to Create a Version of the Recipe that Supports a Newer Version of the Software</title>
  690. <para>
  691. The <filename>devtool upgrade</filename> command upgrades
  692. an existing recipe to that of a more up-to-date version
  693. found upstream.
  694. Throughout the life of software, recipes continually undergo
  695. version upgrades by their upstream publishers.
  696. You can use the <filename>devtool upgrade</filename>
  697. workflow to make sure your recipes you are using for builds
  698. are up-to-date with their upstream counterparts.
  699. <note>
  700. Several methods exist by which you can upgrade recipes.
  701. <filename>devtool upgrade</filename> happens to be one.
  702. You can read about all the methods by which you can
  703. upgrade recipes in the
  704. "<ulink url='&YOCTO_DOCS_DEV_URL;#gs-upgrading-recipes'>Upgrading Recipes</ulink>"
  705. section of the Yocto Project Development Tasks Manual.
  706. </note>
  707. </para>
  708. <para>
  709. The <filename>devtool upgrade</filename> command is flexible
  710. enough to allow you to specify source code revision and
  711. versioning schemes, extract code into or out of the
  712. <filename>devtool</filename>
  713. <ulink url='&YOCTO_DOCS_REF_URL;#devtool-the-workspace-layer-structure'>workspace</ulink>,
  714. and work with any source file forms that the fetchers support.
  715. </para>
  716. <para>
  717. Depending on your particular scenario, the arguments and
  718. options you use with <filename>devtool upgrade</filename> form
  719. different combinations.
  720. The following diagram shows a common development flow
  721. you would use with the <filename>devtool upgrade</filename>
  722. command:
  723. </para>
  724. <para>
  725. <imagedata fileref="figures/sdk-devtool-upgrade-flow.png" align="center" />
  726. </para>
  727. <para>
  728. <orderedlist>
  729. <listitem><para>
  730. <emphasis>Initiate the Upgrade</emphasis>:
  731. The top part of the flow shows a typical scenario by
  732. which you could use
  733. <filename>devtool upgrade</filename>.
  734. The following conditions exist:
  735. <itemizedlist>
  736. <listitem><para>
  737. The recipe exists in some layer external
  738. to the <filename>devtool</filename> workspace.
  739. </para></listitem>
  740. <listitem><para>
  741. The source files for the new release
  742. exist adjacent to the same location pointed to
  743. by
  744. <ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
  745. in the recipe (e.g. a tarball with the new
  746. version number in the name, or as a different
  747. revision in the upstream Git repository).
  748. </para></listitem>
  749. </itemizedlist>
  750. A common situation is where third-party software has
  751. undergone a revision so that it has been upgraded.
  752. The recipe you have access to is likely in your own
  753. layer.
  754. Thus, you need to upgrade the recipe to use the
  755. newer version of the software:
  756. <literallayout class='monospaced'>
  757. $ devtool upgrade -V <replaceable>version recipe</replaceable>
  758. </literallayout>
  759. By default, the <filename>devtool upgrade</filename>
  760. command extracts source code into the
  761. <filename>sources</filename> directory in the
  762. <ulink url='&YOCTO_DOCS_REF_URL;#devtool-the-workspace-layer-structure'>workspace</ulink>.
  763. If you want the code extracted to any other location,
  764. you need to provide the
  765. <replaceable>srctree</replaceable> positional argument
  766. with the command as follows:
  767. <literallayout class='monospaced'>
  768. $ devtool upgrade -V <replaceable>version recipe srctree</replaceable>
  769. </literallayout>
  770. <note>
  771. In this example, the "-V" option specifies the new
  772. version.
  773. If you don't use "-V", the command upgrades the
  774. recipe to the latest version.
  775. </note>
  776. If the source files pointed to by the
  777. <filename>SRC_URI</filename> statement in the recipe
  778. are in a Git repository, you must provide the "-S"
  779. option and specify a revision for the software.</para>
  780. <para>Once <filename>devtool</filename> locates the
  781. recipe, it uses the <filename>SRC_URI</filename>
  782. variable to locate the source code and any local patch
  783. files from other developers are located.
  784. The result is that the command sets up the source
  785. code, the new version of the recipe, and an append file
  786. all within the workspace.
  787. </para></listitem>
  788. <listitem><para><emphasis>
  789. Resolve any Conflicts created by the Upgrade</emphasis>:
  790. At this point, conflicts could exist due to the
  791. software being upgraded to a new version.
  792. Conflicts occur if your recipe specifies some patch
  793. files in <filename>SRC_URI</filename> that conflict
  794. with changes made in the new version of the software.
  795. If this is the case, you need to resolve the conflicts
  796. by editing the source and following the normal
  797. <filename>git rebase</filename> conflict resolution
  798. process.</para>
  799. <para>Before moving onto the next step, be sure to
  800. resolve any such conflicts created through use of a
  801. newer or different version of the software.
  802. </para></listitem>
  803. <listitem><para>
  804. <emphasis>Build the Recipe</emphasis>:
  805. Once you have your recipe in order, you can build it.
  806. You can either use <filename>devtool build</filename>
  807. or <filename>bitbake</filename>.
  808. Either method produces build output that is stored
  809. in
  810. <ulink url='&YOCTO_DOCS_REF_URL;#var-TMPDIR'><filename>TMPDIR</filename></ulink>.
  811. </para></listitem>
  812. <listitem><para>
  813. <emphasis>Deploy the Build Output</emphasis>:
  814. When you use the <filename>devtool build</filename>
  815. command or <filename>bitbake</filename> to build
  816. your recipe, you probably want to see if the resulting
  817. build output works as expected on target hardware.
  818. <note>
  819. This step assumes you have a previously built
  820. image that is already either running in QEMU or
  821. running on actual hardware.
  822. Also, it is assumed that for deployment of the
  823. image to the target, SSH is installed in the image
  824. and if the image is running on real hardware that
  825. you have network access to and from your
  826. development machine.
  827. </note>
  828. You can deploy your build output to that target
  829. hardware by using the
  830. <filename>devtool deploy-target</filename> command:
  831. <literallayout class='monospaced'>
  832. $ devtool deploy-target <replaceable>recipe target</replaceable>
  833. </literallayout>
  834. The <replaceable>target</replaceable> is a live target
  835. machine running as an SSH server.</para>
  836. <para>You can, of course, also deploy the image you
  837. build using the
  838. <filename>devtool build-image</filename> command
  839. to actual hardware.
  840. However, <filename>devtool</filename> does not provide
  841. a specific command that allows you to do this.
  842. </para></listitem>
  843. <listitem><para>
  844. <emphasis>Finish Your Work With the Recipe</emphasis>:
  845. The <filename>devtool finish</filename> command creates
  846. any patches corresponding to commits in the local
  847. Git repository, moves the new recipe to a more
  848. permanent layer, and then resets the recipe so that
  849. the recipe is built normally rather than from the
  850. workspace.
  851. If you specify a destination layer that is the same as
  852. the original source, then the old version of the
  853. recipe and associated files will be removed prior to
  854. adding the new version.
  855. <literallayout class='monospaced'>
  856. $ devtool finish <replaceable>recipe layer</replaceable>
  857. </literallayout>
  858. <note>
  859. Any changes you want to turn into patches must be
  860. committed to the Git repository in the source tree.
  861. </note></para>
  862. <para>As a final process of the
  863. <filename>devtool finish</filename> command, the state
  864. of the standard layers and the upstream source is
  865. restored so that you can build the recipe from those
  866. areas rather than the workspace.
  867. <note>
  868. You can use the <filename>devtool reset</filename>
  869. command to put things back should you decide you
  870. do not want to proceed with your work.
  871. If you do use this command, realize that the source
  872. tree is preserved.
  873. </note>
  874. </para></listitem>
  875. </orderedlist>
  876. </para>
  877. </section>
  878. </section>
  879. <section id='sdk-a-closer-look-at-devtool-add'>
  880. <title>A Closer Look at <filename>devtool add</filename></title>
  881. <para>
  882. The <filename>devtool add</filename> command automatically creates a
  883. recipe based on the source tree with which you provide it.
  884. Currently, the command has support for the following:
  885. <itemizedlist>
  886. <listitem><para>
  887. Autotools (<filename>autoconf</filename> and
  888. <filename>automake</filename>)
  889. </para></listitem>
  890. <listitem><para>
  891. CMake
  892. </para></listitem>
  893. <listitem><para>
  894. Scons
  895. </para></listitem>
  896. <listitem><para>
  897. <filename>qmake</filename>
  898. </para></listitem>
  899. <listitem><para>
  900. Plain <filename>Makefile</filename>
  901. </para></listitem>
  902. <listitem><para>
  903. Out-of-tree kernel module
  904. </para></listitem>
  905. <listitem><para>
  906. Binary package (i.e. "-b" option)
  907. </para></listitem>
  908. <listitem><para>
  909. Node.js module
  910. </para></listitem>
  911. <listitem><para>
  912. Python modules that use <filename>setuptools</filename>
  913. or <filename>distutils</filename>
  914. </para></listitem>
  915. </itemizedlist>
  916. </para>
  917. <para>
  918. Apart from binary packages, the determination of how a source tree
  919. should be treated is automatic based on the files present within
  920. that source tree.
  921. For example, if a <filename>CMakeLists.txt</filename> file is found,
  922. then the source tree is assumed to be using
  923. CMake and is treated accordingly.
  924. <note>
  925. In most cases, you need to edit the automatically generated
  926. recipe in order to make it build properly.
  927. Typically, you would go through several edit and build cycles
  928. until you can build the recipe.
  929. Once the recipe can be built, you could use possible further
  930. iterations to test the recipe on the target device.
  931. </note>
  932. </para>
  933. <para>
  934. The remainder of this section covers specifics regarding how parts
  935. of the recipe are generated.
  936. </para>
  937. <section id='sdk-name-and-version'>
  938. <title>Name and Version</title>
  939. <para>
  940. If you do not specify a name and version on the command
  941. line, <filename>devtool add</filename> attempts to determine
  942. the name and version of the software being built from
  943. various metadata within the source tree.
  944. Furthermore, the command sets the name of the created recipe
  945. file accordingly.
  946. If the name or version cannot be determined, the
  947. <filename>devtool add</filename> command prints an error and
  948. you must re-run the command with both the name and version
  949. or just the name or version specified.
  950. </para>
  951. <para>
  952. Sometimes the name or version determined from the source tree
  953. might be incorrect.
  954. For such a case, you must reset the recipe:
  955. <literallayout class='monospaced'>
  956. $ devtool reset -n <replaceable>recipename</replaceable>
  957. </literallayout>
  958. After running the <filename>devtool reset</filename> command,
  959. you need to run <filename>devtool add</filename> again and
  960. provide the name or the version.
  961. </para>
  962. </section>
  963. <section id='sdk-dependency-detection-and-mapping'>
  964. <title>Dependency Detection and Mapping</title>
  965. <para>
  966. The <filename>devtool add</filename> command attempts to
  967. detect build-time dependencies and map them to other recipes
  968. in the system.
  969. During this mapping, the command fills in the names of those
  970. recipes in the
  971. <ulink url='&YOCTO_DOCS_REF_URL;#var-DEPENDS'><filename>DEPENDS</filename></ulink>
  972. value within the recipe.
  973. If a dependency cannot be mapped, then a comment is placed in
  974. the recipe indicating such.
  975. The inability to map a dependency might be caused because the
  976. naming is not recognized or because the dependency simply is
  977. not available.
  978. For cases where the dependency is not available, you must use
  979. the <filename>devtool add</filename> command to add an
  980. additional recipe to satisfy the dependency and then come
  981. back to the first recipe and add its name to
  982. <filename>DEPENDS</filename>.
  983. </para>
  984. <para>
  985. If you need to add runtime dependencies, you can do so by
  986. adding the following to your recipe:
  987. <literallayout class='monospaced'>
  988. RDEPENDS_${PN} += "dependency1 dependency2 ..."
  989. </literallayout>
  990. <note>
  991. The <filename>devtool add</filename> command often cannot
  992. distinguish between mandatory and optional dependencies.
  993. Consequently, some of the detected dependencies might
  994. in fact be optional.
  995. When in doubt, consult the documentation or the configure
  996. script for the software the recipe is building for further
  997. details.
  998. In some cases, you might find you can substitute the
  999. dependency for an option to disable the associated
  1000. functionality passed to the configure script.
  1001. </note>
  1002. </para>
  1003. </section>
  1004. <section id='sdk-license-detection'>
  1005. <title>License Detection</title>
  1006. <para>
  1007. The <filename>devtool add</filename> command attempts to
  1008. determine if the software you are adding is able to be
  1009. distributed under a common open-source license and sets the
  1010. <ulink url='&YOCTO_DOCS_REF_URL;#var-LICENSE'><filename>LICENSE</filename></ulink>
  1011. value accordingly.
  1012. You should double-check this value against the documentation
  1013. or source files for the software you are building and update
  1014. that <filename>LICENSE</filename> value if necessary.
  1015. </para>
  1016. <para>
  1017. The <filename>devtool add</filename> command also sets the
  1018. <ulink url='&YOCTO_DOCS_REF_URL;#var-LIC_FILES_CHKSUM'><filename>LIC_FILES_CHKSUM</filename></ulink>
  1019. value to point to all files that appear to be license-related.
  1020. However, license statements often appear in comments at the top
  1021. of source files or within documentation.
  1022. Consequently, you might need to amend the
  1023. <filename>LIC_FILES_CHKSUM</filename> variable to point to one
  1024. or more of those comments if present.
  1025. Setting <filename>LIC_FILES_CHKSUM</filename> is particularly
  1026. important for third-party software.
  1027. The mechanism attempts to ensure correct licensing should you
  1028. upgrade the recipe to a newer upstream version in future.
  1029. Any change in licensing is detected and you receive an error
  1030. prompting you to check the license text again.
  1031. </para>
  1032. <para>
  1033. If the <filename>devtool add</filename> command cannot
  1034. determine licensing information, the
  1035. <filename>LICENSE</filename> value is set to "CLOSED" and the
  1036. <filename>LIC_FILES_CHKSUM</filename> value remains unset.
  1037. This behavior allows you to continue with development but is
  1038. unlikely to be correct in all cases.
  1039. Consequently, you should check the documentation or source
  1040. files for the software you are building to determine the actual
  1041. license.
  1042. </para>
  1043. </section>
  1044. <section id='sdk-adding-makefile-only-software'>
  1045. <title>Adding Makefile-Only Software</title>
  1046. <para>
  1047. The use of <filename>make</filename> by itself is very common
  1048. in both proprietary and open source software.
  1049. Unfortunately, Makefiles are often not written with
  1050. cross-compilation in mind.
  1051. Thus, <filename>devtool add</filename> often cannot do very
  1052. much to ensure that these Makefiles build correctly.
  1053. It is very common, for example, to explicitly call
  1054. <filename>gcc</filename> instead of using the
  1055. <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'><filename>CC</filename></ulink>
  1056. variable.
  1057. Usually, in a cross-compilation environment,
  1058. <filename>gcc</filename> is the compiler for the build host
  1059. and the cross-compiler is named something similar to
  1060. <filename>arm-poky-linux-gnueabi-gcc</filename> and might
  1061. require some arguments (e.g. to point to the associated sysroot
  1062. for the target machine).
  1063. </para>
  1064. <para>
  1065. When writing a recipe for Makefile-only software, keep the
  1066. following in mind:
  1067. <itemizedlist>
  1068. <listitem><para>
  1069. You probably need to patch the Makefile to use
  1070. variables instead of hardcoding tools within the
  1071. toolchain such as <filename>gcc</filename> and
  1072. <filename>g++</filename>.
  1073. </para></listitem>
  1074. <listitem><para>
  1075. The environment in which <filename>make</filename> runs
  1076. is set up with various standard variables for
  1077. compilation (e.g. <filename>CC</filename>,
  1078. <filename>CXX</filename>, and so forth) in a similar
  1079. manner to the environment set up by the SDK's
  1080. environment setup script.
  1081. One easy way to see these variables is to run the
  1082. <filename>devtool build</filename> command on the
  1083. recipe and then look in
  1084. <filename>oe-logs/run.do_compile</filename>.
  1085. Towards the top of this file you will see a list of
  1086. environment variables that are being set.
  1087. You can take advantage of these variables within the
  1088. Makefile.
  1089. </para></listitem>
  1090. <listitem><para>
  1091. If the Makefile sets a default for a variable using "=",
  1092. that default overrides the value set in the environment,
  1093. which is usually not desirable.
  1094. In this situation, you can either patch the Makefile
  1095. so it sets the default using the "?=" operator, or
  1096. you can alternatively force the value on the
  1097. <filename>make</filename> command line.
  1098. To force the value on the command line, add the
  1099. variable setting to
  1100. <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OEMAKE'><filename>EXTRA_OEMAKE</filename></ulink>
  1101. or
  1102. <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGECONFIG_CONFARGS'><filename>PACKAGECONFIG_CONFARGS</filename></ulink>
  1103. within the recipe.
  1104. Here is an example using <filename>EXTRA_OEMAKE</filename>:
  1105. <literallayout class='monospaced'>
  1106. EXTRA_OEMAKE += "'CC=${CC}' 'CXX=${CXX}'"
  1107. </literallayout>
  1108. In the above example, single quotes are used around the
  1109. variable settings as the values are likely to contain
  1110. spaces because required default options are passed to
  1111. the compiler.
  1112. </para></listitem>
  1113. <listitem><para>
  1114. Hardcoding paths inside Makefiles is often problematic
  1115. in a cross-compilation environment.
  1116. This is particularly true because those hardcoded paths
  1117. often point to locations on the build host and thus
  1118. will either be read-only or will introduce
  1119. contamination into the cross-compilation by virtue of
  1120. being specific to the build host rather than the target.
  1121. Patching the Makefile to use prefix variables or other
  1122. path variables is usually the way to handle this.
  1123. </para></listitem>
  1124. <listitem><para>
  1125. Sometimes a Makefile runs target-specific commands such
  1126. as <filename>ldconfig</filename>.
  1127. For such cases, you might be able to simply apply
  1128. patches that remove these commands from the Makefile.
  1129. </para></listitem>
  1130. </itemizedlist>
  1131. </para>
  1132. </section>
  1133. <section id='sdk-adding-native-tools'>
  1134. <title>Adding Native Tools</title>
  1135. <para>
  1136. Often, you need to build additional tools that run on the
  1137. build host system as opposed to the target.
  1138. You should indicate this using one of the following methods
  1139. when you run <filename>devtool add</filename>:
  1140. <itemizedlist>
  1141. <listitem><para>
  1142. Specify the name of the recipe such that it ends
  1143. with "-native".
  1144. Specifying the name like this produces a recipe that
  1145. only builds for the build host.
  1146. </para></listitem>
  1147. <listitem><para>
  1148. Specify the "&dash;&dash;also-native" option with the
  1149. <filename>devtool add</filename> command.
  1150. Specifying this option creates a recipe file that still
  1151. builds for the target but also creates a variant with
  1152. a "-native" suffix that builds for the build host.
  1153. </para></listitem>
  1154. </itemizedlist>
  1155. <note>
  1156. If you need to add a tool that is shipped as part of a
  1157. source tree that builds code for the target, you can
  1158. typically accomplish this by building the native and target
  1159. parts separately rather than within the same compilation
  1160. process.
  1161. Realize though that with the "&dash;&dash;also-native" option, you
  1162. can add the tool using just one recipe file.
  1163. </note>
  1164. </para>
  1165. </section>
  1166. <section id='sdk-adding-node-js-modules'>
  1167. <title>Adding Node.js Modules</title>
  1168. <para>
  1169. You can use the <filename>devtool add</filename> command two
  1170. different ways to add Node.js modules: 1) Through
  1171. <filename>npm</filename> and, 2) from a repository or local
  1172. source.
  1173. </para>
  1174. <para>
  1175. Use the following form to add Node.js modules through
  1176. <filename>npm</filename>:
  1177. <literallayout class='monospaced'>
  1178. $ devtool add "npm://registry.npmjs.org;name=forever;version=0.15.1"
  1179. </literallayout>
  1180. The name and version parameters are mandatory.
  1181. Lockdown and shrinkwrap files are generated and pointed to by
  1182. the recipe in order to freeze the version that is fetched for
  1183. the dependencies according to the first time.
  1184. This also saves checksums that are verified on future fetches.
  1185. Together, these behaviors ensure the reproducibility and
  1186. integrity of the build.
  1187. <note><title>Notes</title>
  1188. <itemizedlist>
  1189. <listitem><para>
  1190. You must use quotes around the URL.
  1191. The <filename>devtool add</filename> does not require
  1192. the quotes, but the shell considers ";" as a splitter
  1193. between multiple commands.
  1194. Thus, without the quotes,
  1195. <filename>devtool add</filename> does not receive the
  1196. other parts, which results in several "command not
  1197. found" errors.
  1198. </para></listitem>
  1199. <listitem><para>
  1200. In order to support adding
  1201. Node.js modules, a
  1202. <filename>nodejs</filename> recipe must be part of your
  1203. SDK in order to provide Node.js
  1204. itself.
  1205. </para></listitem>
  1206. </itemizedlist>
  1207. </note>
  1208. </para>
  1209. <para>
  1210. As mentioned earlier, you can also add Node.js modules
  1211. directly from a repository or local source tree.
  1212. To add modules this way, use <filename>devtool add</filename> in
  1213. the following form:
  1214. <literallayout class='monospaced'>
  1215. $ devtool add https://github.com/diversario/node-ssdp
  1216. </literallayout>
  1217. In this example, <filename>devtool</filename> fetches the specified
  1218. Git repository, detects that the code is Node.js code, fetches
  1219. dependencies using <filename>npm</filename>, and sets
  1220. <ulink url='&YOCTO_DOCS_REF_URL;#var-SRC_URI'><filename>SRC_URI</filename></ulink>
  1221. accordingly.
  1222. </para>
  1223. </section>
  1224. </section>
  1225. <section id='sdk-working-with-recipes'>
  1226. <title>Working With Recipes</title>
  1227. <para>
  1228. When building a recipe with <filename>devtool build</filename>, the
  1229. typical build progression is as follows:
  1230. <orderedlist>
  1231. <listitem><para>
  1232. Fetch the source
  1233. </para></listitem>
  1234. <listitem><para>
  1235. Unpack the source
  1236. </para></listitem>
  1237. <listitem><para>
  1238. Configure the source
  1239. </para></listitem>
  1240. <listitem><para>
  1241. Compiling the source
  1242. </para></listitem>
  1243. <listitem><para>
  1244. Install the build output
  1245. </para></listitem>
  1246. <listitem><para>
  1247. Package the installed output
  1248. </para></listitem>
  1249. </orderedlist>
  1250. For recipes in the workspace, fetching and unpacking is disabled
  1251. as the source tree has already been prepared and is persistent.
  1252. Each of these build steps is defined as a function, usually with a
  1253. "do_" prefix.
  1254. These functions are typically shell scripts but can instead be written
  1255. in Python.
  1256. </para>
  1257. <para>
  1258. If you look at the contents of a recipe, you will see that the
  1259. recipe does not include complete instructions for building the
  1260. software.
  1261. Instead, common functionality is encapsulated in classes inherited
  1262. with the <filename>inherit</filename> directive, leaving the recipe
  1263. to describe just the things that are specific to the software to be
  1264. built.
  1265. A <ulink url='&YOCTO_DOCS_REF_URL;#ref-classes-base'><filename>base</filename></ulink>
  1266. class exists that is implicitly inherited by all recipes and provides
  1267. the functionality that most typical recipes need.
  1268. </para>
  1269. <para>
  1270. The remainder of this section presents information useful when
  1271. working with recipes.
  1272. </para>
  1273. <section id='sdk-finding-logs-and-work-files'>
  1274. <title>Finding Logs and Work Files</title>
  1275. <para>
  1276. When you are debugging a recipe that you previously created using
  1277. <filename>devtool add</filename> or whose source you are modifying
  1278. by using the <filename>devtool modify</filename> command, after
  1279. the first run of <filename>devtool build</filename>, you will
  1280. find some symbolic links created within the source tree:
  1281. <filename>oe-logs</filename>, which points to the directory in
  1282. which log files and run scripts for each build step are created
  1283. and <filename>oe-workdir</filename>, which points to the temporary
  1284. work area for the recipe.
  1285. You can use these links to get more information on what is
  1286. happening at each build step.
  1287. </para>
  1288. <para>
  1289. These locations under <filename>oe-workdir</filename> are
  1290. particularly useful:
  1291. <itemizedlist>
  1292. <listitem><para><filename>image/</filename>:
  1293. Contains all of the files installed at the
  1294. <ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-install'><filename>do_install</filename></ulink>
  1295. stage.
  1296. Within a recipe, this directory is referred to by the
  1297. expression
  1298. <filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink><filename>}</filename>.
  1299. </para></listitem>
  1300. <listitem><para><filename>sysroot-destdir/</filename>:
  1301. Contains a subset of files installed within
  1302. <filename>do_install</filename> that have been put into the
  1303. shared sysroot.
  1304. For more information, see the
  1305. "<link linkend='sdk-sharing-files-between-recipes'>Sharing Files Between Recipes</link>"
  1306. section.
  1307. </para></listitem>
  1308. <listitem><para><filename>packages-split/</filename>:
  1309. Contains subdirectories for each package produced by the
  1310. recipe.
  1311. For more information, see the
  1312. "<link linkend='sdk-packaging'>Packaging</link>" section.
  1313. </para></listitem>
  1314. </itemizedlist>
  1315. </para>
  1316. </section>
  1317. <section id='sdk-setting-configure-arguments'>
  1318. <title>Setting Configure Arguments</title>
  1319. <para>
  1320. If the software your recipe is building uses GNU autoconf,
  1321. then a fixed set of arguments is passed to it to enable
  1322. cross-compilation plus any extras specified by
  1323. <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OECONF'><filename>EXTRA_OECONF</filename></ulink>
  1324. or
  1325. <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGECONFIG_CONFARGS'><filename>PACKAGECONFIG_CONFARGS</filename></ulink>
  1326. set within the recipe.
  1327. If you wish to pass additional options, add them to
  1328. <filename>EXTRA_OECONF</filename> or
  1329. <filename>PACKAGECONFIG_CONFARGS</filename>.
  1330. Other supported build tools have similar variables
  1331. (e.g.
  1332. <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OECMAKE'><filename>EXTRA_OECMAKE</filename></ulink>
  1333. for CMake,
  1334. <ulink url='&YOCTO_DOCS_REF_URL;#var-EXTRA_OESCONS'><filename>EXTRA_OESCONS</filename></ulink>
  1335. for Scons, and so forth).
  1336. If you need to pass anything on the <filename>make</filename>
  1337. command line, you can use <filename>EXTRA_OEMAKE</filename> or the
  1338. <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGECONFIG_CONFARGS'><filename>PACKAGECONFIG_CONFARGS</filename></ulink>
  1339. variables to do so.
  1340. </para>
  1341. <para>
  1342. You can use the <filename>devtool configure-help</filename> command
  1343. to help you set the arguments listed in the previous paragraph.
  1344. The command determines the exact options being passed, and shows
  1345. them to you along with any custom arguments specified through
  1346. <filename>EXTRA_OECONF</filename> or
  1347. <filename>PACKAGECONFIG_CONFARGS</filename>.
  1348. If applicable, the command also shows you the output of the
  1349. configure script's "&dash;&dash;help" option as a reference.
  1350. </para>
  1351. </section>
  1352. <section id='sdk-sharing-files-between-recipes'>
  1353. <title>Sharing Files Between Recipes</title>
  1354. <para>
  1355. Recipes often need to use files provided by other recipes on
  1356. the build host.
  1357. For example, an application linking to a common library needs
  1358. access to the library itself and its associated headers.
  1359. The way this access is accomplished within the extensible SDK is
  1360. through the sysroot.
  1361. One sysroot exists per "machine" for which the SDK is being built.
  1362. In practical terms, this means a sysroot exists for the target
  1363. machine, and a sysroot exists for the build host.
  1364. </para>
  1365. <para>
  1366. Recipes should never write files directly into the sysroot.
  1367. Instead, files should be installed into standard locations
  1368. during the
  1369. <ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-install'><filename>do_install</filename></ulink>
  1370. task within the
  1371. <filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-D'><filename>D</filename></ulink><filename>}</filename>
  1372. directory.
  1373. A subset of these files automatically go into the sysroot.
  1374. The reason for this limitation is that almost all files that go
  1375. into the sysroot are cataloged in manifests in order to ensure
  1376. they can be removed later when a recipe is modified or removed.
  1377. Thus, the sysroot is able to remain free from stale files.
  1378. </para>
  1379. </section>
  1380. <section id='sdk-packaging'>
  1381. <title>Packaging</title>
  1382. <para>
  1383. Packaging is not always particularly relevant within the
  1384. extensible SDK.
  1385. However, if you examine how build output gets into the final image
  1386. on the target device, it is important to understand packaging
  1387. because the contents of the image are expressed in terms of
  1388. packages and not recipes.
  1389. </para>
  1390. <para>
  1391. During the
  1392. <ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-package'><filename>do_package</filename></ulink>
  1393. task, files installed during the
  1394. <ulink url='&YOCTO_DOCS_REF_URL;#ref-tasks-install'><filename>do_install</filename></ulink>
  1395. task are split into one main package, which is almost always named
  1396. the same as the recipe, and several other packages.
  1397. This separation is done because not all of those installed files
  1398. are always useful in every image.
  1399. For example, you probably do not need any of the documentation
  1400. installed in a production image.
  1401. Consequently, for each recipe the documentation files are separated
  1402. into a <filename>-doc</filename> package.
  1403. Recipes that package software that has optional modules or
  1404. plugins might do additional package splitting as well.
  1405. </para>
  1406. <para>
  1407. After building a recipe you can see where files have gone by
  1408. looking in the <filename>oe-workdir/packages-split</filename>
  1409. directory, which contains a subdirectory for each package.
  1410. Apart from some advanced cases, the
  1411. <ulink url='&YOCTO_DOCS_REF_URL;#var-PACKAGES'><filename>PACKAGES</filename></ulink>
  1412. and
  1413. <ulink url='&YOCTO_DOCS_REF_URL;#var-FILES'><filename>FILES</filename></ulink>
  1414. variables controls splitting.
  1415. The <filename>PACKAGES</filename> variable lists all of the
  1416. packages to be produced, while the <filename>FILES</filename>
  1417. variable specifies which files to include in each package,
  1418. using an override to specify the package.
  1419. For example, <filename>FILES_${PN}</filename> specifies the files
  1420. to go into the main package (i.e. the main package is named the
  1421. same as the recipe and
  1422. <filename>${</filename><ulink url='&YOCTO_DOCS_REF_URL;#var-PN'><filename>PN</filename></ulink><filename>}</filename>
  1423. evaluates to the recipe name).
  1424. The order of the <filename>PACKAGES</filename> value is significant.
  1425. For each installed file, the first package whose
  1426. <filename>FILES</filename> value matches the file is the package
  1427. into which the file goes.
  1428. Defaults exist for both the <filename>PACKAGES</filename> and
  1429. <filename>FILES</filename> variables.
  1430. Consequently, you might find you do not even need to set these
  1431. variables in your recipe unless the software the recipe is
  1432. building installs files into non-standard locations.
  1433. </para>
  1434. </section>
  1435. </section>
  1436. <section id='sdk-restoring-the-target-device-to-its-original-state'>
  1437. <title>Restoring the Target Device to its Original State</title>
  1438. <para>
  1439. If you use the <filename>devtool deploy-target</filename>
  1440. command to write a recipe's build output to the target, and
  1441. you are working on an existing component of the system, then you
  1442. might find yourself in a situation where you need to restore the
  1443. original files that existed prior to running the
  1444. <filename>devtool deploy-target</filename> command.
  1445. Because the <filename>devtool deploy-target</filename> command
  1446. backs up any files it overwrites, you can use the
  1447. <filename>devtool undeploy-target</filename> to restore those files
  1448. and remove any other files the recipe deployed.
  1449. Consider the following example:
  1450. <literallayout class='monospaced'>
  1451. $ devtool undeploy-target lighttpd root@192.168.7.2
  1452. </literallayout>
  1453. If you have deployed multiple applications, you can remove them
  1454. all at once thus restoring the target device back to its
  1455. original state:
  1456. <literallayout class='monospaced'>
  1457. $ devtool undeploy-target -a root@192.168.7.2
  1458. </literallayout>
  1459. Information about files deployed to the target as well as any
  1460. backed up files are stored on the target itself.
  1461. This storage of course requires some additional space
  1462. on the target machine.
  1463. <note>
  1464. The <filename>devtool deploy-target</filename> and
  1465. <filename>devtool undeploy-target</filename> command do not
  1466. currently interact with any package management system on the
  1467. target device (e.g. RPM or OPKG).
  1468. Consequently, you should not intermingle operations
  1469. <filename>devtool deploy-target</filename> and the package
  1470. manager operations on the target device.
  1471. Doing so could result in a conflicting set of files.
  1472. </note>
  1473. </para>
  1474. </section>
  1475. <section id='sdk-installing-additional-items-into-the-extensible-sdk'>
  1476. <title>Installing Additional Items Into the Extensible SDK</title>
  1477. <para>
  1478. The extensible SDK typically only comes with a small number of tools
  1479. and libraries out of the box.
  1480. If you have a minimal SDK, then it starts mostly empty and is
  1481. populated on-demand.
  1482. However, sometimes you will need to explicitly install extra items
  1483. into the SDK.
  1484. If you need these extra items, you can first search for the items
  1485. using the <filename>devtool search</filename> command.
  1486. For example, suppose you need to link to libGL but you are not sure
  1487. which recipe provides it.
  1488. You can use the following command to find out:
  1489. <literallayout class='monospaced'>
  1490. $ devtool search libGL
  1491. mesa A free implementation of the OpenGL API
  1492. </literallayout>
  1493. Once you know the recipe (i.e. <filename>mesa</filename> in this
  1494. example), you can install it:
  1495. <literallayout class='monospaced'>
  1496. $ devtool sdk-install mesa
  1497. </literallayout>
  1498. By default, the <filename>devtool sdk-install</filename> assumes the
  1499. item is available in pre-built form from your SDK provider.
  1500. If the item is not available and it is acceptable to build the item
  1501. from source, you can add the "-s" option as follows:
  1502. <literallayout class='monospaced'>
  1503. $ devtool sdk-install -s mesa
  1504. </literallayout>
  1505. It is important to remember that building the item from source takes
  1506. significantly longer than installing the pre-built artifact.
  1507. Also, if no recipe exists for the item you want to add to the SDK, you
  1508. must instead add it using the <filename>devtool add</filename> command.
  1509. </para>
  1510. </section>
  1511. <section id='sdk-updating-the-extensible-sdk'>
  1512. <title>Updating the Extensible SDK</title>
  1513. <para>
  1514. If you are working with an extensible SDK that gets occasionally
  1515. updated (e.g. typically when that SDK has been provided to you by
  1516. another party), then you will need to manually pull down those
  1517. updates to your installed SDK.
  1518. </para>
  1519. <para>
  1520. To update your installed SDK, run the following:
  1521. <literallayout class='monospaced'>
  1522. $ devtool sdk-update
  1523. </literallayout>
  1524. The previous command assumes your SDK provider has set the default
  1525. update URL for you.
  1526. If that URL has not been set, you need to specify it yourself as
  1527. follows:
  1528. <literallayout class='monospaced'>
  1529. $ devtool sdk-update <replaceable>path_to_update_directory</replaceable>
  1530. </literallayout>
  1531. <note>
  1532. The URL needs to point specifically to a published SDK and not an
  1533. SDK installer that you would download and install.
  1534. </note>
  1535. </para>
  1536. </section>
  1537. <section id='sdk-creating-a-derivative-sdk-with-additional-components'>
  1538. <title>Creating a Derivative SDK With Additional Components</title>
  1539. <para>
  1540. You might need to produce an SDK that contains your own custom
  1541. libraries for sending to a third party (e.g., if you are a vendor with
  1542. customers needing to build their own software for the target platform).
  1543. If that is the case, then you can produce a derivative SDK based on
  1544. the currently installed SDK fairly easily.
  1545. Use these steps:
  1546. <orderedlist>
  1547. <listitem><para>If necessary, install an extensible SDK that
  1548. you want to use as a base for your derivative SDK.
  1549. </para></listitem>
  1550. <listitem><para>Source the environment script for the SDK.
  1551. </para></listitem>
  1552. <listitem><para>Add the extra libraries or other components
  1553. you want by using the <filename>devtool add</filename>
  1554. command.
  1555. </para></listitem>
  1556. <listitem><para>Run the <filename>devtool build-sdk</filename>
  1557. command.
  1558. </para></listitem>
  1559. </orderedlist>
  1560. The above procedure takes the recipes added to the workspace and
  1561. constructs a new SDK installer containing those recipes and the
  1562. resulting binary artifacts.
  1563. The recipes go into their own separate layer in the constructed
  1564. derivative SDK, leaving the workspace clean and ready for users
  1565. to add their own recipes.
  1566. </para>
  1567. </section>
  1568. </chapter>
  1569. <!--
  1570. vim: expandtab tw=80 ts=4
  1571. -->