Assume I have the following project structure (inherited code - cannot change structure):
MyProject
├── CMakeLists.txt
├── src
│ └── foo.cpp
│ └── bar.cpp
├── include
│ └── foo_public.h
│ └── foo_private.h
│ └── bar_public.h
│ └── bar_private.h
CMakeLists.txt:
cmake_minimum_required(VERSION 3.16)
project(MyProject)
add_library(MyLibrary
foo.cpp
bar.cpp)
target_include_directories(MyLibrary PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
set_target_properties(MyLibrary PROPERTIES PUBLIC_HEADER foo_public.h bar_public.h)
install(TARGETS MyLibrary
LIBRARY DESTINATION ${INSTALL_LOCATION}/lib
PUBLIC_HEADER DESTINATION ${INSTALL_LOCATION}/include)
Will this allow other executables/libraries to link to MyLibrary at the install location without visibility into the private header files?
Does it matter that both the public and private headers are in the same location passed to target_include_directories?
Note: The target environment is Red Hat Enterprise Linux
This statment in CMakeLists.txt:
Means:
MyLibrarytarget or any target linking targetMyLibraryshould useMyProject/includedirectory as include path (sincePUBLICkeyword is used). (PRIVATEwould mean onlyMyLibraryshould use this include path,INTERFACEonly those who link targetMyLibrary).As a result other targets will be able include your private header. This can happen if someone will include your whole project into his source. If someone will just install library, public headers will be copied to respective locations, without private ones.
Best way to fix this is move private headers to
Srcdirectory. You do not have to change anything else.Note good library should contain tests. Those test should not use private headers to check that everything works without private headers. Now your tests will see private headers implicitly, so you may missed that some private symbol is in use in public header.
I recommend to see this instruction what is best practice to organize library project. It contains contains lots of nice technical details. Here is github project.