ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

WRF依赖库安装全攻略:从编译器到NetCDF,理顺气象模式环境配置

WRF依赖库安装全攻略:从编译器到NetCDF,理顺气象模式环境配置 1. 别急着装WRF先把这台机器当实验台收拾干净说实话我在接触WRF之前一直以为搞气象数值模式是那种穿着白大褂、面对超算集群的高端操作。直到自己真正开始折腾才发现第一道坎根本不是模式本身而是环境配置。小白跑WRF第三天这个节点恰好卡在最容易劝退的位置——前两天的热情还在思维也还算清晰但依赖库之间的关系已经开始让人头大了。先聊清楚一个概念WRFWeather Research and Forecasting Model本身是一个庞大的Fortran/C混合项目它不像我们平时装个Python包那样pip install一下就完事。它需要一系列底层库来支撑I/O读写、NetCDF数据格式解析、MPI并行通信、数学计算优化等能力。这些库不装好后面./configure和./compile的时候会蹦出一堆看不懂的错误。这个阶段最忌讳的事情是照着某个教程一顿粘贴复制然后祈祷一次通过。因为我见过太多人包括我自己在依赖库环节反复扑街最后发现根本不是命令敲错而是环境变量、编译器一致性、目录权限这些看不见的坑。所以这篇文章咱们不急着敲命令先把思路理清楚。我们的目标很明确在Linux环境下我用的是CentOS 7.9但Ubuntu 20.04/22.04同样适用把WRF需要的三方依赖库逐个装好、验证通过并且搞清楚每个库到底是干嘛的、为什么非它不可。这套逻辑捋顺了你不光能装WRF以后装其他Fortran项目也能少走弯路。2. 依赖库全景图它们各管哪一块彼此又怎么串起来很多人一看到依赖库清单就开始慌觉得要装的东西太多。其实WRF的依赖库掰着手指头数核心就那几个各自分工非常明确而且是有层级关系的。2.1 编译器是地基Intel还是GCC选错全盘重来WRF对编译器的敏感程度远超一般项目。社区里最主流的两条路线是Intel编译器ifort/icc和GNU编译器gfortran/gcc。Intel编译器的编译效率和运行速度通常更优尤其在大型模拟上优势明显但License获取和安装复杂度相对高一些GCC是开源免费、人人都能装的方案兼容性也做得很好。这里我的建议非常直接如果是新手别碰Intel直接用GCC全家桶。原因有三一是GCC在各大Linux发行版仓库里都有yum install或apt install一条命令就能搞定二是网上90%的WRF报错帖都是基于GCC环境讨论的你遇到问题时搜到的解决方案大概率适用三是Intel编译器需要额外设置一系列环境变量对新手来说是纯纯的负担。需要确认的编译器工具链包括gcc、gfortran、g以及cppC预处理器。还有一个容易被忽略的是m4它是NetCDF等库构建过程中的辅助工具没装的话会在configure阶段报莫名其妙的问题。注意既然决定用GCC那么后续所有库都必须统一用GCC编译千万别混着来——比如NetCDF用gcc编MPI用Intel编最后链接的时候绝对会出问题。这是很多人踩过的坑我先帮你踩了。2.2 压缩与数学库zlib、libpng、jasper解决GRIB数据的读写如果你只是跑理想化案例比如 idealized cases数据格式相对简单但一旦要跑真实气象数据比如从NCEP/ECMWF下载的再分析资料就会碰到GRIB格式。WRF前处理系统WPS里有一个环节叫ungrib它的职责就是解码GRIB数据而这个解码过程依赖三个库zlib最基础的压缩库几乎所有格式处理都离不开它libpngPNG图像格式库用于处理部分图形输出jasperJPEG2000格式的编解码库GRIB2格式数据的核心依赖很多人会问我不跑真实数据是不是就可以跳过这几个库答案是WPS编译的时候默认会检查这些库除非你明确配置禁用否则缺少它们会导致ungrib编译失败。所以别偷懒按顺序老老实实装。2.3 NetCDFWRF的数据通用语言NetCDFNetwork Common Data Form在WRF中的地位怎么强调都不为过。WRF的输入文件、输出文件、中间文件几乎全是NetCDF格式wrfout文件就是典型的NetCDF格式。你可以把它理解成一种自带元数据描述的自描述二进制格式它告诉使用者这个变量叫什么、单位是什么、维度是多少极大方便了科学数据交换。WRF一般要求NetCDF支持Fortran接口因此需要同时安装C库和Fortran库。这里有一个关键细节早期版本的NetCDF是C和Fortran分开的两个包但新版本NetCDF-C和NetCDF-Fortran依然是分开维护的必须先装C库再装Fortran库顺序颠倒会导致Fortran接口找不到C库路径。2.4 MPICH让WRF能从单核跑到多核WRF支持分布式并行计算而并行通信的底层实现靠的是MPIMessage Passing Interface标准。MPICH是MPI标准的一个经典开源实现也有不少人用OpenMPI两者功能上都能满足WRF需求但MPICH在WRF社区中的历史更久、出问题的概率相对低一些。这里要特别提醒MPICH必须和编译器联动编译它默认会用系统编译器但如果你之后切换了编译器版本MPICH也要重新编译一次。否则MPI程序在运行时可能因为库不匹配而崩溃。依赖库的安装顺序按我个人的经验整理如下编译器 → zlib → libpng → jasper → MPICH → NetCDF-C → NetCDF-Fortran。这个顺序不是随意的它遵循先底层后上层的原则每个库都依赖于前一个库提供的工具或头文件。3. 环境变量规划这一步偷懒后面全在还债依赖库安装本身并不复杂真正的分水岭是对环境变量的理解和配置。太多人栽在这里不是库没装好而是WRF configure时找不到库的位置或者找到了错误的版本。3.1 统一目录结构让所有库住在一个小区里我的习惯是在家目录下建一个Build_WRF文件夹里面再分两个子目录LIBRARIES存放所有依赖库WRF存放WRF和WPS源码。这样的好处是路径清晰写环境变量的时候一目了然后期排查问题也方便。具体路径规划如下/home/你的用户名/Build_WRF/LIBRARIES每个依赖库安装时通过--prefix参数指定到自己的子目录比如/home/你的用户名/Build_WRF/LIBRARIES/netcdf /home/你的用户名/Build_WRF/LIBRARIES/mpich /home/你的用户名/Build_WRF/LIBRARIES/jasper这种一库一目录的模式比起全部塞进/usr/local要安全得多。因为你不需要root权限、不会污染系统目录、升级删除也方便。而且当你想在另一台机器上复现环境时直接打包这个目录过去就能用。3.2 PATH、LD_LIBRARY_PATH和NETCDF变量到底怎么配这三个变量是WRF环境配置的三驾马车缺一不可。简单解释一下各自的职责PATH告诉shell去哪里找可执行文件。比如修改PATH后你才可以直接敲nc-config、mpicc这些命令而不用写完整路径。LD_LIBRARY_PATH告诉系统运行时去哪里找动态链接库.so文件。编译时链接还好说运行WRF时如果找不到库会报cannot open shared object file的错误就是因为这个变量没配好。NETCDFWRF源码的configure脚本会读取这个环境变量来确定NetCDF的安装根目录进而查找头文件和库文件。不设置它就等着configure报错吧。我一般把环境变量配置写在~/.bashrc里而不是每次手动export。其中NetCDF相关的配置类似下面这样但具体路径要按你自己的实际情况修改export NETCDF/home/你的用户名/Build_WRF/LIBRARIES/netcdf export PATH$NETCDF/bin:$PATH export LD_LIBRARY_PATH$NETCDF/lib:$LD_LIBRARY_PATHMPICH也是同理装上之后把bin和lib路径追加进去。另外还建议配置CPPFLAGS和LDFLAGS它们分别告诉编译器和链接器去哪里找头文件和库文件在NetCDF-Fortran编译时尤其有用。3.3 每次改完环境变量记得验证而不是盲目继续配置完~/.bashrc后务必执行source ~/.bashrc让配置生效。然后逐个验证别急着进入下一步which gfortran which mpicc which nc-config每一条命令都应该返回一个可执行文件路径。如果某一条显示no xxx in ...说明你的PATH配置有问题这时候停下来检查路径别等到后面编译报错了才回头。4. 逐个编译依赖库完整命令与避坑点现在进入到最实操的部分。为了不让教程变得像流水账我会在每个库后面附上几个我自己实际踩过的坑和判断标准。4.1 zlib、libpng、jasper三兄弟一次装齐这三个库是典型的configure make make install三步走流程。以jasper为例它的构建过程比较典型早期版本用configure2.x以上版本改用CMake但WRF社区常用的还是1.900.x系列cd /home/你的用户名/Build_WRF/LIBRARIES wget https://github.com/jasper-software/jasper/archive/refs/tags/version-1.900.1.tar.gz tar -zxvf jasper-1.900.1.tar.gz cd jasper-version-1.900.1 ./configure --prefix/home/你的用户名/Build_WRF/LIBRARIES/jasper make make install这里要注意jasper 2.x版本改用CMake后生成的库结构和1.x版本有差异而WRF源码里对jasper的查找方式还停留在旧版习惯上所以建议直接用1.900.1省得后面链接时找不着库。zlib和libpng的安装逻辑完全一样就是configure参数和目录不同。装完之后检查一下对应目录的lib和include是否生成了文件ls /home/你的用户名/Build_WRF/LIBRARIES/jasper/lib ls /home/你的用户名/Build_WRF/LIBRARIES/jasper/include如果为空大概率是configure时缺少依赖导致静默降级了回头看看configure输出的前50行有没有error信息。4.2 MPICH并行能力的关键别让编译器出轨MPICH编译时需要指定编译器这里明确告诉它用gcc/gfortrancd /home/你的用户名/Build_WRF/LIBRARIES wget https://www.mpich.org/static/downloads/3.3.2/mpich-3.3.2.tar.gz tar -zxvf mpich-3.3.2.tar.gz cd mpich-3.3.2 ./configure --prefix/home/你的用户名/Build_WRF/LIBRARIES/mpich --disable-fortran make -j4 make install等一下上面这个命令我故意写了一个--disable-fortran这是错的千万别直接复制。MPICH默认会编译Fortran绑定而WRF的并行版本需要MPI的Fortran接口。为什么我要故意写错一次因为很多教程在复制粘贴时容易出错我想提醒你每个参数都要过脑子。正确的做法是不加--disable-fortran让它默认编译即可。如果你想确认MPICH是否支持Fortran装完后可以看include目录下有没有mpif.h文件这个文件是Fortran程序包含MPI接口的头文件没有它WRF编不过去。记得配置环境变量export MPI/home/你的用户名/Build_WRF/LIBRARIES/mpich export PATH$MPI/bin:$PATH export LD_LIBRARY_PATH$MPI/lib:$LD_LIBRARY_PATH验证方式就是执行mpif90 -v能正常输出版本信息说明MPI的Fortran编译器包装器已经可用了。4.3 NetCDF-C和NetCDF-Fortran先C后Fortran顺序定生死NetCDF-C安装过程相对简单唯一需要注意的是指定--disable-dap选项。DAP是远程数据访问协议普通单机跑WRF用不上而启用它会额外引入libcurl依赖给自己找麻烦cd /home/你的用户名/Build_WRF/LIBRARIES wget https://github.com/Unidata/netcdf-c/archive/refs/tags/v4.9.2.tar.gz tar -zxvf v4.9.2.tar.gz cd netcdf-c-4.9.2 ./configure --prefix/home/你的用户名/Build_WRF/LIBRARIES/netcdf --disable-dap make -j4 make install装完后nc-config这个命令会出现在bin目录下它能把NetCDF-C的头文件路径、库路径等内容清晰地列出来后续排查时很有用。可以用nc-config --all查看所有信息。NetCDF-Fortran编译的关键在于需要能找到NetCDF-C的安装位置。此时CPPFLAGS和LDFLAGS必须指向NetCDF目录否则configure会报找不到netcdf.h。命令参考如下cd /home/你的用户名/Build_WRF/LIBRARIES wget https://github.com/Unidata/netcdf-fortran/archive/refs/tags/v4.6.0.tar.gz tar -zxvf v4.6.0.tar.gz cd netcdf-fortran-4.6.0 export CPPFLAGS-I/home/你的用户名/Build_WRF/LIBRARIES/netcdf/include export LDFLAGS-L/home/你的用户名/Build_WRF/LIBRARIES/netcdf/lib ./configure --prefix/home/你的用户名/Build_WRF/LIBRARIES/netcdf make -j4 make install安装成功的标志是bin目录下出现nf-config命令且lib目录下有libnetcdf.a和libnetcdff.a两个静态库文件。粗心的朋友容易只看到C库就以为装完了其实Fortran接口库才是WRF真正需要的。4.4 顺带装一个HDF5需要但并非必须看你的数据需求很多教程会建议装HDF5理由是NetCDF-C在configure时如果检测到HDF5会将NetCDF格式文件默认以HDF5底层格式存储。但对于只跑WRF和WPS的流程来说HDF5并非强制项。只有当你要处理HDF格式的观测数据或使用某些特定工具时才需要。所以我的建议是新手第一遍先跳过HDF5等WRF能跑通了再回头补装也不迟。少一个依赖就少一分出错概率先把主流程打通要紧。5. 依赖库自检清单怎么判断这一阶段真的算过了安装完所有库之后不要急着进入WRF源码编译阶段。花十分钟做一个自检能把后面两天的排查时间省回来。我把检查项整理成了一张清单每一项都很简单但缺一不可。5.1 环境变量验证与编译器一致性先确认三件事gfortran --version和gcc --version能正常输出且版本兼容GCC 8.x以上对WRF 4.x都友好mpif90 --version能显示与gfortran一致的版本信息。如果mpif90显示的不是同一个编译器说明MPICH在编译时没有正确识别系统编译器echo $NETCDF、echo $PATH、echo $LD_LIBRARY_PATH的输出中包含你的依赖库路径特别是第三点很多人配置PATH时把路径写错了但没注意结果编译WRF时怎么都找不到命令。一个实用的排查思路是把路径从短到长逐个检查ls /home/xxx、ls /home/xxx/Build_WRF、ls /home/xxx/Build_WRF/LIBRARIES/netcdf/bin看到底是哪一层目录名拼写有问题。5.2 头文件和库文件完整性检查依赖库编译完各自目录下应该有对应文件列表如下库需要检查的文件zlibinclude/zlib.hlib/libz.alibpnginclude/png.hlib/libpng.ajasperinclude/jasper/jasper.hlib/libjasper.aMPICHinclude/mpi.hinclude/mpif.hlib/libmpi.so或.aNetCDF-Cinclude/netcdf.hlib/libnetcdf.abin/nc-configNetCDF-Fortraninclude/netcdf.modlib/libnetcdff.abin/nf-config这里要注意netcdf.mod是Fortran的模块文件它的缺失通常意味着NetCDF-Fortran没有正确安装。而mpif.h则用于旧的Fortran程序风格WRF需要用到它。5.3 写一个微型Fortran测试程序验证Fortran能调NetCDF和MPI这个步骤虽然要动一点点代码但价值极高。在Build_WRF目录下创建一个test.f90文件program test use netcdf implicit none integer :: ncid, status include mpif.h call MPI_INIT(status) status nf90_create(test.nc, NF90_CLOBBER, ncid) if (status / NF90_NOERR) then print *, NetCDF error: , nf90_strerror(status) else print *, NetCDF test passed end if status nf90_close(ncid) call MPI_FINALIZE(status) end program test然后用mpif90编译mpif90 -o test test.f90 -I$NETCDF/include -L$NETCDF/lib -lnetcdff -lnetcdf如果编译通过且运行时输出NetCDF test passed说明Fortran可以同时使用MPI和NetCDF这一阶段算是真正过关了。如果编译报错把错误信息复制下来搜一下通常比盲目重装更有效。6. 第三天最容易翻车的5个细节以及我怎么救回来的这一节算是压箱底的经验了。以下问题我基本都亲手踩过每一条都能复现希望能帮你跳过。6.1 用了不同版本的编译器编译不同库链接时一锅粥我见过最典型的翻车现场是NetCDF-C用系统自带的gcc编的但MPICH用的却是自己后来安装的gcc两者版本不一致最终WRF链接时报一堆undefined reference错误。要解决这个问题最稳妥的方法是装完自己指定的gcc/gfortran后在编译所有库之前先把CC、CXX、FC、F77环境变量统一指向同一个编译器路径。编译每个库时configure输出里都会有一行checking for Fortran compiler... gfortran留意一下是不是你期望的那个。6.2 目录名带空格或中文configure阶段直接崩这是一个很低级但真实存在的坑。如果你把Build_WRF目录放在带空格路径下比如Windows共享目录挂载过来的configure脚本在解析路径时会因为空格被分割而产生错乱。建议所有路径只用字母、数字、下划线。我自己现在所有计算环境都固定用/home/username/Build_WRF从不搞花活不是没个性是踩怕了。6.3 用了root权限装系统目录结果权限混乱某些教程为了省事会让你sudo make install直接装进/usr/local。这在单机自用场景下问题不大但是当你需要换机器、换用户时就会因为权限不足或路径差异而收拾半天。更关键的是在家目录下安装可以完整复现你的环境这在提交计算任务或者换服务器时非常好用。我的习惯是全程不带sudo所有库装在用户目录下Workflow非常清晰。6.4 版本选择过于激进或过于古老WRF和它的依赖库版本之间存在一个舒适区。比如NetCDF-C 4.9.x配合NetCDF-Fortran 4.6.x是目前出问题最少的组合MPICH 3.3.x也很稳定。不要看到新版就往上冲也不要因为某个老版本教程用了就非它不可。在WRF官网的User Guide里每一版都标注了推荐的依赖库版本范围新版本发布后官方会做兼容性测试跟着官方推荐走永远是最省心的。6.5 想当然跳过某些库configure阶段被反杀有些教程为了简化流程会让理想化试验不需要jasper这类说法带偏。我也曾经天真地跳过jasper结果在编译WPS的ungrib时直接报错。问题的本质是即使你的科学计算不直接使用某个库但WRF的构建系统在configure阶段会检测它们是否存在缺了它就直接拒绝编译相关组件。与其回头补装不如一开始就装齐。回到最开始那个问题为什么小白跑WRF会在第三天卡住因为这一天你从有手就行的下载源码进入到了需要理解构建逻辑的阶段。依赖库的安装不是体力活而是一次对Linux环境、编译链、环境变量、源码构建全流程的密集训练。把这些搞明白了WRF的./configure和./compile反而变得简单许多。第三天装完依赖库深呼吸做个自检确保每一步都经得起推敲。然后休息一下给自己一点正反馈——因为明天开始才是WRF本身编译的硬仗。到时候这些依赖库会组成一条稳定流水线默默支撑你去编译那个庞大的气象模式。祝顺利。
返回列表