cmakeideqt-creator

How to avoid duplicated headers in source-tree using `add_subdirectory` in qt-creator?


Using CMake project in qt-creator, the IDE shows duplicated headers in the source tree.

enter image description here
(Qt-creator version 9.0.2)

When I navigate through the sources, groups of files are expanded and it become quickly inpractical to find a filename in that huge tree.

What I would like is something like this:

enter image description here

Notes:


Minimal? example:

Top CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

set(TARGET "Test_Cmake")
project("${TARGET}")

add_executable(${TARGET})
add_subdirectory("Model")

set( SOURCES classA.cpp )
set( HEADERS classA.hpp )
#source_group("${TARGET}" FILES "${SOURCES};${HEADERS}")
set( LIBS Model)
target_sources( ${TARGET} PRIVATE ${SOURCES} PUBLIC ${HEADERS})
target_link_libraries(${TARGET} ${LIBS} )

Model CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

set(TARGET "Model")

add_library(${TARGET})
set( SOURCES classB.cpp )
set( HEADERS classB.hpp )
#source_group("${TARGET}" FILES "${SOURCES};${HEADERS}")
target_sources( ${TARGET} PRIVATE ${SOURCES} PUBLIC ${HEADERS})

How to create the files:

mkdir Test_cmake && cd "$_"
touch classA.cpp classA.hpp CMakeLists.txt
mkdir Model && cd "$_"
touch classB.cpp classB.hpp CMakeLists.txt
# Then copy above content in each CMakeLists.txt

Solution

  • You add classB.hpp header to the target Model as PUBLIC:

    target_sources( ${TARGET} PRIVATE ${SOURCES} PUBLIC ${HEADERS})
    

    So the header belongs also to the target Test_cmake, which is linked with Model. This is why IDE shows given header in the tree for both targets, Model and Test_cmake.

    For avoid that, use PRIVATE keyword. Usually, the command target_sources is used with PRIVATE keyword only, so it adds sources and the headers only for the single target.

    (Note, that accessibility of a header in the consumer target via #include is regulated by the target_include_directories command and its keywords.)