1

I am creating an C++ library which inside the library codebase includes are more freely defined than on an executable.

For example:

#include "base_task.h" Inside library in comparison to #include "voidmtlib/core/types/base_task.h" in the executable

Now the problem is that while testing out the library function in an executable it seems that I cannot use the includes in the library includes which have been defined to be more freely included by target_include_directories(${PROJECT_NAME} PRIVATE ${all_include_directories}) but if I include in library header file with less free method which is defined in target_incude_directories(${PROJECT_NAME} PUBLIC "include") it works as intended, or if I include to the source file with more free method it works as intended. Could somebody help me to crack this problem or even explain what the problem is.

For additional problems it seems that target_precompile_headers(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/precompiled/pch.h) does not work (does not find included headers for example <thread>) when using my library in an executable unless I set the target_precompile_headers to PUBLIC or in an executable cmakelists define the target_precompiled_header(Sandbox REUSE_FROM voidmtlib).

My problematic cmake code for this library is.

# voidmtlib/CMakeLists.txt

set(src_core_sourcefiles
"src/core/voidmtlib_core.cpp"
"src/core/types/base/base_task.cpp"
"src/core/types/base/base_thread.cpp")

set(src_core_headerfiles
"include/voidmtlib/core/voidmtlib_core.h"
"include/voidmtlib/core/types/base/base_task.h"
"include/voidmtlib/core/types/base/base_thread.h")

set(src_utils_sourcefiles
"src/utils/logger/logger.cpp")

set(src_utils_headerfiles
"include/voidmtlib/utils/logger/logger.h")

set(voidmtlib_public_include_directories
"include")

set(voidmtlib_private_include_directories
"include"
"include/voidmtlib"
"include/voidmtlib/core"
"include/voidmtlib/core/types"
"include/voidmtlib/core/types/base"
"include/voidmtlib/utils"
"include/voidmtlib/utils/logger")


set(dependency_list "spdlog")
set(method_list "find_package;add_subdirectory")

dependency_manager("${dependency_list}" "${method_list}")

#message("${CMAKE_CURRENT_SOURCE_DIR}/${src_core_include}")

if(${USE_FetchContent} AND NOT ${spdlog_dependency_enabled})
    declare_and_make_available("spdlog" "https://github.com/gabime/spdlog.git" "v1.x")
endif()

set(all_src_files ${src_utils_sourcefiles}  ${src_core_sourcefiles})

set(all_hdr_files ${src_utils_headerfiles} ${src_core_headerfiles})

#list(TRANSFORM all_src_files PREPEND ${CMAKE_CURRENT_LIST_DIR}/)

#foreach (file IN LISTS all_src_files)
#    message(${file})
#endforeach ()

add_library(${PROJECT_NAME} ${all_src_files} ${all_hdr_files})

include(GNUInstallDirs)

list(TRANSFORM voidmtlib_private_include_directories PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/)
list(TRANSFORM voidmtlib_public_include_directories PREPEND ${CMAKE_CURRENT_SOURCE_DIR}/)

