CMAKE:使用不同参数重复调用函数会给出相同的结果

CMAKE: repeated calls to function with different arguments give the same results

本文关键字:函数 结果 调用 参数 CMAKE      更新时间:2023-10-16

我有一些帮助程序函数可以帮助我在文件系统中找到共享库和静态库:

我有一个辅助函数,它执行实际搜索,给定一个name和一个suffix

function(do_find_lib LIB_NAME SUFFIX OUT)
    set(CMAKE_FIND_LIBRARY_SUFFIXES ${SUFFIX})
    find_library(FOUND ${LIB_NAME})
    if(NOT FOUND)
        message(SEND_ERROR "unable to find library ${LIB_NAME}")
    endif()
    message(STATUS "search: ${LIB_NAME}.${SUFFIX} result: ${FOUND}")
    set(${OUT} ${FOUND} PARENT_SCOPE)
endfunction()

该函数find_static_lib设置适当的后缀,并调用do_find_lib

function(find_static_lib LIB_NAME OUT)
    if (WIN32 OR MSVC)
        set(SUFFIX ".lib")
    elseif (UNIX)
        set(SUFFIX ".a")
    endif()      
    do_find_lib(${LIB_NAME} ${SUFFIX} FOUND)
    message(STATUS "static lib search: ${LIB_NAME} result: ${FOUND}")
    set(${OUT} ${FOUND} PARENT_SCOPE)
endfunction()

同样,该函数find_shared_lib设置适当的后缀,并调用do_find_lib

function(find_shared_lib LIB_NAME OUT)
    if (WIN32 OR MSVC)
        set(SUFFIX ".dll")
    elseif (UNIX)
        set(SUFFIX ".so")
    endif()      
    do_find_lib(${LIB_NAME} ${SUFFIX} FOUND)
    message(STATUS "shared lib search: ${LIB_NAME} result: ${FOUND}")
    set(${OUT} ${FOUND} PARENT_SCOPE)
endfunction()

根据需要,在我的 cmake 层次结构中的其他地方,我使用这些函数来查找各种库

我第一次使用它时,它可以工作:

首先,我搜索tcmalloc静态库。

find_shared_library(tcmalloc_minimal TCMALLOC)

以下是结果输出:

-- search: tcmalloc_minimal.a result: /usr/local/lib/libtcmalloc_minimal.a
-- static lib search: tcmalloc_minimal result: /usr/local/lib/libtcmalloc_minimal.a

第二次使用它时,它坏了:

接下来,我搜索protobuf共享库。

find_shared_library(protobuf PROTOBUF)

以下是结果输出:

-- search: protobuf.so result: /usr/local/lib/libtcmalloc_minimal.a
-- shared lib search: protobuf result: /usr/local/lib/libtcmalloc_minimal.a

错误:

议员?搜索带有后缀.so protobuf会找到上一个搜索结果,/usr/local/lib/libtcmalloc_minimal.a

问题:

  • 为什么会这样?
  • 我的函数中是否有错误?
  • 我需要做什么才能正确搜索必要的库?

笔记:

我已经完成了删除我的构建目录并重建了生成文件,所以不要相信这是缓存的问题。

来自 find_library 的文档:

将创建一个由 <VAR> 命名的缓存条目来存储此命令的结果。
如果找到库,则结果存储在变量中,除非清除变量,否则不会重复搜索。

这个cmake邮件列表答案显示您必须将变量设置为FOUND-NOTFOUND才能清除缓存。

set(FOUND FOUND-NOTFOUND)

但是,可以说这是一种反模式,因为这样做会破坏find_library的缓存行为

最好

为每个唯一搜索使用唯一的变量名称。

这里的变量称为FOUND_${LIB_NAME}${SUFFIX}

function(do_find_lib LIB_NAME SUFFIX OUT)
    set(CMAKE_FIND_LIBRARY_SUFFIXES ${SUFFIX})
    find_library(FOUND_${LIB_NAME}${SUFFIX} ${LIB_NAME})
    if(NOT FOUND_${LIB_NAME}${SUFFIX})
        message(SEND_ERROR "unable to find library ${LIB_NAME}")
    endif()
    set(${OUT} ${FOUND_${LIB_NAME}${SUFFIX}} PARENT_SCOPE)
endfunction()