【问题标题】:Resolving competing include directories in CMake解决 CMake 中的竞争包含目录
【发布时间】:2019-05-17 17:24:35
【问题描述】:

我有一个需要两个外部库(boost 和 htslib)的 C++ 项目。我将库链接到我的项目目标octopus,如下所示:

find_package (Boost 1.65 REQUIRED COMPONENTS ${REQUIRED_BOOST_LIBRARIES} REQUIRED)
if (Boost_FOUND)
    target_include_directories (octopus PRIVATE ${Boost_INCLUDE_DIR})
    target_link_libraries (octopus ${Boost_LIBRARIES})
endif (Boost_FOUND)
find_package (HTSlib 1.4 REQUIRED)
if (HTSlib_FOUND)
    target_include_directories (octopus PRIVATE ${HTSlib_INCLUDE_DIRS})
    target_link_libraries (octopus ${HTSlib_LIBRARIES})
endif (HTSlib_FOUND)

boosthtslib 通常都安装在/usr/local 中,因此在/usr/local/include 中有头文件。但是,用户可以通过指定 CMake 变量 BOOST_ROOTHTSLIB_ROOT 来指定替代库位置。

问题在于,如果只为其中一个库提供了替代位置,则另一个链接库的包含目录中的头文件(例如在/usr/local/include 中)将包含在两个库中,如果无法比较的版本该库已安装,然后编译可能会失败。例如,如果我将BOOST_ROOT 设置为~/.linuxbrew,那么Boost_INCLUDE_DIR 正确设置为~/.linuxbrew/include,但HTSlib_INCLUDE_DIRS/usr/local/include,其中包含/usr/local/include/boost,出于我不太明白的原因,这些是用于构建的标头,即使它们与 ~/.linuxbrew/lib/boost 中的库不兼容。

如何确保链接库的包含目录仅用于该库?

【问题讨论】:

  • 你不能。您需要指定不重叠的文件夹。 (问题不在于 CMake,而在于文件系统)。
  • 与您的问题无关,但代码中的if(Xyz_FOUND) 条件是不必要的,因为您在find_package 调用中使用了REQUIRED。这意味着当找不到包时 CMake 将出错,因此在这种情况下甚至永远无法到达 ifs。

标签: c++ cmake


【解决方案1】:

考虑哪个头文件是包含目录顺序的问题 - 编译器通常会考虑与任何包含文件夹中的给定名称匹配的第一个文件。虽然您不能告诉编译器在一个特定目录中查找一个文件,而在另一个特定目录中查找另一个文件,但您可以在某种程度上确定包含目录的顺序。听起来在您的情况下,应该先检查 boost 包含目录,因此请尝试在 target_include_directories 调用中使用 BEFORE 关键字,如下所示:

target_include_directories (octopus BEFORE PRIVATE ${Boost_INCLUDE_DIR})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 2019-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多