Skip to content
Arni edited this page Oct 24, 2024 · 54 revisions

Examples on how to include popular libraries using the CPM CMake script. Feel free to extend the list with your own. Please always refer to a specific version or commit, as branches are subject to change and referencing them could impact build reproducibility.

CLI

CPMAddPackage(
  NAME rang
  GITHUB_REPOSITORY agauniyal/rang
  GIT_TAG v3.1.0
)
if(rang_ADDED)
  add_library(rang INTERFACE IMPORTED)
  target_include_directories(rang INTERFACE "${rang_SOURCE_DIR}/include")
endif()
CPMAddPackage(
  NAME linenoise
  GIT_TAG 1.0
  GITHUB_REPOSITORY antirez/linenoise
)

if(linenoise_ADDED)
  add_library(linenoise ${linenoise_SOURCE_DIR}/linenoise.c)
  target_include_directories(linenoise PUBLIC ${linenoise_SOURCE_DIR})
endif()
CPMAddPackage(
  NAME cxxopts
  GITHUB_REPOSITORY jarro2783/cxxopts
  VERSION 2.2.0
  OPTIONS
    "CXXOPTS_BUILD_EXAMPLES Off"
    "CXXOPTS_BUILD_TESTS Off"
)
CPMAddPackage(
  NAME progresscpp
  GITHUB_REPOSITORY prakhar1989/progress-cpp
  GIT_TAG 7bfba0d22d19c41323aa35541618b6ebec9d737c
)
CPMAddPackage(
  NAME tabulate
  GITHUB_REPOSITORY p-ranav/tabulate
  VERSION 1.0
)

Signaling

CPMAddPackage("gh:libsigcplusplus/libsigcplusplus#3.6.0")
if(libsigcplusplus_ADDED)
    set(SIGCPP_INCLUDE_DIRS ${libsigcplusplus_SOURCE_DIR} ${libsigcplusplus_BINARY_DIR} )
    set(SIGCPP_LIBRARY sigc-3.0)
endif()

Testing

CPMAddPackage(
  NAME ut
  GITHUB_REPOSITORY boost-ext/ut
  GIT_TAG 2.1.0
)
CPMAddPackage(
  NAME doctest
  GITHUB_REPOSITORY onqtam/doctest
  GIT_TAG 2.3.2
)
CPMAddPackage(
  NAME Catch2
  GITHUB_REPOSITORY catchorg/Catch2
  VERSION 2.5.0
)
CPMAddPackage(
  NAME gtest
  GITHUB_REPOSITORY google/googletest
  GIT_TAG release-1.8.1
  VERSION 1.8.1
  OPTIONS
      "INSTALL_GTEST OFF"
      "gtest_force_shared_crt ON"
)

Language extensions

Check Arniiiii/AddBoost.cmake.

CPMAddPackage(
  NAME range-v3
  URL https://github.com/ericniebler/range-v3/archive/0.5.0.zip
  VERSION 0.5.0
  # the range-v3 CMakeLists screws with configuration options
  DOWNLOAD_ONLY True
)

if(range-v3_ADDED) 
  add_library(range-v3 INTERFACE IMPORTED)
  target_include_directories(range-v3 INTERFACE "${range-v3_SOURCE_DIR}/include")
endif()
CPMAddPackage(
  NAME variant-lite
  GITHUB_REPOSITORY martinmoene/variant-lite
  VERSION 1.2.2
)

Serialization

CPMAddPackage(
  NAME yaml-cpp
  GITHUB_REPOSITORY jbeder/yaml-cpp
  # 0.6.2 uses deprecated CMake syntax
  VERSION 0.6.3
  # 0.6.3 is not released yet, so use a recent commit
  GIT_TAG 012269756149ae99745b6dafefd415843d7420bb 
  OPTIONS
    "YAML_CPP_BUILD_TESTS Off"
    "YAML_CPP_BUILD_CONTRIB Off"
    "YAML_CPP_BUILD_TOOLS Off"
)
CPMAddPackage(
  NAME nlohmann_json
  VERSION 3.7.3
  # the git repo is incredibly large, so we download the archived include directory
  URL https://github.com/nlohmann/json/releases/download/v3.7.3/include.zip
  URL_HASH SHA256=87b5884741427220d3a33df1363ae0e8b898099fbc59f1c451113f6732891014
)

