Building static/dynamic C++ libraries with CMake

What Exactly is CMake?

CMake, which stands for Cross-Platform Make, is an open-source build system and project configuration tool designed to manage the build process of software projects. It provides a unified, platform-independent way to specify how a project is built, tested, and packaged.

This article will explore ways to use CMake with C++ to build static and dynamic libraries in Linux using simple cpp code.

Static vs. dynamic linking in brief

Here are the quick differences between static and dynamic libraries in C++.

+----------------------+---------------------+----------------------+
|      Aspect          |   Static Libraries  |   Dynamic Libraries  |
+----------------------+---------------------+----------------------+
|   File Format        |  .lib (Windows)     |  .dll (Windows)      |
|                      |  .a (Unix)          |  .so (Unix)          |
+----------------------+---------------------+----------------------+
|   Linking            |  Compile time       |  Runtime             |
+----------------------+---------------------+----------------------+
|   Size               |  Larger executables |  Smaller executables |
+----------------------+---------------------+----------------------+
|   Deployment         |  Self-contained     |  Dynamic library     |
|                      |  executable         |  required during     |
|                      |                     |  execution           |
+----------------------+---------------------+----------------------+
|   Updates            |  Recompilation      |  Easier updates      |
|                      |  required           |  without             |
|                      |                     |  recompilation       |
+----------------------+---------------------+----------------------+

Building Static Library

Let's create a simple C++ project to understand how you can use CMake to build

place these .cpp and .h files in the root folder of your project

// mathlib.h

#ifndef MATHLIB_H
#define MATHLIB_H

class MathLib {
public:
    static int add(int a, int b);
};

#endif
// mathlib.cpp

#include "mathlib.h"

int MathLib::add(int a, int b) {
    return a + b;
}

now create a "CMakeLists.txt" file in the same directory and provide the config as provided below

# CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
# assign a project name
project(MathLib)
# set variable name
set(CMAKE_CXX_STANDARD 14)

# Add the source files to the library
add_library(MathLib STATIC mathlib.cpp)

# Include the headers for the library
target_include_directories(MathLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

create a build directory and switch to it and then build using below bash commands.

mkdir build
cd build
cmake ..
make

At the end you should be able to see libMathLib.a in the build directory


Building dynamic library

Now you know how to build a static library but making some modifications to the CMakeLists.txt file will result in generating a shared object file (.so)

# CMakeLists.txt

cmake_minimum_required(VERSION 3.12)
project(MathLib)

set(CMAKE_CXX_STANDARD 14)

# Add the source files to the library
add_library(MathLib SHARED mathlib.cpp)

# Include the headers for the library
target_include_directories(MathLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

Observe that add_library method we have changed the type of output we want to SHARED instead of STATIC.

follow the same bash commands to build i.e

mkdir build
cd build
cmake ..
make

Now you should be able to see libMathLib.so file in your build directory ready to be used in other projects as a library file.


💡
I will update this article on how you can use these built libraries soon -siva