find_dependency fails when find_package is called in downstream project
I am on the latest CMake, Ubuntu 16.04. Suppose I am building a upstream library that depends on an external library (e.g. Boost):
cmake_minimum_required(VERSION 3.9)
project(mysdk)
add_library(${PROJECT_NAME} mylib.h mylib.cpp)
find_package(Boost COMPONENTS filesystem thread REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::filesystem Boost::thread)
export(TARGETS FILE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)
file(WRITE ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
"include(CMakeFindDependencyMacro)\n"
"find_dependency(Boost COMPONENTS filesystem thread REQUIRED)\n"
"include(\${CMAKE_CURRENT_LIST_DIR}/${CMAKE_PROJECT_NAME}Targets.cmake)\n")
install(DIRECTORY ${PROJECT_SOURCE_DIR}/include
DESTINATION ${CMAKE_INSTALL_PREFIX}
FILES_MATCHING PATTERN "*.h")
install(FILES ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}Config.cmake
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
install(EXPORT ${CMAKE_PROJECT_NAME}Targets NAMESPACE mysdk::
DESTINATION lib/cmake/${CMAKE_PROJECT_NAME})
install(TARGETS ${PROJECT_NAME}
EXPORT ${CMAKE_PROJECT_NAME}Targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
For my downstream clients, when they are linking to the upstream library mysdk
, if they also happen to be using Boost filesystem themselves, their CMakeLists will look like
cmake_minimum_required(VERSION 3.9)
project(myproject)
add_executable(${PROJECT_NAME} main.cpp)
find_package(Boost COMPONENTS filesystem REQUIRED)
find_package(mysdk REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC Boost::filesystem mysdk::mysdk)
This will actually result in CMake error
Target "myproject" links to target "Boost::thread" but the target was not
found. Perhaps a find_package() call is missing for an IMPORTED target, or
an ALIAS target is missing?
If I tell the downstream clients (they aren't suppose to be required to know) that Boost filesystem is already embedded in mysdk so they can modify their CMakelists to
cmake_minimum_required(VERSION 3.9)
project(myproject)
add_executable(${PROJECT_NAME} main.cpp)
find_package(mysdk REQUIRED)
target_link_libraries(${PROJECT_NAME} PUBLIC mysdk::mysdk)
This actually works. However, I believe that if the downstream client added the line find_package(Boost COMPONENTS filesystem REQUIRED)
it should at most be redundant and shouldn't break it for him. Can we fix this?