我在这里有一个项目: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获取共享库?
答案 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})