Important specific of a MODULE library is that it may use symbols (functions and variables) which are not defined in the library (and not defined in the libraries it is linked with). Such feature is very useful when create plugins: a plugin may call functions which are defined in the application which loads that plugin.
A regular SHARED library is not allowed to use undefined symbols.
Also, it is not allowed to link with a library, which contains undefined symbols. For that reason CMake explicitly prohibits linking with a MODULE library. For the same reason CMake doesn't create for a MODULE library additional files, which are used primarily for linking: import files on Windows, so-versions and symlinks on Linux, etc.
For example, an application may allow plugins to create additional windows.
plugin.h:
// Creates a window. // // The function is defined by the application and can be used by plugins. void CreateWindow(const char* name); // Initialize the plugin. // // Called by the application. Should be defined by the plugin itself. void InstantiatePlugin(void);
cool_plugin.c:
#include <plugin.h> void InstantiatePlugin(void) { // Just create two windows CreateWindow("Cool1"); CreateWindow("Cool2"); }
Such plugin can be built with CMake by using a MODULE library:
# CMakeLists.txt # add_library(cool_plugin MODULE cool_plugin.c) target_include_directories(cool_plugin PRIVATE </path/to/directory/with/plugin.h>)
Would one replace MODULE with SHARED in the above code, building the plugin will fail with undefined reference/unresolved external error.
Code of the application itself could look as following:
// application.c #include <plugin.h> int CreateWindow(const char* name) { // ... actually create a window. } int main(void) { // .. Some initialization // ... Load the plugin in the platform-specific way (dlopen or LoadLibrary) void (*instantiate)(void) = ... ; // find function 'InstantiatePlugin' in the plugin instantiate(); }