diff options
Diffstat (limited to 'documentation/sdk-manual/sdk-working-projects.xml')
-rw-r--r-- | documentation/sdk-manual/sdk-working-projects.xml | 653 |
1 files changed, 442 insertions, 211 deletions
diff --git a/documentation/sdk-manual/sdk-working-projects.xml b/documentation/sdk-manual/sdk-working-projects.xml index 6965e3f285f..d8cc4229dc1 100644 --- a/documentation/sdk-manual/sdk-working-projects.xml +++ b/documentation/sdk-manual/sdk-working-projects.xml @@ -8,7 +8,7 @@ <para> You can use the SDK toolchain directly with Makefile, - Autotools, and <trademark class='trade'>Eclipse</trademark> based + Autotools, and <trademark class='trade'>Eclipse</trademark>-based projects. This chapter covers the first two, while the "<link linkend='sdk-eclipse-project'>Developing Applications Using <trademark class='trade'>Eclipse</trademark></link>" @@ -19,263 +19,494 @@ <title>Autotools-Based Projects</title> <para> - Once you have a suitable cross-toolchain installed, it is very easy - to develop a project outside of the OpenEmbedded build system. - This section presents a simple "Helloworld" example that shows how - to set up, compile, and run the project. + Once you have a suitable + <ulink url='&YOCTO_DOCS_REF_URL;#cross-development-toolchain'>cross-development toolchain</ulink> + installed, it is very easy to develop a project using the + <ulink url='https://en.wikipedia.org/wiki/GNU_Build_System'>GNU Autotools-based</ulink> + workflow, which is outside of the + <ulink url='&YOCTO_DOCS_REF_URL;#build-system-term'>OpenEmbedded build system</ulink>. </para> - <section id='creating-and-running-a-project-based-on-gnu-autotools'> - <title>Creating and Running a Project Based on GNU Autotools</title> + <para> + The following figure presents a simple Autotools workflow. + <imagedata fileref="figures/sdk-autotools-flow.png" width="7in" height="8in" align="center" /> + </para> - <para> - Follow these steps to create a simple Autotools-based project: - <orderedlist> - <listitem><para> - <emphasis>Create your directory:</emphasis> - Create a clean directory for your project and then make - that directory your working location: - <literallayout class='monospaced'> + <para> + Follow these steps to create a simple Autotools-based + "Hello World" project: + <note> + For more information on the GNU Autotools workflow, + see the same example on the + <ulink url='https://developer.gnome.org/anjuta-build-tutorial/stable/create-autotools.html.en'>GNOME Developer</ulink> + site. + </note> + <orderedlist> + <listitem><para> + <emphasis>Create a Working Directory and Populate It:</emphasis> + Create a clean directory for your project and then make + that directory your working location. + <literallayout class='monospaced'> $ mkdir $HOME/helloworld $ cd $HOME/helloworld - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Populate the directory:</emphasis> - Create <filename>hello.c</filename>, - <filename>Makefile.am</filename>, - and <filename>configure.ac</filename> files as follows: - <itemizedlist> - <listitem><para> - For <filename>hello.c</filename>, include - these lines: - <literallayout class='monospaced'> + </literallayout> + After setting up the directory, populate it with files + needed for the flow. + You need a project source file, a file to help with + configuration, and a file to help create the Makefile, + and a README file: + <filename>hello.c</filename>, + <filename>configure.ac</filename>, + <filename>Makefile.am</filename>, and + <filename>README</filename>, respectively.</para> + + <para> Use the following command to create an empty README + file, which is required by GNU Coding Standards: + <literallayout class='monospaced'> + $ touch README + </literallayout> + Create the remaining three files as follows: + <itemizedlist> + <listitem><para> + <emphasis><filename>hello.c</filename>:</emphasis> + <literallayout class='monospaced'> #include <stdio.h> main() { printf("Hello World!\n"); } - </literallayout> - </para></listitem> - <listitem><para> - For <filename>Makefile.am</filename>, - include these lines: - <literallayout class='monospaced'> - bin_PROGRAMS = hello - hello_SOURCES = hello.c - </literallayout> - </para></listitem> - <listitem><para> - For <filename>configure.in</filename>, - include these lines: - <literallayout class='monospaced'> + </literallayout> + </para></listitem> + <listitem><para> + <emphasis><filename>configure.ac</filename>:</emphasis> + <literallayout class='monospaced'> AC_INIT(hello,0.1) AM_INIT_AUTOMAKE([foreign]) AC_PROG_CC - AC_PROG_INSTALL - AC_OUTPUT(Makefile) - </literallayout> - </para></listitem> - </itemizedlist> - </para></listitem> - <listitem><para> - <emphasis>Source the cross-toolchain - environment setup file:</emphasis> - As described earlier in the manual, installing the - cross-toolchain creates a cross-toolchain - environment setup script in the directory that the SDK - was installed. - Before you can use the tools to develop your project, - you must source this setup script. - The script begins with the string "environment-setup" - and contains the machine architecture, which is - followed by the string "poky-linux". - Here is an example that sources a script from the - default SDK installation directory that uses the - 32-bit Intel x86 Architecture and the - &DISTRO_NAME; Yocto Project release: - <literallayout class='monospaced'> + AC_CONFIG_FILES(Makefile) + AC_OUTPUT + </literallayout> + </para></listitem> + <listitem><para> + <emphasis><filename>Makefile.am</filename>:</emphasis> + <literallayout class='monospaced'> + bin_PROGRAMS = hello + hello_SOURCES = hello.c + </literallayout> + </para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + <emphasis>Source the Cross-Toolchain + Environment Setup File:</emphasis> + As described earlier in the manual, installing the + cross-toolchain creates a cross-toolchain + environment setup script in the directory that the SDK + was installed. + Before you can use the tools to develop your project, + you must source this setup script. + The script begins with the string "environment-setup" + and contains the machine architecture, which is + followed by the string "poky-linux". + For this example, the command sources a script from the + default SDK installation directory that uses the + 32-bit Intel x86 Architecture and the + &DISTRO_NAME; Yocto Project release: + <literallayout class='monospaced'> $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Generate the local aclocal.m4 - files and create the configure script:</emphasis> - The following GNU Autotools generate the local - <filename>aclocal.m4</filename> files and create the - configure script: - <literallayout class='monospaced'> - $ aclocal - $ autoconf - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Generate files needed by GNU coding - standards:</emphasis> - GNU coding standards require certain files in order - for the project to be compliant. - This command creates those files: - <literallayout class='monospaced'> - $ touch NEWS README AUTHORS ChangeLog - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Generate the configure file:</emphasis> - This command generates the - <filename>configure</filename>: - <literallayout class='monospaced'> - $ automake -a - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Cross-compile the project:</emphasis> - This command compiles the project using the - cross-compiler. - The - <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIGURE_FLAGS'><filename>CONFIGURE_FLAGS</filename></ulink> - environment variable provides the minimal arguments for - GNU configure: - <literallayout class='monospaced'> + </literallayout> + </para></listitem> + <listitem><para> + <emphasis>Create the <filename>configure</filename> Script:</emphasis> + Use the <filename>autoreconf</filename> command to + generate the <filename>configure</filename> script. + <literallayout class='monospaced'> + $ autoreconf + </literallayout> + The <filename>autoreconf</filename> tool takes care + of running the other Autotools such as + <filename>aclocal</filename>, + <filename>autoconf</filename>, and + <filename>automake</filename>. + <note> + If you get errors from + <filename>configure.ac</filename>, which + <filename>autoreconf</filename> runs, that indicate + missing files, you can use the "-i" option, which + ensures missing auxiliary files are copied to the build + host. + </note> + </para></listitem> + <listitem><para> + <emphasis>Cross-Compile the Project:</emphasis> + This command compiles the project using the + cross-compiler. + The + <ulink url='&YOCTO_DOCS_REF_URL;#var-CONFIGURE_FLAGS'><filename>CONFIGURE_FLAGS</filename></ulink> + environment variable provides the minimal arguments for + GNU configure: + <literallayout class='monospaced'> $ ./configure ${CONFIGURE_FLAGS} - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Make and install the project:</emphasis> - These two commands generate and install the project - into the destination directory: - <literallayout class='monospaced'> + </literallayout> + For an Autotools-based project, you can use the + cross-toolchain by just passing the appropriate host + option to <filename>configure.sh</filename>. + The host option you use is derived from the name of the + environment setup script found in the directory in which + you installed the cross-toolchain. + For example, the host option for an ARM-based target that + uses the GNU EABI is + <filename>armv5te-poky-linux-gnueabi</filename>. + You will notice that the name of the script is + <filename>environment-setup-armv5te-poky-linux-gnueabi</filename>. + Thus, the following command works to update your project + and rebuild it using the appropriate cross-toolchain tools: + <literallayout class='monospaced'> + $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=<replaceable>sysroot_dir</replaceable> + </literallayout> + </para></listitem> + <listitem><para> + <emphasis>Make and Install the Project:</emphasis> + These two commands generate and install the project + into the destination directory: + <literallayout class='monospaced'> $ make $ make install DESTDIR=./tmp - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Verify the installation:</emphasis> - This command is a simple way to verify the installation - of your project. - Running the command prints the architecture on which - the binary file can run. - This architecture should be the same architecture that - the installed cross-toolchain supports. - <literallayout class='monospaced'> + </literallayout> + <note> + To learn about environment variables established + when you run the cross-toolchain environment setup + script and how they are used or overridden when + the Makefile, see the + "<link linkend='makefile-based-projects'>Makefile-Based Projects</link>" + section. + </note> + This next command is a simple way to verify the + installation of your project. + Running the command prints the architecture on which + the binary file can run. + This architecture should be the same architecture that + the installed cross-toolchain supports. + <literallayout class='monospaced'> $ file ./tmp/usr/local/bin/hello - </literallayout> - </para></listitem> - <listitem><para> - <emphasis>Execute your project:</emphasis> - To execute the project in the shell, simply enter - the name. - You could also copy the binary to the actual target - hardware and run the project there as well: - <literallayout class='monospaced'> - $ ./hello - </literallayout> - As expected, the project displays the "Hello World!" - message. - </para></listitem> - </orderedlist> - </para> - </section> - - <section id='passing-host-options'> - <title>Passing Host Options</title> - - <para> - For an Autotools-based project, you can use the cross-toolchain - by just passing the appropriate host option to - <filename>configure.sh</filename>. - The host option you use is derived from the name of the - environment setup script found in the directory in which you - installed the cross-toolchain. - For example, the host option for an ARM-based target that uses - the GNU EABI is <filename>armv5te-poky-linux-gnueabi</filename>. - You will notice that the name of the script is - <filename>environment-setup-armv5te-poky-linux-gnueabi</filename>. - Thus, the following command works to update your project and - rebuild it using the appropriate cross-toolchain tools: - <literallayout class='monospaced'> - $ ./configure --host=armv5te-poky-linux-gnueabi \ - --with-libtool-sysroot=<replaceable>sysroot_dir</replaceable> - </literallayout> - <note> - If the <filename>configure</filename> script results in - problems recognizing the - <filename>--with-libtool-sysroot=</filename><replaceable>sysroot-dir</replaceable> - option, regenerate the script to enable the support by - doing the following and then run the script again: + </literallayout> + </para></listitem> + <listitem><para> + <emphasis>Execute Your Project:</emphasis> + To execute the project, you would need to run it on your + target hardware. + If your target hardware happens to be your build host, + you could run the project as follows: <literallayout class='monospaced'> - $ libtoolize --automake - $ aclocal -I ${OECORE_TARGET_SYSROOT}/usr/share/aclocal [-I <replaceable>dir_containing_your_project-specific_m4_macros</replaceable>] - $ autoconf - $ autoheader - $ automake -a + $ ./tmp/usr/local/bin/hello </literallayout> - </note> - </para> - </section> + As expected, the project displays the "Hello World!" + message. + </para></listitem> + </orderedlist> + </para> </section> <section id='makefile-based-projects'> <title>Makefile-Based Projects</title> <para> - For Makefile-based projects, the cross-toolchain environment - variables established by running the cross-toolchain environment - setup script are subject to general <filename>make</filename> - rules. + Simple Makefile-based projects use and interact with the + cross-toolchain environment variables established when you run + the cross-toolchain environment setup script. + The environment variables are subject to general + <filename>make</filename> rules. </para> <para> - To illustrate this, consider the following four cross-toolchain - environment variables: - <literallayout class='monospaced'> - <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'>CC</ulink>=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux - <ulink url='&YOCTO_DOCS_REF_URL;#var-LD'>LD</ulink>=i586-poky-linux-ld --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux - <ulink url='&YOCTO_DOCS_REF_URL;#var-CFLAGS'>CFLAGS</ulink>=-O2 -pipe -g -feliminate-unused-debug-types - <ulink url='&YOCTO_DOCS_REF_URL;#var-CXXFLAGS'>CXXFLAGS</ulink>=-O2 -pipe -g -feliminate-unused-debug-types - </literallayout> - Now, consider the following three cases: + This section presents a simple Makefile development flow and + provides an example that lets you see how you can use + cross-toolchain environment variables and Makefile variables + during development. + <imagedata fileref="figures/sdk-makefile-flow.png" width="6in" height="7in" align="center" /> + </para> + + <para> + The main point of this section is to explain the following three + cases regarding variable behavior: <itemizedlist> <listitem><para> <emphasis>Case 1 - No Variables Set in the - <filename>Makefile</filename>:</emphasis> - Because these variables are not specifically set in the + <filename>Makefile</filename> Map to Equivalent + Environment Variables Set in the SDK Setup Script:</emphasis> + Because matching variables are not specifically set in the <filename>Makefile</filename>, the variables retain their - values based on the environment. + values based on the environment setup script. </para></listitem> <listitem><para> - <emphasis>Case 2 - Variables Set in the - <filename>Makefile</filename>:</emphasis> - Specifically setting variables in the + <emphasis>Case 2 - Variables Are Set in the Makefile that + Map to Equivalent Environment Variables from the SDK + Setup Script:</emphasis> + Specifically setting matching variables in the <filename>Makefile</filename> during the build results in the environment settings of the variables being overwritten. + In this case, the variables you set in the + <filename>Makefile</filename> are used. </para></listitem> <listitem><para> - <emphasis>Case 3 - Variables Set when the - <filename>Makefile</filename> is Executed from the - Command Line:</emphasis> + <emphasis>Case 3 - Variables Are Set Using the Command Line + that Map to Equivalent Environment Variables from the + SDK Setup Script:</emphasis> Executing the <filename>Makefile</filename> from the - command-line results in the variables being overwritten - with command-line content regardless of what is being set - in the <filename>Makefile</filename>. - In this case, environment variables are not considered - unless you use the "-e" flag during the build: - <literallayout class='monospaced'> - $ make -e <replaceable>file</replaceable> - </literallayout> - If you use this flag, then the environment values of the - variables override any variables specifically set in the - <filename>Makefile</filename>. + command line results in the environment variables being + overwritten. + In this case, the command-line content is used. </para></listitem> </itemizedlist> <note> - For the list of variables set up by the cross-toolchain - environment setup script, see the - "<link linkend='sdk-running-the-sdk-environment-setup-script'>Running the SDK Environment Setup Script</link>" - section. + Regardless of how you set your variables, if you use + the "-e" option with <filename>make</filename>, the + variables from the SDK setup script take precedence: + <literallayout class='monospaced'> + $ make -e <replaceable>target</replaceable> + </literallayout> </note> </para> + + <para> + The remainder of this section presents a simple Makefile example + that demonstrates these variable behaviors. + </para> + + <para> + In a new shell environment variables are not established for the + SDK until you run the setup script. + For example, the following commands show a null value for the + compiler variable (i.e. + <ulink url='&YOCTO_DOCS_REF_URL;#var-CC'><filename>CC</filename></ulink>). + <literallayout class='monospaced'> + $ echo ${CC} + + $ + </literallayout> + Running the SDK setup script for a 64-bit build host and an + i586-tuned target architecture for a + <filename>core-image-sato</filename> image using the current + &DISTRO; Yocto Project release and then echoing that variable + shows the value established through the script: + <literallayout class='monospaced'> + $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux + $ echo ${CC} + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux + </literallayout> + </para> + + <para> + To illustrate variable use, work through this simple "Hello World!" + example: + <orderedlist> + <listitem><para> + <emphasis>Create a Working Directory and Populate It:</emphasis> + Create a clean directory for your project and then make + that directory your working location. + <literallayout class='monospaced'> + $ mkdir $HOME/helloworld + $ cd $HOME/helloworld + </literallayout> + After setting up the directory, populate it with files + needed for the flow. + You need a <filename>main.c</filename> file from which you + call your function, a <filename>module.h</filename> file + to contain headers, and a <filename>module.c</filename> + that defines your function. + </para> + + <para>Create the three files as follows: + <itemizedlist> + <listitem><para> + <emphasis><filename>main.c</filename>:</emphasis> + <literallayout class='monospaced'> + #include "module.h" + void sample_func(); + int main() + { + sample_func(); + return 0; + } + </literallayout> + </para></listitem> + <listitem><para> + <emphasis><filename>module.h</filename>:</emphasis> + <literallayout class='monospaced'> + #include <stdio.h> + void sample_func(); + </literallayout> + </para></listitem> + <listitem><para> + <emphasis><filename>module.c</filename>:</emphasis> + <literallayout class='monospaced'> + #include "module.h" + void sample_func() + { + printf("Hello World!"); + printf("\n"); + } + </literallayout> + </para></listitem> + </itemizedlist> + </para></listitem> + <listitem><para> + <emphasis>Source the Cross-Toolchain Environment Setup File:</emphasis> + As described earlier in the manual, installing the + cross-toolchain creates a cross-toolchain environment setup + script in the directory that the SDK was installed. + Before you can use the tools to develop your project, + you must source this setup script. + The script begins with the string "environment-setup" + and contains the machine architecture, which is + followed by the string "poky-linux". + For this example, the command sources a script from the + default SDK installation directory that uses the + 32-bit Intel x86 Architecture and the + &DISTRO_NAME; Yocto Project release: + <literallayout class='monospaced'> + $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux + </literallayout> + </para></listitem> + <listitem><para> + <emphasis>Create the <filename>Makefile</filename>:</emphasis> + For this example, the Makefile contains two lines that + can be used to set the <filename>CC</filename> variable. + One line is identical to the value that is set when you + run the SDK environment setup script, and the other line + sets <filename>CC</filename> to "gcc", the default GNU + compiler on the build host: + <literallayout class='monospaced'> + # CC=i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux + # CC="gcc" + all: main.o module.o + ${CC} main.o module.o -o target_bin + main.o: main.c module.h + ${CC} -I . -c main.c + module.o: module.c module.h + ${CC} -I . -c module.c + clean: + rm -rf *.o + rm target_bin + </literallayout> + </para></listitem> + <listitem><para> + <emphasis>Make the Project:</emphasis> + Use the <filename>make</filename> command to create the + binary output file. + Because variables are commented out in the Makefile, + the value used for <filename>CC</filename> is the value + set when the SDK environment setup file was run: + <literallayout class='monospaced'> + $ make + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin + </literallayout> + From the results of the previous command, you can see that + the compiler used was the compiler established through + the <filename>CC</filename> variable defined in the + setup script.</para> + + <para>You can override the <filename>CC</filename> + environment variable with the same variable as set from + the Makefile by uncommenting the line in the Makefile + and running <filename>make</filename> again. + <literallayout class='monospaced'> + $ make clean + rm -rf *.o + rm target_bin + # + # Edit the Makefile by uncommenting the line that sets CC to "gcc" + # + $ make + gcc -I . -c main.c + gcc -I . -c module.c + gcc main.o module.o -o target_bin + </literallayout> + As shown in the previous example, the cross-toolchain + compiler is not used. + Rather, the default compiler is used.</para> + + <para>This next case shows how to override a variable + by providing the variable as part of the command line. + Go into the Makefile and re-insert the comment character + so that running <filename>make</filename> uses + the established SDK compiler. + However, when you run <filename>make</filename>, use a + command-line argument to set <filename>CC</filename> + to "gcc": + <literallayout class='monospaced'> + $ make clean + rm -rf *.o + rm target_bin + # + # Edit the Makefile to comment out the line setting CC to "gcc" + # + $ make + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin + $ make clean + rm -rf *.o + rm target_bin + $ make CC="gcc" + gcc -I . -c main.c + gcc -I . -c module.c + gcc main.o module.o -o target_bin + </literallayout> + In the previous case, the command-line argument overrides + the SDK environment variable.</para> + + <para>In this last case, edit Makefile again to use the + "gcc" compiler but then use the "-e" option on the + <filename>make</filename> command line: + <literallayout class='monospaced'> + $ make clean + rm -rf *.o + rm target_bin + # + # Edit the Makefile to use "gcc" + # + $ make + gcc -I . -c main.c + gcc -I . -c module.c + gcc main.o module.o -o target_bin + $ make clean + rm -rf *.o + rm target_bin + $ make -e + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c main.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux -I . -c module.c + i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/2.5/sysroots/i586-poky-linux main.o module.o -o target_bin + </literallayout> + In the previous case, the "-e" option forces + <filename>make</filename> to use the SDK environment + variables regardless of the values in the Makefile. + </para></listitem> + <listitem><para> + <emphasis>Execute Your Project:</emphasis> + To execute the project (i.e. + <filename>target_bin</filename>), use the following + command: + <literallayout class='monospaced'> + $ ./target_bin + Hello World! + </literallayout> + <note> + If you used the cross-toolchain compiler to build + <filename>target_bin</filename> and your build host + differs in architecture from that of the target + machine, you need to run your project on the target + device. + </note> + As expected, the project displays the "Hello World!" + message. + </para></listitem> + </orderedlist> + </para> </section> </chapter> <!-- |