Giter VIP home page Giter VIP logo

modern-cmake-sample's Introduction

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=<custom_install_dir>/lib/cmake/JSONUtils
cmake --build build

Run the executable

You are done!

cd example_exec
./build/example_exec

modern-cmake-sample's People

Contributors

clausklein avatar newproggie avatar pabloariasal avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

modern-cmake-sample's Issues

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?

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?

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

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]

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!
######################################################

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?

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.

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

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.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.