target_precompile_headers(PRIVATE) in library project does not work when using library functions in an executable project..

Related question: Question.

There is another problem which seems to stump me, that is it seems that target_precompile_headers with PRIVATE keyword(Which is a good practice) does not seem to work in my executable project, unless I make my target_precompile_headers PUBLIC (Which is a bad practice), How could I fix this issue, without making my target_precompile_headers PUBLIC or should I then just make them PUBLIC ?

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:

====================[ Build | voidmtlib | Internal_Linux_Ninja_Clang_Clion - Clang_Clion_Debug ]====
/bin/cmake --build --target voidmtlib --config Debug --preset Clang_Clion_Debug
[9/9] Linking CXX static library "/mnt/Main/Projects/C&C++/voidmtlib/build/Linux/Ninja Multi-Config/Internal_Linux_Ninja_Clang_Clion/liba/Debug/libvoidmtlib.a"

Build finished

====================[ Build | Sandbox | Internal_Linux_Ninja_Clang_Clion - Clang_Clion_Debug ]====
/bin/cmake --build --target Sandbox --config Debug --preset Clang_Clion_Debug
[8/9] Building CXX object voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o
FAILED: [code=1] voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o 
/bin/clang++ -DCMAKE_INTDIR=\"Debug\" -I"/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include" -g -std=gnu++20 -fcolor-diagnostics -MD -MT voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o -MF voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.d @voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o.modmap -o voidmtlib_examples/Sandbox/CMakeFiles/Sandbox.dir/Debug/main.cpp.o -c '/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:
In file included from /mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include/voidmtlib/core/voidmtlib_core.h:8:
/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include/voidmtlib/core/types/base/base_thread.h:19:7: error: no type named 'jthread' in namespace 'std'
   19 |         std::jthread m_thread;
      |         ~~~~~^
/mnt/Main/Projects/C&C++/voidmtlib/voidmtlib/include/voidmtlib/core/types/base/base_thread.h:20:7: error: no member named 'thread' in namespace 'std'
   20 |         std::thread::id m_thread_id = m_thread.get_id();
      |         ~~~~~^
2 errors generated.
ninja: build stopped: subcommand failed.

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)

base_thread.h which uses the std::jthread and std::thread in library

#ifndef VOIDMTLIB_BASETHREAD_H
#define VOIDMTLIB_BASETHREAD_H

#include "voidmtlib/core/types/base/base_task.h"

namespace voidmtlib::core
{
class base_thread
{
	public:
	base_thread ();
	~base_thread () = default;
	private:
	base_task m_task;
	std::jthread m_thread;
	std::thread::id m_thread_id = m_thread.get_id();


};
}

#endif //VOIDMTLIB_BASETHREAD_H

sandbox.h in executable.

#ifndef VOIDMTLIB_SANDBOX_H
#define VOIDMTLIB_SANDBOX_H

#include <voidmtlib/core/voidmtlib_core.h>

#endif //VOIDMTLIB_SANDBOX_H

main.cpp in executable.

#include <iostream>
#include "include/sandbox.h"

int main ()
{
	voidmtlib::core::voidmtlib_core test;
	test.test_function ();
	std::cout << "Test" << std::endl;
	std::cout << "Hello Sandbox" << std::endl;
	return 0;
}

I have never use precompiled header and I would not do it.

How will you install only our public interface header only?

Use:

target_sources(targetName
      <PRIVATE|PUBLIC|INTERFACE>
          FILE_SET setName
          [TYPE fileType]
          [BASE_DIRS dir1 [dir2...]]
          [FILES file1 [file2...]]
... )

Than your project will be much simpler and clear.

But perhaps this Include directories for target_precompile_headers may help you.