使用CMake在库中查找符号

时间:2017-09-11 19:55:57

标签: linux cmake zlib hdf5

我正在尝试使用CMake查找外部库是否依赖于另一个库。

示例:HDF5库可以选择与zlib链接 在Linux中,可以通过

找到它
readelf -Ws /usr/local/lib/libhdf5.so | grep inflateEnd
54: 0000000000000000     0 FUNC    GLOBAL DEFAULT  UND inflateEnd

使用CMake,似乎可以通过CheckLibraryExists

找到它

https://cmake.org/cmake/help/v3.0/module/CheckLibraryExists.html

在Cmake脚本中

set(CMAKE_REQUIRED_LIBRARIES ${HDF5_LIBRARY})
check_library_exists(${HDF5_LIBRARY} inflateEnd "" NEED_ZLIB)
message(${NEED_ZLIB})
if (NEED_ZLIB)
 message("-- ZLIB library is needed...")
else()
 message("-- ZLIB library is not needed...")
endif()

未找到输出

-- Looking for inflateEnd in /usr/local/lib/libhdf5.so - not found
-- ZLIB library is not needed...

因为这个我做了使用readelf的Cmake版本,它找到了符号

但是,仍然想知道为什么上面的Cmake脚本失败了: - )

工作版本是

set(have_read_symbols "no")
find_program(read_symbols_prg readelf)
if (${read_symbols_prg} MATCHES "readelf")
  set(have_read_symbols "yes")
  message("-- Readelf program found: " ${read_symbols_prg}) 
  execute_process(COMMAND ${read_symbols_prg} -Ws ${HDF5_LIBRARY} OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/symbols.txt)
endif()

if (${have_read_symbols} MATCHES "yes")
  message("-- Detecting if HDF5 library ${HDF5_LIBRARY} needs the ZLIB library...")
  file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/symbols.txt NEED_ZLIB REGEX "inflateEnd")
  if (NEED_ZLIB)
    message("${color_blue}-- ZLIB library is needed...${color_reset}")
  else()
    message("-- ZLIB library is not needed...")
  endif(NEED_ZLIB)
endif()

找到符号

-- Detecting if HDF5 library /usr/local/lib/libhdf5.so needs the ZLIB library...
-- ZLIB library is needed...

1 个答案:

答案 0 :(得分:0)

好的,checkLibraryExists()的Cmake文档中有关如何完成此操作的详细信息,他们只是说“检查函数是否存在”。 checkLibraryExists()尝试链接测试程序,并根据成功与否,将输出变量参数设置为值1或为空。

在这种情况下,要查看的符号必须是libhdf5.so中定义的符号,只能使用zlib库。这种情况只有一个符号,一个名为“H5Z_DEFLATE”的结构,根据zlib案例的#ifdef添加到库中。

所以,这就是诀窍

App Transport Security Settings

但是对于使用Visual Studio的Windows情况,这很容易出错,因为check_library_exists()要检测它,Visual Studio必须将选项设置为zlib库的附加依赖项,这不是成功构建库的必要条件。因此,如果设置了此选项,check_library_exists将检测依赖项,如果未设置,则不会。