【问题标题】:Write CMake Find Netcdf for C and Fortran library为 C 和 Fortran 库编写 CMake Find Netcdf
【发布时间】:2025-12-13 08:45:01
【问题描述】:

大家好,感谢您的帮助,

我是 CMAKE 的新手,我尝试为 C 和 Fortran NETCDF 库编写一个查找库。问题是 fortran 和 C netcdf 的位置和版本可能不同。

对于 fortran 库,我搜索 netcdf.mod(包括模块)和 libnetcdff.so(动态库)而不是 C 库,我搜索 netcdf.h 和 libnetcdf.so

在网上我找到了一个能正确找到 netcdf C 库的魔法代码:

find_path (NETCDF_INCLUDES_C netcdf.h HINTS NETCDF_DIR NETCDF_DIR)
message(" inc =  ${NETCDF_INCLUDES_C}  ")
find_library (NETCDF_LIBRARIES_C  NAMES netcdf)
message(" lib =  ${NETCDF_LIBRARIES_C}  ")

而且两条路径都是正确的。我尝试回复fortran的代码:

find_path (NETCDFF_INCLUDES_F90 netcdff.mod HINTS NETCDFF_DIR NETCDFF_DIR)
message(" inc ff =  ${NETCDFF_INCLUDES_F90}  ")
find_library (NETCDFF_LIBRARIES_F90  NAMES netcdff HINTS NETCDFF_DIR )
message(" lib ff=  ${NETCDFF_LIBRARIES_F90}  ")
mark_as_advanced(NETCDF_LIBRARIES_F90)

但是两个F90路径都是空的,可能是因为我不明白cmake如何找到C库。通过 MODULE ENVIRONMENT 我加载库和模块加载 env var:

   $NETCDFF_HOME $NETCDFF_INC $NETCDFF_INCLUDE $NETCDFF_LIB
   $NETCDF_HOME  $NETCDF_INC  $NETCDF_INCLUDE  $NETCDF_LIB 

我错误地认为 CMAKE 搜索 NETCDF_DIR 变量并进入此搜索 netcdf.h 但在我的 CmakeList 和我的 ENV 中未定义该变量。

CMake 如何找到 C var?以及如何将发现回复到 fortran lib?

谢谢你的帮助

最好的问候

埃里克

【问题讨论】:

  • 您是真的想netcdff.mod 还是想要netcdf.mod?另外我真的不知道cmake,但如果看起来你可能试图存储在NETCDFF_INCLUDES_F90,但你的消息使用${NETCDF_INCLUDES_F90}(即第一个有一个额外的F)
  • 感谢您的回复,在复制和粘贴中出现了一些错误。正确的包含模块文件是 netcdf.mod 并且消息在 NETCDFF_INCLUDES_F90 上,我更正了我之前的帖子。
  • 您运行的是哪个版本的 CMake?
  • 我想你忘记更正模块文件名了。
  • CMAKE版本为3.5.2,模块正确名称为netcdf.mod。

标签: c cmake fortran shared-libraries netcdf


【解决方案1】:

也许我的答案本身不是答案,但你不能只使用 VTK 附带的 FindNetCDF.cmake 吗?
https://github.com/Kitware/VTK/blob/master/CMake/FindNetCDF.cmake
还是来自其他用户的与前一个相似的用户(他们可以查找 Fortran 和 C 组件)?
https://github.com/bilke/cmake-modules/blob/master/FindNetCDF.cmake
https://github.com/jedbrown/cmake-modules/blob/master/FindNetCDF.cmake
如果您包含此文件,那么您可以通过以下方式检索您需要的组件:

set (NETCDF_F90 "YES")
find_package (NetCDF REQUIRED)
include_directories(${NETCDF_INCLUDES})
target_link_libraries (uses_f90_interface ${NETCDF_LIBRARIES})
target_link_libraries (only_uses_c_interface ${NETCDF_LIBRARIES_C}) 

或者在 VTK 版本的情况下,类似

find_package (NetCDF COMPONENTS F90)
include_directories(NETCDF_F90_INCLUDE_DIRS)
target_link_libraries (only_uses_f90_interface ${NETCDF_F90_LIBRARIES})

如 VTK 版本所述,您可以通过以下方式为 C 和 Fortran 库传递不同的搜索目录:

当请求接口时,用户可以访问特定于接口的提示:

NETCDF_${LANG}_INCLUDE_DIR - where to search for interface header files
NETCDF_${LANG}_LIBRARY     - where to search for interface libraries

【讨论】:

  • 我已经尝试过这个例子,但只有在 C 和 Fortran 库位于同一目录中时才能运行。因为首先脚本找到 C 库的位置,然后在同一目录中搜索另一个。
  • 更新了答案,因为当您要求语言特定接口时,您可以为包含和库指定不同的搜索目录...
  • 感谢帮助我试试你的建议!
  • netCDF 可以通过多种不同的方式构建,而 autoconf/automake/libtool 绝对可以轻松找到所需的所有信息。然而,cmake 甚至很难找到基本信息,因为它显然不使用 .so 文件(可以找到所有信息),而只是希望 netCDF 也与 cmake 一起安装,因此存在特殊的 cmake 安装信息.但通常情况并非如此。所以在其他项目中,我也很难将 netCDF 支持放入 cmake 构建中。