You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CMake中如何配置仅让指定源文件集合使用预编译头?

解决CMake预编译头的选择性应用问题

我来帮你搞定这个预编译头的配置需求~你现在的问题是ONLY_FOR_SRC不是CMake内置的生成表达式,所以完全不会生效。要实现仅让SRC中的源文件使用stdafx.h预编译头,SRC2中的文件不使用,我们需要用CMake提供的生成表达式来精准匹配目标文件集合。

正确的配置方案

首先,为了避免路径匹配的歧义(相对/绝对路径不一致),先把SRC和SRC2转成绝对路径:

file(GLOB SRC *.cpp)
list(TRANSFORM SRC PATH_TO_ABSOLUTE)  # 转成绝对路径,确保匹配准确

file(GLOB SRC2 ../xx/*.cpp)
list(TRANSFORM SRC2 PATH_TO_ABSOLUTE)

然后,使用$<IN_LIST>生成表达式来判断当前编译的文件是否属于SRC集合,替换掉原来的ONLY_FOR_SRC:

target_precompile_headers(myapp PRIVATE "$<$<IN_LIST:$<PATH:ABSOLUTE,__FILE__>,${SRC}>:stdafx.h>")

原理说明

  • $<PATH:ABSOLUTE,__FILE__>:获取当前正在编译的源文件的绝对路径,__FILE__是CMake生成表达式中代表当前编译文件的特殊变量。
  • $<IN_LIST:X,Y>:判断X是否存在于列表Y中,这里就是检查当前文件的绝对路径是否在SRC的绝对路径列表里。
  • 整个$<...:stdafx.h>是一个条件生成表达式:当条件成立时,会把stdafx.h作为预编译头应用到当前文件;条件不成立时则忽略。

简化版(可选)

如果你的SRC确实都是当前CMakeLists.txt所在目录下的.cpp文件,也可以不用转绝对路径,直接通过路径父目录判断:

target_precompile_headers(myapp PRIVATE "$<$<STREQUAL:$<PATH:GET_PARENT_PATH,$<PATH:ABSOLUTE,__FILE__>>,$<PATH:ABSOLUTE,${CMAKE_CURRENT_SOURCE_DIR}>>:stdafx.h>")

这个表达式的逻辑是:检查当前文件的父目录是否等于当前CMakeLists.txt所在的目录,是的话就应用预编译头。不过这种方法不如直接匹配SRC列表灵活,如果后续SRC的范围调整,需要同步修改条件,所以更推荐第一种基于列表匹配的方案。

内容的提问来源于stack exchange,提问作者Hyunjik Bae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 06:54:58