Skip to content
Snippets Groups Projects

cmake-project-template

This project is an example showing how to do some pretty nifty cmake/git/cpack integraton. Veyr cool.

Build Instructions

Dependencies

As of Ubuntu 20.04 and July 2022, the dependencies are:

  • libgtest-dev

Other buildtool dependencies:

  • gcc >= 9.4.0
  • cmake >= 3.16
  • git >= 2.25.1

Seems like it should be more? CLion >=2021.3.2, or your favorite flavor of VSCode, or whatever IDE is good.

Build

Things mostly follow a standard cmake build:

cd <cmake-example>
mkdir build
cmake ..
make -j 10

See the user docs for what gets built. There are a few options that can get passed at configure time. These are:

  • -DCMAKE_BUILD_TYPE=[Release|Debug|RelWithDebInfo] This sets the build type. Some stuff-- especially stuff using the Eigen C++ matrix library-- you can expect about an order of magnitude speed increase with Release. It also strips symbols, does all sorts of other useful optimizations (yes, -O3).

Tests

Two test binaries are produced in your out-of-source build dir. These are:

  1. cmake-example-tests: Some example tests you can Just Run.

If anything fails you'll probably want to run the binaries directly. Otherwise, you can use the test integration as:

make test

Install

The install targets are probably in /usr/local, because that's usually how that goes. You can change that by adding -DCMAKE_INSTALL_PREFIX=/path/to/install/dir to your cmake command.

Much better is to use a debian package...

Packaging

Packages are created with:

make cpack_deb

That's it. You can specify dependencies in CPACK_DEBIAN_PACKAGE_DEPENDS in the root CMakeLists.txt file up to date.

The package name format is:

cmake_exampmle-[major.minor.patch]-[debian architecture]-[git info]-[build type].deb

Daemonizing stuff

A very common goal is to run the resulting binary as a daemon. On Ubuntu, this is usually done with systemd.
An example systemd file is provided in <project root>/systemd/example_daemon.service. This file must be installed before it can be used. There are several schools of thought on where to install systemd services. You can do lots of research, figure out a preference, etc-- or just dump it in /etc/systemd/system.

Once installed, these may be run as services via the usual systemctl commands:

sudo systemctl [command] example_daemon.service`

Here's a little systemctl command cheatsheet:

  • start Start the daemon
  • stop Stop the daemon
  • status Print some status info
  • enable Enable the daemon at startup
  • disable Disable the daemon at startup

You can also use journalctl to look at stdout/stderr from services. There are some amazing options, definitely worth looking into. To simply watch the logs from your service:

journalctl -f -u [your-service].service

Aside

All sorts of horribleness went into getting the git autodetection and CPack self-naming to work. Check out the "cmake" folder in general, and git_watcher.cmake and CPackMakeConfig.cmake in particular. Thank goodness for stackoverflow.