CMake precompiled header support via custom PCH compiler extension

Overview

⚠️ This project is obsolete as CMake 3.16 or higher provides native support for precompiled headers. No PRs will be accepted and no further development is planned.

CMake Precompiled Headers

CMakePCHCompiler module defines extra CXXPCH/CPCH "meta"-compiler that compiles .h into .pch/.gch using existing CXX/C compiler.

For convenience it defines

target_precompiled_header(target [...] header
                          [REUSE other_target]
                          [TYPE type])

Uses given header as precompiled header for given target.

Optionally it may share compiled header object with other_target, so it is precompiled just once.

For advanced users it allows customizing precompiler header type passed to compiler, which is normally inferred from the language, e.g. c++-header for CXX.

NOTE: While CMakePCHCompiler ensures that precompiled header is included as first compile unit for each source file, it is still recommended to keep #include "prefix.h" (where prefix.h is your header file you want to pre-compile - header argument) in your source code to ensure your code remains portable regardless of precompiled headers being enabled or not.

For more details how to use precompiled header with your library and/or compiler refer to their documentation i.e. GCC, Qt, etc.

IMPORTANT Before you submit issue report or feature request, please...

  1. Be aware that CMake 3.16 or higher provides built-in support for precompiled headers, and all related to CMake issues should be reported at CMake's issue tracker.
  2. Be aware that this project is now obsolete and no further development is planned and no PRs will be accepted.
  3. Read this README.md file completely to understand intentions and limitations of this project.
  4. Understand that CMakePCHCompiler is neither official nor proper way to provide PCH support in CMake.
  5. Understand that the CMakePCHCompiler authors are neither compensated for their efforts not affiliated with KitWare (CMake's authors).

Why this project existed

In summer 2019 @cristianadam has finished native CMake functionality for precompiled headers that has been merged to mainline CMake and staged for 3.16.0. Until that, native support for precompiled headers was requested for several years at CMake's mailing lists and/or its issue tracker. This project was started in 2015 as a proof-of-concept implementation accompanying RFC: CMake precompiled header support and custom compiler based implementation.

NOTE: This project was and is neither trying to be official nor proper way to provide PCH support in CMake. Authors stated that only viable and future-proof solution was to implement this functionality natively in CMake, and this was done for CMake version 3.16. CMakePCHCompiler authors are not affiliated with KitWare (CMake's authors).

⚠️ Right not this project is considered obsolete, no further development is planned and no PRs will be accepted. It is left here for historical purposes.

See also an umbrella issue at CMake's issue tracker (KitWare's GitLab) for more information on native PCH support effort.

Supported & tested platforms

  1. CMake version 3.0 or higher
  2. Windows with MSVC, tested on VS2015
  3. OSX with Clang, GCC, tested on OSX 10.10 & Xcode 6.1
  4. Linux with GCC, tested on Ubuntu 14.04 LTS & GCC 4.8

Note for MSVC users

Due to the problem in MSVC 2010 and higher's Microsoft.Cpp.Win32.targets deleting PCH, this module currently enforces /Z7 compiler flag for MSVC, hence debug information is stored on .obj files instead of .pdb program database. This is certainly not a perfect solution, but only one that is known to work so far. If you know any better workaround please submit PR. Thanks!

More information can be found at Visual Studio Community and is tracked at issue #21.

Example

cmake_minimum_required(VERSION 3.0)

list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/CMakePCHCompiler)

project(pchtest CXX CXXPCH)

add_library(engine SHARED src/engine.cpp src/library.cpp)
target_precompiled_header(engine src/prefix.h)

add_executable(demo src/demo.cpp)
target_link_libraries(demo engine)
target_precompiled_header(demo src/prefix.h REUSE engine)

What it is about?

CMake does not support precompiled headers by default. There are several modules providing precompiled header support, but all of them use custom commands and complicated wrappers to achieve their goals.

This module is somehow different. It defines a meta C++ compiler that simply just patches compiler command template for precompiled header case.

Next it treats precompiled header file as source file for CXXPCH that makes CMake use CXXPCH patched instead origin CXX compiler template. This ensures that all CXX language flags and specific settings such as these populated by add_definitions are also applied to precompiled header.

Passing same flags during precompiled header and other source files compilation is very important. It is simply impossible to catch all flags, such as these defined after calling target_precompiled_header or these using CMake internal variables such as add_definitions, using custom commands. This is the reason for such implementation.

This module is also transparent to source code. There is absolutely no need to change you source files. Only requirement is a precompiled header .h file added to given target via target_precompiled_header function.

Nevertheless this is not an ideal solution. In perfect world it is CMake that should handle precompiled headers generation internally, based on given compiler command templates. However this may be good start to request native support using simple API of:

target_precompiled_header( 
   
    )
target_precompiled_header(
     
     
                          
      
       )
target_precompiled_header(
        
        
          REUSE 
         
          )
         
        
       
      
     
    
   
  

How does it work?

First, we define new compilers CPCH and CXXPCH using CMAKE_ _* variables. These compilers copy run templates and options from existing C and CXX compilers respectively.

