如何获得CMake将测试程序链接到netCDF库?

时间:2019-11-14 12:11:32

标签: cmake

我在这里有一个项目:https://github.com/edhartnett/ncglm

这是一个小的C库,用于从对地闪电映射器中读取netCDF数据文件。我有一个可以正常工作的自动工具版本,并且正在尝试添加CMake版本。

目录结构很简单,有一个主目录,一个src目录和一个测试目录。

在主目录中,我有:

# This is the main cmake file for ncglm, a library to help read the
# netCDF data files from the Global Lightning Mapper (GLM) instrument
# on GOES-16 and GOES-17.
#
# Ed Hartnett 11/10/19

# This will use any cmake between 3.1 and 3.15, preferint later
# versions with updated policies.
cmake_minimum_required(VERSION 3.1...3.15)
if (${CMAKE_VERSION} VERSION_LESS 3.12)
  cmake_policy(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION})
endif()

# set the project name
project(ncglm VERSION 1.0)

#Add custom CMake Module
SET(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/"
  CACHE INTERNAL "Location of our custom CMake modules.")

# Find netCDF.
include(FindNetCDF)

include_directories("${NETCDF_INCLUDES}")

# Create a config.h.
configure_file(config.h.cmake.in config.h)

# Turn on testing.
enable_testing()
include(CTest)

# Build in this subdirectory.
add_subdirectory(src)
add_subdirectory(test)

在cmake目录中,我有这个:

# - Find NetCDF
# Find the native NetCDF includes and library
#
#  NETCDF_INCLUDES    - where to find netcdf.h, etc
#  NETCDF_LIBRARIES   - Link these libraries when using NetCDF
#  NETCDF_FOUND       - True if NetCDF found including required interfaces (see below)
#
# Your package can require certain interfaces to be FOUND by setting these
#
#  NETCDF_CXX         - require the C++ interface and link the C++ library
#  NETCDF_F77         - require the F77 interface and link the fortran library
#  NETCDF_F90         - require the F90 interface and link the fortran library
#
# The following are not for general use and are included in
# NETCDF_LIBRARIES if the corresponding option above is set.
#
#  NETCDF_LIBRARIES_C    - Just the C interface
#  NETCDF_LIBRARIES_CXX  - C++ interface, if available
#  NETCDF_LIBRARIES_F77  - Fortran 77 interface, if available
#  NETCDF_LIBRARIES_F90  - Fortran 90 interface, if available
#
# Normal usage would be:
#  set (NETCDF_F90 "YES")
#  find_package (NetCDF REQUIRED)
#  target_link_libraries (uses_f90_interface ${NETCDF_LIBRARIES})
#  target_link_libraries (only_uses_c_interface ${NETCDF_LIBRARIES_C})

if (NETCDF_INCLUDES AND NETCDF_LIBRARIES)
  # Already in cache, be silent
  set (NETCDF_FIND_QUIETLY TRUE)
endif (NETCDF_INCLUDES AND NETCDF_LIBRARIES)

find_path (NETCDF_INCLUDES netcdf.h
  HINTS NETCDF_DIR ENV NETCDF_DIR)

find_library (NETCDF_LIBRARIES_C       NAMES netcdf)
mark_as_advanced(NETCDF_LIBRARIES_C)

set (NetCDF_has_interfaces "YES") # will be set to NO if we're missing any interfaces
set (NetCDF_libs "${NETCDF_LIBRARIES_C}")

get_filename_component (NetCDF_lib_dirs "${NETCDF_LIBRARIES_C}" PATH)

