The Meson Build System
http://mesonbuild.com/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
8.1 KiB
192 lines
8.1 KiB
# Copyright 2016-2021 The Meson development team |
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); |
|
# you may not use this file except in compliance with the License. |
|
# You may obtain a copy of the License at |
|
|
|
# http://www.apache.org/licenses/LICENSE-2.0 |
|
|
|
# Unless required by applicable law or agreed to in writing, software |
|
# distributed under the License is distributed on an "AS IS" BASIS, |
|
# 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. |
|
|
|
import os |
|
import shutil |
|
import unittest |
|
import platform |
|
|
|
from mesonbuild.mesonlib import ( |
|
is_windows, is_cygwin |
|
) |
|
from mesonbuild.mesonlib import MesonException |
|
|
|
|
|
|
|
from .baseplatformtests import BasePlatformTests |
|
from .helpers import * |
|
|
|
class BaseLinuxCrossTests(BasePlatformTests): |
|
# Don't pass --libdir when cross-compiling. We have tests that |
|
# check whether meson auto-detects it correctly. |
|
libdir = None |
|
|
|
|
|
def should_run_cross_arm_tests(): |
|
return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm') |
|
|
|
@unittest.skipUnless(not is_windows() and should_run_cross_arm_tests(), "requires ability to cross compile to ARM") |
|
class LinuxCrossArmTests(BaseLinuxCrossTests): |
|
''' |
|
Tests that cross-compilation to Linux/ARM works |
|
''' |
|
|
|
def setUp(self): |
|
super().setUp() |
|
self.meson_cross_file = os.path.join(self.src_root, 'cross', 'ubuntu-armhf.txt') |
|
|
|
def test_cflags_cross_environment_pollution(self): |
|
''' |
|
Test that the CFLAGS environment variable does not pollute the cross |
|
environment. This can't be an ordinary test case because we need to |
|
inspect the compiler database. |
|
''' |
|
testdir = os.path.join(self.common_test_dir, '3 static') |
|
self.init(testdir, override_envvars={'CFLAGS': '-DBUILD_ENVIRONMENT_ONLY'}) |
|
compdb = self.get_compdb() |
|
self.assertNotIn('-DBUILD_ENVIRONMENT_ONLY', compdb[0]['command']) |
|
|
|
def test_cross_file_overrides_always_args(self): |
|
''' |
|
Test that $lang_args in cross files always override get_always_args(). |
|
Needed for overriding the default -D_FILE_OFFSET_BITS=64 on some |
|
architectures such as some Android versions and Raspbian. |
|
https://github.com/mesonbuild/meson/issues/3049 |
|
https://github.com/mesonbuild/meson/issues/3089 |
|
''' |
|
testdir = os.path.join(self.unit_test_dir, '33 cross file overrides always args') |
|
self.meson_cross_file = os.path.join(testdir, 'ubuntu-armhf-overrides.txt') |
|
self.init(testdir) |
|
compdb = self.get_compdb() |
|
self.assertRegex(compdb[0]['command'], '-D_FILE_OFFSET_BITS=64.*-U_FILE_OFFSET_BITS') |
|
self.build() |
|
|
|
def test_cross_libdir(self): |
|
# When cross compiling "libdir" should default to "lib" |
|
# rather than "lib/x86_64-linux-gnu" or something like that. |
|
testdir = os.path.join(self.common_test_dir, '1 trivial') |
|
self.init(testdir) |
|
for i in self.introspect('--buildoptions'): |
|
if i['name'] == 'libdir': |
|
self.assertEqual(i['value'], 'lib') |
|
return |
|
self.assertTrue(False, 'Option libdir not in introspect data.') |
|
|
|
def test_cross_libdir_subproject(self): |
|
# Guard against a regression where calling "subproject" |
|
# would reset the value of libdir to its default value. |
|
testdir = os.path.join(self.unit_test_dir, '76 subdir libdir') |
|
self.init(testdir, extra_args=['--libdir=fuf']) |
|
for i in self.introspect('--buildoptions'): |
|
if i['name'] == 'libdir': |
|
self.assertEqual(i['value'], 'fuf') |
|
return |
|
self.assertTrue(False, 'Libdir specified on command line gets reset.') |
|
|
|
def test_std_remains(self): |
|
# C_std defined in project options must be in effect also when cross compiling. |
|
testdir = os.path.join(self.unit_test_dir, '51 noncross options') |
|
self.init(testdir) |
|
compdb = self.get_compdb() |
|
self.assertRegex(compdb[0]['command'], '-std=c99') |
|
self.build() |
|
|
|
@skipIfNoPkgconfig |
|
def test_pkg_config_option(self): |
|
if not shutil.which('arm-linux-gnueabihf-pkg-config'): |
|
raise unittest.SkipTest('Cross-pkgconfig not found.') |
|
testdir = os.path.join(self.unit_test_dir, '58 pkg_config_path option') |
|
self.init(testdir, extra_args=[ |
|
'-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'), |
|
'-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path'), |
|
]) |
|
|
|
def test_run_native_test(self): |
|
''' |
|
https://github.com/mesonbuild/meson/issues/7997 |
|
check run native test in crossbuild without exe wrapper |
|
''' |
|
testdir = os.path.join(self.unit_test_dir, '88 run native test') |
|
stamp_file = os.path.join(self.builddir, 'native_test_has_run.stamp') |
|
self.init(testdir) |
|
self.build() |
|
self.assertPathDoesNotExist(stamp_file) |
|
self.run_tests() |
|
self.assertPathExists(stamp_file) |
|
|
|
|
|
def should_run_cross_mingw_tests(): |
|
return shutil.which('x86_64-w64-mingw32-gcc') and not (is_windows() or is_cygwin()) |
|
|
|
@unittest.skipUnless(not is_windows() and should_run_cross_mingw_tests(), "requires ability to cross compile with MinGW") |
|
class LinuxCrossMingwTests(BaseLinuxCrossTests): |
|
''' |
|
Tests that cross-compilation to Windows/MinGW works |
|
''' |
|
|
|
def setUp(self): |
|
super().setUp() |
|
self.meson_cross_file = os.path.join(self.src_root, 'cross', 'linux-mingw-w64-64bit.txt') |
|
|
|
def test_exe_wrapper_behaviour(self): |
|
''' |
|
Test that an exe wrapper that isn't found doesn't cause compiler sanity |
|
checks and compiler checks to fail, but causes configure to fail if it |
|
requires running a cross-built executable (custom_target or run_target) |
|
and causes the tests to be skipped if they are run. |
|
''' |
|
testdir = os.path.join(self.unit_test_dir, '36 exe_wrapper behaviour') |
|
# Configures, builds, and tests fine by default |
|
self.init(testdir) |
|
self.build() |
|
self.run_tests() |
|
self.wipe() |
|
os.mkdir(self.builddir) |
|
# Change cross file to use a non-existing exe_wrapper and it should fail |
|
self.meson_cross_file = os.path.join(testdir, 'broken-cross.txt') |
|
# Force tracebacks so we can detect them properly |
|
env = {'MESON_FORCE_BACKTRACE': '1'} |
|
error_message = "An exe_wrapper is needed but was not found. Please define one in cross file and check the command and/or add it to PATH." |
|
|
|
with self.assertRaises(MesonException) as cm: |
|
# Must run in-process or we'll get a generic CalledProcessError |
|
self.init(testdir, extra_args='-Drun-target=false', |
|
inprocess=True, |
|
override_envvars=env) |
|
self.assertEqual(str(cm.exception), error_message) |
|
|
|
with self.assertRaises(MesonException) as cm: |
|
# Must run in-process or we'll get a generic CalledProcessError |
|
self.init(testdir, extra_args='-Dcustom-target=false', |
|
inprocess=True, |
|
override_envvars=env) |
|
self.assertEqual(str(cm.exception), error_message) |
|
|
|
self.init(testdir, extra_args=['-Dcustom-target=false', '-Drun-target=false'], |
|
override_envvars=env) |
|
self.build() |
|
|
|
with self.assertRaises(MesonException) as cm: |
|
# Must run in-process or we'll get a generic CalledProcessError |
|
self.run_tests(inprocess=True, override_envvars=env) |
|
self.assertEqual(str(cm.exception), |
|
"The exe_wrapper defined in the cross file 'broken' was not found. Please check the command and/or add it to PATH.") |
|
|
|
@skipIfNoPkgconfig |
|
def test_cross_pkg_config_option(self): |
|
testdir = os.path.join(self.unit_test_dir, '58 pkg_config_path option') |
|
self.init(testdir, extra_args=[ |
|
'-Dbuild.pkg_config_path=' + os.path.join(testdir, 'build_extra_path'), |
|
'-Dpkg_config_path=' + os.path.join(testdir, 'host_extra_path'), |
|
])
|
|
|