You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

编写可返回空目标的CMake Find模块是否合法可行?及实现方案

编写支持可选系统替代的Find模块:以libtirpc为例

这种做法完全符合CMake惯例,而且是处理这类"系统功能可替代第三方库"场景的标准方式。CMake的Find模块设计本身就允许根据目标环境的差异调整查找逻辑,官方不少模块也采用类似思路。

核心思路

先判断目标系统是否已经提供了所需功能(比如部分Linux发行版的glibc已集成RPC能力),如果是,就标记依赖已满足;否则再尝试查找第三方库(libtirpc)。同时兼容find_package的REQUIRED参数,当用户明确要求必须依赖时,若两种情况都不满足则报错。

完整的FindTIRPC.cmake示例

# - Try to find TIRPC
# Once done, this will define:
#  TIRPC_FOUND - System has TIRPC or built-in RPC support
#  TIRPC_INCLUDE_DIRS - The TIRPC include directories
#  TIRPC_LIBRARIES - The libraries needed to use TIRPC

# First check if system has built-in RPC support
include(CheckSymbolExists)
check_symbol_exists(rpc_createerr rpc/rpc.h HAVE_RPC_IN_STDLIB)

if(HAVE_RPC_IN_STDLIB)
    # System provides RPC functionality natively, no need for libtirpc
    set(TIRPC_FOUND TRUE)
    set(TIRPC_INCLUDE_DIRS "")
    set(TIRPC_LIBRARIES "")
else()
    # Look for libtirpc headers and library
    find_path(TIRPC_INCLUDE_DIR
        NAMES tirpc/rpc.h
        PATHS /usr/include /usr/local/include
    )

    find_library(TIRPC_LIBRARY
        NAMES tirpc
        PATHS /usr/lib /usr/local/lib
    )

    set(TIRPC_INCLUDE_DIRS ${TIRPC_INCLUDE_DIR})
    set(TIRPC_LIBRARIES ${TIRPC_LIBRARY})

    # Handle the REQUIRED argument
    include(FindPackageHandleStandardArgs)
    find_package_handle_standard_args(TIRPC
        DEFAULT_MSG
        TIRPC_INCLUDE_DIR TIRPC_LIBRARY
    )

    # Mark cache variables for user override
    mark_as_advanced(TIRPC_INCLUDE_DIR TIRPC_LIBRARY)
endif()

在项目中使用

在你的CMakeLists.txt里这样调用:

find_package(TIRPC)

# Build your target
add_executable(your_rpc_app src/main.c)

# Link libraries - CMake ignores empty variables automatically
target_link_libraries(your_rpc_app PRIVATE ${TIRPC_LIBRARIES})

# Add include dirs only if needed
if(TIRPC_INCLUDE_DIRS)
    target_include_directories(your_rpc_app PRIVATE ${TIRPC_INCLUDE_DIRS})
endif()

如果代码需要区分两种场景(比如头文件路径不同:rpc/rpc.h vs tirpc/rpc.h),可以在代码里用预编译宏处理:

#ifdef HAVE_RPC_IN_STDLIB
#include <rpc/rpc.h>
#else
#include <tirpc/rpc.h>
#endif

然后在CMake中传递这个宏:

if(HAVE_RPC_IN_STDLIB)
    target_compile_definitions(your_rpc_app PRIVATE HAVE_RPC_IN_STDLIB)
endif()

关于合法性与CMake惯例

完全合规。CMake的Find模块体系就是为了处理这类"依赖存在多种形式"的场景:

  • 优先使用系统原生功能,减少第三方依赖,符合Linux生态的常规做法
  • 兼容find_package的标准参数(如REQUIRED、QUIET),保持接口一致性
  • 官方的Find模块(比如FindThreads)也会根据系统环境调整查找逻辑,这种模式是被官方认可的

内容的提问来源于stack exchange,提问作者einpoklum

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 11:27:15