Hi all, I have created a small example app that links to Boost regex (works) and to a Boost header-only lib property_tree (fails).
Using CMake 3.12.2 on a Ubuntu 18.10 x64, I get this error: [50%] Building CXX object CMakeFiles/dummy.dir/main.cpp.o small_superbuild/src/main.cpp:3:10: fatal error: boost/property_tree/ptree.hpp: No such file or directory #include <boost/property_tree/ptree.hpp> I have used the superbuild pattern to build upstream boost if not found in the system and finally link to the main app called "dummy". The idea is from https://github.com/dev-cafe/cmake-cookbook/tree/master/chapter-08/recipe-02/cxx-example The folder structure for this dummy project is as follow: ******************************************************************************* CMakeLists.txt ******************************************************************************* cmake_minimum_required(VERSION 3.5) set( DUMMY_APP_PROJECT_VERSION 0.1 CACHE INTERNAL "Dummy App project version" FORCE) project(dummy_app VERSION ${DUMMY_APP_PROJECT_VERSION} LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD_REQUIRED ON) # Superbuild stuff set(EP_BASE ${CMAKE_BINARY_DIR}/subprojects) set_property(DIRECTORY PROPERTY EP_BASE ${EP_BASE}) set(STAGED_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/stage) include(ExternalProject) # Add external dependencies add_subdirectory(external/upstream) # Dummy App project (main target) ExternalProject_Add(${PROJECT_NAME}_core DEPENDS boost_external SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/src CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD} -DCMAKE_CXX_EXTENSIONS=${CMAKE_CXX_EXTENSIONS} -DCMAKE_CXX_STANDARD_REQUIRED=${CMAKE_CXX_STANDARD_REQUIRED} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} -DCMAKE_INSTALL_PREFIX=${STAGED_INSTALL_PREFIX}/dummy_app CMAKE_CACHE_ARGS -DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS} -DCMAKE_INCLUDE_PATH:INTERNAL=${BOOST_INCLUDEDIR};${GOOGLETEST_INCLUDEDIR} -DCMAKE_LIBRARY_PATH:INTERNAL=${BOOST_LIBRARYDIR};${GOOGLETEST_LIBRARYDIR} -DDUMMY_APP_PROJECT_VERSION:INTERNAL=${DUMMY_APP_PROJECT_VERSION} -DSTAGED_INSTALL_PREFIX:INTERNAL=${STAGED_INSTALL_PREFIX} -DBOOST_ROOT:INTERNAL=${BOOST_ROOT} -DBOOST_INCLUDEDIR:INTERNAL=${BOOST_INCLUDEDIR} -DBOOST_LIBRARYDIR:INTERNAL=${BOOST_LIBRARYDIR} -DBOOST_MINIMUM_REQUIRED:INTERNAL=${BOOST_MINIMUM_REQUIRED} -DBOOST_COMPONENTS_REQUIRED:INTERNAL=${BOOST_COMPONENTS_REQUIRED} BUILD_ALWAYS 1 ) ******************************************************************************* external/upstream/CMakeLists.txt ******************************************************************************* # Boost dependencies add_subdirectory(boost) ******************************************************************************* external/upstream/boost/CMakeLists.txt ******************************************************************************* set( BOOST_MINIMUM_REQUIRED "1.65" CACHE INTERNAL "Minimum Boost version required by the build" FORCE ) set( BOOST_COMPONENTS_REQUIRED regex CACHE INTERNAL "Boost components required by the build (separated by semicolon)" FORCE ) find_package(Boost ${BOOST_MINIMUM_REQUIRED} COMPONENTS ${BOOST_COMPONENTS_REQUIRED}) if(Boost_FOUND) message(STATUS "Found Boost version ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION} at the host environment") add_library(boost_external INTERFACE) get_filename_component(_boost_root_dir "${Boost_LIBRARY_DIRS}" PATH) set( BOOST_ROOT ${_boost_root_dir} CACHE INTERNAL "Path to externally built Boost installation root" FORCE ) set( BOOST_INCLUDEDIR ${Boost_INCLUDE_DIRS} CACHE INTERNAL "Path to externally built Boost include directories" FORCE ) set( BOOST_LIBRARYDIR ${Boost_LIBRARY_DIRS} CACHE INTERNAL "Path to externally built Boost library directories" FORCE ) # Unset internal variables unset(_boost_root_dir) else() message(STATUS "Boost ${BOOST_MINIMUM_REQUIRED} could not be located. Building Boost instead") if(CMAKE_CXX_COMPILER_ID MATCHES "GNU") if(APPLE) set(_toolset "darwin") else() set(_toolset "gcc") endif() elseif(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang") set(_toolset "clang") elseif(CMAKE_CXX_COMPILER_ID MATCHES "Intel") if(APPLE) set(_toolset "intel-darwin") else() set(_toolset "intel-linux") endif() endif() # Non-empty list. Compiled libraries needed if(NOT "${BOOST_COMPONENTS_REQUIRED}" STREQUAL "") # Replace unit_test_framework (used by CMake's find_package) with test (understood by Boost build toolchain) string(REPLACE "unit_test_framework" "test" _b2_needed_components "${BOOST_COMPONENTS_REQUIRED}") # Generate argument for BUILD_BYPRODUCTS set(_build_byproducts) set(_b2_select_libraries) foreach(_lib IN LISTS _b2_needed_components) list(APPEND _build_byproducts ${STAGED_INSTALL_PREFIX}/boost/lib/libboost_${_lib}${CMAKE_SHARED_LIBRARY_SUFFIX}) list(APPEND _b2_select_libraries --with-${_lib}) endforeach() # Transform the ;-separated list to a ,-separated list (digested by the Boost build toolchain!) string(REPLACE ";" "," _b2_needed_components "${_b2_needed_components}") set(_bootstrap_select_libraries "--with-libraries=${_b2_needed_components}") string(REPLACE ";" ", " printout "${BOOST_COMPONENTS_REQUIRED}") message(STATUS " Libraries to be built: ${printout}") endif() include(ExternalProject) ExternalProject_Add(boost_external GIT_REPOSITORY https://github.com/boostorg/boost.git GIT_TAG "boost-1.65.0" GIT_PROGRESS 0 CONFIGURE_COMMAND <SOURCE_DIR>/bootstrap.sh --with-toolset=${_toolset} --prefix=${STAGED_INSTALL_PREFIX}/boost ${_bootstrap_select_libraries} BUILD_COMMAND <SOURCE_DIR>/b2 -q link=shared threading=multi variant=release toolset=${_toolset} ${_b2_select_libraries} LOG_BUILD 1 BUILD_IN_SOURCE 1 INSTALL_COMMAND <SOURCE_DIR>/b2 -q install link=shared threading=multi variant=release toolset=${_toolset} ${_b2_select_libraries} LOG_INSTALL 1 BUILD_BYPRODUCTS "${_build_byproducts}" ) set( BOOST_ROOT ${STAGED_INSTALL_PREFIX}/boost CACHE INTERNAL "Path to internally built Boost installation root" FORCE ) set( BOOST_INCLUDEDIR ${BOOST_ROOT}/include CACHE INTERNAL "Path to internally built Boost include directories" FORCE ) set( BOOST_LIBRARYDIR ${BOOST_ROOT}/lib CACHE INTERNAL "Path to internally built Boost library directories" FORCE ) # Unset internal variables unset(_toolset) unset(_b2_needed_components) unset(_build_byproducts) unset(_b2_select_libraries) unset(_boostrap_select_libraries) endif() ******************************************************************************* src/CMakeLists.txt ******************************************************************************* # TODO: Properly export target cmake_minimum_required(VERSION 3.5) project(dummy_core VERSION ${DUMMY_APP_PROJECT_VERSION} LANGUAGES CXX) set(DUMMY_APP_SRC main.cpp) add_executable(dummy ${DUMMY_APP_SRC}) set_target_properties(dummy PROPERTIES CXX_STANDARD ${CMAKE_CXX_STANDARD} CXX_EXTENSIONS ${CMAKE_CXX_EXTENSIONS} CXX_STANDARD_REQUIRED ${CMAKE_CXX_STANDARD_REQUIRED}) # Boost is used for CTF parsing find_package(Boost ${BOOST_MINIMUM_REQUIRED} COMPONENTS ${BOOST_COMPONENTS_REQUIRED} REQUIRED) # Includes target_include_directories(dummy PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${BOOST_INCLUDEDIR}) # Libs target_link_libraries(dummy PUBLIC Boost::boost ${Boost_LIBRARIES}) # Install both targets install(TARGETS dummy DESTINATION bin) ******************************************************************************* src/main.cpp ******************************************************************************* #include <iostream> #include <boost/regex.hpp> #include <boost/property_tree/ptree.hpp> #include <boost/property_tree/json_parser.hpp> int main(){ // Header only boost library boost::property_tree::ptree pt; boost::property_tree::read_json("data.json", pt); // regular boost lib std::string line; boost::regex pat( "^Subject: (Re: |Aw: )*(.*)" ); while (std::cin) { std::getline(std::cin, line); boost::smatch matches; if (boost::regex_match(line, matches, pat)) std::cout << matches[2] << std::endl; } } As you can see, linking to a an actual library using this approach is not a problem. However, using property_tree, which is a header only lib, fails to compile. By reading https://cmake.org/cmake/help/v3.12/module/FindBoost.html, I learned that there is a Boost::boost target to link agains for the header-only libs, but doing target_link_libraries(dummy PUBLIC Boost::boost ${Boost_LIBRARIES} Boost::boost) didnt help either. Looking CMakeCache.txt of dummy_core project, I can see Boost_INCLUDE_DIR:PATH=(...)/small_superbuild/build/stage/boost/include, which does not include (...)/small_superbuild/build/subprojects/Source/boost_external/libs/property_tree/include/ Any idea what is happening? -- Thiago -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: https://cmake.org/mailman/listinfo/cmake