Get dependencies with cmake

Overview

cmake-get

A cmake module to get dependencies. This module can be used in config mode or in script mode.

Installation

The module is just one file 'CMakeGet.cmake' which can be copied into your project and then included. It can also be installed with cmake:

mkdir build
cd build
cmake ..
cmake --build . --target install

And then it can be used with find_package(CMakeGet).

Config mode

In config mode, this is similiar to cmake's ExternalProject with some differences:

  • Dependencies are installed during cmake configuration instead of during build. This avoids the need of writing super build projects as cmake's find_* commands can be used to find the dependencies all in the same build project.
  • Non-cmake build steps can be put in a recipe that can be shared and re-used by many users, instead of rewriting the build steps for every projects.
  • A BUILD_DEPS variable is provided to enable the installation of dependencies(it defaults to OFF). This allows dependencies to be disabled for when a user wants to use a package manager to install the dependencies, but then can be enabled when the user doesn't want to use a package manager.

To setup with cmake, first list the dependecies in a requirements.txt file and the add something like this to cmake:

cmake_get_from(requirements.txt PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps)
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_BINARY_DIR}/deps)

Also, if recipes are used, its best not to list them in the requirements.txt file. Instead just install them in the cmake itself:

cmake_get(pfultz2/cget-recipes PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps)
cmake_get_from(requirements.txt PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps)
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_BINARY_DIR}/deps)

Of course, this still has the same weakness as ExternalProject as the toolchain is not transitive.

Script mode

Script mode enables the ability to write a cmake script to install a dependency. This can help with toolchain transitivity as the user can invoke the script with all the same cmake settings. The disadvantage is that the user has an extra step to install dependencies. For example, a script 'dependencies.cmake' like this could be made to install dependencies from a 'requirements.txt':

#!/usr/bin/env cmake -P

set(ARGS)
foreach(i RANGE 4 ${CMAKE_ARGC})
    list(APPEND ARGS ${CMAKE_ARGV${i}})
endforeach()

set(_PREFIX ${CMAKE_ARGV3})

# Make sure this is in the module path
list(APPEND CMAKE_MODULE_PATH ${CMAKEGET_MODULE_PATH})
include(CMakeGet)

get_filename_component(PREFIX ${_PREFIX} ABSOLUTE)
# Install recipes
cmake_get(pfultz2/cget-recipes PREFIX ${PREFIX} CMAKE_ARGS ${ARGS})
cmake_get_from(requirements.txt PREFIX ${PREFIX} CMAKE_ARGS ${ARGS})

So then the user would run this instead:

./dependencies.cmake deps/
mkdir build
cd build
cmake -DCMAKE_PREFIX_PATH=../deps/ ..

Reference

cmake_get

cmake_get(<pkg>
    [PREFIX <prefix>]
    [HASH <hash>]
    [CMAKE_FILE <cmake-file>]
    [CMAKE_ARGS <args>...]
)

This will install a cmake package. It will run something equivalent to this in order to install the package:

mkdir build
cd build
cmake .. -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_INSTALL_PREFIX=${PREFIX} ${CMAKE_ARGS}
cmake --build .
cmake --build . --target install
  • <pkg>
    This is the package to be installed as described here. It can be a URL or even a recipe.
  • PREFIX <prefix>
    This is prefix to where the package will be installed.
  • HASH <hash>
    This is a checksum hash that will be checked on a package.
  • CMAKE_FILE <cmake-file>
    This is a cmake file that will be used to build the package. This is useful for a package that does not provide a cmake file already.
  • CMAKE_ARGS <args>...
    This is additional cmake arguments that are passed to the configuration step.

cmake_get_from

cmake_get_from(<filename>
    [PREFIX <prefix>]
    [CMAKE_ARGS <args>...]
)

This will install a list of packages stored in a file.

  • <filename>
    This a file that will list packages to be installed, The format of the file is described here.
  • PREFIX <prefix>
    This is prefix to where the package will be installed.
  • CMAKE_ARGS <args>...
    This is additional cmake arguments that are passed to the configuration step.
You might also like...
CMake project for BL602 RISC-V processor
CMake project for BL602 RISC-V processor