target_precompile_headers(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/precompiled/pch.h" "${CMAKE_CURRENT_SOURCE_DIR}/precompiled/pch.cpp")

#target_sources(${PROJECT_NAME} PUBLIC ${all_hdr_files})
#target_sources(${PROJECT_NAME} PUBLIC ${all_src_files})

target_include_directories(${PROJECT_NAME} PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>" "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>")
target_include_directories(${PROJECT_NAME} PRIVATE "${voidmtlib_private_include_directories}")




target_link_libraries(${PROJECT_NAME} PRIVATE spdlog::spdlog)

#include(CMakePrintHelpers)

#cmake_print_properties(TARGETS ${PROJECT_NAME} PROPERTIES INCLUDE_DIRECTORIES)

the current error:

-- Package spdlog has been added going to the next package
-- Configuring done (0.0s)
-- Generating done (0.0s)
-- Build files have been written to: /mnt/Main/Projects/C&C++/voidmtlib/build/Linux/Ninja Multi-Config/Internal_Linux_Ninja_Clang_Clion/bin
[5/11] Generating CXX dyndep file voidmtlib/CMakeFiles/voidmtlib.dir/Debug/CXX.dd

Build finished

====================[ Build | Sandbox | Internal_Linux_Ninja_Clang_Clion - Clang_Clion_Debug ]====
/bin/cmake --build --target Sandbox --config Debug --preset Clang_Clion_Debug
[1/14] Scanning '/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib_examples/Sandbox/main.cpp' for CXX dependencies
FAILED: [code=1] voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi 
"/usr/bin/clang-scan-deps" -format=p1689 -- /bin/clang++ -DCMAKE_INTDIR=\"Debug\" -I"/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include" -g -std=gnu++20 -fcolor-diagnostics -x c++ '/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib_examples/Sandbox/main.cpp' -c -o voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o -resource-dir "/usr/lib/clang/21" -MT voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi -MD -MF voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi.d > voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi.tmp && mv voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi.tmp voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.ddi
Error while scanning dependencies for /mnt/Main/Projects/C&C++/voidmtlib/voidmtlib_examples/Sandbox/main.cpp:
In file included from /mnt/Main/Projects/C&C++/voidmtlib/voidmtlib_examples/Sandbox/main.cpp:2:
In file included from /mnt/Main/Projects/C&C++/voidmtlib/voidmtlib_examples/Sandbox/include/sandbox.h:8:
/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include/voidmtlib/core/voidmtlib_core.h:8:10: fatal error: 'base_task.h' file not found
[5/14] Scanning '/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/src/utils/logger/logger.cpp' for CXX dependencies
ninja: build stopped: subcommand failed.

base_task.h file not found while it is used by voidmtlib_core.h in more free method while building the sandbox/main.cpp.

IDE: Clion.

Generator: Ninja Multi-Config

File structure:

├── cmake
│   ├── dependency_utils.cmake
│   └── fetchcontent_utils.cmake
├── CMakeLists.txt
├── CMakePresets.json
├── CMakeUserPresets.json
├── README.md
├── voidmtlib
│   ├── CMakeLists.txt
│   ├── include
│   │   └── voidmtlib
│   │       ├── core
│   │       │   ├── types
│   │       │   │   └── base
│   │       │   │       ├── base_task.h
│   │       │   │       └── base_thread.h
│   │       │   └── voidmtlib_core.h
│   │       └── utils
│   │           └── logger
│   │               └── logger.h
│   ├── precompiled
│   │   ├── pch.cpp
│   │   └── pch.h
│   ├── src
│   │   ├── core
│   │   │   ├── types
│   │   │   │   └── base
│   │   │   │       ├── base_task.cpp
│   │   │   │       └── base_thread.cpp
│   │   │   └── voidmtlib_core.cpp
│   │   └── utils
│   │       └── logger
│   │           └── logger.cpp
│   └── vendor
└── voidmtlib_examples
    ├── CMakeLists.txt
    ├── README.md
    └── Sandbox
        ├── CMakeLists.txt
        ├── include
        │   └── sandbox.h
        └── main.cpp

Sandbox/CMakeLists.txt

#Sandbox/Cmakelists.txt

add_executable(Sandbox main.cpp include/sandbox.h)

target_link_libraries(Sandbox PRIVATE voidmtlib)
New contributor
ALEPHVOID is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
1

1 Answer 1

1

The base path of base_task.h is listed in the list voidmtlib_private_include_directories that is set as private include directories of the project voidmtlib. The only public include directory is ${CMAKE_CURRENT_SOURCE_DIR}/include. It's seen in the build command

-I"/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include"

The fix for the build errors: the examples must include the file like

#include "voidmtlib/core/types/base_task.h"
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for answering, my question but the voidmtlib_examples/Sandbox/include/sandbox.h (Which is in executable scope) uses the include file like this #include "voidmtlib/core/voidmtlib_core.h" and voidmtlib_core.h(which is in library scope) includes like this #include "base_task". So by your answer should then I use includes in library scope like this #include "voidmtlib/core/types/base_task" which I truly do not want to happen (because of atomization) or is there another more elegant solution to this problem.
Public header files like voidmtlib_core.h also must use #include "voidmtlib/core/types/base_task.h"
It seems that is the best answer to the problem of scopes, but another problem still persists because base_thread.h (which has dependency to base_task.h) uses std::jthread (which is defined in <thread> library) and well unless I set my target_precompiled_headers to PUBLIC(Which is a bad practice) it does not find the functions associated with <thread> function in executable. Edit: Should then I #include precompiled header in library code or is there another solution.
It's better to ask a new question. SO policy doesn't allow several questions in a single post.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.