gfortran将c库与conda链接



我正试图在没有超级用户权限的Ubuntu 18.04服务器上使用conda编译一个C++/Fortran程序。

我能够在Ubuntu 18.04 PC上用相同的源代码正确编译程序(也使用conda(,但在服务器上我遇到了一堆错误。此刻,我被一个";未找到库-未定义引用";错误:

gfortran -o glm -Wl,--export-dynamic obj/glm_globals.o obj/glm_util.o obj/glm_csv.o obj/glm_mobl.o obj/glm_mixu.o obj/glm_wqual.o obj/glm_layers.o obj/glm_surface.o obj/glm_input.o obj/glm_plot.o obj/glm_output.o obj/glm_ncdf.o obj/glm_lnum.o obj/glm_init.o obj/glm_flow.o obj/glm_mixer.o obj/glm_deep.o obj/glm_stress.o obj/glm_bird.o obj/glm_model.o obj/glm_types.o obj/glm_const.o obj/glm_debug.o obj/glm_main.o obj/glm_zones.o -L/local/XXX/my_name/PycharmProjects/glm/glm_source/GLM/../libutil/lib -lutil -L/local/XXX/my_name/anaconda3/lib -lnetcdf -L/usr/lib -L/local/XXX/my_name/PycharmProjects/glm/glm_source/GLM/../libplot/lib -lplot -lgd -lpng -ljpeg -lm -lX11    -lgfortran
/local/XXX/my_name/anaconda3/bin/ld: warning: libpthread.so.0, needed by /local/XXX/my_name/anaconda3/lib/libnetcdf.so, not found (try using -rpath or -rpath-link)
/local/XXX/my_name/anaconda3/bin/ld: warning: libxcb.so.1, needed by /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libX11.so, not found (try using -rpath or -rpath-link)
/local/XXX/my_name/anaconda3/bin/ld: warning: libdl.so.2, needed by /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libX11.so, not found (try using -rpath or -rpath-link)
/local/XXX/my_name/anaconda3/bin/ld: warning: librt.so.1, needed by /local/XXX/my_name/anaconda3/lib/./libhdf5_hl.so.100, not found (try using -rpath or -rpath-link)
/local/XXX/my_name/anaconda3/bin/ld: warning: libresolv.so.2, needed by /local/XXX/my_name/anaconda3/lib/././libgssapi_krb5.so.2, not found (try using -rpath or -rpath-link)
/local/XXX/my_name/anaconda3/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libX11.so: undefined reference to `dlopen@GLIBC_2.2.5'
/local/XXX/my_name/anaconda3/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/libX11.so: undefined reference to `xcb_wait_for_event'
/local/XXX/my_name/anaconda3/bin/ld: /local/XXX/my_name/anaconda3/lib/././libkrb5.so.3: undefined reference to `__res_nsearch@GLIBC_2.2.5'
...
collect2: error: ld returned 1 exit status
Makefile:277: recipe for target 'glm' failed
make: *** [glm] Error 1

我可以看到链接器找不到的共享库libpthread.so.0、librt.so.1、libdl.so.2、libresolv.so.2是glibc的一部分。因此,我认为连接到该库存在某种问题。

在之前的一次尝试中,我尝试使用conda安装glibc。这导致conda以";分段故障(堆芯倾倒(";当我试图编译时。我不得不重新安装蟒蛇才能让蟒蛇再次工作。

在过去的几天里,我还尝试按照警告中的建议添加-rpath,添加LD_LIBRARY_PATH,添加包含带有-L的共享库的目录。什么都没用。

此刻我感到很失落。你知道可能出了什么问题吗?

附言:在我的电脑上编译和在服务器上编译的区别在于,我在电脑上的系统中安装了缺失的库,但在服务器上的conda上。因此,在服务器上编译时,我不得不用-L添加这些库的位置。

这个答案是一个建议的替代工作流程,旨在避免问题,而不是在OP中准确诊断问题。

根据我的经验,我发现Conda Forge编译器包有助于简化编译自定义环境的创建和使用。举个例子,这里是我用来构建kallisto软件的环境的YAML定义。对于你的情况,我希望有类似的东西

fortran编译器.yaml

name: fortran-compiler  # name it what you want
channels:
- conda-forge
- defaults
dependencies:
- fortran-compiler
- cxx-compiler
- libpng
- libgd
- jpeg
- libnetcdf
- openlibm
- xorg-libx11
# include the other required libraries

使用创建环境

conda env create -f fortran-compiler.yaml

然后在激活该环境的情况下运行编译。激活环境应该自动管理链接器的外观,以便在环境中找到库(这在一定程度上是Conda Forge*-compiler包提供的(。这个想法是让尽可能多的库来自环境本身。

我发现这种方法将手动定位和包括库路径的数量保持在最低限度。然而,它确实需要追踪Conda Forge中的库(例如,搜索libx11(,不幸的是,这并不总是从库名称到包名称的一对一映射。其优点是,以这种方式定义的编译环境可以促进跨平台的传输——例如,我为kallisto提供的示例YAML在osx-64linux-64上都可以工作,而不会有任何更改——因为它明确定义了Conda将提供共享库。

也许有更简单的方法可以做到这一点,但这至少是我在多次尝试直接使用gccclangAnaconda包的糟糕经历后发现的有效方法。

最新更新