CMakePCHCompiler
CMakePCHCompiler copied to clipboard
Alternative to separate CXXPCH compiler definition
In project README
CMake does not allow to insert source file to existing target once it has been defined.
But source can be insert before add_executable/library
.
Even if it was possible, we could not ensure precompiled header is built first in main target, but adding it as subtarget we can.
It's possible with OBJECT_DEPENDS
property on source files.
We cannot prevent header.pch, which is output of CPCH/CXXPCH compiler from being linked when it is in part of main target, but if we put it into OBJECT library, then by definition we skip linking process. Also we take the result object to be a recompiled header for main target.
Output can be changed witho dummy .o file without code.
project(pchtest CXX)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_executable(${PROJECT_NAME} "main.cpp" "pch.cpp" "pch.h" "pch_dummy.cpp")
add_compile_options(${PROJECT_NAME} PUBLIC -Wall -Werror -Winvalid-pch)
set_source_files_properties(pch.cpp PROPERTIES COMPILE_OPTIONS "-x;c++-header" OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pchtest.dir/pch_dummy.cpp.o)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/pch.h.gch
COMMAND ${CMAKE_COMMAND} -E rename ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pchtest.dir/pch.cpp.o ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/pch.h.gch
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pchtest.dir/pch_dummy.cpp.o ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pchtest.dir/pch.cpp.o
COMMAND ${CMAKE_COMMAND} -E touch ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/pch.h.gch
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/pchtest.dir/pch.cpp.o
COMMENT "Copy PCH"
)
set_source_files_properties(main.cpp PROPERTIES OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/pch.h.gch COMPILE_OPTIONS "-include;${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/pch.h")
Full example here.
Works with CMake 3.14.3, gcc 8.3.1 and Makefile generator. Ninja generator doesn't works but it seems a CMake bug. I opened an issue here.
Okay, your idea is really fine. But this is completely different approach that one here, so it should be rather brand new project than addition to this one.
If what your are saying it true and there is no caveat and it works better then I am happy and okay to shutdown this repo. 👍
Now you if can provide CMAKE module that does that job, rather than fixed CMakeLists then all I can say is great!
However, note that so far you have generated the PCH but it still has to be included for all other source files which I believe does not happen in the example above. And of course the dependency cycle for Ninja has to be fixed too I believe.
My approach doesn't work with Ninja only Make. Also I didn't (and can't) test it with MSVC. I opened an issue on CMake bugtracker. -include
doesn't apply for AUTOMOC'ed sources and I can't find how to workaround this.
I rewrite my pch with compile_commands.json. Now it can be build with Makefiles or Ninja on Linux or macOS (Windows MinGW doesn't tested yet). https://travis-ci.org/drizt/pchtest
My PCHLinkTarget module now is almost finished. Yes, it moved to new repository. I tested it with macOS, Linux, MinGW on Windows and MSYS in both Ninja and Makefiles modes. All works file. Also I suscessfully aplied it to my complex project with many modules and pch files.
Great to see the progress. But also keep in mind that you may want to support MSVC. Also wanted to ask why PCHLinkTarget
/pch_link_target
name? I don't get why there is a word "link" there.
I just saved/used your function name. It does the same work but in another way.
That one caught my eye:
CMake does not allow to insert source file to existing target once it has been defined.
It does via target_sources() and maybe directly via the SOURCES target property.
target_sources
added in CMake 3.1