Next we provide target_precompiled_header function that enabled precompiled header on given target.

Pre-compiler header is build in new target.pch subtarget using:

add_library(${target}.pch OBJECT ${header})

This is done on purpose because of few reasons:

  1. CMake does not allow to insert source file to existing target once it has been defined.

  2. Even if it was possible, we could not ensure precompiled header is built first in main target, but adding it as subtarget we can.

  3. 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.

License

Copyright (c) 2015-2019 CMakePCHCompiler Authors

This code is licensed under the MIT License, see LICENSE for details.

Comments
  • Failed to compile the PCH

    Failed to compile the PCH

    I tried this with a C++ module in ReactOS, but got:

    FAILED: E:\RosBE\i386\bin\g++.exe   -DDBG=1 -DKDBG=1 -DUSE_COMPILER_EXCEPTIONS -DWINVER=0x502 -D_M_IX86 -D_NETSHELL_ -D_SEH_ENABLE_TRACE -D_SETUPAPI_VER=0x502 -D_USE_32BIT_TIME_T -D_USE_PSEH3=1 -D_WIN32_IE=0x600 -D_WIN32_WINDOWS=0x502 -D_WIN32_WINNT=0x600 -D_X86_ -D__REACTOS__ -D__i386__ -D_inline=__inline -Di386 -g dll/shellext/netshell e:/reactos-vanilla/dll/shellext/netshell e:/reactos-vanilla/include e:/reactos-vanilla/include/psdk e:/reactos-vanilla/include/dxsdk include include/psdk include/dxsdk include/reactos e:/reactos-vanilla/include/crt e:/reactos-vanilla/include/ddk e:/reactos-vanilla/include/ndk e:/reactos-vanilla/include/reactos e:/reactos-vanilla/include/reactos/libs -x c++-header -o dll/shellext/netshell/CMakeFiles/netshell.pch.dir/precomp.h.gch -c e:/reactos-vanilla/dll/shellext/netshell/precomp.h
    e:/reactos-vanilla/dll/shellext/netshell/precomp.h:21:27: fatal error: shlguid_undoc.h: No such file or directory
    

    Notice that header folders are not prefixed with -I for inclusions.

    opened by AmineKhaldi 22
  • Nanoant pull request

    Nanoant pull request

    Hi!

    I think I've finally straightened everything out. It's almost impossible to go over everything here. Luckily after so many extensive changes this PR is saying "Able to merge" so I think it's good to just go with it.

    Some reservations: I think it would be better if the PCH file went into the binary folders in the MSVC targets, but I don't know how to do that. Currently it goes into the CMakeFiles folders, and it's not release/debug specific, so a clean is probably needed to switch from debug to release, etc. This is nothing new. (Also including headers in the target is not practical. Under GCC it won't work, and I'm unsure about MSVC, but in general, the module cannot consider this use case, and users must accept this limitation. End-users can include the headers themselves I think, manually. But CMake conflates headers with sources, and the custom PCH compilers collide with CMake's naive approach.)

    https://github.com/nanoant/CMakePCHCompiler/issues/12 (EDITED: Previously listed as 7. Sorry.)

    Because of code in an MSVC script file, called Microsoft.Cpp.Win32.targets, the old way would not normally work on MSVC2010 forward. I worked on many things (paths with spaces, install(EXPORT), and so on) that I can't all recollect before getting to the final step, only to not be able to build under MSVC.

    Today I tried some things based on readings, and made it work by forcing /Z7 and including the OBJ outputted by the PCH target in the target sources. This is a straightforward fix compared to using /Zi and PDB and avoids PDB altogether, which was an additional synchronization problem before. Currently only the PCH/GCH files must be referred to by their naked paths. I'd love it if $<TARGET_OBJECTS> worked for all purposes, but I'm pretty sure that it doesn't. I may explore this and file a feature-request with CMake if to no avail.

    I've had the opportunity to better understand the module after spending so much time struggling to make it work in a real cross-platform use-case. So I've also made many nuanced improvements along the way, to I think, make it easier to understand. There were some unexplained sly tricks, which I've not added comments on, but have duplicated and changed the names of some variables to better communicate their intent.

    https://github.com/nanoant/CMakePCHCompiler/issues/4

    Also in this is a fix for the outstanding NOTFOUND issue, which is actually where my work began, before getting sucked down the proverbial rabbit hole. I don't know if this simple fix will solve everyone's NOTFOUND issue, but it solved mine, and I expect it will solve many if not all's.

    This MSVC fix preserves the REUSE feature, although I've not tested it. To MSVC the PCH is always technically reused, because it's shared by the project-module that generates it and the consuming module. The way CMakePCHCompiler works (its workflow) is really not consistent with MSVC, but I prefer to code it this way, so that it follows the same beats as the GCH pathway; and in fact, if it diverged into the more natural MSVC approach, the REUSE option might otherwise not have worked, or would not be practical. So this is a happy ending.

    In any case, this works for me, and I can't think of anything to change off the top of my head :)

    opened by mick-p1982 13
  • Doesn't work with multiple language targets.

    Doesn't work with multiple language targets.

    It doesn't work when target mixes multiple languages (C, C++, Objective-C, ObjectiveC++). target_precompiled_header should generate a separate header for each language, or use the pch only for the language it was compiled for.

    enhancement wontfix 
    opened by smilediver 9
  • Can't find PCH file during build.

    Can't find PCH file during build.

    I am testing this module out with our software but I can't get it to compile. After calling add_library(), I call target_precompiled_header(${target} ${pch_path}) to add the PCH to it. CMake will run successfully if I use the absolute or relative path to the .pch file but when I try to compile the code I get one of the following errors:

    (relative path) cc1plus: fatal error: /home/smcmich1/repo/visionworkbench/build/src/vw/Core/CMakeFiles/VwCore.pch.dir/../stdafx.h: No such file or directory

    (absolute path) cc1plus: fatal error: /home/smcmich1/repo/visionworkbench/build/src/vw/Core/CMakeFiles/VwCore.pch.dir//home/smcmich1/repo/visionworkbench/src/vw/stdafx.h: No such file or directory

    Do you know what could be going wrong? The PCH file is located at /home/smcmich1/repo/visionworkbench/src/vw/stdafx.h. CMake is being called from the "build" subfolder and the code is located in the "src" subfolder. The project line is: project (VisionWorkbench C CXX CXXPCH CPCH)

    This is on Red Hat 6, with CMake 3.5.2, and GCC 4.9.3.

    Thanks, Scott

    opened by ScottMcMichael 8
  • wrong -isystem /usr/include in pch.h compilations flags

    wrong -isystem /usr/include in pch.h compilations flags

    OS Fedora 29

    I can set manually C++ standard. But in this case I got another error.

    [[email protected] debug]$ make 
    /usr/bin/cmake -S/home/taurus/tmp/pchtest -B/home/taurus/tmp/pchtest/debug --check-build-system CMakeFiles/Makefile.cmake 0
    -- Configuring done
    CMake Debug Log at CMakeLists.txt:16 (target_link_libraries):
      Used includes for target pchtest:
    
       * /usr/include/qt5
       * /usr/include/qt5/QtCore
       * /usr/lib64/qt5/mkspecs/linux-g++
    
    
    
    CMake Debug Log at CMakeLists.txt:16 (target_link_libraries):
      Used includes for target pchtest:
    
       * /usr/include/qt5/QtGui
       * /usr/include
    
    
    
    CMake Debug Log at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:110 (set_target_properties):
      Used includes for target pchtest.pch:
    
       * /usr/include/qt5
       * /usr/include/qt5/QtCore
       * /usr/lib64/qt5/mkspecs/linux-g++
    
    Call Stack (most recent call first):
      CMakeLists.txt:17 (target_precompiled_header)
    
    
    CMake Debug Log at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:110 (set_target_properties):
      Used includes for target pchtest.pch:
    
       * /usr/include/qt5/QtGui
       * /usr/include
    
    Call Stack (most recent call first):
      CMakeLists.txt:17 (target_precompiled_header)
    
    
    -- Generating done
    -- Build files have been written to: /home/taurus/tmp/pchtest/debug
    /usr/bin/cmake -E cmake_progress_start /home/taurus/tmp/pchtest/debug/CMakeFiles /home/taurus/tmp/pchtest/debug/CMakeFiles/progress.marks
    make -f CMakeFiles/Makefile2 all
    make[1]: Entering directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch_autogen.dir/build.make CMakeFiles/pchtest.pch_autogen.dir/depend
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    cd /home/taurus/tmp/pchtest/debug && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch_autogen.dir/DependInfo.cmake --color=
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch_autogen.dir/build.make CMakeFiles/pchtest.pch_autogen.dir/build
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    [ 14%] Automatic MOC for target pchtest.pch
    /usr/bin/cmake -E cmake_autogen /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch_autogen.dir/AutogenInfo.cmake Debug
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    [ 14%] Built target pchtest.pch_autogen
    make -f CMakeFiles/pchtest.pch.dir/build.make CMakeFiles/pchtest.pch.dir/depend
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    cd /home/taurus/tmp/pchtest/debug && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch.dir/DependInfo.cmake --color=
    Scanning dependencies of target pchtest.pch
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch.dir/build.make CMakeFiles/pchtest.pch.dir/build
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    [ 28%] Building CXX object CMakeFiles/pchtest.pch.dir/pchtest.pch_autogen/mocs_compilation.cpp.o
    /usr/lib64/ccache/c++  -DQT_CORE_LIB -DQT_GUI_LIB -I/home/taurus/tmp/pchtest/debug -I/home/taurus/tmp/pchtest -I/home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtCore -isystem /usr/lib64/qt5/mkspecs/linux-g++ -isystem /usr/include/qt5/QtGui  -g   -std=gnu++11 -fPIC -std=gnu++11 -o CMakeFiles/pchtest.pch.dir/pchtest.pch_autogen/mocs_compilation.cpp.o -c /home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/mocs_compilation.cpp
    [ 42%] Building CXXPCH object CMakeFiles/pchtest.pch.dir/pch.h.gch
    /usr/lib64/ccache/c++  -DQT_CORE_LIB -DQT_GUI_LIB -I/home/taurus/tmp/pchtest/debug -I/home/taurus/tmp/pchtest -I/home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtCore -isystem /usr/lib64/qt5/mkspecs/linux-g++ -isystem /usr/include/qt5/QtGui -isystem /usr/include  -g   -std=gnu++11 -fPIC -x c++-header -o CMakeFiles/pchtest.pch.dir/pch.h.gch -c /home/taurus/tmp/pchtest/pch.h
    In file included from /usr/include/c++/8/bits/stl_algo.h:59,
                     from /usr/include/c++/8/algorithm:62,
                     from /usr/include/qt5/QtCore/qglobal.h:142,
                     from /usr/include/qt5/QtCore/qcoreapplication.h:43,
                     from /usr/include/qt5/QtCore/QCoreApplication:1,
                     from /home/taurus/tmp/pchtest/pch.h:1:
    /usr/include/c++/8/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
     #include_next <stdlib.h>
                   ^~~~~~~~~~
    compilation terminated.
    make[2]: *** [CMakeFiles/pchtest.pch.dir/build.make:79: CMakeFiles/pchtest.pch.dir/pch.h.gch] Error 1
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make[1]: *** [CMakeFiles/Makefile2:114: CMakeFiles/pchtest.pch.dir/all] Error 2
    make[1]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make: *** [Makefile:87: all] Error 2
    [[email protected] debug]$ cd ..
    [[email protected] pchtest]$ ll
    total 32
    drwxrwxr-x 3 taurus taurus 4096 Apr 29 21:41 cmake
    -rw-rw-r-- 1 taurus taurus  568 Apr 29 22:54 CMakeLists.txt
    -rw-rw-r-- 1 taurus taurus 9922 Apr 29 22:06 CMakeLists.txt.user
    drwxrwxr-x 5 taurus taurus 4096 Apr 29 22:53 debug
    -rw-rw-r-- 1 taurus taurus  142 Apr 29 21:40 main.cpp
    -rw-rw-r-- 1 taurus taurus   28 Apr 29 21:40 pch.h
    [[email protected] pchtest]$ cd cmake/
    [[email protected] cmake]$ rm -fr *
    [[email protected] cmake]$ cp -r ~/develop/CM
    cmake/            CMakePCHCompiler/ cmoss/            
    [[email protected] cmake]$ cp -r ~/develop/CMak
    cmake/            CMakePCHCompiler/ 
    [[email protected] cmake]$ cp -r ~/develop/CMakePCHCompiler .
    [[email protected] cmake]$ ll
    total 4
    drwxrwxr-x 4 taurus taurus 4096 Apr 29 22:54 CMakePCHCompiler
    [[email protected] cmake]$ cd ../debug/
    [[email protected] debug]$ make
    /usr/bin/cmake -S/home/taurus/tmp/pchtest -B/home/taurus/tmp/pchtest/debug --check-build-system CMakeFiles/Makefile.cmake 0
    -- Configuring done
    CMake Debug Log at CMakeLists.txt:19 (target_link_libraries):
      Used includes for target pchtest:
    
       * /usr/include/qt5
       * /usr/include/qt5/QtCore
       * /usr/lib64/qt5/mkspecs/linux-g++
    
    
    
    CMake Debug Log at CMakeLists.txt:19 (target_link_libraries):
      Used includes for target pchtest:
    
       * /usr/include/qt5/QtGui
       * /usr/include
    
    
    
    CMake Debug Log at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:110 (set_target_properties):
      Used includes for target pchtest.pch:
    
       * /usr/include/qt5
       * /usr/include/qt5/QtCore
       * /usr/lib64/qt5/mkspecs/linux-g++
    
    Call Stack (most recent call first):
      CMakeLists.txt:20 (target_precompiled_header)
    
    
    CMake Debug Log at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:110 (set_target_properties):
      Used includes for target pchtest.pch:
    
       * /usr/include/qt5/QtGui
       * /usr/include
    
    Call Stack (most recent call first):
      CMakeLists.txt:20 (target_precompiled_header)
    
    
    -- Generating done
    -- Build files have been written to: /home/taurus/tmp/pchtest/debug
    /usr/bin/cmake -E cmake_progress_start /home/taurus/tmp/pchtest/debug/CMakeFiles /home/taurus/tmp/pchtest/debug/CMakeFiles/progress.marks
    make -f CMakeFiles/Makefile2 all
    make[1]: Entering directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch_autogen.dir/build.make CMakeFiles/pchtest.pch_autogen.dir/depend
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    cd /home/taurus/tmp/pchtest/debug && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch_autogen.dir/DependInfo.cmake --color=
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch_autogen.dir/build.make CMakeFiles/pchtest.pch_autogen.dir/build
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    [ 14%] Automatic MOC for target pchtest.pch
    /usr/bin/cmake -E cmake_autogen /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch_autogen.dir/AutogenInfo.cmake Debug
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    [ 14%] Built target pchtest.pch_autogen
    make -f CMakeFiles/pchtest.pch.dir/build.make CMakeFiles/pchtest.pch.dir/depend
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    cd /home/taurus/tmp/pchtest/debug && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug /home/taurus/tmp/pchtest/debug/CMakeFiles/pchtest.pch.dir/DependInfo.cmake --color=
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make -f CMakeFiles/pchtest.pch.dir/build.make CMakeFiles/pchtest.pch.dir/build
    make[2]: Entering directory '/home/taurus/tmp/pchtest/debug'
    [ 28%] Building CXX object CMakeFiles/pchtest.pch.dir/pchtest.pch_autogen/mocs_compilation.cpp.o
    /usr/lib64/ccache/c++  -DQT_CORE_LIB -DQT_GUI_LIB -I/home/taurus/tmp/pchtest/debug -I/home/taurus/tmp/pchtest -I/home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtCore -isystem /usr/lib64/qt5/mkspecs/linux-g++ -isystem /usr/include/qt5/QtGui  -std=c++11 -g   -fPIC -std=gnu++11 -o CMakeFiles/pchtest.pch.dir/pchtest.pch_autogen/mocs_compilation.cpp.o -c /home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/mocs_compilation.cpp
    [ 42%] Building CXXPCH object CMakeFiles/pchtest.pch.dir/pch.h.gch
    /usr/lib64/ccache/c++  -DQT_CORE_LIB -DQT_GUI_LIB -I/home/taurus/tmp/pchtest/debug -I/home/taurus/tmp/pchtest -I/home/taurus/tmp/pchtest/debug/pchtest.pch_autogen/include -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtCore -isystem /usr/lib64/qt5/mkspecs/linux-g++ -isystem /usr/include/qt5/QtGui -isystem /usr/include  -std=c++11 -g   -fPIC -x c++-header -o CMakeFiles/pchtest.pch.dir/pch.h.gch -c /home/taurus/tmp/pchtest/pch.h
    In file included from /usr/include/c++/8/bits/stl_algo.h:59,
                     from /usr/include/c++/8/algorithm:62,
                     from /usr/include/qt5/QtCore/qglobal.h:142,
                     from /usr/include/qt5/QtCore/qcoreapplication.h:43,
                     from /usr/include/qt5/QtCore/QCoreApplication:1,
                     from /home/taurus/tmp/pchtest/pch.h:1:
    /usr/include/c++/8/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
     #include_next <stdlib.h>
                   ^~~~~~~~~~
    compilation terminated.
    make[2]: *** [CMakeFiles/pchtest.pch.dir/build.make:79: CMakeFiles/pchtest.pch.dir/pch.h.gch] Error 1
    make[2]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make[1]: *** [CMakeFiles/Makefile2:114: CMakeFiles/pchtest.pch.dir/all] Error 2
    make[1]: Leaving directory '/home/taurus/tmp/pchtest/debug'
    make: *** [Makefile:87: all] Error 2
    

    PCH adds -isystem /usr/include which missing in normal compilation process. This flag comes from Qt5::Gui library.

    wontfix 
    opened by drizt 7
  • -iframework flag is not applied for pch target

    -iframework flag is not applied for pch target

    Problem. Compilation error on macOS

    pch compilation command:

    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++  -DHAVE_QT5 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_CAST_FROM_ASCII -DQT_WIDGETS_LIB -I/Users/taurus/devel/torrent-file-editor -I/Users/taurus/devel/torrent-file-editor/test -I/Library/Frameworks/Sparkle.framework/Headers -isystem /usr/local/Qt/5.5/clang_64/lib/QtCore.framework -isystem /usr/local/Qt/5.5/clang_64/lib/QtCore.framework/Headers -isystem /usr/local/Qt/5.5/clang_64/./mkspecs/macx-clang -isystem /usr/local/Qt/5.5/clang_64/lib/QtGui.framework -isystem /usr/local/Qt/5.5/clang_64/lib/QtGui.framework/Headers -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/OpenGL.framework/Headers -isystem /usr/local/Qt/5.5/clang_64/lib/QtWidgets.framework -isystem /usr/local/Qt/5.5/clang_64/lib/QtWidgets.framework/Headers  -stdlib=libc++ -Wall -Wextra -pedantic -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -mmacosx-version-min=10.7   -std=gnu++11 -fPIC -x c++-header -o CMakeFiles/torrent-file-editor.pch.dir/pch.h.pch -c /Users/taurus/devel/torrent-file-editor/pch.h
    

    But must be something link

    clang++  -DHAVE_QT5 -DQT_CORE_LIB -DQT_GUI_LIB -DQT_NO_CAST_FROM_ASCII -DQT_WIDGETS_LIB -I../ -I. -I/Library/Frameworks/Sparkle.framework/Headers -iframework /usr/local/Qt/5.5/clang_64/lib -isystem /usr/local/Qt/5.5/clang_64/lib/QtCore.framework/Headers -isystem /usr/local/Qt/5.5/clang_64/./mkspecs/macx-clang -isystem /usr/local/Qt/5.5/clang_64/lib/QtGui.framework/Headers -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/System/Library/Frameworks/OpenGL.framework/Headers -isystem /usr/local/Qt/5.5/clang_64/lib/QtWidgets.framework/Headers -stdlib=libc++ -Wall -Wextra -pedantic -g -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk -mmacosx-version-min=10.7   -F/Library/Frameworks  -include /Users/taurus/devel/torrent-file-editor/pch.h -fPIC -std=gnu++11 -MD -MT CMakeFiles/torrent-file-editor.dir/datewidget.cpp.o -MF CMakeFiles/torrent-file-editor.dir/datewidget.cpp.o.d -o CMakeFiles/torrent-file-editor.dir/datewidget.cpp.o -c ../datewidget.cpp
    

    Second command has -iframework /usr/local/Qt/5.5/clang_64/lib. In first command this flag is missing. You can look error on Travis.

    CMake generator has complex rules to make includes flags. CMake sources. CMake generator loop over includes dirs and tries to find directory where frameworks are placed. So if it see /usr/local/Qt/5.5/clang_64/lib/QtGui.framework it drop last path part i.e. new string will be /usr/local/Qt/5.5/clang_64/lib then prepend it with -iframework.

    On /usr/local/Qt/5.5/clang_64/lib/QtGui.framework input. Output will be: -iframework /usr/local/Qt/5.5/clang_64/lib.

    I don't know why such transformation is not applied for pch target.

    bug 
    opened by drizt 6
  • get_target_property() called with non-existent target

    get_target_property() called with non-existent target "NOTFOUND".

    I'm porting a rather large code base CMake and shopping around for a precompiled header solution. Yours seems like the cleanest, but I've had no luck getting it to work.

    When I attempt to add a precompiled header to any of my targets, I get the following two errors repeated for several thousand lines. CMake version 3.2.3. Since the stack isn't real, I don't know how to start debugging the issue. Any assistance would be appreciated.

    CMake Error at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:229 (get_target_property):
      get_target_property() called with non-existent target "NOTFOUND".
    Call Stack (most recent call first):
      Some weird path:9999 (__watch_pch_last_hook)
    
    
    CMake Error at cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:236 (set_target_properties):
      set_target_properties Can not find target to add properties to:
      NOTFOUND.pch
    Call Stack (most recent call first):
      Some weird path:9999 (__watch_pch_last_hook)
    
    opened by parkercoates 6
  • Fix for NOTFOUND issue in some (or all) cases.

    Fix for NOTFOUND issue in some (or all) cases.

    Check that the CMAKE_PCH_COMPILER_TARGETS is not empty.

    You may not want to indent this, or might know how to fix the RANGE parameters instead. I'm new to Github and CMake.

    In a nontrivial project tree the root may not have any targets, and some of the sub-directories might not use precompiled headers.

    This appears to work for one precompiled header in one sub-directory. I will be back if sub-directories clash.

    opened by mick-p1982 5
  • Fixes for VS2015 and CMake 3.0

    Fixes for VS2015 and CMake 3.0

    • Use full paths to include files and pch files.
    • Link to output lib for MSVC 2015
    • Add missing CMake 3.0.2+ flags.

    There might be a better way of doing this (I'm not a cmake guru), but this changes for things working for me.

    opened by cdglove 4
  • CMakePCHCompiler doesnt check for header dependency updates

    CMakePCHCompiler doesnt check for header dependency updates

    hi,

    I use CMakePCHCompiler to generate a pch file from a header file which points to a number of sub header files. One problem I've been facing is that when I update one of my subheaders, cmake doesn't seem to know that it needs to recompile the main header file into pch. as a result I will frequently deal with compilation issues unless I do a make clean.

    If there are any already built-in features which i am not aware of that will cause the main pch file to recompile after some manually speciified file changes, please let me know.

    Thanks in advance.

    wontfix 
    opened by lolidontknowwhatimdoing 4
  • Wrong C++ standard - GNU extensions enabled in PCH file but disabled in CMake

    Wrong C++ standard - GNU extensions enabled in PCH file but disabled in CMake

    On macOS, using brew llvm, it's setting the -std=gnu++17 flag instead of the -std=c++17 flag I use for the rest of the project and I get the following error when it actually uses the pch: 'GNU extensions was enabled in PCH file but is currently disabled'.

    bug 
    opened by martinhanzik 3
  • Support multiple configurations/platforms in Visual Studio

    Support multiple configurations/platforms in Visual Studio

    To avoid issues when switching configurations/platforms in Visual Studio, store the pch in a directory based on the $(Configuration) and $(Platform) macros.

    opened by 0x1F9F1 1
  • Setting CMAKE_CXX_STANDARD leads to error

    Setting CMAKE_CXX_STANDARD leads to error

    Setting CMAKE_CXX_STANDARD leads to error

    Minimal CMakeLists.txt example reproducing bug or showing requested feature:

    cmake_minimum_required(VERSION 3.0)
    
    # Choose C++ standard
    set(CMAKE_CXX_STANDARD 17)
    
    list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/CMakePCHCompiler)
    
    project(pchtest CXX CXXPCH)
    
    add_library(engine src/engine.cpp src/library.cpp)
    target_precompiled_header(engine src/prefix.h)
    
    add_executable(demo src/demo.cpp)
    target_link_libraries(demo engine)
    target_precompiled_header(demo src/prefix.h REUSE engine)
    

    Leads to error:

    CMake Error at /home/user/workspace/CMakePCHCompiler/CMakePCHCompiler.cmake:116 (add_library):
      CXXPCH_STANDARD is set to invalid value '17'
    Call Stack (most recent call first):
      CMakeLists.txt:10 (target_precompiled_header)
    

    Additional information

    • OS [Ubuntu]
    • CMake version [3.14.1]
    • Compiler type and version [GCC 7.2]
    opened by chronoxor 1
  • OpenGL::GL causes build failure

    OpenGL::GL causes build failure

    For some reason, using target_link_libraries(... OpenGL::GL) causes -isystem /usr/include to be added to the PCH build, which apparently causes breakage:

    /usr/include/c++/8.3.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
     #include_next <stdlib.h>
                   ^~~~~~~~~~
    compilation terminated.
    

    This doesn't seem to be added to the actual build (e.g., does not occur in compile_commands.json).

    Minimal example

    Minimal CMakeLists.txt example reproducing bug or showing requested feature:

    cmake_minimum_required(VERSION 3.11)
    
    list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake/CMakePCHCompiler)
    
    project(test CXX CXXPCH)
    
    find_package(OpenGL REQUIRED COMPONENTS OpenGL)
    
    add_executable(demo demo.cpp)
    target_link_libraries(demo PRIVATE
      OpenGL::GL
      )
    
    target_precompiled_header(demo prefix.h)
    

    Of course, one must have some minimal prefix.h:

    #include <cstdlib>
    

    This is the only difference:

    $ /usr/bin/g++   -isystem /usr/include  -O3 -DNDEBUG   -x c++-header -o CMakeFiles/demo.pch.dir/prefix.h.gch -c /home/rpav/tmp/test/prefix.h
    
    
    In file included from /home/rpav/tmp/test/prefix.h:1:
    /usr/include/c++/8.3.0/cstdlib:75:15: fatal error: stdlib.h: No such file or directory
     #include_next <stdlib.h>
                   ^~~~~~~~~~
    compilation terminated.
    $ /usr/bin/g++  -O3 -DNDEBUG   -x c++-header -o CMakeFiles/demo.pch.dir/prefix.h.gch -c /home/rpav/tmp/test/prefix.h
    $
    

    Additional information

    • OS: Linux (Arch, current)
    • CMake version 3.14.4
    • Compiler type and version: gcc-8.3 (also clang-8.0)
    • Additional Libraries used: Platform GL (nvidia)
    opened by rpav 2
  • PCH breaks clang code model in Qt Creator.

    PCH breaks clang code model in Qt Creator.

    It's not CMakePCHCompiler problem. It's common. Qt Creator uses clang to have good syntax higlighting. This option is optional but by default it's enabled. This means Qt Creator compiles each file with clang with compile options which set by CMake project + plus something set in Qt Creator settings. For example. I use such command to compile my file

    g++ -g -O2 -DFOO=bar -Wall -include CMakeFiles/pch.dir/pch.h -o main.cpp.o -c main.cpp
    

    Qt Creator based on this command use such command to parse main.cpp

    clang++ -g -O2 -DFOO=bar -Wall -include CMakeFiles/pch.dir/pch.h -pedantic -o main.cpp.o -c main.cpp
    

    This command fails due gcc pch format is not compatible with clang pch format. So Qt Creator can't parse main.cpp and colorize source code. I opened QTCREATORBUG-22427. Also I found a workaround for this. Need to put pch.h near with pch.h.gch and compile sources with -Wno-invalid-pch

    opened by drizt 0
  • Alternative to separate CXXPCH compiler definition

    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.

    enhancement question 
    opened by drizt 8
  • Doesn't work on linux cmake 3.10.2

    Doesn't work on linux cmake 3.10.2

    -- The C compiler identification is GNU 7.3.0 -- The CXX compiler identification is GNU 7.3.0 -- Could not determine Eclipse version, assuming at least 3.6 (Helios). Adjust CMAKE_ECLIPSE_VERSION if this is wrong. -- Check for working C compiler: /usr/bin/cc -- Check for working C compiler: /usr/bin/cc -- works -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Detecting C compile features -- Detecting C compile features - done -- Check for working CXX compiler: /usr/bin/c++ -- Check for working CXX compiler: /usr/bin/c++ -- works -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Warning at build/cmake/CMakePCHCompiler/CMakePCHCompiler.cmake:39 (message): Precompiled headers not supported for Call Stack (most recent call first): src/librender/CMakeLists.txt:9 (target_precompiled_header) -- Generating done

    Looking at the source it is missing CMAKE_PCH_COMPILER_LANGUAGE

    If I set CMAKE_PCH_COMPILER_LANGUAGE to CXX the following error comes up:

    CMake Error: Error required internal CMake variable not set, cmake may not be built correctly. Missing variable is: CMAKE_CXXPCH_COMPILE_OBJECT

    bug details needed 
    opened by EngiBob 3
