Creating debian packages — CMake

Karthik Kalyanaraman
4 min readMar 23, 2019

--

source: xkcd comics

In this story, I will walk through the process of writing a simple C++ program and packaging it up into a .deb file that you can install as a Ubuntu application. CMake and CPack makes it quite simple that it can be easily extended to any platform(.exe for Windows, .rpm for linux etc.)

If you’re here just for the code, feel free to fork from https://github.com/kakaly/cmake

Step 1

Let’s write a simple C++ library function that takes in two integer parameters, adds them and returns the result.

header file: add_num.h
source file: add_num.cpp

Let’s write the main function separately and use the created library,

main.cpp

Now, let’s compile and run main.cpp(g++ main.cpp), you should be able to get “3” as console out. But, now what if we want to have a better directory structure. Something like,

directory stucture

Bigger projects generally tend to have headers and source files separated from each other. Each library is built as an independent unit called target and linked together into the final executable that can be installed and run. This makes the code base modular, flexible and scalable. There are various build tools that help us to achieve this. I prefer CMake because it is declarative, cross-platform and integrates well with various IDEs.

Step 2

Let’s create a CMakeLists.txt in our project root and add the following instructions.

CMakeLists.txt
  • Line 1 specifies the CMake version we are using. This is a required instruction.
  • Line 3 — We are telling CMake that we would like to create a project inside this directory and call it “addnum”.
  • Line 5 — We tell CMake to create a static library called “addnum” using the file, src/add_num.cpp. The add_library() command creates what we call, “target” in the CMake world. Here the target is is a static library.
  • Line 6–9 — We tell CMake to use header files from the include directory for the target, “addnum”. CMAKE_CURRENT_SOURCE_DIR is a CMake variable that gives the current path of the directory where we are calling it.
  • Line 11 — We tell CMake to create another target, “addnumapp” using src/main.cpp. But, this time we tell it to make it into an executable(platform agnostic) instead of a library.
  • Line 12 — The executable that we just created uses the library we created in Line 5. So we tell CMake to link the library “addnum” to the executable target, “addnumapp”.
  • At this point, you should be able to run CMake and get a built executable that you can run from command line and execute it. So far, we have done exactly what we previously did by running “g++ main.cpp”.
  • CMake automatically picks up the compiler installed on the system. So you don’t need to worry about calling the compiler explicitly.

Step 3

In this step, let’s create an debian package that we can install and run on a Ubuntu system. Lines 14–23 specifically deals with this.

  • Line 14–19 — We tell CMake what to do at install time using the install() command. We tell the command what target we want to use for the installer(“addnumapp”). We also tell the destination where we would want to install, in this case it’s the “home/” directory. The RUNTIME and LIBRARY destinations specify the destination where we would like the libraries to be placed in case we had other libraries.
  • Line 21–23 — CPack is the packaging tool CMake uses. These instructions are self-explanatory.

Step 4

Let’s run CMake inside our build directory,

console output

First we run, cmake .. , this configures and generates the project files. Then we run cmake — build ., this builds our static library and the execuable (ie) both the targets, addnum and addnumapp in this case. Notice how CMake links addnum to addnumapp before completing the build.

Next, we run cpack , this packages up addnumapp into an installable debian package. Let’s look at our build/ dir now,

build/ dir

Notice the addnum-0.1.1-Linux.deb. Let’s double click that and check if it installs.

installed “addnum”

Let’s check our home/ directory to see if it installed the application.

/home/ directory

There we go! That’s it! We created a simple Ubuntu application from scratch written using C++ and built, packaged using CMake and CPack respectively.

With little tweaks to CPack, you can create installers for any other platform quite easily.

Hope you enjoyed reading this story!

📝 Read this story later in Journal.

🗞 Wake up every Sunday morning to the week’s most noteworthy Tech stories, opinions, and news waiting in your inbox: Get the noteworthy newsletter >

--

--

Karthik Kalyanaraman
Karthik Kalyanaraman

Written by Karthik Kalyanaraman

Software Engineer | Curious about technology and the economics of the tech industry | https://twitter.com/karthikkalyan90

Responses (2)

Write a response