Example library that shows best practices and proper usage of CMake by using targets

Overview

Modern CMake Sample

Sample project that shows proper modern CMake usage on a dummy library and an executable that uses it. Accompanying code to my blog post It's Time To Do CMake Right

Build Instructions

Dependencies

  • cmake >= 3.13
  • Boost >= 1.65
  • rapidjson >= 1.1

Building the Library

cd libjsonutils
cmake -Bbuild
cmake --build build

You can run the tests:

cmake --build build -- test

Installing the library

You can install the lib in two ways. First, in a classical way: put it somewhere in your system so that executable can find it, or two, build it but register it in the CMake's User Package Registry, avoiding installation.

Normal Installation

sudo cmake --build build -- install

This will install the example library under /usr/local/ on UNIX systems.

Alternatively, you can specify a custom installation directory by setting -DCMAKE_INSTALL_PREFIX in the cmake configure step:

cmake -Bbuild -DCMAKE_INSTALL_PREFIX=<custom_install_dir>
sudo cmake --build build -- install

To uninstall the library, you can run:

cd build
xargs rm < install_manifest.txt

see F.A.Q

Using CMake's User Package Registry

Instead of actually installing the library, you can just build it and register the build in CMake's User Package Registry

cd libjsonutils
cmake -Bbuild -DCMAKE_EXPORT_PACKAGE_REGISTRY

This will register the library's build in CMake's User Package Registry (on UNIX systems it defaults to ~/.cmake).

This is convenient, as packages depending on the library (e.g. via find_package) will be able to find it through the registry, even when the library hasn't been installed.

Building the example executable

If the library is in the CMake's User Package Registry or installed in a system known location, like /usr/local/, you just build the executable with:

cd example_exec
cmake -Bbuild
cmake --build build

If you installed the library in a custom location you must point CMake to the installation directory:

cd example_exec
cmake -Bbuild -DJSONUtils_DIR=
   
    /lib/cmake/JSONUtils
cmake --build build

   

Run the executable

You are done!