bl602_cmake_base CMake project for BL602 RISC-V processor How to build NOTE : This project uses a pre-compiled version of the Buffalo SDK (bl_iot_sdk)

A CMake toolchain file for iOS, macOS, watchOS & tvOS C/C++/Obj-C++ development

A CMake toolchain file for iOS, macOS, watchOS & tvOS C/C++/Obj-C++ development

curl cmake module libcurl build with msvc x86

curl-msvc Infomation curl cmake module libcurl build with MSVC10.0 arch (x86 | i386) source from https://github.com/curl/curl tags: curl-7_79_1 Usage

NeoWorld is a resampler using the CMake build system

NeoWorld is a resampler using the CMake build system. It's designed for utsu, OpenUTAU, and UTAU.

A CMake addon that avoids you writing boilerplate code for resource management.

SHader INJ(I)ector SHINJI (originally SHader INJector) is a CMake addon that avoids you writing boilerplate code for resource management and exposes s

A CMake starter template using CPM

Cmake Starter About A lightweight Cmake project meant for a binary application (not a shared library), tests with catch2 are configured, CPM is the pa

Non-intrusive CMake dependency management

cmodule Non-intrusive CMake dependency management. Normally CMake's find_package() looks for packages installed on host system (and compiled for host

Simple library for embedding static resources into C++ binaries using CMake

libromfs libromfs is an easy way to bundle resources directly into any C++ application and access them through a simple interface. The main advantage

Project to enable using CMake from a Maven build.

CMake-Maven-Project Introduction A Maven project for the CMake build system. It can be used by including it as a plugin within your Maven project's po

