cmodule

cmodule - non-intrusive CMake dependency management.

Normally CMake’s find_package looks for packages installed on host system (and compiled for host system). When using cmodule, find_package downloads packages and compiles them for each target independently, using current CMake toolchain. This, among other things, allows using C/C++ libraries (like boost) when cross-compiling for Android, iOS, WebAssembly (Emscripten), etc. Downloaded and unpacked sources are shared between targets, while binaries are compiled for each target independently.

CMake integration

After initializing cmodule, regular find_package calls will work in top level CMake project and all subprojects:

include(FetchContent)
FetchContent_Declare(
  cmodule
  URL "https://github.com/scapix-com/cmodule/archive/refs/tags/v2.0.1.tar.gz"
  URL_HASH SHA256=a9477bbefb43b6fabdc2dc044207fe42cca63999c60b6baf06ba0c62fa116ec5
)
FetchContent_MakeAvailable(cmodule)

find_package(Boost REQUIRED COMPONENTS filesystem iostreams)
target_link_libraries(${target} PUBLIC Boost::filesystem Boost::iostreams)

find_package(ZLIB REQUIRED)
target_link_libraries(${target} PRIVATE ZLIB::ZLIB)

find_package(BZip2 REQUIRED)
target_link_libraries(${target} PRIVATE BZip2::BZip2)

Releases

To insure reproducible builds, always use specific cmodule release. This insures your project always uses the same version of all cmodule libraries. Upgrade to the next cmodule version when you are ready to rebuild using new versions of libraries.

Parameters

  • CMODULE_CACHE_SOURCE_DIR - Directory to store package sources downloaded by cmodule. Default is <USER_HOME_DIR>/.cmodule. Specify empty string to disable source cache (sources will be downloaded/unpacked independently for each target).
  • CMODULE_DISABLE_WARNINGS - Disable all compiler warnings and CMake deprecation warnings for libraries built by cmodule. Default: YES.

You can override default values before including cmodule:

set(CMODULE_CACHE_SOURCE_DIR ${CMAKE_SOURCE_DIR}/.cmodule CACHE PATH "")
set(CMODULE_DISABLE_WARNINGS YES CACHE BOOL "")

Use CMake standard BUILD_SHARED_LIBS option to control type of created libraries. You can specify different BUILD_SHARED_LIBS before each find_package call:

set(BUILD_SHARED_LIBS ON)
find_package(BZip2 REQUIRED)
target_link_libraries(target PRIVATE BZip2::BZip2)

Some libraries support building both static and shared libraries simultaneously. This can be enabled using library specific options:

option(ZSTD_BUILD_STATIC "" ON)
option(ZSTD_BUILD_SHARED "" ON)
find_package(Zstd REQUIRED)
target_link_libraries(target1 PRIVATE zstd::libzstd_static)
target_link_libraries(target2 PRIVATE zstd::libzstd_shared)

How cmodule differs from other package managers?

Other package managers (like hunter), share binaries compiled for a particular target platform, but do not share download/unpack/store of library sources. This is designed to save build time and disk space for situations when you have multiple independently built projects which use a lot of the same libraries.

cmodule does the opposite: it shares download/unpack/store of library sources, but does not share binaries compiled for a particular platform (they are still shared between different targets in the same CMake build, but not between independently built CMake projects). If your projects are built together (as part of the same CMake build), and you cross-compile for multiple platforms (just building all Android ABIs is 4 different platforms), cmodule is a better choice: it shares download/unpack/store of library sources, while building libraries with EXACTLY the same CMake platform toolchain as the rest of the project.