cd example_exec
./build/example_exec
Comments
  • find_dependency() does not support COMPONENTS argument before 3.8.0

    find_dependency() does not support COMPONENTS argument before 3.8.0

    after building the lib, I wanted to compile the example, but upon putting cmake .. in a build directory, I got

    `CMake Error at /usr/share/cmake-3.5/Modules/CMakeFindDependencyMacro.cmake:45 (message): Invalid arguments to find_dependency Call Stack (most recent call first): /usr/local/lib/cmake/JSONUtils/JSONUtilsConfig.cmake:5 (find_dependency) CMakeLists.txt:6 (find_package)

    -- Configuring incomplete, errors occurred! See also "/home/me/tempRepos/modern-cmake-sample/example_exec/build/CMakeFiles/CMakeOutput.log". `

    what seems to be the problem here?

    bug 
    opened by CDitzel 7
  • Pimp the modern cmake examples to be modern

    Pimp the modern cmake examples to be modern

    Prevent most cmakelint warnings. Prevent to download gtest if found on build host. Use modern boost version 1.71.0 Use ctest too.

    Note: the test fails!

    opened by ClausKlein 4
  • Error while configuring using cmake (unable to find boost)

    Error while configuring using cmake (unable to find boost)

    I get the following error while using Ubuntu 18 and cmake 3.19. Is "boost_headers" a package name or am I missing something here?

    ############################################ CMake Error at CMakeLists.txt:10 (find_package): Could not find a package configuration file provided by "boost_headers" (requested version 1.71) with any of the following names:

    boost_headersConfig.cmake
    boost_headers-config.cmake
    

    Add the installation prefix of "boost_headers" to CMAKE_PREFIX_PATH or set "boost_headers_DIR" to a directory containing one of the above files. If "boost_headers" provides a separate development package or SDK, be sure it has been installed.

    -- Configuring incomplete, errors occurred! ######################################################

    opened by nelrufus 2
  • Include setup and commands in the readme file

    Include setup and commands in the readme file

    It would be nice if the readme included the necessary commands for beginners to execute the sample.

    i.e. - how to get boost, how to build boost (./bootstrap.sh ; ./b2 --with-regex stage), how to let cmake find them (export BOOST_ROOT=/path/to/boost_1_55_0, export CMAKE_PREFIX_PATH=/path/to/rapidjson_repo), where to run cmake from (cd libjsonutils ; mkdir build; cd build; cmake ..), etc

    help wanted 
    opened by teeks99 2
  • Incorrect generated include path for rapidjson

    Incorrect generated include path for rapidjson

    When I run this with the CMAKE_PREFIX_PATH=~/tmp/rapidjson (for the git repo), it finds ~/tmp/rapidjson/include/rapidjson as the include directory. However, in json_utils.h it #include <rapidjson/document.h>. Because the rapidjson is in both the include path and the header file, it fails to find the file.

    Is there a way that FindRapidJSON.cmake can include the directory one level up from where rapidjson.h is located?

    opened by teeks99 2
  • libjsonutils cmake warning

    libjsonutils cmake warning

    I am not sure how to solve CMP0048 CMake warning, does anyone know how to solve this? See below:

    /snap/clion/61/bin/cmake/linux/bin/cmake -DCMAKE_BUILD_TYPE= -G "CodeBlocks - Unix Makefiles" /home/jonb/Projects/cmake-test/modern-cmake-sample/libjsonutils
    -- Boost version: 1.65.1
    -- Found the following Boost libraries:
    --   regex
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/jonb/Projects/cmake-test/modern-cmake-sample/libjsonutils/googletest-download
    [ 11%] Performing update step for 'googletest'
    Current branch master is up to date.
    [ 22%] No configure step for 'googletest'
    [ 33%] No build step for 'googletest'
    [ 44%] No install step for 'googletest'
    [ 55%] No test step for 'googletest'
    [ 66%] Completed 'googletest'
    [100%] Built target googletest
    CMake Warning (dev) at googletest-src/CMakeLists.txt:3 (project):
      Policy CMP0048 is not set: project() command manages VERSION variables.
      Run "cmake --help-policy CMP0048" for policy details.  Use the cmake_policy
      command to set the policy and suppress this warning.
    
      The following variable(s) would be set to empty:
    
        PROJECT_VERSION
        PROJECT_VERSION_MAJOR
        PROJECT_VERSION_MINOR
        PROJECT_VERSION_PATCH
    This warning is for project developers.  Use -Wno-dev to suppress it.
    
    -- Configuring done
    -- Generating done
    -- Build files have been written to: /home/jonb/Projects/cmake-test/modern-cmake-sample/libjsonutils
    
    [Finished]
    
    opened by jbbjarnason 1
  • Missing license

    Missing license

    You should specify a license so people know whether they're allowed to reuse parts of your examples. Even though it's open-source, it's not currently free software.

    opened by MTres19 1
  • Adding tests for file_utils.h

    Adding tests for file_utils.h

    As a beginner in cmake I'd like to see how to implement tests for private sources of the target (here it would be file_utils.h) Now I do something like

    target_include_directories(tests
            PRIVATE
            ${CMAKE_CURRENT_SOURCE_DIR}/../src
            )
    

    in test directory. Is it correct?

    opened by Dzordzu 0
  • Feature/test use package

    Feature/test use package

    Use FetchContent to get googletest framework

    Add test of installed target and cmake config package Idea from cmake-cookbook https://www.packtpub.com/application-development/cmake-cookbook

    opened by ClausKlein 0
  • Add build instructions

    Add build instructions

    To address #4, I successfully built on Ubuntu 16.04 with no difficulty. Similar instructions on the README should work on any system. Tricky part is to get the dependencies right from system package manager.

    opened by gokhanettin 0
  • Exporting targets of library in case of subdirectories

    Exporting targets of library in case of subdirectories

    What if the lib itself would be structured into several subprojects by means of the add_subdirectory() command in the top-level CMakeLists.txt. Can you maybe show, how to proceed then? Where do the exporting and installation commands go? into every individual subproject or do you define them all together in the root cmake file? Daniel Pfeiffer is not clear on this as well and I would appreciate it, if you could shed some light on this issue

    opened by CDitzel 1
  • Build fails with boost 1.55 and gcc

    Build fails with boost 1.55 and gcc

    Does the version of boost you used have some patch applied to optional? I see this error.

    tomkent@frink:~/tmp/modern-cmake-sample/libjsonutils/build$ make
    [ 12%] Building CXX object CMakeFiles/jsonutils.dir/src/json_utils.cpp.o
    In file included from /home/tomkent/tmp/modern-cmake-sample/libjsonutils/include/jsonutils/json_utils.h:6:0,
                     from /home/tomkent/tmp/modern-cmake-sample/libjsonutils/src/json_utils.cpp:1:
    /home/tomkent/tmp/boost_1_55_0/boost/optional/optional.hpp: In instantiation of ‘void boost::optional_detail::optional_base<T>::construct(boost::optional_detail::optional_base<T>::argument_type) [with T = rapidjson::GenericDocument<rapidjson::UTF8<> >; boost::optional_detail::optional_base<T>::argument_type = const rapidjson::GenericDocument<rapidjson::UTF8<> >&]’:
    /home/tomkent/tmp/boost_1_55_0/boost/optional/optional.hpp:230:16:   required from ‘boost::optional_detail::optional_base<T>::optional_base(boost::optional_detail::optional_base<T>::argument_type) [with T = rapidjson::GenericDocument<rapidjson::UTF8<> >; boost::optional_detail::optional_base<T>::argument_type = const rapidjson::GenericDocument<rapidjson::UTF8<> >&]’
    /home/tomkent/tmp/boost_1_55_0/boost/optional/optional.hpp:526:46:   required from ‘boost::optional<T>::optional(boost::optional<T>::argument_type) [with T = rapidjson::GenericDocument<rapidjson::UTF8<> >; boost::optional<T>::argument_type = const rapidjson::GenericDocument<rapidjson::UTF8<> >&]’
    /home/tomkent/tmp/modern-cmake-sample/libjsonutils/src/json_utils.cpp:20:16:   required from here
    /home/tomkent/tmp/rapidjson/include/rapidjson/document.h:1902:5: error: ‘rapidjson::GenericDocument<Encoding, Allocator, StackAllocator>::GenericDocument(const rapidjson::GenericDocument<Encoding, Allocator, StackAllocator>&) [with Encoding = rapidjson::UTF8<>; Allocator = rapidjson::MemoryPoolAllocator<>; StackAllocator = rapidjson::CrtAllocator]’ is private
         GenericDocument(const GenericDocument&);
         ^
    In file included from /home/tomkent/tmp/boost_1_55_0/boost/optional.hpp:15:0,
                     from /home/tomkent/tmp/modern-cmake-sample/libjsonutils/include/jsonutils/json_utils.h:5,
                     from /home/tomkent/tmp/modern-cmake-sample/libjsonutils/src/json_utils.cpp:1:
    /home/tomkent/tmp/boost_1_55_0/boost/optional/optional.hpp:346:8: error: within this context
            new (m_storage.address()) internal_type(val) ;
            ^
    CMakeFiles/jsonutils.dir/build.make:62: recipe for target 'CMakeFiles/jsonutils.dir/src/json_utils.cpp.o' failed
    make[2]: *** [CMakeFiles/jsonutils.dir/src/json_utils.cpp.o] Error 1
    CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/jsonutils.dir/all' failed
    make[1]: *** [CMakeFiles/jsonutils.dir/all] Error 2
    Makefile:127: recipe for target 'all' failed
    make: *** [all] Error 2
    tomkent@frink:~/tmp/modern-cmake-sample/libjsonutils/build$ 
    tomkent@frink:~/tmp/modern-cmake-sample/libjsonutils/build$ gcc --version
    gcc (Ubuntu 5.4.0-6ubuntu1~16.04.6) 5.4.0 20160609
    Copyright (C) 2015 Free Software Foundation, Inc.
    This is free software; see the source for copying conditions.  There is NO
    warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    
    
    opened by teeks99 5
