📜 ⬆️ ⬇️

CMake - create dynamic libraries

Introduction


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

CMake does not directly build, it only generates assembly control files from CMakeLists.txt files.

Dynamic libraries. Theory


Creating static linking dynamic libraries in Windows OS differs from GNU / Linux OS.
')
On Windows, this requires a bunch of .dll (dynamic link library) + .lib (library) files.
On the GNU / Linux OS, this only requires one .so (shared object) file.

Dynamic libraries. Practice


In practice, I want to write a convenient, identical code on both operating systems.

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

#ifndef __linux__ #if defined( <target_name>_EXPORTS ) #define DLL_<target_name>_EXPORT __declspec(dllexport) #else // !BUILDING_DLL #define DLL_<target_name>_EXPORT __declspec(dllimport) #endif // BUILDING_DLL #else #define DLL_<target_name>_EXPORT #endif // __linux__ 

Accordingly, for each exported class from the library, it is necessary to prescribe this macro:

 class DLL_<target_name>_EXPORT <class_name> 

In this case, on the Windows OS, all classes / methods that are marked with this macro are exported, and on the GNU / Linux OS, 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. To do this, for each target (target) that is declared as SHARED (dynamic library), you need to 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_<target_name>_EXPORT 

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

Then this file (.def) is passed to the linker to create a .lib file. At the output to Windows OS, a bunch of .lib + .dll is obtained

Results


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

Source: https://habr.com/ru/post/278207/


All Articles