Cmake在windows支持预编译头文件(stdafx.h)

时间:2022-06-06
本文章向大家介绍Cmake在windows支持预编译头文件(stdafx.h),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

      最近一直在研究cmake构建项目,之前接触cmake的时候就感觉不太喜欢cmake,觉得它太乱了,产生了太多的中间文件,产生的项目文件也不是特别友好,在windows下,生成的项目文件经常需要修改,而在linux和常规的makefile风格也打不一致,文件太多,不方便学习研究。

      不够经过这段时间系统的研究,觉得cmake还是非常强大的,吃透之后它的确非常方便,比手工写makefile要简单的多,因此在linux使用cmake我觉得是非常合适的,不过在windows则相对要差一些。cmake的主要优势在于自动生成项目文件,如果熟练掌握,对于自动构架项目还是有很大帮助的。

      本文主要讲下在windows下使用cmake给项目添加预编译头文件功能,做过windows项目的同学都知道,windows下使用预编译头文件非常普遍,能加快编译速度,一些头文件交叉引用问题也能使用它来解决,但是cmake对这块支持不是很完善,资料也很少,我在网上查询了很久,才找到一个合适的方案,下面就详细讲下这个方案。

      为了复用预编译这个功能,我们把预编译相关的cmake功能编写成一个文件,比如叫msvcpch.cmake。

#msvcpch.cmake
#声明一个宏,参数如下
#USE_MSVC_PCH        :宏名字
#PCH_TARGET          :项目名称
#PCH_HEADER_FILE     :预编译头文件名称(stdafx.h)
#PCH_SOURCE_FILE     :预编译源文件名称(stdafx.cpp)
MACRO(USE_MSVC_PCH PCH_TARGET PCH_HEADER_FILE PCH_SOURCE_FILE)
IF(MSVC)
	# 获取预编译头文件的文件名,通常是stdafx
	GET_FILENAME_COMPONENT(PCH_NAME ${PCH_HEADER_FILE} NAME_WE)
	
	# 生成预编译文件的路径
	IF(CMAKE_CONFIGURATION_TYPES)
  	# 如果有配置选项(Debug/Release),路径添加以及配置选项
		SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH/${CMAKE_CFG_INTDIR}")
	ELSE(CMAKE_CONFIGURATION_TYPES)
		SET(PCH_DIR "${CMAKE_CURRENT_BINARY_DIR}/PCH")
	ENDIF(CMAKE_CONFIGURATION_TYPES)
 
	# 创建预编译文件的路径
	FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/PCH)
 
	# 设置项目属性,使用预编译头文件
	SET_TARGET_PROPERTIES(${PCH_TARGET} PROPERTIES COMPILE_FLAGS 
		"/Yu${PCH_HEADER_FILE} /FI${PCH_HEADER_FILE} /Fp${PCH_DIR}/${PCH_NAME}.pch")
 
	# 预编译源文件(stdafx.cpp)设置属性,创建预编译文件
	SET_SOURCE_FILES_PROPERTIES(${PCH_SOURCE_FILE} PROPERTIES COMPILE_FLAGS
		"/Yc${PCH_HEADER_FILE}")
    
	# 把预编译文件寄到清除列表
	SET_DIRECTORY_PROPERTIES(PROPERTIES
		ADDITIONAL_MAKE_CLEAN_FILES ${PCH_DIR}/${PCH_NAME}.pch)
ENDIF(MSVC)
ENDMACRO(USE_MSVC_PCH)

需要注意的是,PCH_HEADER_FILE (stdafx.h)不需要路径,只传文件名即可,而PCH_SOURCE_FILE(stdafx.cpp)则需要传完整路径,即在VS项目文件(.vcxproj)中能访问的正确路径,可以是相对路径,也可以绝对路径。

      编写好这个文件之后,我们以后写cmake文件的时候可以可以直接引用它了。如下则是使用的示例:

if (CMAKE_SYSTEM_NAME MATCHES "Windows")
	# msvcpch.cmake的路径
	set(MSVCCMAKE_PCH ${CMAKE_SOURCE_DIR}/build/)
	# 预编译头文件和源文件的路径
	set(STDAFX_PCH_H ${CMAKE_SOURCE_DIR}/Protocol/stdafx.h)
	set(STDAFX_PCH_C ${CMAKE_SOURCE_DIR}/Protocol/stdafx.cpp)	
	
	# 添加预编译cmake的路径
	LIST(APPEND CMAKE_MODULE_PATH ${MSVCCMAKE_PCH})
	# 包含msvcpch.cmake
	INCLUDE(msvcpch)
endif ()
 
 
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
	# 添加源文件,生成可执行文件
	add_executable(Proxy ${proxy_src} ${STDAFX_PCH_C})
	# 添加链接库
	target_link_libraries(Proxy Comm)	
	# 此处是关键,添加我们在msvcpch.cmake定义的宏
	USE_MSVC_PCH(Proxy stdafx.h ${STDAFX_PCH_C})
endif ()

好了,使用上面的方法就可以给vs的工程添加预编译头文件的支持了。