在CMake中指定显式头文件

Specify explicit header files in CMake

本文关键字:文件 CMake      更新时间:2023-10-16

我已经预编译了头文件stdafx.h,这是特定于每个目标。我的CMake项目大致如下所示:

include_directories(<prefix>/include_a)
include_directories(<prefix>/include_b)  #<---- contains stdafx.h that should NOT be used
include_directories(<project_dir>/)  #<----- contains stdafx.h that should be used
add_executable(<project_name> <sources>)

问题:我想排除作为<prefix>/include_b目录一部分的预编译头。如果不可能,那么显式地指定头文件。我知道gcc支持-include选项,但CMake是否有更干净的选项符合我的要求?

把我的评论变成答案

如果你不想强制包含文件(这不是CMake明确支持的),我认为答案在于你的包含路径的顺序。

首先这里是我用来重现你的问题的测试代码:

cmake_minimum_required(VERSION 3.0)
project(IncDirOrder)
file(WRITE "prefix/include_a/stdafx.h" "#error include_a/stdafx.h")
file(WRITE "prefix/include_b/stdafx.h" "#error include_b/stdafx.h")
file(WRITE "include/stdafx.h" "")
file(WRITE "main.cpp" "#include "stdafx.h"nint main() { return 0; }")
include_directories(prefix/include_a)
include_directories(prefix/include_b)  
include_directories(include)  
add_executable(${PROJECT_NAME} main.cpp)

影响包含路径顺序的可能解决方案

  1. 重新排序include_directories()调用(如果可能):

    include_directories(include)  
    include_directories(prefix/include_a)
    include_directories(prefix/include_b)  
    
  2. BEFORE关键词的使用:

    include_directories(BEFORE include)  
    

    target_include_directories(${PROJECT_NAME} BEFORE PUBLIC include)
    
  3. 假设其他预编译的头文件也附带一个库,我通常建议使用target_include_directories()。然后,您将自动获得所需的行为(本地包含确实优先于接口包含):

    cmake_minimum_required(VERSION 3.0)
    project(IncDirOrderWithLibs)
    file(WRITE "prefix/source_a/stdafx.cpp" "#define LibAn#include "stdafx.h"")
    file(WRITE "prefix/include_a/stdafx.h" "#ifndef LibAn#error include_a/stdafx.hn#endif")
    file(WRITE "prefix/source_b/stdafx.cpp" "#define LibBn#include "stdafx.h"")
    file(WRITE "prefix/include_b/stdafx.h" "#ifndef LibBn#error include_b/stdafx.hn#endif")
    file(WRITE "include/stdafx.h" "")
    file(WRITE "main.cpp" "#include "stdafx.h"nint main() { return 0; }")
    add_library(LibA "prefix/source_a/stdafx.cpp")
    target_include_directories(LibA PUBLIC prefix/include_a)
    add_library(LibB "prefix/source_b/stdafx.cpp")
    target_link_libraries(LibB LibA)
    target_include_directories(LibB PUBLIC prefix/include_b)
    add_executable(${PROJECT_NAME} main.cpp)
    target_link_libraries(${PROJECT_NAME} LibB)
    target_include_directories(${PROJECT_NAME} PRIVATE include)
    

引用

  • Cmake设置变量是递归的吗?
  • CMake Build System: Transitive Usage Requirements