【问题标题】:gfortran linking c libraries with condagfortran 将 c 库与 conda 链接
【发布时间】:2020-10-07 10:45:49
【问题描述】:

我正在尝试在没有超级用户权限的 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 因“分段错误(核心转储)”而崩溃。我必须重新安装 anaconda 才能让 conda 再次工作。

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

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

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

【问题讨论】:

    标签: linux compiler-errors conda cross-compiling gfortran


    【解决方案1】:

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

    根据我的经验,我发现 Conda Forge 编译器包有助于简化自定义编译环境的创建和使用。例如,here is the YAML definition 是我用来构建kallisto 软件的环境。对于您的情况,我希望像

    fortran-compiler.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 中的库(例如,search for libx11),不幸的是,这并不总是从库名称到包名称的一对一映射。优点是这样定义的编译环境可以促进跨平台传输 - 例如,我为 kallisto 提供的示例 YAML 可以在 osx-64linux-64 上运行没有任何更改 - 因为它明确定义 Conda 将提供共享库。

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

    【讨论】:

    • 谢谢,效果很好。除了您的解决方案之外,我只需修改我的 gfortran 调用以使用 -L 指示虚拟环境中库的位置。没有更多错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-22
    • 1970-01-01
    • 2013-09-03
    • 1970-01-01
    相关资源
    最近更新 更多