Owner
Pablo Arias
Pablo Arias
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 395 Dec 24, 2022
This tries to be a minimal cmake example, that covers sources resources dependencies and packaging.

Minimal CMake Example This project tries to be a minimal cmake example. It covers sources, resources, dependencies and packaging. I created this proje

Arne Döring 158 Dec 25, 2022
Helpful example of a gtest and cmake set up for C++.

What is this? This is an example setup of cmake with google test. I got it working after consulting the google test primer, among other things. Hopefu

David Y. Zhang 302 Dec 10, 2022
Example of a gtest and cmake set up for C++ on Travis-CI.

What is this? This is an example setup of Travis-CI with cmake and google test. I finally got all three working together nicely with the help of dmono

Gunnar 41 Apr 30, 2021
Installation example for a C++ project (Windows) with Cmake.

CMakeInstallExample Installation example for a C++ project (Windows) with Cmake. Contents This project demonstrates how to use cmake with cpack to gen

Paul T 30 Jan 3, 2023
Example project which demonstrates various CMake features.

CMake example Example project which demonstrates various CMake features. CDash testing dashboard (probably empty but you can submit your test result t

Radovan Bast 142 Nov 4, 2022
Tutorial/Example to deal with modern cmake.

modern_cmake Tutorial/Example to deal with modern cmake. This tutorial assume that you already know how to write a CMakeLists.txt Introduction This re

Marc Schweitzer 24 Nov 14, 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 74 Dec 26, 2022
📦 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.6k Jan 9, 2023
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 65 Dec 6, 2022
cmake-font-lock - Advanced, type aware, highlight support for CMake

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

Anders Lindgren 39 Oct 2, 2022
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 163 Dec 5, 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] [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 29 Nov 2, 2022
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

WerWolv 28 Nov 30, 2022
A template C++ repository, using CMake and Catch

C++ Project Template This is a template project for C++. It uses CMake to build and Catch for unit tests. It is integrated with Travis CI, and builds

Joshua Peterson 49 Oct 23, 2022
A toolchain file and examples using cmake for iOS development

ios-cmake A toolchain file and examples using cmake for iOS development. This is a fork of a similar project found on https://code.google.com/p/ios-cm

Bogdan Cristea 304 Nov 30, 2022
CMake module for building IDL files with MIDL and generating CLR DLL using Tlbimp

FindIDL CMake module for building IDL files with MIDL and generating CLR DLL using Tlbimp. Introduction Requirements Usage find_package() add_idl() ad

Apriorit Inc. 17 Dec 7, 2022
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.

null 5 Dec 23, 2022