8

我正在使用 cmake 来管理我的项目的编译,这是我第一次使用 cmake。这个工具非常方便,因为有大量的脚本和函数可以检查是否所有必要的库都安装在给定的计算机上。但是,有时,这些通用 sripts 不涵盖某些特定情况,或者它们对于给定的库根本不可用。我的问题如下:

什么是正确的 cmake 风格的方法来验证给定的头文件(hpp 或 h)在包含路径中是否可用?

理由:

最直接的方法可能是使用 CHECK_INCLUDE_FILE 宏。例如,如果我想使用 UnitTest++ 库,我可以编写

CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
  message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()

不幸的是,如果这样做,变量 HAVE_UNITTESTXX 将存储在缓存中。如果我在我的系统中安装 UnitTest++ 库,cmake 仍然会抱怨未安装 UnitTest++.h。我可以手动删除缓存,但标准的查找包功能不需要这样做。我也可以像这样升级代码

CHECK_INCLUDE_FILE_CXX("UnitTest++.h" HAVE_UNITTESTXX)
IF(NOT HAVE_UNITTESTXX)
  UNSET(HAVE_UNITTESTXX CACHE)
  message( FATAL_ERROR "UnitTest++ is not found" )
ENDIF()

此解决方案有效,但看起来不太好。我想知道一种 cmake 方法来完成这项任务。

最好的祝福!

4

1 回答 1

4

您正在寻找的答案已经在CMake Wiki上。他们清楚地告诉CMakeCache.txt您手动删除困扰您的文件或缓存行。

不幸的是,没有更清洁的方法可以做到这一点。你的已经是最好的了。我认为 CMake 在一切正常时会尽量方便,因此缓存,并在失败时尝试强制您删除并重新生成它。

另一方面,您可以编写一个CHECK_INCLUDE_FILE_CXX_ERROR宏(或任何更简洁的名称)来包装您的致命错误消息,这样您就不必每次都重复相同的代码:

macro(CHECK_INCLUDE_FILE_CXX_ERROR INCLUDE_FILE HAVE_FILE)
    CHECK_INCLUDE_FILE_CXX(${INCLUDE_FILE} ${HAVE_FILE})
    IF(NOT ${HAVE_FILE})
        UNSET(HAVE_UNITTESTXX CACHE)
        message( FATAL_ERROR "${INCLUDE_FILE} is not found" )
    ENDIF()
endmacro()

然后像这样使用它:

CHECK_INCLUDE_FILE_CXX_ERROR("UnitTest++.h" HAVE_UNITTESTXX)
于 2013-05-10T16:41:33.747 回答