macro (NetCDF_check_interface lang header libs)
  if (NETCDF_${lang})
    find_path (NETCDF_INCLUDES_${lang} NAMES ${header}
      HINTS "${NETCDF_INCLUDES}" NO_DEFAULT_PATH)
    find_library (NETCDF_LIBRARIES_${lang} NAMES ${libs}
      HINTS "${NetCDF_lib_dirs}" NO_DEFAULT_PATH)
    mark_as_advanced (NETCDF_INCLUDES_${lang} NETCDF_LIBRARIES_${lang})
    if (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
      list (INSERT NetCDF_libs 0 ${NETCDF_LIBRARIES_${lang}}) # prepend so that -lnetcdf is last
    else (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
      set (NetCDF_has_interfaces "NO")
      message (STATUS "Failed to find NetCDF interface for ${lang}")
    endif (NETCDF_INCLUDES_${lang} AND NETCDF_LIBRARIES_${lang})
  endif (NETCDF_${lang})
endmacro (NetCDF_check_interface)

NetCDF_check_interface (CXX netcdfcpp.h netcdf_c++)
NetCDF_check_interface (F77 netcdf.inc  netcdff)
NetCDF_check_interface (F90 netcdf.mod  netcdff)

set (NETCDF_LIBRARIES "${NetCDF_libs}" CACHE STRING "All NetCDF libraries required for interface level")

# handle the QUIETLY and REQUIRED arguments and set NETCDF_FOUND to TRUE if
# all listed variables are TRUE
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (NetCDF DEFAULT_MSG NETCDF_LIBRARIES NETCDF_INCLUDES NetCDF_has_interfaces)

mark_as_advanced (NETCDF_LIBRARIES NETCDF_INCLUDES)

现在在我的测试目录中,我正在尝试构建测试。它必须链接到src目录中内置的netcdf库和ncglm库。我正在尝试:

# This is the cmake build file for the test directory of the ncglm library.
#
# Ed Hartnett 11/10/19

enable_testing()
include_directories(${NETCDF_INCLUDES})
include_directories(${CMAKE_SOURCE_DIR}/src)
link_directories(${CMAKE_SOURCE_DIR}/src)
add_executable(tst_glm_read tst_glm_read.c un_test.h tst_utils.c)
target_link_libraries(tst_glm_read PRIVATE ${NETCDF_LIBRARIES}/libnetcdf.so)
target_link_libraries(tst_glm_read PRIVATE ${CMAKE_BINARY_DIR}/src/libncglm.a)

它不起作用。它确实会建立测试,但不会运行它:

ed@mikado:~/ncglm/build$ cmake -DNETCDF_INCLUDES=/usr/local/netcdf-c-4.7.2_hdf5-1.10.5/include -DNETCDF_LIBRARIES=/usr/local/netcdf-c-4.7.2_hdf5-1.10.5/lib .. && make
-- The C compiler identification is GNU 7.4.0
-- The CXX compiler identification is GNU 7.4.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found NetCDF: /usr/local/netcdf-c-4.7.2_hdf5-1.10.5/lib  
-- Configuring done
-- Generating done
-- Build files have been written to: /home/ed/ncglm/build
Scanning dependencies of target ncglm
[ 20%] Building C object src/CMakeFiles/ncglm.dir/glm_read.c.o
[ 40%] Linking C static library libncglm.a
[ 40%] Built target ncglm
Scanning dependencies of target tst_glm_read
[ 60%] Building C object test/CMakeFiles/tst_glm_read.dir/tst_glm_read.c.o
[ 80%] Building C object test/CMakeFiles/tst_glm_read.dir/tst_utils.c.o
[100%] Linking C executable tst_glm_read
[100%] Built target tst_glm_read
ed@mikado:~/ncglm/build$ make test
Running tests...
Test project /home/ed/ncglm/build
No tests were found!!!

如何使它运行测试。

还有,有什么更好的方法可以链接到我的库吗?

此外,如何使用cmake获取共享库?

1 个答案:

答案 0 :(得分:1)

您的test/CMakeLists.txt文件存在一些问题。您没有正确扩展NETCDF_*变量;它们不仅需要${},还需要$。另外,link_directories()接受路径作为参数,而不是实际的库文件。尝试在此处放置包含netcdf库的路径,或者在调用${NETCDF_LIBRARIES}时简单地放置target_link_libraries()。另一个nitpick首选绝对路径(使用${CMAKE_SOURCE_DIR})来进行这些调用,因此重新排列项目目录并不一定会破坏CMake:

enable_testing()
include_directories(${NETCDF_INCLUDES})
include_directories(${CMAKE_SOURCE_DIR}/src)
link_directories(${CMAKE_SOURCE_DIR}/src)
add_executable(tst_glm_read tst_glm_read.c un_test.h tst_utils.c)
target_link_libraries(tst_glm_read PRIVATE ${NETCDF_LIBRARIES})