Owner
Adam Strzelecki
PET / CBCT / HPC Engineer, PhD
Adam Strzelecki
cmake-font-lock - Advanced, type aware, highlight support for CMake

cmake-font-lock - Advanced, type aware, highlight support for CMake

Anders Lindgren 39 Oct 2, 2022
📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Setup-free CMake dependency management CPM.cmake is a CMake script that adds dependency management capabilities to CMake. It's built as a thin wrapper

CPM.cmake 1.6k Jan 9, 2023
CMake checks cache helper modules – for fast CI CMake builds!

cmake-checks-cache Cross platform CMake projects do platform introspection by the means of "Check" macros. Have a look at CMake's How To Write Platfor

Cristian Adam 65 Dec 6, 2022
CMake scripts for painless usage of SuiteSparse+METIS from Visual Studio and the rest of Windows/Linux/OSX IDEs supported by CMake

CMake scripts for painless usage of Tim Davis' SuiteSparse (CHOLMOD,UMFPACK,AMD,LDL,SPQR,...) and METIS from Visual Studio and the rest of Windows/Lin

Jose Luis Blanco-Claraco 395 Dec 24, 2022
cmake-avr - a cmake toolchain for AVR projects

cmake-avr - a cmake toolchain for AVR projects Testing the example provided The toolchain was created and tested within the following environment: Lin

