Issue
I'm very deep diving into CMake PUBLIC,PRIVATE,INTERFACE. According to the docs, INTERFACE for include path shall be used when you want your library to provide interface includes to the one depending on the library, but your sources inside library won't see these includes.
I have this disk organization:
- mylib
- src
- include/mylib/mylib.h
- mylib/mylib.c
- CMakeLists.txt
In CMakeLists.txt
I have:
cmake_minimum_required(VERSION 3.22)
add_library(mylib INTERFACE)
target_sources(mylib PUBLIC ${CMAKE_CURRENT_LIST_DIR}/src/mylib/mylib.c)
target_include_directories(mylib INTERFACE ${CMAKE_CURRENT_LIST_DIR}/src/include)
And my target includes mylib like:
add_subdirectory("middlewares/mylib" mylib)
target_link_libraries(${CMAKE_PROJECT_NAME} mylib)
And it compiles. mylib.c
in the library can see the include path mylib.h
, even if this one is defined as INTERFACE which, according to the CMake, it shouldn't be visible.
- Why does it work?
- Since library is a one-header and since lib dependant on it will needs its header, shall I rather use PUBLIC?
Solution
It's the target ${CMAKE_PROJECT_NAME}
that compiles mylib.c
, not mylib
.
mylib
being an INTERFACE
library doesn't introduce do any build steps at all, but is just a library where information is attached. In this case the relevant information attached is:
- The source files to add to the linking target (
target_sources(... PUBLIC ...)
) - The include directories (
target_include_directories(... INTERFACE ...)
)
So both necessary pieces of information is applied to ${CMAKE_PROJECT_NAME}
and the compilation works "as unexpected".
Answered By - fabian Answer Checked By - Candace Johnson (WPSolving Volunteer)