Search code examples
c++boostcmakegit-submodules

My c++ project uses boost but when used as a submodule it does not find boost anymore


I have a project "A" that depends on boost, and works quite well.

I created a new project "B", where I included "A" as a submodule. However when I try to compile my project "A" cannot find the boost files anymore. I am using cmake, and from what I searched so far, it seems that the "CMakeLists.txt" for "B" needs to be modified but I fail to understand where...

In the CMakeLists.txt of project A I invoke boost as follows:

find_package(Boost REQUIRED OPTIONAL_COMPONENTS iostreams filesystem)
link_libraries(Boost::boost)
if (Boost_FILESYSTEM_FOUND)
    message("Boost filesystem: Found")
else()
    message("Boost filesystem: Not Found")
endif()
if (Boost_IOSTREAMS_FOUND)
    message("Boost iostreams: Found")
else()
    message("Boost iostreams: Not Found")
endif()

And in project B I included project A as follows:

add_subdirectory(extern/project_A)

When I include the following in my main.cpp in project B:

#include "extern/project_A/some_file.h"

some code...

I get the following error:

cannot open source file "boost/math/distributions.hpp"
'boost/math/distributions.hpp' file not found

where "boost/math/distributions.hpp" is used in my "some_file.h". When project A is not used as a submodule, the project builds without error and the boost files are found. From there I presume that my error lies in the CMakeLists.txt file.

Why is it breaking down when A is used as a submodule?


Solution

  • In general in cmake you should add settings to targets with target_* rather than using the directory based commands. Target settings are automatically propagated to dependencies.

    link_libraries only applies to targets created after the link_libraries call and only to targets in the current directory or subdirectory. Therefore the link_libraries(Boost::boost) setting isn't propagated outside of project A to project B or anything else that uses it.

    If instead you use:

    target_link_libraries(projectA Boost::boost)
    

    Then regardless of which directory you call the following from:

    target_link_libraries(projectB projectA)
    

    projectB will automatically link to boost and have the includes available.