# Transitive Dependencies

**URL:** https://discourse.cmake.org/t/transitive-dependencies/6645
**Category:** Code
**Tags:** tool:cmake
**Created:** [October 11, 2022, 9:34pm UTC](https://discourse.cmake.org/t/transitive-dependencies/6645 "2022-10-11T21:34:32Z")
**Posts on this page:** 2
**Page:** 1

<div class="post-metadata">

### Author: ![DaAwesomeP](https://discourse.cmake.org/user_avatar/discourse.cmake.org/daawesomep/32/2794_2.png) [@DaAwesomeP](https://discourse.cmake.org/u/DaAwesomeP)
#### Post date: [October 11, 2022, 9:34pm UTC](https://discourse.cmake.org/t/transitive-dependencies/6645/1 "2022-10-11T21:34:32Z")

</div>

Hello!

I have two projects. `projectA` and `projectB`. Project A depends on `projectB`. `projectB` depends on system dependencies. When I build project A, I get a bunch of linker errors.

`projectB`:

```auto
cmake_minimum_required(VERSION 3.18 FATAL_ERROR)
project(projectB LANGUAGES CXX)

set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS
    YES
    CACHE BOOL "Export all symbols")

add_definitions(-DBOOST_LOG_DYN_LINK)
find_package(Boost 1.74.0 REQUIRED COMPONENTS log)
find_package(OpenSSL 1.1.0 REQUIRED)

find_package(PkgConfig)
pkg_check_modules(LIBSOMETHING libosomething>=0.1.0 REQUIRED)

add_library(
  ${CMAKE_PROJECT_NAME}
  include/projectB/projectB.hpp
  src/projectB.cpp)
add_library("${CMAKE_PROJECT_NAME}::${CMAKE_PROJECT_NAME}" ALIAS "${CMAKE_PROJECT_NAME}")

target_compile_features(${CMAKE_PROJECT_NAME} PUBLIC cxx_std_17)
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE -Werror)
set_target_properties(
  ${CMAKE_PROJECT_NAME}
  PROPERTIES LINKER_LANGUAGE CXX)

target_include_directories(
  ${CMAKE_PROJECT_NAME}
  PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
         $<INSTALL_INTERFACE:include>)

target_include_directories(${CMAKE_PROJECT_NAME}
                           PRIVATE lib/local-dep-1)
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE lib/local-dep-2/src)

set(TARGETS_EXPORT_NAME "${CMAKE_PROJECT_NAME}Config")
install(
  TARGETS ${CMAKE_PROJECT_NAME}
  EXPORT "${TARGETS_EXPORT_NAME}"
  LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
  RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
  INCLUDES DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
export(
  TARGETS ${CMAKE_PROJECT_NAME}
  NAMESPACE ${CMAKE_PROJECT_NAME}::
  FILE "${CMAKE_CURRENT_BINARY_DIR}/${TARGETS_EXPORT_NAME}.cmake"
)
install(
  EXPORT ${TARGETS_EXPORT_NAME}
  DESTINATION "${CMAKE_INSTALL_DATADIR}/${CMAKE_PROJECT_NAME}/cmake"
  NAMESPACE ${CMAKE_PROJECT_NAME}::
)

```

`projectA` (excerpt):

```auto
get_filename_component( PROJECTB_PATH "${CMAKE_CURRENT_SOURCE_DIR}/lib/projectB" ABSOLUTE )
set(projectB_DIR "${PROJECTB_PATH}/_builds/${CMAKE_BUILD_TYPE}")
find_package(projectB REQUIRED)

```

I then add the `projectB::projectB` library to the target. This results some issues:

- I have to add include directories for `lib/projectB/lib/local-dep-1` and `lib/projectB/lib/local-dep-2/src` to `projectA`.
- `projectA` has linker errors with finding OpenSSL and `libsomething`.
- More of a minor annoyance than an issue, but `projectA` will not automatically build `projectB` to generate `projectBConfig.cmake`.

Is this the right way to do this? How do I have `projectA` pick up on linking OpenSSL and `libsomething`?

---

<div class="post-metadata">

### Author: ![Angew](https://discourse.cmake.org/user_avatar/discourse.cmake.org/angew/32/229_2.png) [@Angew](https://discourse.cmake.org/u/Angew)
#### Post date: [October 12, 2022, 7:17am UTC](https://discourse.cmake.org/t/transitive-dependencies/6645/2 "2022-10-12T07:17:31Z")

</div>

> [@DaAwesomeP](#):
>
> - I have to add include directories for `lib/projectB/lib/local-dep-1` and `lib/projectB/lib/local-dep-2/src` to `projectA`.

In `projectB`, you’ve marked these include directories as `PRIVATE`, meaning they apply to `projectB` only, not to its consumers. If its consumers also need these include directories (as this implies), make them `PUBLIC` instead.

> [@DaAwesomeP](#):
>
> - `projectA` has linker errors with finding OpenSSL and `libsomething`.

I can’t see anything in `projectB`’s CMakeList that would indicate `projectB` is linking against `OpenSSL` and `libsomething`. Even if you build `projectB` as a static library, you should include the relevant `target_link_libraries()` command so that CMake knows those dependencies are necessary. In the case of static libraries, they will be propagated to consumers too (since static libraries don’t link).

> [@DaAwesomeP](#):
>
> - More of a minor annoyance than an issue, but `projectA` will not automatically build `projectB` to generate `projectBConfig.cmake`.

That is the correct behaviour when using an external package (using `find_package()`) — that is intended for picking up pre-supplied dependencies. If you want to build your dependencies, I believe you should look into CMake’s [dependency guide](https://cmake.org/cmake/help/latest/guide/using-dependencies/index.html) and [`FetchContent`](https://cmake.org/cmake/help/latest/module/FetchContent.html) module.
