BUGFIX: broken/missing Fortran code/unit tests

pull/4838/head
Michael Hirsch, Ph.D 6 years ago committed by Jussi Pakkanen
parent 3fc8a0dc41
commit 8636f31d9c
  1. 5
      mesonbuild/compilers/c.py
  2. 2
      mesonbuild/compilers/compilers.py
  3. 13
      mesonbuild/compilers/fortran.py
  4. 2
      mesonbuild/environment.py
  5. 6
      run_unittests.py
  6. 5
      test cases/fortran/1 basic/meson.build
  7. 56
      test cases/fortran/10 find library/gzip.f90
  8. 78
      test cases/fortran/10 find library/main.f90
  9. 15
      test cases/fortran/4 self dependency/selfdep.f90
  10. 10
      test cases/fortran/5 static/main.f90
  11. 18
      test cases/fortran/5 static/static_hello.f90
  12. 18
      test cases/fortran/6 dynamic/dynamic.f90
  13. 9
      test cases/fortran/6 dynamic/main.f90
  14. 4
      test cases/fortran/8 module names/mod1.f90
  15. 4
      test cases/fortran/8 module names/mod2.f90
  16. 11
      test cases/fortran/8 module names/test.f90
  17. 12
      test cases/fortran/9 cpp/fortran.f
  18. 2
      test cases/fortran/9 cpp/meson.build

@ -19,6 +19,7 @@ import subprocess
import functools
import itertools
from pathlib import Path
from typing import List
from .. import mlog
from .. import coredata
@ -456,7 +457,7 @@ class CCompiler(Compiler):
return self.compiles(code, env, extra_args=extra_args,
dependencies=dependencies, mode='link')
def run(self, code, env, *, extra_args=None, dependencies=None):
def run(self, code: str, env, *, extra_args=None, dependencies=None):
if self.is_cross and self.exe_wrapper is None:
raise CrossNoRunException('Can not run test applications in this cross environment.')
with self._build_wrapper(code, env, extra_args, dependencies, mode='link', want_output=True) as p:
@ -978,7 +979,7 @@ class CCompiler(Compiler):
return [f.as_posix()]
@staticmethod
def _get_file_from_list(files):
def _get_file_from_list(files: List[str]) -> str:
for f in files:
if os.path.isfile(f):
return f

@ -1795,7 +1795,7 @@ class ArmclangCompiler:
EnvironmentException('armlink version string not found')
# Using the regular expression from environment.search_version,
# which is used for searching compiler version
version_regex = '(?<!(\d|\.))(\d{1,2}(\.\d+)+(-[a-zA-Z0-9]+)?)'
version_regex = r'(?<!(\d|\.))(\d{1,2}(\.\d+)+(-[a-zA-Z0-9]+)?)'
linker_ver = re.search(version_regex, ver_str)
if linker_ver:
linker_ver = linker_ver.group(0)

@ -11,6 +11,8 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from typing import List
import subprocess, os
from .c import CCompiler
from .compilers import (
@ -29,7 +31,7 @@ from .compilers import (
)
from mesonbuild.mesonlib import EnvironmentException, is_osx
import subprocess, os
class FortranCompiler(Compiler):
library_dirs_cache = CCompiler.library_dirs_cache
@ -228,7 +230,7 @@ end program prog
dependencies=dependencies)
def run(self, code, env, *, extra_args=None, dependencies=None):
return CCompiler.run(self, code, env, extra_args, dependencies)
return CCompiler.run(self, code, env, extra_args=extra_args, dependencies=dependencies)
def _get_patterns(self, *args, **kwargs):
return CCompiler._get_patterns(self, *args, **kwargs)
@ -263,6 +265,13 @@ end program prog
def has_multi_arguments(self, args, env):
return CCompiler.has_multi_arguments(self, args, env)
@classmethod
def _get_trials_from_pattern(cls, pattern, directory, libname):
return CCompiler._get_trials_from_pattern(pattern, directory, libname)
@staticmethod
def _get_file_from_list(files) -> List[str]:
return CCompiler._get_file_from_list(files)
class GnuFortranCompiler(GnuCompiler, FortranCompiler):
def __init__(self, exelist, version, compiler_type, is_cross, exe_wrapper=None, defines=None, **kwargs):

