Skip to content

Commit 51737f8

Browse files
author
Christoph Hellmann Santos
committed
Add how to guide for vendoring a non cmake package
Signed-off-by: Christoph Hellmann Santos <[email protected]>
1 parent 687cd01 commit 51737f8

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
Vendoring a non CMAKE package using AddExternalProject
2+
======================================================
3+
4+
Sometimes you need to vendor a package that doesn't use CMAKE, because it is not in any distribution.
5+
This How-To-Guide gives you some hints on how to do that, using the example of the lely_core_libraries package.
6+
7+
The lely_core_libraries package is a C++ library that is used by the ros2_canopen stack. It uses autotools as
8+
build system and is only available via ppa for Ubuntu. To make it available in rosdistro, we need to vendor it.
9+
10+
Step 1: Create a new ament_cmake package
11+
----------------------------------------
12+
13+
First you need to create an ament cmake package in your workspace.
14+
15+
.. code:: bash
16+
17+
cd ~/ros2_ws/src
18+
ros2 pkg create --build-type ament_cmake <package_name>
19+
20+
Once you have created the package, delete all folders in the package, we do not need them.
21+
22+
Step 2: Add the external project to CMakeLists.txt
23+
--------------------------------------------------
24+
Open the CMakeLists.txt file and add the following code after the find_package() calls.
25+
26+
.. code::
27+
28+
include(ExternalProject)
29+
ExternalProject_Add(upstr_lely_core_libraries
30+
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/upstream
31+
INSTALL_DIR "${CMAKE_INSTALL_PREFIX}"
32+
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/build
33+
GIT_REPOSITORY https://gitlab.com/lely_industries/lely-core.git
34+
GIT_TAG 7824cbb2ac08d091c4fa2fb397669b938de9e3f5
35+
TIMEOUT 60
36+
UPDATE_COMMAND
37+
COMMAND git reset --hard
38+
COMMAND git apply --whitespace=fix --reject ${CMAKE_CURRENT_SOURCE_DIR}/patches/0001-Fix-dcf-tools.patch
39+
CONFIGURE_COMMAND autoreconf -i <SOURCE_DIR>
40+
COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --disable-cython --disable-doc --disable-tests --disable-static --disable-diag
41+
BUILD_COMMAND $(MAKE) -C ${CMAKE_CURRENT_BINARY_DIR}/build
42+
INSTALL_COMMAND ""
43+
)
44+
45+
Lets inspect a few details of the ExternalProject_Add() call.
46+
You'll first need to configure your external project. You can find all available
47+
options in the `documentation <https://cmake.org/cmake/help/latest/module/ExternalProject.html>`_.
48+
In our case we need to set the source directory, the binary directory (build directory) and the install directory
49+
to configure the paths used during build and installation.
50+
We also need to define where the source is that we want to build, for us it is a git repository
51+
at a specific commit. We set the timeout to fetch the sources to 60 seconds.
52+
53+
.. code::
54+
55+
# Configuration
56+
SOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR}/upstream
57+
INSTALL_DIR "${CMAKE_INSTALL_PREFIX}"
58+
BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/build
59+
GIT_REPOSITORY https://gitlab.com/lely_industries/lely-core.git
60+
GIT_TAG 7824cbb2ac08d091c4fa2fb397669b938de9e3f5
61+
TIMEOUT 60
62+
63+
Next you can define an update or patch step. In the case of lely_core_libraries
64+
we need to apply a patch to fix the installation of a component.
65+
66+
.. code::
67+
68+
# UPDATE step apply patch to fix dcf-tools install
69+
UPDATE_COMMAND
70+
COMMAND git reset --hard
71+
COMMAND git apply --whitespace=fix --reject ${CMAKE_CURRENT_SOURCE_DIR}/patches/0001-Fix-dcf-tools.patch
72+
73+
The next step is the configure step. For autotools projects you need to call
74+
autoreconf and then the configure script.
75+
You need to add the ``--prefix=<INSTALL_DIR>`` option to the configure script to
76+
make sure the project is installed into the workspaces install directory.
77+
78+
.. code::
79+
80+
# CONFIGURE step execute autoreconf and configure
81+
CONFIGURE_COMMAND autoreconf -i <SOURCE_DIR>
82+
COMMAND <SOURCE_DIR>/configure --prefix=<INSTALL_DIR> --disable-cython --disable-doc --disable-tests --disable-static --disable-diag
83+
84+
The build step is the easiest one, just call make in the build directory.
85+
86+
.. code::
87+
88+
# BUILD STEP execute make
89+
BUILD_COMMAND $(MAKE) -C ${CMAKE_CURRENT_BINARY_DIR}/build
90+
91+
The last step is the install step. In our case we do not want to install the
92+
package from external project as this will break debian and rpm builds.
93+
We need to call it from the main flow in the CMakeLists.txt file.
94+
95+
Step 3: Add install in CMakeLists.txt
96+
-------------------------------------
97+
98+
To install the package we need to add the ``make install`` command of the external
99+
project as an install command.
100+
101+
.. code:: cmake
102+
103+
install(CODE "execute_process(COMMAND make install WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/build)")
104+
105+
This will run the ``make install`` command of the external project during
106+
the install step of the main CMakeLists.txt file.
107+
108+
Step 4: Update package.xml with dependencies
109+
--------------------------------------------
110+
111+
Now you will need to update the package.xml file with the dependencies of
112+
the external project. In our case we need python3-empy.
113+
114+
.. code:: xml
115+
116+
<depend>python3-empy</depend>
117+
118+
Also make sure that versioning and licensing information are correct.
119+
120+
Step 5: Build the package
121+
-------------------------
122+
123+
You can now build the package using colcon and check if the external project
124+
builds.
125+
126+
.. code:: bash
127+
128+
colcon build --packages-select <package_name>
129+
130+
If successful, you can check if the external project was correctly installed.
131+
Check in the install folder of your workspace if the you find all headers and
132+
libraries and other files in the include and lib folders.
133+
134+
You can also test if it is possible to build the package as a debian using bloom.
135+
To do so run the following commands in the packages root folder.
136+
137+
.. code:: bash
138+
139+
bloom-generate rosdebian --os-name ubuntu --os-version bionic --ros-distro dashing
140+
fakeroot debian/rules binary
141+
142+
If the debian builds successfully, you can be reasonably sure that a bloom release will
143+
build on the build farm.
144+
145+
For more checks also check prerelease tests.

0 commit comments

Comments
 (0)