【发布时间】:2021-10-23 09:20:34
【问题描述】:
我是 Fortran 的初学者,正在运行由 Fortran 编写的模型。当我尝试编译它时,我收到一条错误消息,例如:
libtool: link: (cd ".libs" && rm -f "libgrib_api_f77.so" && ln -s "libgrib_api_f77.so.1.0.0" "libgrib_api_f77.so")
libtool: link: ar cru .libs/libgrib_api_f77.a grib_fortran.o grib_f77.o
libtool: link: ranlib .libs/libgrib_api_f77.a
libtool: link: ( cd ".libs" && rm -f "libgrib_api_f77.la" && ln -s "../libgrib_api_f77.la" "libgrib_api_f77.la" )
gfortran -c -o same_int_long.o same_int_long.f90
same_int_long.f90:23:18:
17 | call check_long(x2(1),x2(2),ret)
| 2
......
23 | call check_long(x4(1),x4(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:29:18:
17 | call check_long(x2(1),x2(2),ret)
| 2
......
29 | call check_long(x8(1),x8(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
same_int_long.f90:51:17:
45 | call check_int(x2(1),x2(2),ret)
| 2
......
51 | call check_int(x4(1),x4(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(4)/INTEGER(2)).
same_int_long.f90:57:17:
45 | call check_int(x2(1),x2(2),ret)
| 2
......
57 | call check_int(x8(1),x8(2),ret)
| 1
Error: Type mismatch between actual argument at (1) and actual argument at (2) (INTEGER(8)/INTEGER(2)).
make[2]: *** [Makefile:546: same_int_long.o] Error 1
make[2]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source/fortran'
make[1]: *** [Makefile:604: all-recursive] Error 1
make[1]: Leaving directory '/gpfs/home3/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source'
make: *** [Makefile:398: /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran/include/grib_api.mod] Error 2
我所做的基本上是按照模型的安装:
第一步
(base) [eccei339@int3 ~]$ mkdir snellius_surfex
(base) [eccei339@int3 ~]$ cp open_surfex_v8_1_20200107.tar-2.gz snellius_surfex/
(base) [eccei339@int3 ~]$ cd snellius_surfex/
(base) [eccei339@int3 snellius_surfex]$ tar zxvf open_surfex_v8_1_20200107.tar-2.gz
…(省略 tar zxvf 日志信息)
第 2 步:一些必要的环境变量
(base) [eccei339@int3 snellius_surfex]$ export VER_MPI="NOMPI"
(base) [eccei339@int3 snellius_surfex]$ export OMP_NUM_THREADS=1
(base) [eccei339@int3 snellius_surfex]$ module load 2021
(base) [eccei339@int3 snellius_surfex]$ module load GCC/10.3.0
(base) [eccei339@int3 snellius_surfex]$ ls
open_SURFEX_V8_1 open_surfex_v8_1_20200107.tar-2.gz
(这里我按照软件安装说明导出了一些必要的env var)
第 3 步:配置
(base) [eccei339@int3 snellius_surfex]$ cd open_SURFEX_V8_1/src/
(base) [eccei339@int3 src]$ ls
ASSIM Makefile Rules.bullXI15.mk Rules.MCgfortran.mk SURFEX
configure Makefile.SURFEX.mk Rules.bullXI16.mk Rules.SX8.mk
FORC OFFLIN Rules.LXgfortran.mk Rules.zgfortran.mk
include Rules.AIX64.mk Rules.LXifort.mk Rules.zifort.mk
LIB Rules.bgfortran.mk Rules.LXpgi.mk scripts
(base) [eccei339@int3 src]$ ./configure
(省略“configure”命令的长日志信息)
(base) [eccei339@int3 src]$ . ../conf/profile_surfex-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0
(软件安装说明的必要步骤)
第 4 步:制作大师
(base) [eccei339@int3 src]$ make
find: ‘/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/dir_obj-LXgfortran-SFX-V8-1-1-NOMPI-OMP-O2-X0/MASTER’: No such file or directory
cd /home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source && LDFLAGS= FCFLAGS= CPPFLAGS="" \
./configure --disable-jpeg --prefix=/home/eccei339/snellius_surfex/open_SURFEX_V8_1/src/LIB/grib_api-1.17.0-Source-LXgfortran FC="gfortran" && \
make -j 1 clean && \
make -j 1 && \
make -j 1 install && \
make -j 1 clean
checking build system type... x86_64-unknown-linux-gnu
checking host system type... x86_64-unknown-linux-gnu
checking how to print strings... printf
checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
(省略长日志信息,最后几行是本问题描述开头显示的错误消息。)
我上网查了一下,这可能是因为 GCC 10 比旧的 GCC 更严格(我去年用旧的 GCC 编译了这个模型并做了,但是这次失败了,因为我们的服务器转移到了一个新的系统,因此 GCC 从旧版本升级到新版本)。来自 Google 的一些信息说我可以添加如下内容:
export FCFLAGS="-w -fallow-argument-mismatch -O2"
export FFLAGS="-w -fallow-argument-mismatch -O2"
但我在步骤 2 中尝试了导出一些基本环境变量,但它仍然无法正常工作。所以我想知道有没有人可以帮助我?非常感谢!
更新:http://distfiles.macports.org/grib_api/的grib_api-1.17.0-Source/fortran/same_int_long.f90源代码如下:
! Copyright 2005-2016 ECMWF.
!
! This software is licensed under the terms of the Apache Licence Version 2.0
! which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
!
! In applying this licence, ECMWF does not waive the privileges and immunities granted to it by
! virtue of its status as an intergovernmental organisation nor does it submit to any jurisdiction.
integer function kind_of_long()
integer(2), dimension(2) :: x2 = (/1, 2/)
integer(4), dimension(2) :: x4 = (/1, 2/)
integer(8), dimension(2) :: x8 = (/1, 2/)
character(len=1) :: ret
kind_of_long=-1
call check_long(x2(1),x2(2),ret)
if (ret == 't') then
kind_of_long=2
return
endif
call check_long(x4(1),x4(2),ret)
if (ret == 't') then
kind_of_long=4
return
endif
call check_long(x8(1),x8(2),ret)
if (ret == 't') then
kind_of_long=8
return
endif
end function kind_of_long
integer function kind_of_int()
integer(2), dimension(2) :: x2 = (/1, 2/)
integer(4), dimension(2) :: x4 = (/1, 2/)
integer(8), dimension(2) :: x8 = (/1, 2/)
character(len=1) :: ret
kind_of_int=-1
call check_int(x2(1),x2(2),ret)
if (ret == 't') then
kind_of_int=2
return
endif
call check_int(x4(1),x4(2),ret)
if (ret == 't') then
kind_of_int=4
return
endif
call check_int(x8(1),x8(2),ret)
if (ret == 't') then
kind_of_int=8
return
endif
end function kind_of_int
program same_int_long
integer ki,kl
ki=kind_of_int()
kl=kind_of_long()
if (ki /= kl) then
write (*,'(i1)') 0
else
write (*,'(i1)') 1
endif
end program same_int_long
这里是make的完整日志信息:https://drive.google.com/file/d/14rkj2ay39Rv84QBL6UDiSdlIAfhuEt_z/view?usp=sharing
【问题讨论】:
-
为了能够说出任何我们需要查看可以运行的完整代码 (MWE) 的内容,至少我们需要
x..和check_long的声明/定义 -
嗨@Albert,感谢您的回复!但我认为这与
x..或check_long无关...应该是因为不匹配错误...似乎较旧的GCC在编译它们时可以容忍代码中的这种不匹配,但是GCC 10不能... -
您必须出示代码。在传递参数时使用参数的声明和子例程内的声明。这不太可能是由于 GCC10 造成的,更有可能是声明中存在一些不可移植性。值得注意的是,如果您知道原因,就不会在这里寻求帮助,所以如果人们认为声明是必要的,这确实意味着它们很可能是需要的。
-
嗨@VladimirF,感谢您的回复!查了一下日志信息,发现是
gfortran -c -o same_int_long.o same_int_long.f90使用make编译master的时候报错了。而且我找不到这个 .f90 文件在哪里...我只知道./configure的日志信息,它在grib_api-1.17.0-Source/fortran/same_int_long.f90... -
@XuShan 很可能是关于
x..或check_long,旧的编译器在编译过程中对不同大小类型不同长度的变量更加宽松,导致运行过程中出现未定义的行为时间和可能的错误。所以显示你的代码。
标签: linux makefile fortran gnu-make gfortran