Link types should be computed automatically
Please correct me if I'm wrong, but it seems to me that for C and C++ projects, if the CMakeLists.txt writer lists source files and header files in their calls to add_library
, add_executable
and target_sources
, then CMake has access to all the information that it needs to determine whether link libraries and include directories should be declared as PRIVATE
, PUBLIC
or INTERFACE
(I don't know how you collectively refer to these keywords, so I'm calling them the "link type") in the calls to target_link_libraries
and target_include_directories
. In particular, the CMakeLists.txt writer tells CMake what files comprise each target, what directories to resolve include directives against and what compiler options to use. CMake doesn't know the include graph, but it has all the information that's needed to compute it. So if it is preferable for CMake to use the correct link type, rather than acting as if all the link types are PUBLIC
, wouldn't it be ideal for CMake to just compute the link types itself?
Manually determining the correct link types is not trivial, especially if you already have a large project with thousands of files and hundreds of targets, and you're trying to introduce link types for the first time. Determining the correct link types involves analysing the transitive closure of a target X
's constituent files within the include graph (except for files belonging to targets that X
indirectly depends on), to determine whether a header file belonging to a target library Y
is transitively included by: a) a source file of X
, but not one of its header files; b) a header file of X
, but not one of its source files; or c) both a header file of X
and a source file of X
. Even once you've established the correct link types for a project, every time you add or remove an include directive from a source or header file, you have to repeat the include graph analysis to see if/how these transitive inclusion relationships have changed.
For a real life example of how hard this can be, consider the Qt project. The developers announced last October that they are deprecating Qbs, and that in the long term they plan to switch to using CMake to build Qt itself. The src
folder of Qt Base 5.12 contains 4995 files with the extension .h
or .cpp
(I haven't counted the targets or the include directives). If you were asked to write CMake scripts for such a large project from scratch, how would you go about determining the correct link types? The only viable solution that I've found for my smaller project (which has about 1000 files, 2000 internal include directives and 100 targets) is to write a shell script that will do the include graph analysis described above for me. Why not build this feature into CMake?