qiBuild and ROS build system¶
Introduction¶
This section is targeted towards ROS users wanting to know more about qiBuild.
General comparison¶
First, qiBuild and the ROS build system have much in common.
They are both based on CMake, and provide a set of tools to manage multiple projects, and dependencies between projects.
What is in qiBuild and not in the ROS build ecosystem¶
- Ability to create redistributable, pre-compiled packages. (ROS supports generation of Ubuntu, Fedora, Homebrew packages, though)
- Easy cross-compilation (ROS only deals with cross-compilation through provided CMake but does not deal with extra packages and different build folders according to the architectures)
- qitoolchain provides a clean way to package and use third-party dependencies without touching the system, which will work on any Linux distribution (ROS deals with this by using existing infrastructures to create its own third party packages when needed)
What is in the ROS build ecosystem and not in qiBuild¶
- ability to build sources in one common out of source build folder or in individual isolated build folders per projects.
- Parallel builds of projects when using one build space (default behavior).
- Python support : automatic handling of $PYTHONPATH variable, of
setup.py
, no copy of sources during build - special targets to build/run tests
- no need to use external tools to build the sources, you can call
cmake ../ && make
from the command line after copying a specificCMakeLists.txt
file at the root of your workspace - tools to install/visualize dependencies
- workspace chaining: you can create several workspaces with several projects
and use them by chaining appropriate environment variables (which is done on
Unix by sourcing a
setup.sh
file) - a release tool
bloom
, to automatically bump versions, create packages
CMake equivalences¶
Gist¶
catkin¶
Catkin never wraps any CMake functionality and only provides additional CMake functionality. What you need to do in catkin is define what other packages need to know about your package. This is done by calling one macro:
find_package(catkin)
catkin_package(DEPENDS ${DEPENDENCY_NAMES}
INCLUDE_DIRS ${LIST_OF_INCLUDE_DIRS_TO_EXPORT}
LIBRARIES ${LIST_OF_LIBRARIES_TO_EXPORT}
)
This will define the fooConfig.cmake
and fooConfig-version.cmake
files
that other packages will need. For everything else, you need to write things
explicitly, using standard CMake. For example, to use a catkin package, you
need to call:
find_package(catkin COMPONENT foo)
include_directories(${foo_INCLUDE_DIRS})
target_link_libraries(bar ${foo_LIBRARIES})
The folder hierarchy is then a src
folder with all your sources, and it
stays untouched. An out-of-source build
folder that contains all the
temporary files used for building and an out-of-source/out-of-build devel
folder that contains an FHS compliant set of built libraries and executables.
qibuild¶
With qibuild, you do not need to specify what you export as it is done automatically when defining a library/executable:
qi_create_lib()
qi_create_bin()
Using another package is then just a matter of calling:
qi_use_lib(bar FOO)
Each qiproject is built in the source folder in a build
folder that is
proper to a specific toolchain.
Initialization¶
catkin¶
find_package(catkin)
qibuild¶
find_package(qibuild)
If qibuild
is installed on the system, it just works,
but the qibuild command line tool is also smart
enough to pass -Dqibuild_DIR
when necessary.
Output paths¶
catkin¶
Catkin lets you decide what you want to install and where using standard CMake. For convenience, it defines variables you can reuse (CATKIN_PACKAGE_BIN_DESTINATION, CATKIN_PACKAGE_SHARE_DESTINATION ...) and that correspond to standard locations on your distro or OS.
install(${EXEC_TARGET} ${CATKIN_PACKAGE_BIN_DESTINATION})
The output path devel
is outside the build dir and outside the source dir.
qibuild¶
N/A : automatically set. Default SDK layout.
Output path is inside build dir, in a directory named sdk/ (temporary build results are NOT in build/sdk)
Adding executables¶
qibuild¶
qi_create_bin()
Goes away from the CMake defaults:
@rpath
on mac (actual CMake 2.8.12 is going to do that by default too)- install
rpath
set to$ORIGIN/../lib
on Linux _d
prefix on Visual Studio when building in debug- install rules (force install in
<prefix>/bin
)
Adding libraries¶
qibuild¶
qi_create_lib()
Goes away from the CMake defaults:
@rpath
on mac (actual CMake 2.8.12 is going to do that by default too)- install
rpath
set to relative to$ORIGIN
on linux, so thatdlopen(<prefix>/lib/plugin/foo.so)
finds the dependencies in<prefix>/lib/libbar.so
Management of dependencies¶
ROS¶
- Looks for dependencies using the
catkin_pkg
library and meta-info stored in apackage.xml
- 3rd party dependencies can be installed using rosdep, otherwise whatever is on the system is used.
qibuild¶
- Looks for dependencies using qibuild and qibuild.manifest
- Never tries to install anything, uses libraries from the system when found or can use pre-compiled packages with qitoolchain.
- Runs cmake inside the source dirs of the buildable dependencies, during qibuild configure, then cmake –build inside the build directories of the buildable dependencies, during qibuild make
3rd party dependencies¶
catkin¶
Standard CMake:
find_package(Boost COMPONENTS thread)
include_directories(${BOOST_INCLUDE_DIRS})
add_library(${PROJECT_NAME} ${LIST_OF_SOURCE_FILES})
target_link_libraries(${PROJECT_NAME} ${BOOST_LIBRARIES})
qibuild¶
qi_create_lib(${PROJECT_NAME} ${LIST_OF_SOURCE_FILES})
qi_use_lib(myproject BOOST_THREAD)
Easy to use but requires the manual creation of one CMake file per 3rd party. The flip side is that you can inherit dependencies:
qi_create_lib(foo)
qi_use_lib(foo bar)
qi_create_bin(baz)
qi_use_lib(baz foo) # baz links with foo and bar
(Something cmake 2.8.12 kinda does, but which much greater complexity because they handle all the corner cases)
Python support¶
catkin¶
Catkin only deals with Python using standard setuptools (and can therefore deal
with standard Python code, SWIG ...). Just write your setup.py
and then
call the following macro from your CMakeLists.txt
.
catkin_python_setup()
Also, catkin does not copy your source Python files to the devel space to
avoid confusion and ease development: it creates __init__.py
files that
refer to your sources.
qibuild¶
qiBuild has direct support for SWIG projects:
include(qibuild/swig/python)
qi_swig_wrap_python(_foo foo.i
SRC bar.cpp
DEPENDS ...)
Using qiBuild with the ROS build ecosystem at the same time¶
If you create ROS packages in their own workspace and source the setup.sh
,
all environment variables are set to enable using those ROS packages from any
CMake project using find_package(catkin COMPONENTS foo)
, hence from qibuild
projects too.
qibuild projects have some limitations for now: they do not provide a
fooConfig-version.cmake
file yet, and need to be find_package()
-ed from
a qibuild project.