aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDylan Baker <dylan@pnwbakers.com>2019-06-24 16:41:10 -0700
committerGitHub <noreply@github.com>2019-06-24 16:41:10 -0700
commitec97bedd8afbf3bcb53b03365fb06fcf8c51b516 (patch)
treee468478fa96d3dd7bd96735008e82c756d884e5e
parente2039da5d99dc8fe4255069ef8ab14459766bf2d (diff)
parentf990c3eee456a186548dcc48f1d2dca5d8172fe4 (diff)
downloadmeson-ec97bedd8afbf3bcb53b03365fb06fcf8c51b516.zip
meson-ec97bedd8afbf3bcb53b03365fb06fcf8c51b516.tar.gz
meson-ec97bedd8afbf3bcb53b03365fb06fcf8c51b516.tar.bz2
Merge pull request #5524 from scivision/icl_ifort
Add ifort on Windows
-rw-r--r--mesonbuild/backend/ninjabackend.py6
-rw-r--r--mesonbuild/compilers/fortran.py27
-rw-r--r--mesonbuild/dependencies/misc.py6
-rw-r--r--mesonbuild/environment.py6
-rw-r--r--mesonbuild/interpreter.py16
-rwxr-xr-xrun_project_tests.py8
-rw-r--r--test cases/fortran/10 find library/meson.build8
-rw-r--r--test cases/fortran/13 coarray/meson.build3
-rw-r--r--test cases/fortran/6 dynamic/meson.build6
9 files changed, 54 insertions, 32 deletions
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 54535ff..a454e6a 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -2164,7 +2164,7 @@ https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47485'''))
# outdir argument instead.
# https://github.com/mesonbuild/meson/issues/1348
if not is_generated:
- abs_src = os.path.join(build_dir, rel_src)
+ abs_src = Path(build_dir) / rel_src
extra_deps += self.get_fortran_deps(compiler, abs_src, target)
# Dependency hack. Remove once multiple outputs in Ninja is fixed:
# https://groups.google.com/forum/#!topic/ninja-build/j-2RfBIOd_8
@@ -2802,7 +2802,7 @@ def _scan_fortran_file_deps(src: Path, srcdir: Path, dirname: Path, tdeps, compi
# a common occurrence, which would lead to lots of
# distracting noise.
continue
- srcfile = srcdir / tdeps[usename].fname
+ srcfile = srcdir / tdeps[usename].fname # type: Path
if not srcfile.is_file():
if srcfile.name != src.name: # generated source file
pass
@@ -2824,7 +2824,7 @@ def _scan_fortran_file_deps(src: Path, srcdir: Path, dirname: Path, tdeps, compi
ancestor_child = '_'.join(parents)
if ancestor_child not in tdeps:
raise MesonException("submodule {} relies on ancestor module {} that was not found.".format(submodmatch.group(2).lower(), ancestor_child.split('_')[0]))
- submodsrcfile = srcdir / tdeps[ancestor_child].fname
+ submodsrcfile = srcdir / tdeps[ancestor_child].fname # type: Path
if not submodsrcfile.is_file():
if submodsrcfile.name != src.name: # generated source file
pass
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index fe23b6b..effdbad 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -65,10 +65,14 @@ class FortranCompiler(CLikeCompiler, Compiler):
extra_flags = environment.coredata.get_external_args(self.for_machine, self.language)
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
extra_flags += self.get_always_args()
- # %% build the test executable
- pc = subprocess.Popen(self.exelist + extra_flags + [str(source_name), '-o', str(binary_name)])
- pc.wait()
- if pc.returncode != 0:
+ # %% build the test executable "sanitycheckf"
+ # cwd=work_dir is necessary on Windows especially for Intel compilers to avoid error: cannot write on sanitycheckf.obj
+ # this is a defect with how Windows handles files and ifort's object file-writing behavior vis concurrent ProcessPoolExecutor.
+ # This simple workaround solves the issue.
+ # FIXME: cwd=str(work_dir) is for Python 3.5 on Windows, when 3.5 is deprcated, this can become cwd=work_dir
+ returncode = subprocess.run(self.exelist + extra_flags + [str(source_name), '-o', str(binary_name)],
+ cwd=str(work_dir)).returncode
+ if returncode != 0:
raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string())
if self.is_cross:
if self.exe_wrapper is None:
@@ -79,9 +83,8 @@ class FortranCompiler(CLikeCompiler, Compiler):
cmdlist = [str(binary_name)]
# %% Run the test executable
try:
- pe = subprocess.Popen(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
- pe.wait()
- if pe.returncode != 0:
+ returncode = subprocess.run(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
+ if returncode != 0:
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
except OSError:
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
@@ -137,9 +140,7 @@ class FortranCompiler(CLikeCompiler, Compiler):
return filename
def find_library(self, libname, env, extra_dirs, libtype: LibType = LibType.PREFER_SHARED):
- code = '''program main
- call exit(0)
- end program main'''
+ code = '''stop; end program'''
return self.find_library_impl(libname, env, extra_dirs, code, libtype)
def has_multi_arguments(self, args, env):
@@ -158,7 +159,7 @@ class FortranCompiler(CLikeCompiler, Compiler):
'the compiler you are using. has_link_argument or '
'other similar method can be used instead.'
.format(arg))
- code = 'program main\ncall exit(0)\nend program main'
+ code = 'stop; end program'
return self.has_arguments(args, env, code, mode='compile')
@@ -271,8 +272,8 @@ class IntelClFortranCompiler(IntelVisualStudioLikeCompiler, FortranCompiler):
'custom': [],
}
- def __init__(self, exelist, version, is_cross, target: str, exe_wrapper=None):
- FortranCompiler.__init__(self, exelist, version, is_cross, exe_wrapper)
+ def __init__(self, exelist, for_machine: MachineChoice, version, is_cross, target: str, exe_wrapper=None):
+ FortranCompiler.__init__(self, exelist, for_machine, version, is_cross, exe_wrapper)
IntelVisualStudioLikeCompiler.__init__(self, target)
default_warn_args = ['/warn:general', '/warn:truncated_source']
diff --git a/mesonbuild/dependencies/misc.py b/mesonbuild/dependencies/misc.py
index e5fab64..1bb1b6e 100644
--- a/mesonbuild/dependencies/misc.py
+++ b/mesonbuild/dependencies/misc.py
@@ -66,6 +66,10 @@ class CoarrayDependency(ExternalDependency):
self.is_found = True
self.link_args = ['-coarray=shared']
self.compile_args = self.link_args
+ elif cid == 'intel-cl':
+ """ Coarrays are built into Intel compilers, no external library needed """
+ self.is_found = True
+ self.compile_args = ['/Qcoarray:shared']
elif cid == 'nagfor':
""" NAG doesn't require any special arguments for Coarray """
self.is_found = True
@@ -213,7 +217,7 @@ class MPIDependency(ExternalDependency):
if not self.is_found and mesonlib.is_windows():
# only Intel Fortran compiler is compatible with Microsoft MPI at this time.
- if language == 'fortran' and environment.detect_fortran_compiler(self.for_machine).name_string() != 'intel':
+ if language == 'fortran' and environment.detect_fortran_compiler(self.for_machine).name_string() != 'intel-cl':
return
result = self._try_msmpi()
if result is not None:
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 555c21c..0cf511f 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -792,7 +792,7 @@ class Environment:
else:
compiler_type = CompilerType.PGI_STANDARD
cls = PGICCompiler if lang == 'c' else PGICPPCompiler
- return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, compiler_type, exe_wrap)
+ return cls(ccache + compiler, version, compiler_type, for_machine, is_cross, exe_wrap)
if '(ICC)' in out:
if self.machines[for_machine].is_darwin():
compiler_type = CompilerType.ICC_OSX
@@ -854,7 +854,7 @@ class Environment:
return cls(ccache + compiler, version, for_machine, exe_wrap)
raise EnvironmentException('Could not find suitable CUDA compiler: "' + ' '.join(compilers) + '"')
- def detect_fortran_compiler(self, for_machine):
+ def detect_fortran_compiler(self, for_machine: MachineChoice):
popen_exceptions = {}
compilers, ccache, exe_wrap = self._get_compilers('fortran', for_machine)
is_cross = not self.machines.matches_build_machine(for_machine)
@@ -901,7 +901,7 @@ class Environment:
if 'Intel(R) Visual Fortran' in err:
version = search_version(err)
target = 'x86' if 'IA-32' in err else 'x86_64'
- return IntelClFortranCompiler(compiler, version, is_cross, target, exe_wrap)
+ return IntelClFortranCompiler(compiler, version, for_machine, is_cross, target, exe_wrap)
if 'ifort (IFORT)' in out:
return IntelFortranCompiler(compiler, version, for_machine, is_cross, exe_wrap, full_version=full_version)
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index dbe623c..59a3642 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -40,7 +40,7 @@ from collections import namedtuple
from itertools import chain
from pathlib import PurePath
import functools
-import typing
+from typing import Sequence, List, Union, Optional, Iterator, Dict, Any
import importlib
@@ -874,10 +874,10 @@ class RunTargetHolder(InterpreterObject, ObjectHolder):
return r.format(self.__class__.__name__, h.get_id(), h.command)
class Test(InterpreterObject):
- def __init__(self, name: str, project: str, suite: typing.List[str], exe: build.Executable,
- depends: typing.List[typing.Union[build.CustomTarget, build.BuildTarget]],
- is_parallel: bool, cmd_args: typing.List[str], env: build.EnvironmentVariables,
- should_fail: bool, timeout: int, workdir: typing.Optional[str], protocol: str):
+ def __init__(self, name: str, project: str, suite: List[str], exe: build.Executable,
+ depends: List[Union[build.CustomTarget, build.BuildTarget]],
+ is_parallel: bool, cmd_args: List[str], env: build.EnvironmentVariables,
+ should_fail: bool, timeout: int, workdir: Optional[str], protocol: str):
InterpreterObject.__init__(self)
self.name = name
self.suite = suite
@@ -2773,7 +2773,7 @@ external dependencies (including libraries) must go to "dependencies".''')
self.validate_arguments(args, 0, [])
raise Exception()
- def add_languages(self, args, required):
+ def add_languages(self, args: Sequence[str], required: bool) -> bool:
success = self.add_languages_for(args, required, MachineChoice.BUILD)
success &= self.add_languages_for(args, required, MachineChoice.HOST)
return success
@@ -3831,7 +3831,7 @@ different subdirectory.
# TODO make cross agnostic, just taking into account for_machine
# TODO PerMachine[T], Iterator[T]
- def get_argdict_on_crossness(self, dicts_per_machine: PerMachine, kwargs) -> typing.Iterator:
+ def get_argdict_on_crossness(self, dicts_per_machine: PerMachine, kwargs) -> Iterator:
for_native = kwargs.get('native', not self.environment.is_cross_build())
if not isinstance(for_native, bool):
raise InterpreterException('Keyword native must be a boolean.')
@@ -4218,7 +4218,7 @@ This will become a hard error in the future.''', location=self.current_node)
return varname in self.variables
@staticmethod
- def machine_from_native_kwarg(kwargs: typing.Dict[str, typing.Any]) -> MachineChoice:
+ def machine_from_native_kwarg(kwargs: Dict[str, Any]) -> MachineChoice:
native = kwargs.get('native', False)
if not isinstance(native, bool):
raise InvalidArguments('Argument to "native" must be a boolean.')
diff --git a/run_project_tests.py b/run_project_tests.py
index c15b93b..3bd3253 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -600,6 +600,12 @@ def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]:
gathered_tests: list of tuple of str, list of pathlib.Path, bool
tests to run
"""
+
+ ninja_fortran_compiler = shutil.which('gfortran') or shutil.which('flang') or shutil.which('pgfortran') or (not mesonlib.is_windows() and shutil.which('ifort'))
+ ninja_fortran = backend is Backend.ninja and ninja_fortran_compiler
+ vs_fortran = mesonlib.is_windows() and backend is Backend.vs and shutil.which('ifort')
+ skip_fortran = not(ninja_fortran or vs_fortran)
+
# Name, subdirectory, skip condition.
all_tests = [
('cmake', 'cmake', not shutil.which('cmake') or (os.environ.get('compiler') == 'msvc2015' and under_ci)),
@@ -621,7 +627,7 @@ def detect_tests_to_run(only: List[str]) -> List[Tuple[str, List[Path], bool]]:
('d', 'd', backend is not Backend.ninja or not have_d_compiler()),
('objective c', 'objc', backend not in (Backend.ninja, Backend.xcode) or not have_objc_compiler()),
('objective c++', 'objcpp', backend not in (Backend.ninja, Backend.xcode) or not have_objcpp_compiler()),
- ('fortran', 'fortran', backend is not Backend.ninja or not shutil.which('gfortran')),
+ ('fortran', 'fortran', skip_fortran),
('swift', 'swift', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('swiftc')),
('cuda', 'cuda', backend not in (Backend.ninja, Backend.xcode) or not shutil.which('nvcc')),
('python3', 'python3', backend is not Backend.ninja),
diff --git a/test cases/fortran/10 find library/meson.build b/test cases/fortran/10 find library/meson.build
index be66888..2a2ef31 100644
--- a/test cases/fortran/10 find library/meson.build
+++ b/test cases/fortran/10 find library/meson.build
@@ -1,9 +1,13 @@
project('find fortran library', 'fortran')
-fortranc = meson.get_compiler('fortran')
+fc = meson.get_compiler('fortran')
sources = ['main.f90', 'gzip.f90']
-zlib = fortranc.find_library('z')
+zlib = fc.find_library('z', required: false)
+
+if not zlib.found()
+ error('MESON_SKIP_TEST: Z library not available.')
+endif
exe = executable('zlibtest', sources, dependencies : zlib)
test('testzlib', exe)
diff --git a/test cases/fortran/13 coarray/meson.build b/test cases/fortran/13 coarray/meson.build
index 57aa29e..3160aa6 100644
--- a/test cases/fortran/13 coarray/meson.build
+++ b/test cases/fortran/13 coarray/meson.build
@@ -1,4 +1,5 @@
-project('Fortran coarray', 'fortran')
+project('Fortran coarray', 'fortran',
+ meson_version: '>=0.50')
# coarray is required because single-image fallback is an intrinsic feature
coarray = dependency('coarray', required : true)
diff --git a/test cases/fortran/6 dynamic/meson.build b/test cases/fortran/6 dynamic/meson.build
index e5e259f..244a38b 100644
--- a/test cases/fortran/6 dynamic/meson.build
+++ b/test cases/fortran/6 dynamic/meson.build
@@ -1,5 +1,11 @@
project('dynamic_fortran', 'fortran')
+if meson.get_compiler('fortran').get_id() == 'intel-cl'
+ error('MESON_SKIP_TEST: Windows ifort does not use shared_library in a sane way')
+ # !DEC$ ATTRIBUTES DLLEXPORT must be used!
+ # https://software.intel.com/en-us/node/535306
+endif
+
dynamic = shared_library('dynamic', 'dynamic.f90')
exe = executable('test_exe', 'main.f90', link_with : dynamic)
test('dynamic-fortran', exe)