@ -321,7 +321,7 @@ def search_version(text):
# This regex is reaching magic levels. If it ever needs
# to be updated, do not complexify but convert to something
# saner instead.
version_regex = '(?<!(\d|\.))(\d{1,2}(\.\d+)+(-[a-zA-Z0-9]+)?)'
version_regex = r'(?<!(\d|\.))(\d{1,2}(\.\d+)+(-[a-zA-Z0-9]+)?)'
match = re.search(version_regex, text)
if match:
return match.group(0)

@ -5304,11 +5304,15 @@ class NativeFileTests(BasePlatformTests):
if comp.id == 'gcc':
if shutil.which('ifort'):
return 'ifort', 'intel'
elif shutil.which('flang'):
return 'flang', 'flang'
elif shutil.which('pgfortran'):
return 'pgfortran', 'pgi'
# XXX: there are several other fortran compilers meson
# supports, but I don't have any of them to test with
raise unittest.SkipTest('No alternate Fortran implementation.')
if not shutil.which('gfortran'):
raise unittest.SkipTest('No alternate C# implementation.')
raise unittest.SkipTest('No alternate Fortran implementation.')
return 'gfortran', 'gcc'
self.helper_for_compiler('fortran', cb)

@ -1,6 +1,9 @@
project('simple fortran', 'fortran')
add_global_arguments('-fbounds-check', language : 'fortran')
fc = meson.get_compiler('fortran')
if fc == 'gcc'
add_global_arguments('-fbounds-check', language : 'fortran')
endif
e = executable('simple', 'simple.f90',
fortran_args : '-ffree-form')

@ -1,32 +1,32 @@
module gzip
interface
function gzopen(path, mode) bind(C)
use iso_c_binding, only: c_char, c_ptr
implicit none
character(c_char), intent(in) :: path(*), mode(*)
type(c_ptr) :: gzopen
end function gzopen
end interface
interface
function gzwrite(file, buf, len) bind(C)
use iso_c_binding, only: c_int, c_ptr
implicit none
type(c_ptr), value, intent(in) :: file
type(*), intent(in) :: buf
integer(c_int), value, intent(in) :: len
integer(c_int) :: gzwrite
end function gzwrite
end interface
interface
function gzclose(file) bind(C)
use iso_c_binding, only: c_int, c_ptr
implicit none
type(c_ptr), value, intent(in) :: file
integer(c_int) :: gzclose
end function gzclose
end interface
use iso_c_binding, only: c_char, c_ptr, c_int
implicit none
interface
type(c_ptr) function gzopen(path, mode) bind(C)
import c_char, c_ptr
character(kind=c_char), intent(in) :: path(*), mode(*)
end function gzopen
end interface
interface
integer(c_int) function gzwrite(file, buf, len) bind(C)
import c_int, c_ptr, c_char
type(c_ptr), value, intent(in) :: file
character(kind=c_char), intent(in) :: buf
integer(c_int), value, intent(in) :: len
end function gzwrite
end interface
interface
integer(c_int) function gzclose(file) bind(C)
import c_int, c_ptr
type(c_ptr), value, intent(in) :: file
end function gzclose
end interface
end module gzip

