1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301
|
\page developingwithcmake Developing with Ignition CMake
# Developing with Ignition CMake
This tutorial documents various tips and strategies for developing with Ignition CMake.
## Helpful CMake flags
There are several flags that control the results of the CMake tool.
Some of these flags are built into CMake, where some are Ignition CMake specific.
All of the following flags may be set as part of an individual CMake invocation.
Alternatively, the flags may be passed to `colcon` using techniques described later in this document.
### Setting the build type
The `CMAKE_BUILD_TYPE` variable controls the type of binary output from the build stage.
This will have an impact on the flags passed to the compiler and linker.
The available options are:
* `RelWithDebInfo`: Mostly optimized build, but with debug symbols.
* `Debug`: Debug build without optimizations, with debug symbols enabled.
* `Release`: Fully optimized build, no debug symbols.
* `MinSizeRel`: Fully optimized build, minimal binary size
* `Coverage`: Build with additional information required for the [`gcov` analysis tool](https://en.wikipedia.org/wiki/Gcov)
* `Profile`: Use flags that are helpful with the [`gprof` profiling tool](https://en.wikipedia.org/wiki/Gprof)
More information about flags applied can be found in [IgnSetCompilerFlags.cmake](https://github.com/ignitionrobotics/ign-cmake/blob/ign-cmake2/cmake/IgnSetCompilerFlags.cmake)
If left unspecified, `CMAKE_BUILD_TYPE` is set to `RelWithDebInfo`
To change the build type, set the CMake flag:
```
-DCMAKE_BUILD_TYPE=Debug
```
### Disabling or suppressing warnings about optional components
Many ignition packages come with optional component libraries.
These optional components will typically have additional dependencies that the
package's core library does not require. If you are missing the dependencies of
any optional components, you will receive a cmake warning like
```
-- Skipping component [component_name]: Missing dependency [dependency_name].
^~~~~ Set SKIP_component_name=true in cmake to suppress this warning.
```
If you do not care about the specified component, you can safely ignore this
warning. The configuration and build steps will succeed without any problem. The
only side effect is the optional component will not be built.
If you do want to build the optional component, then you will need to install
whichever dependencies were said to be missing and then rerun cmake.
If you do *not* want to build the optional component and you want to suppress
the warning about the missing dependencies, you can set the cmake flag:
```
-DSKIP_component_name=true
```
where you should replace `component_name` with the actual name of the component
as specified inside the angle brackets `[]` of the warning.
### Creating a compilation database
`CMake` can optionally generate a compilation data base that may be used with a variety of code completion tools.
By default, a compilation database is *not generated*
To enable compilation database generation, set the CMake flag:
```
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
```
For more information about what the compilation database is, consult the [`clang` documentation](https://clang.llvm.org/docs/JSONCompilationDatabase.html)
Some examples of utilities that can use the compilation database:
* [`coc.vim`](https://github.com/neoclide/coc.nvim): Code completion for VIM
* [`YouCompleteMe`](https://github.com/ycm-core/YouCompleteMe) Code completion for VIM
### Using the ninja build system
Rather than using `make`, it may be desired to use the [Ninja](https://ninja-build.org/) build tool.
By default `make` will be used.
To change the build system type, set the CMake flag:
```
-GNinja
```
### Address sanitizer (ASan)
The `gcc` and `clang` compilers have a set of flags to generate instrumented builds for detecting memory leaks.
By default, address sanitizer is *not used*.
To enable address sanitizer, set all of the following flags:
```
-DCMAKE_CXX_FLAGS="-fsanitize=address -fsanitize=leak -g"
-DCMAKE_C_FLAGS="-fsanitize=address -fsanitize=leak -g"
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak"
-DCMAKE_MODULE_LINKER_FLAGS="-fsanitize=address -fsanitize=leak"
```
This will report if memory is leaked during execution of binaries or tests.
More information about address santizier can be found in the [ASan documentation](https://github.com/google/sanitizers/wiki/AddressSanitizer).
Note: Address sanitizer may have an impact on the performance of execution.
### Using CCache
When you are doing frequent rebuilds, you can use a program to cache intermediate compiler results.
First, install [`ccache`](https://ccache.dev/) and configure it to an appropriate cache size for your system:
```
$ sudo apt update && sudo apt install ccache
$ ccache -M10G
Set cache size limit to 10.0 GB
```
Then set the CMake flags:
```
-DCMAKE_C_COMPILER_LAUNCHER=ccache
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
```
### Enabling/Disabling Documentation
When you are doing frequent rebuilds, it generally doesn't make sense to rebuild documentation each build.
By default, building documentation is *enabled*.
To disable building documentation, set the CMake flag:
```
-DBUILD_DOCS=OFF
```
### Enabling/Disabling Tests
If your intent is to only produce libraries and executables, it is possible to disables tests.
By default, building tests is *enabled*.
To disable building tests, set the CMake flag:
```
-DBUILD_TESTING=OFF
```
### Enabling/Disabling Buildsystem Tests
There are additional tests of the Ignition CMake buildsystem.
It is recommend to run these tests when making modifications to the Ignition CMake codebase.
By default, building buildsystem tests is *disabled*.
To enable building buildsystem tests, set the CMake flags:
```
-DBUILD_TESTING=ON
-DBUILDSYSTEM_TESTING=ON
```
## Developing with Colcon and vcstool
[`colcon`](https://colcon.readthedocs.io/en/released/) is a tool that improves the workflow of building and testing multiple software packages.
As an Ignition collection is composed of multiple packages that are frequently built and tested together, `colcon` eases this workflow.
The basic outline of obtaining Ignition source packages via `vcs` and building with `colcon` is available in the [Ignition source installation documentation](https://ignitionrobotics.org/docs/latest/install_ubuntu_src).
### Passing CMake flags via command line
When performing `colcon` builds, flags may be passed to Ignition CMake to configure the build.
This can be done via the `--cmake-args` flag in `colcon`:
```
colcon build --cmake-args -DCMAKE_EXPORT_COMPILE_COMMANDS=1
```
### Passing colcon mixins via command line
To ease configuration of common flags, `colcon` has a concept of `mixins`, that are flags that "shortcut" groups of behavior.
The set of readily-available defaults is in the [colcon-mixin-repository](https://github.com/colcon/colcon-mixin-repository).
To install:
```
$ colcon mixin add default https://raw.githubusercontent.com/colcon/colcon-mixin-repository/master/index.yaml
$ colcon mixin update default
$ colcon mixin show
```
An example of building with `colcon` with two mixins:
* [`ccache` mixin](https://github.com/colcon/colcon-mixin-repository/blob/master/ccache.mixin)
* [`rel-with-db-info` mixin](https://github.com/colcon/colcon-mixin-repository/blob/master/build-type.mixin)
```
colcon build --mixin ccache rel-with-deb-info
```
This will build with the flags applied from the requested mixins.
Colcon allows you to create your own mixins for commonly-reused command line flags.
For more information about creating mixins, consult the [`colcon mixin` documentation](https://colcon.readthedocs.io/en/released/reference/mixin-arguments.html)
### Using a defaults file
It is useful to be able to apply a consistent set of flags across an entire Ignition collection when building.
One mechanism for accomplishing this is a `defaults.yaml` file.
This is a file of configuration options that `colcon` will read to customize the default behavior.
More information about the `defaults.yaml` file can be found in the corresponding [`colcon` documentation](https://colcon.readthedocs.io/en/released/user/configuration.html#defaults-yaml)
For the following, if you do not have `colcon` or `vcs` installed, consult the [Ignition source installation documentation](https://ignitionrobotics.org/docs/latest/install_ubuntu_src).
To try this out, first create an Ignition source workspace:
```
mkdir -p ~/ign_edifice/src
cd ~/ign_edifice/
wget https://raw.githubusercontent.com/ignition-tooling/gazebodistro/main/collection-edifice.yaml
vcs import src < collection-edifice.yaml
```
Then add a `~/ign_edifice/defaults.yaml` file with compilation flags:
```
{
"build": {
"merge-install": true,
"symlink-install": true,
"cmake-args": [
"--no-warn-unused-cli",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=1",
"-DCMAKE_BUILD_TYPE=RelWithDebInfo",
]
}
}
```
To build with this defaults file, first export the correct environment variable and execute colcon:
```
cd ~/ign_edifice
export COLCON_DEFAULTS_FILE=`pwd`/defaults.yaml
colcon build
```
### Using a defaults file with mixins
Mixins can also be applied via the `defaults.yaml` file:
```
{
"build": {
"merge-install": true,
"symlink-install": true,
"mixins": [
"compile-commands",
"rel-with-deb-info",
]
}
}
```
### Setting a per-workspace defaults file with direnv
Optionally, defaults can be applied user-wide by placing a defaults file at `$COLCON_HOME/defaults.yaml` (which is `~/.colcon/defaults.yaml` by default).
In order to manage per-workspace settings, a tool like [`direnv`](https://direnv.net/) can be used to automate the application of the environment variable.
Once `direnv` is installed and configured with your shell of choice, do the following:
```
$ cd ~/ign_edifice/
# The environment variable will be unset
$ echo $COLCON_DEFAULTS_FILE
$ echo export COLCON_DEFAULTS_FILE=`pwd`/defaults.yaml > .envrc
direnv: error .envrc is blocked, Run `direnv allow` to approve its content
$ direnv allow
direnv: loading ~/ign_edifice/.envrc
direnv: export +COLCON_DEFAULTS_FILE
$ echo $COLCON_DEFAULTS_FILE
~/ign_edifice/defaults.yaml
```
Once this is configured, the environment will be applied each time you navigate to the `~/ign_edifice` directory or its children.
|