当前位置:  开发笔记 > 编程语言 > 正文

使用CMake预编译的头文件

如何解决《使用CMake预编译的头文件》经验,为你挑选了7个好方法。

我在网上看到了一些关于在CMake中对预编译头文件进行黑客攻击的一些(旧)帖子.它们看起来都有点遍布整个地方,每个人都有自己的方式.目前最好的方法是什么?



1> sakra..:

有一个名为"Cotire"的第三方CMake模块可以自动使用基于CMake的构建系统的预编译头,并且还支持统一构建.


+1导致我cotire.这是一件非常好的工作.
@onqtam这么简单,它是如此庞大,以至于我什至都看不到如何简单地使用cmake和gcc进行预编译

2> larsmoa..:

我使用以下宏来生成和使用预编译头:

MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
  IF(MSVC)
    GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
    SET(PrecompiledBinary "${CMAKE_CURRENT_BINARY_DIR}/${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)

假设你有一个带有所有源文件的变量$ {MySources},你想要使用的代码就是

ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
ADD_LIBRARY(MyLibrary ${MySources})

代码在非MSVC平台上仍然可以正常运行.很简约 :)


请注意,/ Yu的论据是非常字面的.例如`/ YuC:/ foo/bar.h`将强制您传递`/ FpC:/ foo/bar.h`标志或将`#include `放在顶部将所有.cpp文件作为第一个include语句.MSVC对`#include`参数进行字符串比较,它不检查它是否指向与给`/ Yu`相同的文件.因此,`#include `将无效并发出错误C2857.

3> Dave Hillier..:

这是一个代码片段,允许您为项目使用预编译头.将以下内容添加到您的CMakeLists.txt中,myprecompiledheadersmyproject_SOURCE_FILES在适当时替换:

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)



4> 小智..:

我最终使用了larsm宏的改编版本.对pch路径使用$(IntDir)可以使调试和发布版本的预编译头分开.

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})


$ {IntDir}抽象很有帮助.谢谢.

5> martjno..:

改编自Dave,但效率更高(设置目标属性,而不是每个文件):

if (MSVC)
   set_target_properties(abc PROPERTIES COMPILE_FLAGS "/Yustd.h")
   set_source_files_properties(std.cpp PROPERTIES COMPILE_FLAGS "/Ycstd.h")
endif(MSVC)


我曾经使用过这个解决方案,但它只适用于项目只包含c ++文件的情况.由于COMPILE_FLAGS应用于所有源文件,因此它也将应用于c文件(例如MIDL生成的文件),这些文件与c ++ PCH不同.使用Dave的解决方案时,您可以使用get_source_file_property(_language $ {src_file} LANGUAGE),并且只设置编译器标志(如果它确实是CXX文件).
可以使用[set_source_files_properties](http://www.cmake.org)[/Y- ](http://msdn.microsoft.com/en-us/library/1hy7a92h.aspx)为单个文件选择性地关闭它. /cmake/help/v2.8.12/cmake.html#command:set_source_files_properties)

6> janisozaur..:

CMake刚刚获得了对PCH的支持,应该在2019年10月1日到期的即将发布的3.16版本中可用:

https://gitlab.kitware.com/cmake/cmake/merge_requests/3553

  target_precompile_headers(
     [header1...]
    [ [header2...] ...])

关于支持在目标之间共享PCH的讨论正在进行中:https ://gitlab.kitware.com/cmake/cmake/issues/19659

https://blog.qt.io/blog/2019/08/01/precompiled-headers-and-unity-jumbo-builds-in-upcoming-cmake/中提供了一些其他上下文(动机,数字)



7> Roman Kruglo..:

如果你不想推倒重来,只使用两种Cotire作为顶端回答暗示或简单的一个- 的cmake-预编译头 在这里.要使用它只需包含模块并调用:

include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( targetName StdAfx.h FORCEINCLUDE SOURCE_CXX StdAfx.cpp )

推荐阅读
路人甲
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有