Why CMake does not propagate the PUBLIC include directories between libraries?

I have a C++ project with three shared libraries, let’s call them libA, libB and libC. libA is dependant to both libB and libC. All of these three libraries are located inside a folder called utilities. Here is what I have:

Root CMakeLists.txt file:

cmake_minimum_required (VERSION 3.20) # Required because of policy CMP0074

project(Test VERSION 2022)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
file(TO_CMAKE_PATH $ENV{SHARED_PATH} SHARED_PATH)

add_subdirectory (utilities)

for libB I have the CMakeLists.txt like this:

add_library(libB SHARED
   inc/libB.h
   inc/libBExport.h
   src/libB.cpp
)

target_include_directories(libB
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
   PUBLIC ${SHARED_PATH}/inc
)

target_compile_definitions(libB
   PRIVATE LIBB_DLL)

and the same goes for libC:

add_library(libC SHARED
   inc/libC.h
   inc/libCExport.h
   src/libC.cpp
)

target_include_directories(libC
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
   PUBLIC ${SHARED_PATH}/inc
)

target_compile_definitions(libC
   PRIVATE LIBC_DLL)

Now, the CMakeLists.txt file for libA is like this:

add_library(libA SHARED
   inc/libA.h
   inc/libAExport.h
   src/libA.cpp
)

target_include_directories(libA
   PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc
   PUBLIC ${SHARED_PATH}/inc
    )

target_link_directories(libA
   PUBLIC libB
   PUBLIC libC
)

target_compile_definitions(libA
   PRIVATE  LIBA_DLL)

Now, I generate the Visual Studio solution file using cmake:

> cmake -G "Visual Studio 16 2019" -A x64

Everything goes fine. But when opening the solution with VS2019, libB and libC are compiling fine, but libA cannot be compiled with this error:

D:\code\proj\utilities\inc\libA.h(5,10): fatal error C1083: Cannot open include file: 'libB.h': No such file or directory
D:\code\proj\utilities\inc\libA.h(9,10): fatal error C1083: Cannot open include file: 'libC.h': No such file or directory

Can someone explain me why the the PUBLIC include directories of libB and libC are not inherited to libA?

>Solution :

Instead of the following:

target_link_directories(libA
   PUBLIC libB
   PUBLIC libC
)

You should use target_link_libraries().

target_link_libraries(libA
   PUBLIC libB
   PUBLIC libC
)

This will setup a dependency between the libraries which sets the include path, compiler settings, additional link directories, and additional link libraries.

Leave a Reply