@ -1,40 +1,38 @@
program main
use iso_c_binding, only: c_int, c_char, c_null_char, c_ptr
use gzip, only: gzopen, gzwrite, gzclose
implicit none
character(kind=c_char,len=*), parameter :: path = &
c_char_"test.gz"//c_null_char
character(kind=c_char,len=*), parameter :: mode = &
c_char_"wb9"//c_null_char
integer(c_int), parameter :: buffer_size = 512
type(c_ptr) :: file
character(len=buffer_size) :: buffer
integer(c_int) :: ret
integer :: i
! open file
file = gzopen(path, mode)
! fill buffer with data
do i=1,buffer_size/4
write(buffer(4*(i-1)+1:4*i), '(i3.3, a)') i, new_line('')
end do
ret = gzwrite(file, buffer, buffer_size)
if (ret.ne.buffer_size) then
write(*,'(a, i3, a, i3, a)') 'Error: ', ret, ' / ', buffer_size, &
' bytes written.'
stop 1
end if
! close file
ret = gzclose(file)
if (ret.ne.0) then
print *, 'Error: failure to close file with error code ', ret
stop 1
end if
end program main
use iso_fortran_env, only: stderr=>error_unit
use iso_c_binding, only: c_int, c_char, c_null_char, c_ptr
use gzip, only: gzopen, gzwrite, gzclose
implicit none
character(kind=c_char,len=*), parameter :: path = c_char_"test.gz"//c_null_char
character(kind=c_char,len=*), parameter :: mode = c_char_"wb9"//c_null_char
integer(c_int), parameter :: buffer_size = 512
type(c_ptr) :: file
character(kind=c_char, len=buffer_size) :: buffer
integer(c_int) :: ret
integer :: i
! open file
file = gzopen(path, mode)
! fill buffer with data
do i=1,buffer_size/4
write(buffer(4*(i-1)+1:4*i), '(i3.3, a)') i, new_line('')
end do
ret = gzwrite(file, buffer, buffer_size)
if (ret /= buffer_size) then
write(stderr,'(a, i3, a, i3, a)') 'Error: ', ret, ' / ', buffer_size, &
' bytes written.'
stop 1
end if
! close file
ret = gzclose(file)
if (ret /= 0) then
write(stderr,*) 'Error: failure to close file with error code ', ret
stop 1
end if
end program

@ -1,11 +1,18 @@
MODULE Circle
REAL, PARAMETER :: Pi = 3.1415927
MODULE geom
type :: circle
REAL :: Pi = 4.*atan(1.)
REAL :: radius
END MODULE Circle
end type circle
END MODULE geom
PROGRAM prog
use Circle
use geom, only : circle
IMPLICIT NONE
type(circle) :: ell
ell%radius = 3.
END PROGRAM prog

@ -1,6 +1,6 @@
program hello
use static_hello
implicit none
call static_say_hello()
end program hello
use static_hello
implicit none
call static_say_hello()
end program

@ -1,17 +1,17 @@
module static_hello
implicit none
implicit none
private
public :: static_say_hello
private
public :: static_say_hello
interface static_say_hello
module procedure say_hello
end interface static_say_hello
interface static_say_hello
module procedure say_hello
end interface static_say_hello
contains
subroutine say_hello
print *, "Static library called."
end subroutine say_hello
subroutine say_hello
print *, "Static library called."
end subroutine say_hello
end module static_hello

@ -1,17 +1,17 @@
module dynamic
implicit none
implicit none
private
public :: hello
private
public :: hello
interface hello
module procedure say
end interface hello
interface hello
module procedure say
end interface hello
contains
subroutine say
print *, "Hello, hello..."
end subroutine say
subroutine say
print *, "Hello from shared library."
end subroutine say
end module dynamic

@ -1,6 +1,5 @@
program main
use dynamic
implicit none
use dynamic, only: hello
implicit none
call hello()
end program main
call hello()
end program

@ -1,6 +1,6 @@
module MyMod1
implicit none
implicit none
integer, parameter :: myModVal1 = 1
integer, parameter :: myModVal1 = 1
end module MyMod1

@ -1,6 +1,6 @@
module mymod2
implicit none
implicit none
integer, parameter :: myModVal2 = 2
integer, parameter :: myModVal2 = 2
end module mymod2

@ -1,7 +1,8 @@
program test
use mymod1
use MyMod2
use mymod1
use MyMod2
integer, parameter :: testVar = myModVal1 + myModVal2
implicit none
end program test
integer, parameter :: testVar = myModVal1 + myModVal2
end program

@ -1,5 +1,11 @@
function fortran() bind(C)
use, intrinsic :: iso_c_binding
real(kind=c_double) :: fortran
fortran = 2.0**rand(1)
use, intrinsic :: iso_c_binding, only: dp=>c_double
implicit none
real(dp) :: r, fortran
call random_number(r)
fortran = 2._dp**r
end function fortran

@ -15,7 +15,7 @@ endif
e = executable(
'cppfort',
['main.cpp', 'fortran.f'],
dependencies : [link_with],
dependencies : link_with,
)
test('C++ FORTRAN', e)

Loading…
Cancel
Save