aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/snippets/sanity-check.md17
-rw-r--r--mesonbuild/compilers/c.py51
-rw-r--r--mesonbuild/compilers/fortran.py15
-rw-r--r--mesonbuild/compilers/objc.py10
-rw-r--r--mesonbuild/compilers/objcpp.py13
-rw-r--r--mesonbuild/compilers/swift.py16
-rw-r--r--mesonbuild/compilers/vala.py21
-rwxr-xr-xrun_project_tests.py2
-rwxr-xr-xrun_unittests.py11
-rw-r--r--test cases/common/177 initial c_args/meson.build2
-rw-r--r--test cases/common/177 initial c_args/test_args.txt2
11 files changed, 120 insertions, 40 deletions
diff --git a/docs/markdown/snippets/sanity-check.md b/docs/markdown/snippets/sanity-check.md
new file mode 100644
index 0000000..d5ed80d
--- /dev/null
+++ b/docs/markdown/snippets/sanity-check.md
@@ -0,0 +1,17 @@
+## Sanity checking compilers with user flags
+
+Sanity checks previously only used user-specified flags for cross compilers, but
+now do in all cases.
+
+All compilers meson might decide to use for the build are "sanity checked"
+before other tests are run. This usually involves building simple executable and
+trying to run it. Previously user flags (compilation and/or linking flags) were
+used for sanity checking cross compilers, but not native compilers. This is
+because such flags might be essential for a cross binary to succeed, but usually
+aren't for a native compiler.
+
+In recent releases, there has been an effort to minimize the special-casing of
+cross or native builds so as to make building more predictable in less-tested
+cases. Since this the user flags are necessary for cross, but not harmful for
+native, it makes more sense to use them in all sanity checks than use them in no
+sanity checks, so this is what we now do.
diff --git a/mesonbuild/compilers/c.py b/mesonbuild/compilers/c.py
index 2560c82..bcf8243 100644
--- a/mesonbuild/compilers/c.py
+++ b/mesonbuild/compilers/c.py
@@ -309,9 +309,9 @@ class CCompiler(Compiler):
mlog.debug('Sanity testing ' + self.get_display_language() + ' compiler:', ' '.join(self.exelist))
mlog.debug('Is cross compiler: %s.' % str(self.is_cross))
- extra_flags = []
source_name = os.path.join(work_dir, sname)
binname = sname.rsplit('.', 1)[0]
+ mode = 'link'
if self.is_cross:
binname += '_cross'
if self.exe_wrapper is None:
@@ -320,7 +320,9 @@ class CCompiler(Compiler):
# on OSX the compiler binary is the same but you need
# a ton of compiler flags to differentiate between
# arm and x86_64. So just compile.
- extra_flags += self.get_compile_only_args()
+ mode = 'compile'
+ extra_flags = self._get_basic_compiler_args(environment, mode)
+
# Is a valid executable output for all toolchains and platforms
binname += '.exe'
# Write binary check source
@@ -392,6 +394,29 @@ class CCompiler(Compiler):
return self.compiles(t.format(**fargs), env, extra_args=extra_args,
dependencies=dependencies)
+ def _get_basic_compiler_args(self, env, mode):
+ args = []
+ # Select a CRT if needed since we're linking
+ if mode == 'link':
+ args += self.get_linker_debug_crt_args()
+ if env.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ if mode in {'compile', 'preprocess'}:
+ # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
+ sys_args = env.coredata.get_external_args(for_machine, self.language)
+ # Apparently it is a thing to inject linker flags both
+ # via CFLAGS _and_ LDFLAGS, even though the former are
+ # also used during linking. These flags can break
+ # argument checks. Thanks, Autotools.
+ cleaned_sys_args = self.remove_linkerlike_args(sys_args)
+ args += cleaned_sys_args
+ elif mode == 'link':
+ # Add LDFLAGS from the env
+ args += env.coredata.get_external_link_args(for_machine, self.language)
+ return args
+
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
if extra_args is None:
extra_args = []
@@ -415,25 +440,9 @@ class CCompiler(Compiler):
args += d.get_link_args()
if d.need_threads():
args += self.thread_link_flags(env)
- # Select a CRT if needed since we're linking
- if mode == 'link':
- args += self.get_linker_debug_crt_args()
- if env.is_cross_build() and not self.is_cross:
- for_machine = MachineChoice.BUILD
- else:
- for_machine = MachineChoice.HOST
- if mode in {'compile', 'preprocess'}:
- # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env
- sys_args = env.coredata.get_external_args(for_machine, self.language)
- # Apparently it is a thing to inject linker flags both
- # via CFLAGS _and_ LDFLAGS, even though the former are
- # also used during linking. These flags can break
- # argument checks. Thanks, Autotools.
- cleaned_sys_args = self.remove_linkerlike_args(sys_args)
- args += cleaned_sys_args
- elif mode == 'link':
- # Add LDFLAGS from the env
- args += env.coredata.get_external_link_args(for_machine, self.language)
+
+ args += self._get_basic_compiler_args(env, mode)
+
args += self.get_compiler_check_args()
# extra_args must override all other arguments, so we add them last
args += extra_args
diff --git a/mesonbuild/compilers/fortran.py b/mesonbuild/compilers/fortran.py
index a16f2b5..5afbb3d 100644
--- a/mesonbuild/compilers/fortran.py
+++ b/mesonbuild/compilers/fortran.py
@@ -31,7 +31,9 @@ from .compilers import (
PGICompiler
)
-from mesonbuild.mesonlib import EnvironmentException, is_osx, LibType
+from mesonbuild.mesonlib import (
+ EnvironmentException, MachineChoice, is_osx, LibType
+)
class FortranCompiler(Compiler):
@@ -79,7 +81,13 @@ class FortranCompiler(Compiler):
binary_name = os.path.join(work_dir, 'sanitycheckf')
with open(source_name, 'w') as ofile:
ofile.write('print *, "Fortran compilation is working."; end')
- pc = subprocess.Popen(self.exelist + [source_name, '-o', binary_name])
+ if environment.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ extra_flags = environment.coredata.get_external_args(for_machine, self.language)
+ extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
+ pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string())
@@ -223,6 +231,9 @@ class FortranCompiler(Compiler):
def gen_import_library_args(self, implibname):
return CCompiler.gen_import_library_args(self, implibname)
+ def _get_basic_compiler_args(self, env, mode):
+ return CCompiler._get_basic_compiler_args(self, env, mode)
+
def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
return CCompiler._get_compiler_check_args(self, env, extra_args, dependencies, mode='compile')
diff --git a/mesonbuild/compilers/objc.py b/mesonbuild/compilers/objc.py
index 8dfd0a2..c4a7019 100644
--- a/mesonbuild/compilers/objc.py
+++ b/mesonbuild/compilers/objc.py
@@ -14,7 +14,7 @@
import os.path, subprocess
-from ..mesonlib import EnvironmentException
+from ..mesonlib import EnvironmentException, MachineChoice
from .c import CCompiler
from .compilers import ClangCompiler, GnuCompiler
@@ -31,9 +31,15 @@ class ObjCCompiler(CCompiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjc.m')
binary_name = os.path.join(work_dir, 'sanitycheckobjc')
- extra_flags = []
+ if environment.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ extra_flags = environment.coredata.get_external_args(for_machine, self.language)
if self.is_cross:
extra_flags += self.get_compile_only_args()
+ else:
+ extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'int main(int argc, char **argv) { return 0; }\n')
diff --git a/mesonbuild/compilers/objcpp.py b/mesonbuild/compilers/objcpp.py
index e66d730..4c23d0a 100644
--- a/mesonbuild/compilers/objcpp.py
+++ b/mesonbuild/compilers/objcpp.py
@@ -14,7 +14,7 @@
import os.path, subprocess
-from ..mesonlib import EnvironmentException
+from ..mesonlib import EnvironmentException, MachineChoice
from .cpp import CPPCompiler
from .compilers import ClangCompiler, GnuCompiler
@@ -31,11 +31,20 @@ class ObjCPPCompiler(CPPCompiler):
# TODO try to use sanity_check_impl instead of duplicated code
source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm')
binary_name = os.path.join(work_dir, 'sanitycheckobjcpp')
+ if environment.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ extra_flags = environment.coredata.get_external_args(for_machine, self.language)
+ if self.is_cross:
+ extra_flags += self.get_compile_only_args()
+ else:
+ extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('#import<stdio.h>\n'
'class MyClass;'
'int main(int argc, char **argv) { return 0; }\n')
- pc = subprocess.Popen(self.exelist + [source_name, '-o', binary_name])
+ pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name])
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('ObjC++ compiler %s can not compile programs.' % self.name_string())
diff --git a/mesonbuild/compilers/swift.py b/mesonbuild/compilers/swift.py
index 94e6736..17705ac 100644
--- a/mesonbuild/compilers/swift.py
+++ b/mesonbuild/compilers/swift.py
@@ -14,7 +14,7 @@
import subprocess, os.path
-from ..mesonlib import EnvironmentException
+from ..mesonlib import EnvironmentException, MachineChoice
from .compilers import Compiler, swift_buildtype_args, clike_debug_args
@@ -102,13 +102,25 @@ class SwiftCompiler(Compiler):
src = 'swifttest.swift'
source_name = os.path.join(work_dir, src)
output_name = os.path.join(work_dir, 'swifttest')
+ if environment.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ extra_flags = environment.coredata.get_external_args(for_machine, self.language)
+ if self.is_cross:
+ extra_flags += self.get_compile_only_args()
+ else:
+ extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
with open(source_name, 'w') as ofile:
ofile.write('''print("Swift compilation is working.")
''')
- pc = subprocess.Popen(self.exelist + ['-emit-executable', '-o', output_name, src], cwd=work_dir)
+ pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir)
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string())
+ if self.is_cross:
+ # Can't check if the binaries run so we have to assume they do
+ return
if subprocess.call(output_name) != 0:
raise EnvironmentException('Executables created by Swift compiler %s are not runnable.' % self.name_string())
diff --git a/mesonbuild/compilers/vala.py b/mesonbuild/compilers/vala.py
index b463f0d..98b8b42 100644
--- a/mesonbuild/compilers/vala.py
+++ b/mesonbuild/compilers/vala.py
@@ -15,7 +15,7 @@
import os.path
from .. import mlog
-from ..mesonlib import EnvironmentException, version_compare
+from ..mesonlib import EnvironmentException, MachineChoice, version_compare
from .compilers import Compiler
@@ -87,7 +87,16 @@ class ValaCompiler(Compiler):
def sanity_check(self, work_dir, environment):
code = 'class MesonSanityCheck : Object { }'
- with self.compile(code, [], 'compile') as p:
+ if environment.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ extra_flags = environment.coredata.get_external_args(for_machine, self.language)
+ if self.is_cross:
+ extra_flags += self.get_compile_only_args()
+ else:
+ extra_flags += environment.coredata.get_external_link_args(for_machine, self.language)
+ with self.compile(code, extra_flags, 'compile') as p:
if p.returncode != 0:
msg = 'Vala compiler {!r} can not compile programs' \
''.format(self.name_string())
@@ -105,8 +114,14 @@ class ValaCompiler(Compiler):
# no extra dirs are specified.
if not extra_dirs:
code = 'class MesonFindLibrary : Object { }'
+ if env.is_cross_build() and not self.is_cross:
+ for_machine = MachineChoice.BUILD
+ else:
+ for_machine = MachineChoice.HOST
+ args = env.coredata.get_external_args(for_machine, self.language)
vapi_args = ['--pkg', libname]
- with self.compile(code, vapi_args, 'compile') as p:
+ args += vapi_args
+ with self.compile(code, args, 'compile') as p:
if p.returncode == 0:
return vapi_args
# Not found? Try to find the vapi file itself.
diff --git a/run_project_tests.py b/run_project_tests.py
index 467d522..be6ecd9 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -460,6 +460,7 @@ def have_objc_compiler():
return False
if not objc_comp:
return False
+ env.coredata.process_new_compilers('objc', objc_comp, None, env)
try:
objc_comp.sanity_check(env.get_scratch_dir(), env)
except mesonlib.MesonException:
@@ -475,6 +476,7 @@ def have_objcpp_compiler():
return False
if not objcpp_comp:
return False
+ env.coredata.process_new_compilers('objcpp', objcpp_comp, None, env)
try:
objcpp_comp.sanity_check(env.get_scratch_dir(), env)
except mesonlib.MesonException:
diff --git a/run_unittests.py b/run_unittests.py
index f381efc..7ceb553 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -4373,12 +4373,11 @@ class LinuxlikeTests(BasePlatformTests):
cmd_std = '-std=FAIL'
env_flags = p.upper() + 'FLAGS'
os.environ[env_flags] = cmd_std
- self.init(testdir)
- cmd = self.get_compdb()[0]['command']
- qcmd_std = " {} ".format(cmd_std)
- self.assertIn(qcmd_std, cmd)
- with self.assertRaises(subprocess.CalledProcessError,
- msg='{} should have failed'.format(qcmd_std)):
+ with self.assertRaises((subprocess.CalledProcessError, mesonbuild.mesonlib.EnvironmentException),
+ msg='C compiler should have failed with -std=FAIL'):
+ self.init(testdir)
+ # ICC won't fail in the above because additional flags are needed to
+ # make unknown -std=... options errors.
self.build()
def test_compiler_c_stds(self):
diff --git a/test cases/common/177 initial c_args/meson.build b/test cases/common/177 initial c_args/meson.build
index 169d2bd..638f8c2 100644
--- a/test cases/common/177 initial c_args/meson.build
+++ b/test cases/common/177 initial c_args/meson.build
@@ -3,5 +3,5 @@ project('options', 'c')
# Test passing c_args and c_link_args options from the command line.
assert(get_option('c_args') == ['-funroll-loops'],
'Incorrect value for c_args option.')
-assert(get_option('c_link_args') == ['-random_linker_option'],
+assert(get_option('c_link_args') == ['-Dtest_harmless_but_useless_link_arg'],
'Incorrect value for c_link_args option.')
diff --git a/test cases/common/177 initial c_args/test_args.txt b/test cases/common/177 initial c_args/test_args.txt
index 9a6da06..166e481 100644
--- a/test cases/common/177 initial c_args/test_args.txt
+++ b/test cases/common/177 initial c_args/test_args.txt
@@ -1,4 +1,4 @@
# This file is not read by meson itself, but by the test framework.
# It is not possible to pass arguments to meson from a file.
['-Dc_args=-march=native', '-Dc_args=-funroll-loops',
- '-Dc_link_args=-random_linker_option']
+ '-Dc_link_args=-Dtest_harmless_but_useless_link_arg']