Skip to content

Commit 30b1774

Browse files
eli-schwartzxclaesse
authored andcommitted
compilers: unify fortran sanity check with its parent Clike handling
We *mostly* just need to do the same thing. Plug in one utility method to make sanity_check_impl find the right compile args, and plug in DEVNULL to the test run. It's that simple. This solves a few inconsistencies. The main one is that fortran never logged the sanity checks to the Meson debug log, making it hard to debug. There's also some interesting quirks we built up in the dedicated fortran handling. For example: - in commit 5b109c9 we added cwd to building the fortran executable, with a wordy comment about how the compiler has defects. But the clike base has always done that on general principle anyway, so we would never have had that bug in the first place. - in commit d6be782 we added special deletion of an old "bad existing exe file" just for fortran. Looking at the PR discussion for this odd requirement, it turns out that the real problem is mixing WSL and native Windows without deleting the build directory. This is apparently fortran specific simply because "contemporary Windows 10 Fortran users" switch between the two? The actual problem is that this never used .exe as the output name, so Windows thinks you want to run something other than the thing you asked to run, because it's not even a Window executable. But... the common clike handling could have fixed that without needing special cases.
1 parent 332968d commit 30b1774

File tree

2 files changed

+14
-40
lines changed

2 files changed

+14
-40
lines changed

mesonbuild/compilers/fortran.py

Lines changed: 11 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,8 @@
1313
# limitations under the License.
1414
from __future__ import annotations
1515

16-
from pathlib import Path
1716
import typing as T
18-
import subprocess, os
17+
import os
1918

2019
from .. import coredata
2120
from .compilers import (
@@ -32,7 +31,7 @@
3231
from .mixins.pgi import PGICompiler
3332

3433
from mesonbuild.mesonlib import (
35-
version_compare, EnvironmentException, MesonException,
34+
version_compare, MesonException,
3635
LibType, OptionKey,
3736
)
3837

@@ -67,41 +66,15 @@ def has_function(self, funcname: str, prefix: str, env: 'Environment', *,
6766
"meson.get_compiler('fortran').links('block; end block; end program')\n\n"
6867
'that example is to see if the compiler has Fortran 2008 Block element.')
6968

70-
def sanity_check(self, work_dir_: str, environment: 'Environment') -> None:
71-
work_dir = Path(work_dir_)
72-
source_name = work_dir / 'sanitycheckf.f90'
73-
binary_name = work_dir / 'sanitycheckf'
74-
if binary_name.is_file():
75-
binary_name.unlink()
76-
77-
source_name.write_text('program main; print *, "Fortran compilation is working."; end program', encoding='utf-8')
78-
79-
extra_flags: T.List[str] = []
80-
extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
81-
extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
82-
extra_flags += self.get_always_args()
83-
# %% build the test executable "sanitycheckf"
84-
# cwd=work_dir is necessary on Windows especially for Intel compilers to avoid error: cannot write on sanitycheckf.obj
85-
# this is a defect with how Windows handles files and ifort's object file-writing behavior vis concurrent ProcessPoolExecutor.
86-
# This simple workaround solves the issue.
87-
returncode = subprocess.run(self.exelist + extra_flags + [str(source_name), '-o', str(binary_name)],
88-
cwd=work_dir).returncode
89-
if returncode != 0:
90-
raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string())
91-
if self.is_cross:
92-
if self.exe_wrapper is None:
93-
# Can't check if the binaries run so we have to assume they do
94-
return
95-
cmdlist = self.exe_wrapper.get_command() + [str(binary_name)]
96-
else:
97-
cmdlist = [str(binary_name)]
98-
# %% Run the test executable
99-
try:
100-
returncode = subprocess.run(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL).returncode
101-
if returncode != 0:
102-
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
103-
except OSError:
104-
raise EnvironmentException('Executables created by Fortran compiler %s are not runnable.' % self.name_string())
69+
def _get_basic_compiler_args(self, env: 'Environment', mode: CompileCheckMode) -> T.Tuple[T.List[str], T.List[str]]:
70+
cargs = env.coredata.get_external_args(self.for_machine, self.language)
71+
largs = env.coredata.get_external_link_args(self.for_machine, self.language)
72+
return cargs, largs
73+
74+
def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
75+
source_name = 'sanitycheckf.f90'
76+
code = 'program main; print *, "Fortran compilation is working."; end program\n'
77+
return self._sanity_check_impl(work_dir, environment, source_name, code)
10578

10679
def get_buildtype_args(self, buildtype: str) -> T.List[str]:
10780
return gnulike_buildtype_args[buildtype]

mesonbuild/compilers/mixins/clike.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,7 @@ def _sanity_check_impl(self, work_dir: str, environment: 'Environment',
294294
if self.is_cross:
295295
binname += '_cross'
296296
if self.exe_wrapper is None:
297-
# Linking cross built apps is painful. You can't really
297+
# Linking cross built C/C++ apps is painful. You can't really
298298
# tell if you should use -nostdlib or not and for example
299299
# on OSX the compiler binary is the same but you need
300300
# a ton of compiler flags to differentiate between
@@ -332,7 +332,8 @@ def _sanity_check_impl(self, work_dir: str, environment: 'Environment',
332332
cmdlist = [binary_name]
333333
mlog.debug('Running test binary command: ', mesonlib.join_args(cmdlist))
334334
try:
335-
pe = subprocess.run(cmdlist)
335+
# fortran code writes to stdout
336+
pe = subprocess.run(cmdlist, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
336337
except Exception as e:
337338
raise mesonlib.EnvironmentException(f'Could not invoke sanity test executable: {e!s}.')
338339
if pe.returncode != 0:

0 commit comments

Comments
 (0)