Matthias Kleemann 163 Dec 5, 2022
Make CMake less painful when trying to write Modern Flexible CMake

Izzy's eXtension Modules IXM is a CMake library for writing Modern flexible CMake. This means: Reducing the amount of CMake written Selecting reasonab

IXM 107 Sep 1, 2022
CMake module to enable code coverage easily and generate coverage reports with CMake targets.

CMake-codecov CMake module to enable code coverage easily and generate coverage reports with CMake targets. Include into your project To use Findcodec

HPC 82 Nov 30, 2022
unmaintained - CMake module to activate certain C++ standard, feature checks and appropriate automated workarounds - basically an improved version of cmake-compile-features

Compatibility This library provides an advanced target_compile_features() and write_compiler_detection_header(). The problem with those is that they a

Jonathan Müller 74 Dec 26, 2022
[CMake] [BSD-2] CMake module to find ICU

FindICU.cmake A CMake module to find International Components for Unicode (ICU) Library Note that CMake, since its version 3.7.0, includes a FindICU m

julp 29 Nov 2, 2022
CMake macro to determine the language of a header file

CMake Determine Header Language CMake macro to determine the language of a header file. Status Travis CI (Ubuntu) AppVeyor (Windows) Coverage Biicode

ポリ平方 POLYSQUARE 4 Dec 7, 2018
custom lua godot engine module

