【问题标题】:Specify explicit header files in CMake在 CMake 中指定显式头文件
【发布时间】:2016-09-18 19:15:24
【问题描述】:

我已经预编译了针对每个目标的头文件 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>)

问题:我想排除作为&lt;prefix&gt;/include_b 目录一部分的预编译头文件。如果那不可能,则明确指定头文件。我知道gcc 支持-include 选项,但是CMake 有什么更简洁的选项可以满足我的要求吗?

【问题讨论】:

  • 如果您不想强制包含文件(CMake 未明确支持;请参见例如here),我认为答案在于包含路径的顺序。隐藏在"CMake Build System: Transitive Usage Requirements" documentation 中的一个示例:请参阅“例如,如果目标的链接库必须按 lib1 lib2 lib3 的顺序指定,但包含目录...”。
  • stdafx.h 闻起来像 Visual Studio,但你没有放 msvc 标签?
  • @Florian 忘了更新这个,是的,事实上这就是我最终更改订单的原因。
  • @JohanBoule 是的,因为我正在为其他平台进行交叉编译

标签: c++ gcc cmake


【解决方案1】:

把我的评论变成答案

如果您不想强制包含文件(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)
    

参考文献

【讨论】:

    猜你喜欢
    • 2014-01-24
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-04
    • 1970-01-01
    相关资源
    最近更新 更多