Glu*_*ous 99 c++ gcc cmake precompiled-headers visual-studio
我在网上看到了一些关于在CMake中对预编译头文件进行黑客攻击的一些(旧)帖子.它们看起来都有点遍布整个地方,每个人都有自己的方式.目前最好的方法是什么?
sak*_*kra 78
有一个名为"Cotire"的第三方CMake模块可以自动使用基于CMake的构建系统的预编译头,并且还支持统一构建.
lar*_*moa 35
我使用以下宏来生成和使用预编译头:
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)
Run Code Online (Sandbox Code Playgroud)
假设你有一个带有所有源文件的变量$ {MySources},你想要使用的代码就是
ADD_MSVC_PRECOMPILED_HEADER("precompiled.h" "precompiled.cpp" MySources)
ADD_LIBRARY(MyLibrary ${MySources})
Run Code Online (Sandbox Code Playgroud)
代码在非MSVC平台上仍然可以正常运行.很简约 :)
Dav*_*ier 20
这是一个代码片段,允许您为项目使用预编译头.将以下内容添加到您的CMakeLists.txt中,myprecompiledheaders并myproject_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)
Run Code Online (Sandbox Code Playgroud)
小智 13
我最终使用了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})
Run Code Online (Sandbox Code Playgroud)
mar*_*jno 13
改编自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)
Run Code Online (Sandbox Code Playgroud)
CMake刚刚获得了对PCH的支持,应该在2019年10月1日到期的即将发布的3.16版本中可用:
https://gitlab.kitware.com/cmake/cmake/merge_requests/3553
target_precompile_headers(<target>
<INTERFACE|PUBLIC|PRIVATE> [header1...]
[<INTERFACE|PUBLIC|PRIVATE> [header2...] ...])
Run Code Online (Sandbox Code Playgroud)
关于支持在目标之间共享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/中提供了一些其他上下文(动机,数字)
如果你不想推倒重来,只使用两种Cotire作为顶端回答暗示或简单的一个- 的cmake-预编译头 在这里.要使用它只需包含模块并调用:
include( cmake-precompiled-header/PrecompiledHeader.cmake )
add_precompiled_header( targetName StdAfx.h FORCEINCLUDE SOURCE_CXX StdAfx.cpp )
Run Code Online (Sandbox Code Playgroud)
Dir*_*eld -18
甚至不要去那里。预编译标头意味着每当标头之一发生更改时,您都必须重建所有内容。如果您有一个能够实现这一点的构建系统,那么您很幸运。通常情况下,您的构建会失败,直到您意识到您更改了正在预编译的某些内容,因此您需要进行完全重建。您可以通过预编译您绝对不会改变的标头来避免这种情况,但这样您也会放弃很大一部分速度增益。
另一个问题是,您的命名空间会被各种您不知道或不关心的符号污染,而这些符号在您使用预编译头的许多地方都是不知道或不关心的。