I have a C++ project that requires two external libraries (boost and htslib). I link the libraries to my projects target octopus as follows:
find_package (Boost 1.65 REQUIRED COMPONENTS ${REQUIRED_BOOST_LIBRARIES} REQUIRED)
if (Boost_FOUND)
target_include_directories (octopus PRIVATE ${Boost_INCLUDE_DIR})
target_link_libraries (octopus ${Boost_LIBRARIES})
endif (Boost_FOUND)
find_package (HTSlib 1.4 REQUIRED)
if (HTSlib_FOUND)
target_include_directories (octopus PRIVATE ${HTSlib_INCLUDE_DIRS})
target_link_libraries (octopus ${HTSlib_LIBRARIES})
endif (HTSlib_FOUND)
Both boost and htslib are usually installed into /usr/local, and therefore have header files in /usr/local/include. However, users can specify alternative library locations by specifying CMake variables BOOST_ROOT and HTSLIB_ROOT.
The problem is that if only one of the libraries is given an alternative location, then the header files in the include directory of the other linked library (e.g. in /usr/local/include) get included for both libraries, and if incomparable versions of the library are installed then compilation can fail. For example, if I set BOOST_ROOT to ~/.linuxbrew then Boost_INCLUDE_DIR is correctly set to ~/.linuxbrew/include, but HTSlib_INCLUDE_DIRS is /usr/local/include, which contains /usr/local/include/boost, and for reasons I don't quite understand, these are the headers used for building, even though they are incompatible with the libraries in ~/.linuxbrew/lib/boost.
How can I ensure that the include directory for a linked library are used only for that library?
if(Xyz_FOUND)conditions in your code are unnecessary, because you're usingREQUIREDin thefind_packagecalls. That means CMake will error out when the packages are not found, so theifs are never even reached in that case. - Angew is no longer proud of SO