Using toolchains

In this tutorial, you will learn how to build your projects using pre-compiled packages.

Using Aldebaran toolchains

Aldebaran C++ SDKs and cross-toolchains are, by definition, toolchains.

Using them is done with

$ qitoolchain create <name> /path/to/toolchain.xml

Adding packages to a toolchain

Requirements

The requirements for this tutorial are the same as in the Managing dependencies between projects tutorial.

You should have:

  • a properly configured qiBuild worktree
  • two projects, world and hello, with hello depending on the world library.

You can find these two projects here helloworld.zip

The goal of this tutorial is to manage to compile hello, using a pre-compiled binary of world.

Creating the world package

Generating a package for the world project is done with:

$ qibuild package world

This will create a package named world.tar.gz in QI_WORK_TREE/package/world.tar.gz (or world.tar.gz on windows)

Inside the package, you will have:

world
|__ include
    |__ world
       |__ world.hpp
    lib
       |__ libworld.so
    share
      cmake
        |__ world-config.cmake

Note

The archive generated by qibuid always contain a properly named top directory. This is annoying only when using the build-in zip extractor of Windows, you will end up with world/world/ ...), so get over it or just use 7zip.

The LFS hierarchy is still preserved, and it is the same as in build/sdk.

The world-config.cmake is a standard CMake file, but it can be used even after installing the world package, because it only uses relative paths.

So the world package is usable anywhere.

Note

The world-config.cmake does not even requires qibuild to be used by an other CMake project, all it does is calling standard CMake functions.

Create a toolchain from scratch

If you are already using a Aldebaran toolchain, you can skip this section.

Otherwise, you have to create a toolchain from scratch for qibuild to use:

$ qitoolchain create <TOOLCHAIN_NAME> --default

You are free to choose any name for your toolchain, but it is advised to pick one from this set of configurations:

  • linux32
  • linux64
  • mac32
  • mac64
  • win32-vs2008
  • win32-vs2010
  • mingw

Here we will assume you chose linux32.

Here we used the --default option. If you don’t, you will have to add -c linux32 to every qibuild command.

The only thing the default option does is to set QI_WORK_TREE/.qi/qibuild.xml so that it looks like:

 <qibuild version="1" >
  <defaults config="linux32" />
</qibuild>

So it’s easy to change your mind later.

This will create a directory looking like: ~/.local/share/qi/toolchains/linux32/ where every packages will be put.

You can check that your toolchain has been created with:

$ qitoolchain status

Toolchain linux32
No feed
No packages

Adding the world package to the toolchain

Now you can use:

$ qitoolchain add-package -c linux32 world /path/to/worktree/package/world.tar.gz

You can check that your package has been added with:

$ qitoolchain status

Toolchain linux32
No feed
  Packages:
    world
      in /home/user/.local/share/qi/toolchains/linux32/world

This will simply:

  • copy the world package somewhere in you toolchain directory.
  • configure some files so that qibuild knows that the linux32 toolchain can provide the world package

When resolving dependencies of the hello project, qibuild will see that you use a toolchain called linux32 and that this toolchain provides the world project, so it’s enough to set CMAKE_MODULE_PATHS to path/to/linux/toolchain/world

The world project will not be built when you use qibuild make hello, unless you specify it explicitly on the command line:

$ qibuild configure world hello

Creating toolchain feeds

Now, that you have a nice local toolchain, and a world package, you may want other people to be able to use the world package, without them having to recompile it from source.

So here we are going to create a remote configuration file, so that other developers can simply download the world package from a server.

We will assume you have access to a FTP or a HTTP sever.

First, upload the world package, so that is accessible with the url: http://example.com/packages/world.tar.gz

Next, create a feed.xml accessible with the url: http://example.com/feed.xml, looking like

<toolchain>

  <package
    name="world"
    url = "http://example.com/packages/world.tar.gz"
  />

</toolchain>

Then, from an other machine, run

$ qitoolchain create linux32 http://example.com/feed.xml

Getting package world from http://example.com/packages/world.tar.gz
Toolchain linux32: adding package world

You can see that the feed has been stored in your qibuild configuration:

$ qitoolchain status

Toolchain linux32
Using feed from http://example.com/feed.xml
  Packages:
    foo
      in /home/user/.local/share/qi/toolchains/linux32/world

Note: if you HTTP or FTP server is protected by a password, you can put the username and password in the .config/qi/qibuild.xml configuration file.

See the section qibuild.xml configuration file syntax for details.

You can also add the Aldebaran C++ SDKs or cross toolchains as if they were packages. (This sound a bit weird, but it works)

For instance, assuming you were using the atom cross-toolchain and cross-compiled the world package, you can create a feed looking like

 <toolchain>
  <package name="atom-ctc"  url="http://example.com/packages/aldebaran-ctc.tar.gz"
    toolchain_file="cross-config.cmake" />

  <package name="hello"  url="http://example.com/packages/world.tar.gz" />
</toolchain>

Don’t forget the toolchain_file attribute of the atom-ctc package, though.

Full feed.xml specification

The full specification can be found in the Toolchain feed syntax section

Just for fun

You can always add something like

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../xsl/toolchain.xsl"?>

With an xsl looking like

<html xsl:version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
  <body >
    <h2> Packages </h2>
    <ul>
      <xsl:for-each select="toolchain/package">
      <li>
        <a>
        <xsl:attribute name="href">
          <xsl:value-of select="@url" />
        </xsl:attribute>
        <xsl:value-of select="@name" />
        </a>
      </li>
      </xsl:for-each>
    </ul>
    <h2> Feeds </h2>
    <ul>
      <xsl:for-each select="toolchain/feed">
      <li>
        <a>
        <xsl:attribute name="href">
          <xsl:value-of select="@url" />
        </xsl:attribute>
        <xsl:value-of select="@url" />
        </a>
      </li>
      </xsl:for-each>
    </ul>
  </body>
</html>