在CMake中指定显式头文件

时间:2016-09-18 19:15:24

标签: c++ gcc cmake

我有预编译的头文件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是否有更符合我要求的清洁选项?

1 个答案:

答案 0 :(得分:0)

将我的评论转化为答案

如果您不想强制包含文件(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 LibA\n#include \"stdafx.h\"")
    file(WRITE "prefix/include_a/stdafx.h" "#ifndef LibA\n#error include_a/stdafx.h\n#endif")
    file(WRITE "prefix/source_b/stdafx.cpp" "#define LibB\n#include \"stdafx.h\"")
    file(WRITE "prefix/include_b/stdafx.h" "#ifndef LibB\n#error include_b/stdafx.h\n#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)
    
  4. <强>参考