如何在cmake中使用CHECK_INCLUDE_FILES宏?

时间:2013-09-15 03:47:34

标签: cmake

我需要将我的程序与Kerberos身份验证库(gssapi_krb5)链接,并在源文件中包含相应的标头gssapi/gssapi.hgssapi/gssapi_krb5.h

目前,如果标头不存在,编译将继续,并且编译时错误表示未找到标头文件。 我想在cmake文件中实现的是检查头文件是否存在,如果没有找到则停止编译。

我将以下代码添加到我的CMakeList.txt文件中。

INCLUDE(CheckIncludeFiles)

CHECK_INCLUDE_FILES(gssapi/gssapi.h;gssapi/gssapi_krb5.h HAVE_KRB_HEADERS)
IF (NOT HAVE_KRB_HEADERS)
    RETURN()
ENDIF (NOT HAVE_KRB_HEADERS)

但它仍然没有按照我的预期行事。 我想要以下几行:

-- Looking for gssapi/gssapi.h - found
-- Looking for gssapi/gssapi_krb5.h - not found

但失败了。 此外,使用HAVE_KRB_HEADERS宏输出时,变量message为空。 编译继续,直到发生上述错误。

我在网上某处读到,这可能是因为CMake缓存。 我对CMake很新,对这个概念不太清楚。 我的CMake版本是2.6。 我怎么能让这段代码工作?谢谢!

2 个答案:

答案 0 :(得分:5)

我不能说我是CheckIncludeFiles的忠实粉丝,因为它很难做对。原则上它是好的 - 它实际上创建了微小的c文件,#include请求的标题并尝试编译它们,但它似乎太容易出错。

我通常更喜欢使用find_path和/或find_file来完成这项工作。这不会检查找到的任何文件的内容,但通常如果找到所需的标题,则其内容很好!

如果我需要知道标题所在的文件夹,我会使用find_path。这通常是因为我需要检查同一文件夹中的其他文件(如您的情况),或者更常见的是因为我需要将文件夹添加到include_directories调用。

find_file生成文件的完整路径(如果找到)。对于标题,通常我不需要CMakeLists中其他位置的路径 - 它只是在find_file之后立即用来检查实际找到的文件。

所以,这就是我如何检查“gssapi / gssapi.h”和“gssapi / gssapi_krb5.h”

find_path(GssApiIncludes gssapi.h PATHS <list of folders you'd expect to find it in>)
if(NOT GssApiIncludes)
  message(FATAL_ERROR "Can't find folder containing gssapi.h")
endif()

find_file(GssKrb gssapi_krb5.h PATHS ${GssApiIncludes} NO_DEFAULT_PATH)
if(NOT GssKrb)
  message(FATAL_ERROR "Can't find gssapi_krb5.h in ${GssApiIncludes}")
endif()

如果您这样做,那么如果需要,您可以添加

include_directories(${GssApiIncludes})

这样你可以在你的源代码中做到

#include "gssapi.h"
#include "gssapi_krb5.h"

答案 1 :(得分:0)

对于必须使用CHECK_INCLUDE_FILES的任何人,文档中都会列出一个名为CMAKE_REQUIRED_INCLUDES的变量,您可以在其中设置除默认标头之外的其他包含路径。

LIST(APPEND CMAKE_REQUIRED_INCLUDES "gssapi")

如果其他所有方法均失败,则可以手动设置-I<dir>标志。但是,不建议这样做。

#note the extra space before `-I`
STRING(APPEND CMAKE_C_FLAGS " -Igssapi")
STRING(APPEND CMAKE_CXX_FLAGS " -Igssapi") #for C++

还请注意,C ++标头具有另一个称为CheckIncludeFileCXX的宏。