Use Boost as a git submodule with CMake
Asked Answered
N

2

9

I want to use the Boost library for my C++ project (more precisely, I'm interested in the Boost Graph Library). I'd like it to be inside my git repository, as a git submodule, as it's done for every other dependency.

For example, if I want to start a project with fmt dependency as a git submodule, I do:

mkdir my_project
cd my_project
git init .

Then, I want to add fmt as a submodule, on tag 8.0.0:

mkdir deps
git submodule add https://github.com/fmtlib/fmt.git deps/fmt
cd deps/fmt
git checkout 8.0.0

Then, I go back to my project's root folder:

cd ../..

And I create the following files:

  • main.cpp
#include <fmt/format.h>

int main() {
    fmt::print("Hello, World!\n");
    return 0;
}
  • CMakeLists.txt
cmake_minimum_required(VERSION 3.17)
project(test_boost)

add_subdirectory(deps/fmt)

add_executable(test_boost main.cpp)
target_link_libraries(test_boost fmt::fmt)

Then, we're able to build:

mkdir build
cd build
cmake ..
make

And the binary works fine, expectedly printing Hello, World!, which is great.

Now if I want to add boost, version 1.77.0:

git submodule add https://github.com/boostorg/boost deps/boost
git submodule update --init --recursive  # To get Boost's own submodules.
cd deps/boost
git checkout boost-1.77.0
cd ../..

Now I want to use this boost folder as dependency of my project, and this is where it gets tricky. I read here that from version 1.77, I should be able to use find_package() to do this, as it obseletes the FindBoost thing:

find_package(Boost 1.77.0 REQUIRED CONFIG PATHS deps/boost/tools/boost_install)

But I get the following error:

-- Module support is disabled.
-- Version: 8.0.1
-- Build type: Debug
-- CXX_STANDARD: 11
-- Required features: cxx_variadic_templates
CMake Error at CMakeLists.txt:6 (find_package):
  Could not find a configuration file for package "Boost" that is compatible
  with requested version "1.77.0".

  The following configuration files were considered but not accepted:

    /home/me/tests/boost_so/my_project/deps/boost/tools/boost_install/BoostConfig.cmake, version: unknown



-- Configuring incomplete, errors occurred!
See also "/home/me/tests/boost_so/my_project/cmake-build-debug/CMakeFiles/CMakeOutput.log".
See also "/home/me/tests/boost_so/my_project/cmake-build-debug/CMakeFiles/CMakeError.log".

I tried other things as well, but I run into one of the following errors:

  • The same one as above.
  • CMake uses my Boost installation from /usr/local, which is not what I want.

I'm using CMake 3.17.2. Is it possible to do this or am I missing something ?

Nitroglycerin answered 30/9, 2021 at 16:29 Comment(4)
you might need to build boost I imagine before find_package works? It'd probably make your life much easier to use a package manager like conan or vcpkgBaecher
I don't need to build fmt with the add_subdirectory(deps/fmt), it's built if needed as part of my project build process, so I'm confused ...Nitroglycerin
You cannot use find_package(Boost) without installing the Boost. BTW, you could open the file BoostConfig.cmake and find following lines: "# This CMake configuration file, installed as part of the Boost build and installation procedure done by b2 install, provides support for find_package(Boost)." If you need only a header-only part of the Boost, you could just add proper include directory.Overline
...don't. It's not worth the pain IME. Use vcpkg or Conan.Hamm
N
5

I found a solution which seems quite simple. You can just add_subdirectory() as shown for fmt.

The complete CMakeLists.txt file looks like this:

cmake_minimum_required(VERSION 3.17)
project(test_boost)

add_subdirectory(deps/fmt)
add_subdirectory(deps/boost EXCLUDE_FROM_ALL)

add_executable(test_boost main.cpp)
target_link_libraries(test_boost fmt::fmt Boost::graph)

Then, you can see that the following compiles and runs fine:

#include <fmt/format.h>
#include <boost/graph/adjacency_list.hpp>
#include <array>
#include <utility>
#include <iostream>

int main() {
    fmt::print("Hello, World!\n");

    enum { topLeft, topRight, bottomRight, bottomLeft };

    std::array<std::pair<int, int>, 4> edges{{
                                                     std::make_pair(topLeft, topRight),
                                                     std::make_pair(topRight, bottomRight),
                                                     std::make_pair(bottomRight, bottomLeft),
                                                     std::make_pair(bottomLeft, topLeft)
                                             }};

    typedef boost::adjacency_list<boost::setS, boost::vecS,
            boost::undirectedS> graph;
    graph g{edges.begin(), edges.end(), 4};

    std::cout << boost::num_vertices(g) << '\n';
    std::cout << boost::num_edges(g) << '\n';

    g.clear();
    return 0;
}

Which outputs

Hello, World!
4
4
Nitroglycerin answered 9/11, 2021 at 16:6 Comment(1)
Do you know, how this can be done with odeint?Smashed
L
1

That link also lists the version of Cmake you need to use . To be able to use FindBoost you need cmake version 3.21.3 or newer but you are using 3.17.2

Lazare answered 30/9, 2021 at 16:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.