CMake - creating dynamic libraries

Introduction


CMake (from the English cross platform make) is a cross-platform automation system for building software from source code.

CMake is not directly involved in the assembly, but only generates assembly control files from the CMakeLists.txt files.

Dynamic libraries. Theory


Creating dynamic link libraries with Windows is different from GNU / Linux.

On Windows, this requires a bunch of .dll (dynamic link library) + .lib (library) files.
On GNU / Linux, this requires only one .so (shared object) file.

Dynamic libraries. Practice


In practice, I want to write convenient, identical code on both OSs.

In each project (or on several projects one) there was a conditional compilation:

#ifndef __linux__
    #if defined( _EXPORTS )
        #define DLL__EXPORT __declspec(dllexport)
    #else // !BUILDING_DLL
        #define DLL__EXPORT __declspec(dllimport)
    #endif // BUILDING_DLL
#else
    #define DLL__EXPORT
#endif // __linux__

Accordingly, for each exported class from the library, you must register this macro:

class DLL__EXPORT 

In this case, on Windows, all classes / methods that are marked with this macro are exported, and on GNU / Linux, by default, everything is exported, because no macro to hide classes / methods.

With the release of CMake version 3.4.0, it became possible to create libraries with classes that are exported by default. For this, in each target (target), which are declared as SHARED (dynamic library), you must enable the property:

set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)


An example of a small library:
# Проверка версии CMake
cmake_minimum_required( VERSION 3.4.0 )
# Если версия установленой программы ниже, то ошибка выполнения
# Название проекта и проверка доступности компиляторя с++
project( shared_lib CXX )			
# Установка переменной со списком исходников
set( SOURCE_LIB example.cpp )		
# Включение экспорта всех символов для создания динамической библиотеки
set ( CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON )
# Создание динамической библиотеки с именем example
add_library( example SHARED ${SOURCE_LIB} )	


And remove the definition and use of macros from the code:

DLL__EXPORT

This property automatically creates a module definition (.def) with all global characters from a .obj file for a dynamic library on Windows.

Next, this file (.def) is passed to the linker to create the .lib file. On output on Windows, you get a bunch of .lib + .dll

Summary


The code has become more readable, there are no extra lines. And the probability of an error occurring during incorrect spelling of the conditional compilation block and macro definition among developers is reduced to zero. There is only one additional line in the CMakeLists file.

Also popular now: