123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- .. SPDX-License-Identifier: CC-BY-SA-2.0-UK
- ********************************
- Using the SDK Toolchain Directly
- ********************************
- You can use the SDK toolchain directly with Makefile and Autotools-based
- projects.
- Autotools-Based Projects
- ========================
- Once you have a suitable :ref:`sdk-manual/intro:the cross-development toolchain`
- installed, it is very easy to develop a project using the :wikipedia:`GNU
- Autotools-based <GNU_Build_System>` workflow, which is outside of the
- :term:`OpenEmbedded Build System`.
- The following figure presents a simple Autotools workflow.
- .. image:: figures/sdk-autotools-flow.png
- :align: center
- :width: 70%
- 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
- GNOME Developer
- site.
- #. *Create a Working Directory and Populate It:* Create a clean
- directory for your project and then make that directory your working
- location::
- $ mkdir $HOME/helloworld
- $ cd $HOME/helloworld
- 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:
- ``hello.c``, ``configure.ac``, ``Makefile.am``, and ``README``,
- respectively.
- Use the following command to create an empty README file, which is
- required by GNU Coding Standards::
- $ touch README
- Create the remaining
- three files as follows:
- - ``hello.c``::
- #include <stdio.h>
- main()
- {
- printf("Hello World!\n");
- }
- - ``configure.ac``::
- AC_INIT(hello,0.1)
- AM_INIT_AUTOMAKE([foreign])
- AC_PROG_CC
- AC_CONFIG_FILES(Makefile)
- AC_OUTPUT
- - ``Makefile.am``::
- bin_PROGRAMS = hello
- hello_SOURCES = hello.c
- #. *Source the Cross-Toolchain Environment Setup File:* 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; Yocto
- Project release::
- $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
- Another example is sourcing the environment setup directly in a Yocto
- build::
- $ source tmp/deploy/images/qemux86-64/environment-setup-core2-64-poky-linux
- #. *Create the configure Script:* Use the ``autoreconf`` command to
- generate the ``configure`` script::
- $ autoreconf
- The ``autoreconf``
- tool takes care of running the other Autotools such as ``aclocal``,
- ``autoconf``, and ``automake``.
- .. note::
- If you get errors from ``configure.ac``, which ``autoreconf``
- runs, that indicate missing files, you can use the "-i" option,
- which ensures missing auxiliary files are copied to the build
- host.
- #. *Cross-Compile the Project:* This command compiles the project using
- the cross-compiler. The
- :term:`CONFIGURE_FLAGS`
- environment variable provides the minimal arguments for GNU
- configure::
- $ ./configure ${CONFIGURE_FLAGS}
- For an Autotools-based
- project, you can use the cross-toolchain by just passing the
- appropriate host option to ``configure.sh``. 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
- ``armv5te-poky-linux-gnueabi``. You will notice that the name of the
- script is ``environment-setup-armv5te-poky-linux-gnueabi``. Thus, the
- following command works to update your project and rebuild it using
- the appropriate cross-toolchain tools::
- $ ./configure --host=armv5te-poky-linux-gnueabi --with-libtool-sysroot=sysroot_dir
- #. *Make and Install the Project:* These two commands generate and
- install the project into the destination directory::
- $ make
- $ make install DESTDIR=./tmp
- .. note::
- To learn about environment variables established when you run the
- cross-toolchain environment setup script and how they are used or
- overridden by the Makefile, see the
- :ref:`sdk-manual/working-projects:makefile-based projects` section.
- 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::
- $ file ./tmp/usr/local/bin/hello
- #. *Execute Your Project:* 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::
- $ ./tmp/usr/local/bin/hello
- As expected, the project displays the "Hello World!" message.
- Makefile-Based Projects
- =======================
- 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 ``make`` rules.
- 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.
- .. image:: figures/sdk-makefile-flow.png
- :align: center
- :width: 70%
- The main point of this section is to explain the following three cases
- regarding variable behavior:
- - *Case 1 --- No Variables Set in the Makefile Map to Equivalent
- Environment Variables Set in the SDK Setup Script:* Because matching
- variables are not specifically set in the ``Makefile``, the variables
- retain their values based on the environment setup script.
- - *Case 2 --- Variables Are Set in the Makefile that Map to Equivalent
- Environment Variables from the SDK Setup Script:* Specifically
- setting matching variables in the ``Makefile`` during the build
- results in the environment settings of the variables being
- overwritten. In this case, the variables you set in the ``Makefile``
- are used.
- - *Case 3 --- Variables Are Set Using the Command Line that Map to
- Equivalent Environment Variables from the SDK Setup Script:*
- Executing the ``Makefile`` from the command line results in the
- environment variables being overwritten. In this case, the
- command-line content is used.
- .. note::
- Regardless of how you set your variables, if you use the "-e" option
- with ``make``, the variables from the SDK setup script take precedence::
- $ make -e target
- The remainder of this section presents a simple Makefile example that
- demonstrates these variable behaviors.
- 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.
- :term:`CC`)::
- $ echo ${CC}
- $
- Running the
- SDK setup script for a 64-bit build host and an i586-tuned target
- architecture for a ``core-image-sato`` image using the current &DISTRO;
- Yocto Project release and then echoing that variable shows the value
- established through the script::
- $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
- $ echo ${CC}
- i586-poky-linux-gcc -m32 -march=i586 --sysroot=/opt/poky/&DISTRO;/sysroots/i586-poky-linux
- To illustrate variable use, work through this simple "Hello World!"
- example:
- #. *Create a Working Directory and Populate It:* Create a clean
- directory for your project and then make that directory your working
- location::
- $ mkdir $HOME/helloworld
- $ cd $HOME/helloworld
- After
- setting up the directory, populate it with files needed for the flow.
- You need a ``main.c`` file from which you call your function, a
- ``module.h`` file to contain headers, and a ``module.c`` that defines
- your function.
- Create the three files as follows:
- - ``main.c``::
- #include "module.h"
- void sample_func();
- int main()
- {
- sample_func();
- return 0;
- }
- - ``module.h``::
- #include <stdio.h>
- void sample_func();
- - ``module.c``::
- #include "module.h"
- void sample_func()
- {
- printf("Hello World!");
- printf("\n");
- }
- #. *Source the Cross-Toolchain Environment Setup File:* 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::
- $ source /opt/poky/&DISTRO;/environment-setup-i586-poky-linux
- Another example is sourcing the environment setup directly in a Yocto
- build::
- $ source tmp/deploy/images/qemux86-64/environment-setup-core2-64-poky-linux
- #. *Create the Makefile:* For this example, the Makefile contains
- two lines that can be used to set the :term:`CC` variable. One line is
- identical to the value that is set when you run the SDK environment
- setup script, and the other line sets :term:`CC` to "gcc", the default
- GNU compiler on the build host::
- # 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
- #. *Make the Project:* Use the ``make`` command to create the binary
- output file. Because variables are commented out in the Makefile, the
- value used for :term:`CC` is the value set when the SDK environment setup
- file was run::
- $ 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
- From the results of the previous command, you can see that
- the compiler used was the compiler established through the :term:`CC`
- variable defined in the setup script.
- You can override the :term:`CC` environment variable with the same
- variable as set from the Makefile by uncommenting the line in the
- Makefile and running ``make`` again::
- $ 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
- As shown in the previous example, the
- cross-toolchain compiler is not used. Rather, the default compiler is
- used.
- 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 ``make`` uses the
- established SDK compiler. However, when you run ``make``, use a
- command-line argument to set :term:`CC` to "gcc"::
- $ 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
- In the previous case, the command-line argument overrides the SDK
- environment variable.
- In this last case, edit Makefile again to use the "gcc" compiler but
- then use the "-e" option on the ``make`` command line::
- $ 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
- In the previous case, the "-e" option forces ``make`` to
- use the SDK environment variables regardless of the values in the
- Makefile.
- #. *Execute Your Project:* To execute the project (i.e. ``target_bin``),
- use the following command::
- $ ./target_bin
- Hello World!
- .. note::
- If you used the cross-toolchain compiler to build
- target_bin
- and your build host differs in architecture from that of the
- target machine, you need to run your project on the target device.
- As expected, the project displays the "Hello World!" message.
|