HDF5 库无法使用 -mcmodel=large 进行编译

Posted

技术标签:

【中文标题】HDF5 库无法使用 -mcmodel=large 进行编译【英文标题】:The HDF5 library does not compile with -mcmodel=large 【发布时间】:2014-10-21 04:30:57 【问题描述】:

我正在尝试编译一个大型 FORTRAN 应用程序,并且需要将 HDF5 库链接到它。该程序需要使用 gfortran 编译,并且需要 -mcmodel=large 选项。仅使用 -mcmodel=medium 时,我收到如下错误消息:

:(.text+0x3019): relocation truncated to fit: R_X86_64_32 against `.lrodata'

我正在使用 configure 编译 HDF5 库:

./configure --enable-static-exec --enable-fortran FCFLAGS="-mcmodel=large" CFLAGS="-mcmodel=large"
make -j
make install

编译 FORTRAN 程序时,我得到:

H5_ff.f90:(.text+0x23): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0x3c): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0x52): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0x68): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0x89): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0x9f): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o
H5_ff.f90:(.text+0xb5): relocation truncated to fit: R_X86_64_PC32 against symbol `predefined_types_' defined in COMMON section in /tmp/ccHO0WzS.o

我在 linux 上,正在使用 gfortran 版本:4.7.2。

使用 -mcmodel=medium 编译有效,但前提是我减少了 FORTRAN 程序中变量的大小。那么,当使用 -mcmodel=large 时,我该如何使用 gfortran 和 HDF5 库编译 FORTRAN 程序?

我不能在这里展示真正的程序,但是为了理解这个想法,这里有一个重现错误的fortran程序:

PROGRAM test
IMPLICIT NONE
DOUBLE PRECISION tst(1000,1000,1000,1),bf
COMMON /tt/ tst
bf = tst(1,1,1,1)
print *,'Hello World.'
call kk
END PROGRAM


SUBROUTINE kk
USE H5LT
USE HDF5
IMPLICIT NONE
INTEGER(KIND=4)::errcode
call h5open_f(errcode)
print *,"Hello Subroutine."
END SUBROUTINE

编译:

gfortran -o tst -mcmodel=large tst.f90 -I./hdf5/hdf5/include -L./hdf5/hdf5/lib ./hdf5/hdf5/lib/libhdf5hl_fortran.a ./hdf5/hdf5/lib/libhdf5_hl.a ./hdf5/hdf5/lib/libhdf5_fortran.a ./hdf5/hdf5/lib/libhdf5.a -lz -lrt -ldl -lm -Wl,-rpath -Wl,./hdf5/hdf5/lib

并假设 ./hdf5/hdf5 中的 HDF5 库。然而,这个程序可以用 -mcmodel=medium 编译和运行,但我的真实程序没有。我无法想出一个不能用 -mcmodel=medium 编译但使用 -mcmodel=large 编译的简单程序。我什至不确定为什么 -mcmodel=medium 不适用于真正的程序。

HDF5 库在此处可用:http://www.hdfgroup.org/HDF5/release/obtain5.html

【问题讨论】:

请展示大数组的声明部分和维度的值。更好的是,想出一个仍然失败的完全可编译的示例。 对,我就是这么做的。但正如我在问题中解释的那样,这个虚拟程序并不能完全重现问题。 为我工作 gfortran-4.7 -mcmodel=large large.f90 -I/usr/include -lhdf5_fortran --> ./a.out Hello World. Hello Subroutine. 使用我在 OpenSUSE 中预装的 hdf5。 按照您在问题第一部分中的建议,查找对-mcmodel=large 失败的代码。当您执行“编译 FORTRAN 程序时,我得到:”时,编译命令的外观如何? 会不会是--enable-static-exec 标志?我可能是错的,但我认为这和-mcmodel=large 一起玩不好。你的机器有多少内存? 【参考方案1】:

我认为这是因为您的大型数组位于 COMMON 块中。这会将数组放在TEXT 段中。将其与 --enable-static-exec 结合使用意味着 TEXT 段超过 2GB。

通过删除 --enable-static-exec,您现在正在使用动态库,并已设法将 TEXT 段拉到 2GB 以下。

我敢说,如果你需要-mcmodel=large,你不应该把它和--enable-static-exec混在一起。

【讨论】:

以上是关于HDF5 库无法使用 -mcmodel=large 进行编译的主要内容,如果未能解决你的问题,请参考以下文章

将整个(大)架构转换为 hdf5

在 Windows 上使用带有 CMake 的 HDF5 库(错误:“找不到 HDF5”)

hdf5 Java 库入门

HDF5:构建 Fortran 库 (Windows)

链接静态 HDF5 Fortran 库

在 Windows 下通过 CMake 使用预编译的 HDF5 库