Using pre-compiled headers with CMake

后端 未结 14 2153
刺人心
刺人心 2020-12-12 10:39

I have seen a few (old) posts on the \'net about hacking together some support for pre-compiled headers in CMake. They all seem a bit all-over the place and everyone has the

相关标签:
14条回答
  • 2020-12-12 10:58

    if you don't wanna reinvent the wheel, just use either Cotire as the top answer suggests or a simpler one - cmake-precompiled-header here. To use it just include the module and call:

    include( cmake-precompiled-header/PrecompiledHeader.cmake )
    add_precompiled_header( targetName StdAfx.h FORCEINCLUDE SOURCE_CXX StdAfx.cpp )
    
    0 讨论(0)
  • 2020-12-12 10:59

    Here is a code snippet to allow you to use precompiled header for your project. Add the following to your CMakeLists.txt replacing myprecompiledheaders and myproject_SOURCE_FILES as appropriate:

    if (MSVC)
    
        set_source_files_properties(myprecompiledheaders.cpp
            PROPERTIES
            COMPILE_FLAGS "/Ycmyprecompiledheaders.h"
            )
        foreach( src_file ${myproject_SOURCE_FILES} )
            set_source_files_properties(
                ${src_file}
                PROPERTIES
                COMPILE_FLAGS "/Yumyprecompiledheaders.h"
                )
        endforeach( src_file ${myproject_SOURCE_FILES} )
        list(APPEND myproject_SOURCE_FILES myprecompiledheaders.cpp)
    endif (MSVC)
    
    0 讨论(0)
  • 2020-12-12 10:59

    IMHO the best way is to set PCH for whole project, as martjno suggested, combined with ability of ignoring PCH for some sources if needed (e.g. generated sources):

    # set PCH for VS project
    function(SET_TARGET_PRECOMPILED_HEADER Target PrecompiledHeader PrecompiledSource)
      if(MSVC)
         SET_TARGET_PROPERTIES(${Target} PROPERTIES COMPILE_FLAGS "/Yu${PrecompiledHeader}")
         set_source_files_properties(${PrecompiledSource} PROPERTIES COMPILE_FLAGS "/Yc${PrecompiledHeader}")
      endif(MSVC)
    endfunction(SET_TARGET_PRECOMPILED_HEADER)
    
    # ignore PCH for a specified list of files
    function(IGNORE_PRECOMPILED_HEADER SourcesVar)
      if(MSVC)  
        set_source_files_properties(${${SourcesVar}} PROPERTIES COMPILE_FLAGS "/Y-")
      endif(MSVC)
    endfunction(IGNORE_PRECOMPILED_HEADER)
    

    So, if you have some target MY_TARGET, and list of generated sources IGNORE_PCH_SRC_LIST you'll simply do:

    SET_TARGET_PRECOMPILED_HEADER(MY_TARGET stdafx.h stdafx.cpp)
    IGNORE_PRECOMPILED_HEADER(IGNORE_PCH_SRC_LIST)
    

    This aproach is tested and works perfectly.

    0 讨论(0)
  • 2020-12-12 11:01

    I ended up using an adapted version of larsm macro. Using $(IntDir) for pch path keeps precompiled headers for debug and release builds separate.

    MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
      IF(MSVC)
        GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
        SET(PrecompiledBinary "$(IntDir)/${PrecompiledBasename}.pch")
        SET(Sources ${${SourcesVar}})
    
        SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
                                    PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                               OBJECT_OUTPUTS "${PrecompiledBinary}")
        SET_SOURCE_FILES_PROPERTIES(${Sources}
                                    PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeader}\" /FI\"${PrecompiledHeader}\" /Fp\"${PrecompiledBinary}\""
                                               OBJECT_DEPENDS "${PrecompiledBinary}")  
        # Add precompiled header to SourcesVar
        LIST(APPEND ${SourcesVar} ${PrecompiledSource})
      ENDIF(MSVC)
    ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
    
    ADD_MSVC_PRECOMPILED_HEADER("stdafx.h" "stdafx.cpp" MY_SRCS)
    ADD_EXECUTABLE(MyApp ${MY_SRCS})
    
    0 讨论(0)
  • 2020-12-12 11:05

    Don't even go there. Precompiled headers mean that whenever one of the headers changes, you have to rebuild everything. You're lucky if you have a build system that realizes this. More often than never, your build will just fail until you realize that you changed something that is being precompiled, and therefore you need to do a full rebuild. You can avoid this mostly by precompiling the headers that you are absolutely positive won't change, but then you're giving up a large part of the speed gain as well.

    The other problem is that your namespace gets polluted with all kinds of symbols that you don't know or care about in many places where you'd be using the precompiled headers.

    0 讨论(0)
  • 2020-12-12 11:06

    Well when builds take 10+ minutes on a quad core machine every time you change a single line in any of the project files it tells you its time to add precompiled headers for windows. On *nux I would just use ccache and not worry about that.

    I have implemented in my main application and a few of the libraries that it uses. It works great to this point. One thing that also is needed is you have to create the pch source and header file and in the source file include all the headers that you want to be precompiled. I did this for 12 years with MFC but it took me a few minutes to recall that..

    0 讨论(0)
提交回复
热议问题