if (nlohmann_json_ADDED)
  add_library(nlohmann_json INTERFACE IMPORTED)
  target_include_directories(nlohmann_json INTERFACE ${nlohmann_json_SOURCE_DIR}/include)
endif()
CPMAddPackage(
  NAME cereal
  VERSION 1.2.2
  GITHUB_REPOSITORY USCiLab/cereal
  OPTIONS
    "SKIP_PORTABILITY_TEST ON"
    "JUST_INSTALL_CEREAL ON"
)
CPMAddPackage(
  NAME pugixml
  URL https://github.com/zeux/pugixml/releases/download/v1.13/pugixml-1.13.tar.gz
  VERSION 1.13
  DOWNLOAD_ONLY YES
)

if(pugixml_ADDED)
  # Header-only for simplicity, see manual for more options
  add_library(pugixml INTERFACE)
  target_compile_definitions(pugixml INTERFACE PUGIXML_HEADER_ONLY)
  target_include_directories(pugixml INTERFACE ${pugixml_SOURCE_DIR}/src)
endif()

Benchmarking

CPMAddPackage(
  NAME benchmark
  GITHUB_REPOSITORY google/benchmark
  VERSION 1.5.0
  OPTIONS
   "BENCHMARK_ENABLE_TESTING Off"
   "BENCHMARK_USE_LIBCXX ON"
)

if (benchmark_ADDED)
  # patch benchmark target
  set_target_properties(benchmark PROPERTIES CXX_STANDARD 17)
endif()

Scripting languages

CPMAddPackage(
  NAME lua
  GIT_REPOSITORY https://github.com/lua/lua.git
  VERSION 5.3.5
  DOWNLOAD_ONLY YES
)

