CMake项目添加预编译头

本文主要记录为CMake项目添加预编译头支持,以及过程中遇到的坑,比如set_target_properties连续调用两次失效的问题。

各个编译器支持预编译头指令不同,这里仅以Visual Studio为例进行说明。

操作步骤

  • 创建cmake宏文件PrecompiledHeader.cmake
#-------------------------------------------------------
# Support macro to use a precompiled header
# Usage:
#   use_precompiled_header(TARGET HEADER_FILE SRC_FILE)
#-------------------------------------------------------

macro(use_precompiled_header TARGET HEADER_FILE SRC_FILE)
  get_filename_component(HEADER ${HEADER_FILE} NAME)

  # Use MSVC_IDE to exclude NMake from using PCHs
  if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD)

    set_property(TARGET ${TARGET} APPEND_STRING PROPERTY
      COMPILE_FLAGS " /Yu\"${HEADER}\"")
    set_property(TARGET ${TARGET} APPEND_STRING PROPERTY
      COMPILE_FLAGS " /FI\"${HEADER}\"")
    set_source_files_properties(${SRC_FILE}
      PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}")
  elseif (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGXX)
  endif ()
endmacro(use_precompiled_header)
  • 在主工程的CMakeLists.txt中添加依赖
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/Tools/CMake)
include(PrecompiledHeader)
  • 在需要使用预编译头的项目中调用use_precompiled_header宏函数
use_precompiled_header(${PROJECT_NAME}
    "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h"
    "${CMAKE_CURRENT_SOURCE_DIR}/stdafx.cpp")

踩坑记录

  • set_target_properties连续调用两次,导致前一次调用无效

PrecompiledHeader.cmake文件中,最开始使用了如下的代码

if (MSVC AND NOT NMAKE AND NOT OGRE_UNITY_BUILD)
    set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /Yu"${HEADER}")
    set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS /FI"${HEADER}")
    set_source_files_properties(${SRC_FILE}
      PPROPERTIES COMPILE_FLAGS /Yc"${HEADER}"
    )

可是发现永远只有/FI生效,后来查找了大量资料,替换为了set_property APPEND的形式,才最终解决。