Godot Lua Module Table of contents: About Features TODO Compiling Examples Contributing And Feature Requests About This is a Godot engine module that

Trey Moller 65 Jan 7, 2023
CMake project for BL602 RISC-V processor

bl602_cmake_base CMake project for BL602 RISC-V processor How to build NOTE : This project uses a pre-compiled version of the Buffalo SDK (bl_iot_sdk)

null 9 Jan 6, 2022
A CMake toolchain file for iOS, macOS, watchOS & tvOS C/C++/Obj-C++ development

A CMake toolchain file for iOS, macOS, watchOS & tvOS C/C++/Obj-C++ development

Alexander Widerberg 1.4k Jan 4, 2023
curl cmake module libcurl build with msvc x86

curl-msvc Infomation curl cmake module libcurl build with MSVC10.0 arch (x86 | i386) source from https://github.com/curl/curl tags: curl-7_79_1 Usage

Jason Payne 0 May 16, 2022
NeoWorld is a resampler using the CMake build system

NeoWorld is a resampler using the CMake build system. It's designed for utsu, OpenUTAU, and UTAU.

null 5 Dec 23, 2022
A CMake addon that avoids you writing boilerplate code for resource management.

SHader INJ(I)ector SHINJI (originally SHader INJector) is a CMake addon that avoids you writing boilerplate code for resource management and exposes s

Lorenzo Rutayisire 6 Dec 14, 2022
A CMake starter template using CPM

Cmake Starter About A lightweight Cmake project meant for a binary application (not a shared library), tests with catch2 are configured, CPM is the pa

Matt Williams 1 Jul 14, 2022
Non-intrusive CMake dependency management

cmodule Non-intrusive CMake dependency management. Normally CMake's find_package() looks for packages installed on host system (and compiled for host

scapix.com 14 Sep 29, 2022
Simple library for embedding static resources into C++ binaries using CMake

libromfs libromfs is an easy way to bundle resources directly into any C++ application and access them through a simple interface. The main advantage

WerWolv 28 Nov 30, 2022