if (lua_ADDED)
  # lua has no CMake support, so we create our own target

  FILE(GLOB lua_sources ${lua_SOURCE_DIR}/*.c)
  list(REMOVE_ITEM lua_sources "${lua_SOURCE_DIR}/lua.c" "${lua_SOURCE_DIR}/luac.c")
  add_library(lua STATIC ${lua_sources})

  target_include_directories(lua
    PUBLIC
      $<BUILD_INTERFACE:${lua_SOURCE_DIR}>
  )
endif()
CPMAddPackage(
  NAME sol2
  URL https://github.com/ThePhD/sol2/archive/v3.0.2.zip
  VERSION 3.0.2
  DOWNLOAD_ONLY YES
)

if (sol2_ADDED)
  add_library(sol2 INTERFACE IMPORTED)
  target_include_directories(sol2 INTERFACE ${sol2_SOURCE_DIR}/include)
  target_link_libraries(sol2 INTERFACE lua)
endif()

I/O

CPMAddPackage(
  NAME FileWatcher
  GIT_TAG ee0b97efd206282ef8bb4b9c10c90c941de4a52b
  GIT_REPOSITORY https://github.com/apetrone/simplefilewatcher.git
)

if (FileWatcher_ADDED)
  file (GLOB FileWatcherSources ${FileWatcher_SOURCE_DIR}/source/*.cpp)
  add_library(FileWatcher ${FileWatcherSources})
  target_include_directories(FileWatcher PUBLIC ${FileWatcher_SOURCE_DIR}/include)
endif()
CPMAddPackage(
  NAME fmt
  GIT_TAG 6.1.2
  GITHUB_REPOSITORY fmtlib/fmt
)
find_package(Threads REQUIRED)

CPMAddPackage(
  NAME asio
  VERSION 1.16.1
  GITHUB_REPOSITORY chriskohlhoff/asio
  GIT_TAG asio-1-16-1   # asio uses non-standard version tag, we must specify GIT_TAG
)

# To save bandwidth, you can simply download the source zip
CPMAddPackage(
  NAME asio
  VERSION 1.16.1
  URL https://github.com/chriskohlhoff/asio/archive/asio-1-16-1.zip
)

# ASIO doesn't use CMake, we have to configure it manually.
# Extra notes for using on Windows:
# 1) If _WIN32_WINNT is not set, ASIO assumes _WIN32_WINNT=0x0501, i.e. Windows XP target,
# which is definitely not the platform which most users target.
# 2) WIN32_LEAN_AND_MEAN is defined to make Winsock2 work.
if(asio_ADDED)
  add_library(asio INTERFACE)

  target_include_directories(asio
    INTERFACE ${asio_SOURCE_DIR}/asio/include
  )

  target_compile_definitions(asio
    INTERFACE
      ASIO_STANDALONE
      ASIO_NO_DEPRECATED
  )

  target_link_libraries(asio
    INTERFACE
      Threads::Threads
  )

  if(WIN32)
    # macro see @ https://stackoverflow.com/a/40217291/1746503
    macro(get_win32_winnt version)
      if (CMAKE_SYSTEM_VERSION)
        set(ver ${CMAKE_SYSTEM_VERSION})
        string(REGEX MATCH "^([0-9]+).([0-9])" ver ${ver})
        string(REGEX MATCH "^([0-9]+)" verMajor ${ver})
        if ("${verMajor}" MATCHES "10")
          set(verMajor "A")
          string(REGEX REPLACE "^([0-9]+)" ${verMajor} ver ${ver})
        endif ("${verMajor}" MATCHES "10")
        string(REPLACE "." "" ver ${ver})
        string(REGEX REPLACE "([0-9A-Z])" "0\\1" ver ${ver})
        set(${version} "0x${ver}")
      endif()
    endmacro()

    if(NOT DEFINED _WIN32_WINNT)
      get_win32_winnt(ver)
      set(_WIN32_WINNT ${ver})
    endif()

    message(STATUS "Set _WIN32_WINNET=${_WIN32_WINNT}")

    target_compile_definitions(asio
      INTERFACE
        _WIN32_WINNT=${_WIN32_WINNT}
        WIN32_LEAN_AND_MEAN
    )
  endif()
endif()
CPMAddPackage(
  NAME easylogingpp
  VERSION 9.96.7
  GITHUB_REPOSITORY amrayn/easyloggingpp
  OPTIONS
  "build_static_lib ON"
  "lib_utc_datetime ON"
)
# target_include_directories(<<Target>> SYSTEM PRIVATE "${easylogingpp_SOURCE_DIR}/src" <<etc>>)
# target_link_libraries(<<Target>> PRIVATE easyloggingpp <<etc>>)

Until fmtlog haven't merged a better CMake part, you can use this version

CPMAddPackage(
 NAME fmtlog
 GIT_REPOSITORY "https://github.com/Arniiiii/fmtlog_cmake_fix" 
 TAG master 
 OPTIONS "fmtlog_ENABLE_CPM ON"
)

Entity Component Systems

CPMAddPackage(
  NAME EnTT
  VERSION 3.1.1
  GITHUB_REPOSITORY skypjack/entt
  # EnTT's CMakeLists screws with configuration options
  DOWNLOAD_ONLY True
)

if (EnTT_ADDED)
  add_library(EnTT INTERFACE)
  target_include_directories(EnTT INTERFACE ${EnTT_SOURCE_DIR}/src)
endif()

Reflection

CPMAddPackage(
  NAME meta
  VERSION 1.4.7
  GITHUB_REPOSITORY skypjack/meta
  # the project's CMakeLists messes with configuration options
  DOWNLOAD_ONLY True
)

if (meta_ADDED)
  add_library(meta INTERFACE)
  target_include_directories(meta INTERFACE ${meta_SOURCE_DIR}/src)
endif()
CPMAddPackage(
  NAME rttr # link against RTTR::Core_Lib
  VERSION 0.9.6
  GITHUB_REPOSITORY rttrorg/rttr
  OPTIONS
    "BUILD_RTTR_DYNAMIC Off"
    "BUILD_UNIT_TESTS Off"
    "BUILD_STATIC On"
    "BUILD_PACKAGE Off"
    "BUILD_WITH_RTTI On"
    "BUILD_EXAMPLES Off"
    "BUILD_DOCUMENTATION Off"
    "BUILD_INSTALLER Off"
    "USE_PCH Off"
    "CUSTOM_DOXYGEN_STYLE Off"
)

Linear Algebra

CPMAddPackage(
  NAME Eigen
  VERSION 3.2.8
  URL https://gitlab.com/libeigen/eigen/-/archive/3.2.8/eigen-3.2.8.tar.gz
  # Eigen's CMakelists are not intended for library use
  DOWNLOAD_ONLY YES 
)

if(Eigen_ADDED)
  add_library(Eigen INTERFACE IMPORTED)
  target_include_directories(Eigen INTERFACE ${Eigen_SOURCE_DIR})
endif()
CPMAddPackage(
        NAME CLAPACK
        VERSION 3.2.1
        URL http://www.netlib.org/clapack/clapack-3.2.1-CMAKE.tgz
)
# we need to set proper include headers
if(CLAPACK_ADDED)
  # Set include directories for the targets
  target_include_directories(f2c INTERFACE "${CLAPACK_SOURCE_DIR}/INCLUDE")
  target_include_directories(lapack INTERFACE "${CLAPACK_SOURCE_DIR}/INCLUDE")
endif()
CPMAddPackage(
        NAME gsl
        GITHUB_REPOSITORY ampl/gsl
        VERSION 2.5.0
)

CMake scripts

CPMAddPackage(
  NAME Format.cmake
  GITHUB_REPOSITORY TheLartians/Format.cmake
  VERSION 1.0
)
CPMAddPackage(
  NAME GroupSourcesByFolder.cmake
  GITHUB_REPOSITORY TheLartians/GroupSourcesByFolder.cmake
  VERSION 1.0
)
CPMAddPackage(
  NAME Ccache.cmake
  GITHUB_REPOSITORY TheLartians/Ccache.cmake
  VERSION 1.2
)
CPMAddPackage(
  NAME CPMLicenses.cmake 
  GITHUB_REPOSITORY TheLartians/CPMLicenses.cmake
  VERSION 0.0.4
)

cpm_licenses_create_disclaimer_target(
  write-licenses "${CMAKE_CURRENT_BINARY_DIR}/third_party.txt" "${CPM_PACKAGES}"
)

Graphics / OpenGL

CPMAddPackage(
  NAME FreeImage
  GITHUB_REPOSITORY Kanma/FreeImage
  GIT_TAG 6bb613d9402926b3846dea1b417f20b6c596c5dc
)

if(FreeImage_ADDED)
  target_include_directories(freeimage INTERFACE "${FreeImage_SOURCE_DIR}")
endif()
CPMAddPackage(
  NAME freetype
  GIT_REPOSITORY https://github.com/aseprite/freetype2.git
  GIT_TAG VER-2-10-0
  VERSION 2.10.0
)

if (freetype_ADDED)
  add_library(Freetype::Freetype ALIAS freetype)
endif()
CPMAddPackage(
        NAME GLFW
        GITHUB_REPOSITORY glfw/glfw
        GIT_TAG 3.3.2
        OPTIONS
          "GLFW_BUILD_TESTS OFF"
          "GLFW_BUILD_EXAMPLES OFF"
          "GLFW_BULID_DOCS OFF"
)
# ImGui
CPMAddPackage(
  NAME imgui
  VERSION 1.91.1
  GITHUB_REPOSITORY ocornut/imgui
  DOWNLOAD_ONLY TRUE
)

# CMakeLists.txt from https://gist.githubusercontent.com/rokups/f771217b2d530d170db5cb1e08e9a8f4
file(
  DOWNLOAD
  "https://gist.githubusercontent.com/rokups/f771217b2d530d170db5cb1e08e9a8f4/raw/4c2c14374ab878ca2f45daabfed4c156468e4e27/CMakeLists.txt"
  "${imgui_SOURCE_DIR}/CMakeLists.txt"
  EXPECTED_HASH SHA256=fd62f69364ce13a4f7633a9b50ae6672c466bcc44be60c69c45c0c6e225bb086
)

# Options
set(IMGUI_EXAMPLES FALSE)
set(IMGUI_DEMO FALSE)
set(IMGUI_ENABLE_STDLIB_SUPPORT TRUE)
# FreeType (https://github.com/cpm-cmake/CPM.cmake/wiki/More-Snippets#freetype)
set(FREETYPE_FOUND TRUE)
set(FREETYPE_INCLUDE_DIRS "")
set(FREETYPE_LIBRARIES Freetype::Freetype)

# Add subdirectory
add_subdirectory(${imgui_SOURCE_DIR} EXCLUDE_FROM_ALL SYSTEM)
CPMAddPackage("gh:SFML/SFML#2.5.1")
CPMAddPackage("gh:ocornut/imgui#docking")
CPMAddPackage(
    GITHUB_REPOSITORY "eliasdaler/imgui-sfml"
    VERSION "2.3"
    OPTIONS "IMGUI_DIR ${imgui_SOURCE_DIR}"
)
add_compile_definitions(IMGUI_DISABLE_DEMO_WINDOWS) # imgui-sfml doesn't compile demo by default
CPMAddPackage(
  NAME Vulkan-Headers
  GITHUB_REPOSITORY KhronosGroup/Vulkan-Headers
  GIT_TAG v1.3.269
)

# Vulkan-Headers defines a header target but not one for the module.
if(Vulkan-Headers_ADDED)
  add_library(Vulkan-Module)
  target_sources(Vulkan-Module
    PUBLIC FILE_SET CXX_MODULES
    BASE_DIRS "${Vulkan-Headers_SOURCE_DIR}/include"
    FILES "${Vulkan-Headers_SOURCE_DIR}/include/vulkan/vulkan.cppm"
  )
  target_compile_definitions(Vulkan-Module PUBLIC
    # Your options here, project-dependent:
    # https://github.com/KhronosGroup/Vulkan-Hpp#configuration-options
  )
  target_link_libraries(Vulkan-Module PUBLIC Vulkan-Headers)
endif()
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)

project(wxWidgetsExample)

# ---- Dependencies ----

include(../../cmake/CPM.cmake)

CPMAddPackage("gh:wxWidgets/[email protected]")

# ---- Executable (with gui) ----

add_executable(wxWidgetsExample main.cpp)
target_link_libraries(wxWidgetsExample wx::core)


# ---- Executable (only console) ----

add_executable(wxWidgetsConsoleExample console.cpp)
target_compile_definitions(wxWidgetsConsoleExample PRIVATE "-DwxUSE_GUI=0")
target_link_libraries(wxWidgetsConsoleExample wx::base)

Scientific / Math Libraries

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${GEOS_SOURCE_DIR}/cmake")

CPMAddPackage(
  NAME geos
  GITHUB_REPOSITORY libgeos/geos
  GIT_TAG 3.8.1
)
CPMAddPackage("https://github.com/AcademySoftwareFoundation/Imath.git#v3.1.5")
if (Imath_ADDED)
  target_include_directories(Imath INTERFACE "$<BUILD_INTERFACE:${Imath_SOURCE_DIR}/src/*.h>")
endif()
# target_link_libraries(<<Target>> Imath <<etc>>)

Date / Time Libraries

CPMAddPackage(
        NAME date
        GITHUB_REPOSITORY HowardHinnant/date
        VERSION 3.0.0
)

In C++ code, include the library's header files like this:

#include "date/date.h"

In your CMakeLists.txt, reference the library using date or date::date (see also issue 148):

add_executable(mytarget ...)

target_link_libraries(mytarget date::date)
```****