我需要将我的程序与Kerberos身份验证库(gssapi_krb5
)链接,并在源文件中包含相应的标头gssapi/gssapi.h
和gssapi/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。 我怎么能让这段代码工作?谢谢!
答案 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
的宏。