編譯WRF時出現DSO missing from command line

助教們好,不好意思打擾了,我已經安裝了Dependencies,目前在編譯的WRF程式的時候會遇到一些DSO missing 的錯誤,以下是編譯時出現的錯誤訊息:

(上略)
           echo removing external declaration of iargc for gfortran ; \
   /usr/bin/cpp -P -nostdinc -P -traditional-cpp -I/home/u7807382/wrf-hw/opt/netcdf-c-4.7.3//include -I../ioapi_share diffwrf.F90 | sed '/integer *, *external.*iargc/d' > diffwrf.f ;\
        else \
   /usr/bin/cpp -P -nostdinc -P -traditional-cpp -I/home/u7807382/wrf-hw/opt/netcdf-c-4.7.3//include -I../ioapi_share diffwrf.F90 > diffwrf.f ; \
        fi
time mpif90 -f90=ifort -ip -fp-model precise -w -ftz -align all -fno-alias -FR -convert big_endian -xHost -fp-model fast=2 -no-heap-arrays -no-prec-div -no-prec-sqrt -fno-common -xCORE-AVX2  -real-size 32 -i4  -qopenmp -fpp -auto -c  -I/home/u7807382/wrf-hw/opt/netcdf-c-4.7.3//include -I../ioapi_share diffwrf.f
0.56user 0.10system 0:00.72elapsed 92%CPU (0avgtext+0avgdata 101016maxresident)k
0inputs+648outputs (0major+30602minor)pagefaults 0swaps
diffwrf io_netcdf is being built now. 
ld: /home/u7807382/wrf-hw/opt/netcdf-c-4.7.3//lib/libnetcdf.a(libnchdf5_la-nc4hdf.o): undefined reference to symbol 'H5DSattach_scale'
/home/u7807382/wrf-hw/opt/hdf5-1.8.21/lib/libhdf5_hl.so.10: error adding symbols: DSO missing from command line

real    0m0.911s
user    0m0.433s
sys     0m0.222s
make[2]: [diffwrf] Error 1 (ignored)
make[2]: Leaving directory `/home/u7807382/wrf-hw/build/WRF_ISC21/external/io_netcdf'
make[2]: Entering directory `/home/u7807382/wrf-hw/build/WRF_ISC21/external/io_netcdf'
make[2]: Nothing to be done for `all'.
make[2]: Leaving directory `/home/u7807382/wrf-hw/build/WRF_ISC21/external/io_netcdf'
SKIPPING PIO BUILD make -i -r NETCDFPATH= FC=ifort -ip -fp-model precise -w -ftz -align all -fno-alias -FR -convert big_endian -xHost -fp-model fast=2 -no-heap-arrays -no-prec-div -no-prec-sqrt -fno-common -xCORE-AVX2  -real-size 32 -i4  -qopenmp -fpp -auto RANLIB=ranlib CPP=/usr/bin/cpp -P -nostdinc LDFLAGS=-qopenmp -fpp -auto -O3 -ip -fp-model precise -w -ftz -align all -fno-alias -FR -convert big_endian -xHost -fp-model fast=2 -no-heap-arrays -no-prec-div -no-prec-sqrt -fno-common -xCORE-AVX2  -ip -xHost -fp-model fast=2 -no-prec-div -no-prec-sqrt -ftz -align all -fno-alias -fno-common -xCORE-AVX2  TRADFLAG=-traditional-cpp ESMF_IO_LIB_EXT=-L/home/u7807382/wrf-hw/build/WRF_ISC21/external/esmf_time_f90 -lesmf_time LIB_LOCAL= ESMF_MOD_DEPENDENCE=/home/u7807382/wrf-hw/build/WRF_ISC21/external/esmf_time_f90/module_utility.o AR=INTERNAL_BUILD_ERROR_SHOULD_NOT_NEED_AR
(下略)

我在opt中檢查hdf5是否有正確安裝,但是我在hdf5的lib中有找到libhdf5_hl.so.10(錯誤訊息中missing的檔案) 。以下是搜尋的結果

[u7807382@lgn303 lib]$ ls -al  | grep libhdf5_hl.so.10
lrwxrwxrwx 1 u7807382 TRI113244      20 Jan 31 19:48 libhdf5_hl.so -> libhdf5_hl.so.10.2.2
lrwxrwxrwx 1 u7807382 TRI113244      20 Feb  4 15:17 libhdf5_hl.so.10 -> libhdf5_hl.so.10.2.2
-rwxr-xr-x 1 u7807382 TRI113244  148136 Jan 31 19:48 libhdf5_hl.so.10.2.2

想要請問助教這個錯誤是因為安裝Dependency 時的錯誤導致的嗎,想請問可能的解決方法?

謝謝助教,感激不盡!

1個讚

同學好,

這是如果大家照著我們提供的步驟編譯,就會遇到的其中一個問題。

如果搜尋 DSO missing from command line, 就會找到別人對這個訊息的解釋

The DSO missing from command line message will be displayed when the linker does not find the required symbol with it’s normal search but the symbol is available in one of the dependencies of a directly specified dynamic library.

簡單一點來說,就是發生了 undefined symbol, 而 Linker 留意到你提供的某個 .so 裡面有需要的 symbol, 但是你沒有加 Linker flag (-l) 來叫他使用這個 .so, 所以他不會使用,但還是好心地印出了 DSO missing from command line 這個訊息提醒你是不是忘了加 Linker flag.

也就是說,真正的錯誤訊息是上面的 undefined reference to symbol 'H5DSattach_scale', DSO missing from command line 只是一個提醒而已。

因此,第一個解決方法就是手動加上 -lhdf5_hl 這個 Linker flag 來讓 Linker 使用 libhdf5_hl.so
至於要怎麼加,可以直接修改 Makefile (善用 grep 之類的工具來找出在 Makefile 中的位置),或是手動將 target 產生,就可以繼續編譯了。


這裡同學可能會有疑問:明明 HDF5 是 NetCDF 的 dependency, 為什麼在編譯 WRF 時卻又要 Link HDF5

這是因為 NetCDF 是做成 Static Library (libnetcdf.a)。
還記得 .a 就是單純地將一堆 .o 檔打包起來嗎?這些 NetCDF 的 .o 裡面需要使用 HDF5 的 symbol, 但在打包成 .a 時並沒有 Link, 因此 Link 的工作就變成是使用這個 Static Library 的程式要做。

而如果我們將 NetCDF 編譯為 Shared Library, 就不會有這樣的問題。因為 Shared Object (.so) 已經經過 Link 這個步驟了,需要的 libraries 都已經打包進去 (static linking) 或是標注了 (dynamic linking, 你可以 ldd 一個 .so 看看),因此就不需要麻煩使用這個 Library 的程式 Link 了。

因此,第二個解決方式,就是將 NetCDF 編譯為 Shared Library。

如果還有說明不清楚的,歡迎再繼續提問!

助教您好:
目前已經成功編譯了,非常感謝助教撥冗回答我的疑問!