Comments
  • Installation problem

    Installation problem

    I have the following cmake script:

    set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
    
    include(CMakeGet)
    
    cmake_get(pfultz2/cget-recipes
              PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps)
    cmake_get_from(${CMAKE_SOURCE_DIR}/requirements.txt
              PREFIX ${CMAKE_CURRENT_BINARY_DIR}/deps)
    list(APPEND CMAKE_PREFIX_PATH ${CMAKE_CURRENT_BINARY_DIR}/deps)
    

    My requirements.txt has the following contents:

    boost
    sfml
    nlohmann/json
    fmtlib/fmt
    

    When I configure the project, I get the foloowing error (after downloading a number of packages):

    CMake Error at CMakeLists.txt:9 (include):
      include could not find load file:
    
        /boost.cmake
    
    
    -- Configuring incomplete, errors occurred!
    See also "/private/var/folders/d0/czkmg12j3036n3_skqccd62w0000gn/T/cget-23-35-10-DvU0L-1/build/CMakeFiles/CMakeOutput.log".
    CMake Error at cmake/CMakeGet.cmake:130 (message):
      Process failed:
      COMMAND;/usr/local/Cellar/cmake/3.9.2/bin/cmake;-DCMAKE_PREFIX_PATH=/Users/tamas/work/JacobInTheDark/build/deps;-DCMAKE_INSTALL_PREFIX=/Users/tamas/work/JacobInTheDark/build/deps;-DCGET_CMAKE_ORIGINAL_SOURCE_FILE=/var/folders/d0/czkmg12j3036n3_skqccd62w0000gn/T/cget-23-35-10-DvU0L-1/download/boost_1_64_0/__cget_original_cmake_file__.cmake;-DBOOST_WITHOUT_CONTEXT=1;-DBOOST_WITHOUT_COROUTINE=1;-DBOOST_WITHOUT_COROUTINE2=1;-DBOOST_WITHOUT_PYTHON=1;/var/folders/d0/czkmg12j3036n3_skqccd62w0000gn/T/cget-23-35-10-DvU0L-1/download/boost_1_64_0;WORKING_DIRECTORY;/var/folders/d0/czkmg12j3036n3_skqccd62w0000gn/T/cget-23-35-10-DvU0L-1/build
    Call Stack (most recent call first):
      cmake/CMakeGet.cmake:161 (cget_exec)
      cmake/CMakeGet.cmake:354 (cget_install_dir)
      cmake/CMakeGet.cmake:405 (cmake_get)
      cmake/CMakeGet.cmake:336 (cmake_get_from)
      cmake/CMakeGet.cmake:405 (cmake_get)
      CMakeLists.txt:11 (cmake_get_from)
    

    I suspect that this is because there is a variable before /boost.cmake that is expanded to nothing. But I don't know where this cmake script is located to further debug.

    I've pasted to full output here: https://pastebin.com/DM8C0Mb1

    opened by sztomi 4
  • Cmake warning : list command no longer ignores empty elements.

    Cmake warning : list command no longer ignores empty elements.

    CMake Warning (dev) at cmake/CMakeGet.cmake:264 (list):
      Policy CMP0007 is not set: list command no longer ignores empty elements.
      Run "cmake --help-policy CMP0007" for policy details.  Use the cmake_policy
      command to set the policy and suppress this warning.  List has value =
      [https:;;github.com;akheron;jansson;archive;HEAD.tar.gz].
    Call Stack (most recent call first):
      cmake/CMakeGet.cmake:347 (cget_fetch)
      cmake/CMakeGet.cmake:405 (cmake_get)
      dependencies.cmake:14 (cmake_get_from)
    This warning is for project developers.  Use -Wno-dev to suppress it.
    

    The current implementation of cmake-get rises an empty list element warning each time a dependency is being pulled. This is due to the following line replacing each slash by a semicolon. This causes Cmake to generate empty list elements when parsing URL schemas (https:// turns into https:;;).

    Thank you for your amazing work and the time you spend on this module 👍

    opened by vallahaye 0
  • Avoiding rebuilds?

    Avoiding rebuilds?

    I'm using the script mode to install dependencies but when I add dependencies to requirements.txt, cmake-get redownloads and rebuilds everything. This is very inefficient. Is there a way to avoid the constant rebuilds?

    opened by sohailsomani 1
Owner
Paul Fultz II
Paul Fultz II
📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Setup-free CMake dependency management CPM.cmake is a CMake script that adds dependency management capabilities to CMake. It's built as a thin wrapper

CPM.cmake 1.4k Oct 2, 2022
CMake checks cache helper modules – for fast CI CMake builds!

cmake-checks-cache Cross platform CMake projects do platform introspection by the means of "Check" macros. Have a look at CMake's How To Write Platfor

Cristian Adam 60 Aug 17, 2022
CMake scripts for painless usage of SuiteSparse+METIS from Visual Studio and the rest of Windows/Linux/OSX IDEs supported by CMake

CMake scripts for painless usage of Tim Davis' SuiteSparse (CHOLMOD,UMFPACK,AMD,LDL,SPQR,...) and METIS from Visual Studio and the rest of Windows/Lin

Jose Luis Blanco-Claraco 390 Sep 30, 2022
cmake-font-lock - Advanced, type aware, highlight support for CMake

cmake-font-lock - Advanced, type aware, highlight support for CMake

Anders Lindgren 37 Dec 30, 2021
cmake-avr - a cmake toolchain for AVR projects

cmake-avr - a cmake toolchain for AVR projects Testing the example provided The toolchain was created and tested within the following environment: Lin

Matthias Kleemann 161 Oct 2, 2022
Make CMake less painful when trying to write Modern Flexible CMake

Izzy's eXtension Modules IXM is a CMake library for writing Modern flexible CMake. This means: Reducing the amount of CMake written Selecting reasonab

IXM 107 Sep 1, 2022
CMake module to enable code coverage easily and generate coverage reports with CMake targets.

CMake-codecov CMake module to enable code coverage easily and generate coverage reports with CMake targets. Include into your project To use Findcodec

HPC 80 Sep 27, 2022
unmaintained - CMake module to activate certain C++ standard, feature checks and appropriate automated workarounds - basically an improved version of cmake-compile-features

Compatibility This library provides an advanced target_compile_features() and write_compiler_detection_header(). The problem with those is that they a

Jonathan Müller 72 Apr 14, 2022
[CMake] [BSD-2] CMake module to find ICU

FindICU.cmake A CMake module to find International Components for Unicode (ICU) Library Note that CMake, since its version 3.7.0, includes a FindICU m

julp 28 Sep 1, 2022
muon is an implementation of the meson build system in C with minimal dependencies.

muon muon is an implementation of the meson build system in C with minimal dependencies. Non-features bug-for-bug compatibility with meson. In fact, m

Stone Tickle 43 Sep 21, 2022