aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/markdown/Generating-sources.md7
-rw-r--r--mesonbuild/ast/introspection.py3
-rw-r--r--mesonbuild/backend/ninjabackend.py28
-rw-r--r--mesonbuild/dependencies/base.py213
-rw-r--r--mesonbuild/dependencies/data/CMakeLists.txt18
-rw-r--r--mesonbuild/dependencies/data/CMakePathInfo.txt29
-rw-r--r--mesonbuild/environment.py11
-rwxr-xr-xrun_unittests.py31
-rw-r--r--setup.py2
-rw-r--r--test cases/fortran/4 self dependency/meson.build2
-rw-r--r--test cases/fortran/4 self dependency/src/selfdep_mod.f906
-rw-r--r--test cases/fortran/7 generated/prog.f908
-rw-r--r--test cases/unit/53 introspect buildoptions/main.c6
-rw-r--r--test cases/unit/53 introspect buildoptions/meson.build5
14 files changed, 293 insertions, 76 deletions
diff --git a/docs/markdown/Generating-sources.md b/docs/markdown/Generating-sources.md
index 306bee3..ef7d5ac 100644
--- a/docs/markdown/Generating-sources.md
+++ b/docs/markdown/Generating-sources.md
@@ -111,11 +111,16 @@ and library dependency, especially if there are many generated headers:
```meson
idep_foo = declare_dependency(
- sources : [foo_h, bar_h],
+ include_directories : libfoo.private_dir_include(),
link_with : [libfoo],
)
```
+Adding the static library's private include directory to
+`include_directories` of `declare_dependency` will make sure all headers
+are generated before any sources of a target linking against libfoo are
+built.
+
See [dependencies](Dependencies.md#declaring-your-own), and
[reference](Reference-manual.md#decalre_dependency) for more information.
diff --git a/mesonbuild/ast/introspection.py b/mesonbuild/ast/introspection.py
index 0917015..f0ff43f 100644
--- a/mesonbuild/ast/introspection.py
+++ b/mesonbuild/ast/introspection.py
@@ -142,10 +142,11 @@ class IntrospectionInterpreter(AstInterpreter):
}]
def build_target(self, node, args, kwargs, targetclass):
+ args = self.flatten_args(args)
if not args:
return
kwargs = self.flatten_kwargs(kwargs, True)
- name = self.flatten_args(args)[0]
+ name = args[0]
srcqueue = [node]
if 'sources' in kwargs:
srcqueue += kwargs['sources']
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 16962a4..0a1681f 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -19,7 +19,7 @@ import pickle
import subprocess
from collections import OrderedDict
import itertools
-from pathlib import PurePath
+from pathlib import PurePath, Path
from functools import lru_cache
from . import backends
@@ -1851,9 +1851,11 @@ rule FORTRAN_DEP_HACK%s
mod_files = []
usere = re.compile(r"\s*use,?\s*(?:non_intrinsic)?\s*(?:::)?\s*(\w+)", re.IGNORECASE)
submodre = re.compile(r"\s*\bsubmodule\b\s+\((\w+:?\w+)\)\s+(\w+)\s*$", re.IGNORECASE)
- dirname = self.get_target_private_dir(target)
+ dirname = Path(self.get_target_private_dir(target))
tdeps = self.fortran_deps[target.get_basename()]
- with open(src, encoding='ascii', errors='ignore') as f:
+ src = Path(src)
+ srcdir = Path(self.source_dir)
+ with src.open(encoding='ascii', errors='ignore') as f:
for line in f:
usematch = usere.match(line)
if usematch is not None:
@@ -1876,10 +1878,14 @@ rule FORTRAN_DEP_HACK%s
# Check if a source uses a module it exports itself.
# Potential bug if multiple targets have a file with
# the same name.
- if mod_source_file.fname == os.path.basename(src):
- continue
+ try:
+ if (srcdir / mod_source_file.fname).samefile(src):
+ continue
+ except FileNotFoundError:
+ pass
+
mod_name = compiler.module_name_to_filename(usename)
- mod_files.append(os.path.join(dirname, mod_name))
+ mod_files.append(str(dirname / mod_name))
else:
submodmatch = submodre.match(line)
if submodmatch is not None:
@@ -1890,10 +1896,14 @@ rule FORTRAN_DEP_HACK%s
for parent in parents:
if parent not in tdeps:
raise MesonException("submodule {} relies on parent module {} that was not found.".format(submodmatch.group(2).lower(), parent))
- if tdeps[parent].fname == os.path.basename(src): # same file
- continue
+
+ try:
+ if (srcdir / tdeps[parent].fname).samefile(src):
+ continue
+ except FileNotFoundError:
+ pass
mod_name = compiler.module_name_to_filename(parent)
- mod_files.append(os.path.join(dirname, mod_name))
+ mod_files.append(str(dirname / mod_name))
return mod_files
diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py
index f4e47cf..b9fcc11 100644
--- a/mesonbuild/dependencies/base.py
+++ b/mesonbuild/dependencies/base.py
@@ -26,14 +26,14 @@ import textwrap
import platform
import itertools
import ctypes
-from typing import List
+from typing import List, Tuple
from enum import Enum
from pathlib import Path, PurePath
from .. import mlog
from .. import mesonlib
from ..compilers import clib_langs
-from ..environment import BinaryTable, Environment
+from ..environment import BinaryTable, Environment, MachineInfo
from ..mesonlib import MachineChoice, MesonException, OrderedSet, PerMachine
from ..mesonlib import Popen_safe, version_compare_many, version_compare, listify
from ..mesonlib import Version
@@ -916,12 +916,14 @@ class CMakeDependency(ExternalDependency):
# multiple times in the same Meson invocation.
class_cmakebin = PerMachine(None, None, None)
class_cmakevers = PerMachine(None, None, None)
+ class_cmakeinfo = PerMachine(None, None, None)
# We cache all pkg-config subprocess invocations to avoid redundant calls
cmake_cache = {}
# Version string for the minimum CMake version
class_cmake_version = '>=3.4'
# CMake generators to try (empty for no generator)
class_cmake_generators = ['', 'Ninja', 'Unix Makefiles', 'Visual Studio 10 2010']
+ class_working_generator = None
def _gen_exception(self, msg):
return DependencyException('Dependency {} not found: {}'.format(self.name, msg))
@@ -934,6 +936,7 @@ class CMakeDependency(ExternalDependency):
# stored in the pickled coredata and recovered.
self.cmakebin = None
self.cmakevers = None
+ self.cmakeinfo = None
# Dict of CMake variables: '<var_name>': ['list', 'of', 'values']
self.vars = {}
@@ -1009,6 +1012,12 @@ class CMakeDependency(ExternalDependency):
mlog.debug(msg)
return
+ if CMakeDependency.class_cmakeinfo[for_machine] is None:
+ CMakeDependency.class_cmakeinfo[for_machine] = self._get_cmake_info()
+ self.cmakeinfo = CMakeDependency.class_cmakeinfo[for_machine]
+ if self.cmakeinfo is None:
+ raise self._gen_exception('Unable to obtain CMake system information')
+
modules = kwargs.get('modules', [])
cm_path = kwargs.get('cmake_module_path', [])
cm_args = kwargs.get('cmake_args', [])
@@ -1021,6 +1030,8 @@ class CMakeDependency(ExternalDependency):
cm_path = [x if os.path.isabs(x) else os.path.join(environment.get_source_dir(), x) for x in cm_path]
if cm_path:
cm_args += ['-DCMAKE_MODULE_PATH={}'.format(';'.join(cm_path))]
+ if not self._preliminary_find_check(name, cm_path, environment.machines[for_machine]):
+ return
self._detect_dep(name, modules, cm_args)
def __repr__(self):
@@ -1028,6 +1039,166 @@ class CMakeDependency(ExternalDependency):
return s.format(self.__class__.__name__, self.name, self.is_found,
self.version_reqs)
+ def _get_cmake_info(self):
+ mlog.debug("Extracting basic cmake information")
+ res = {}
+
+ # Try different CMake generators since specifying no generator may fail
+ # in cygwin for some reason
+ gen_list = []
+ # First try the last working generator
+ if CMakeDependency.class_working_generator is not None:
+ gen_list += [CMakeDependency.class_working_generator]
+ gen_list += CMakeDependency.class_cmake_generators
+
+ for i in gen_list:
+ mlog.debug('Try CMake generator: {}'.format(i if len(i) > 0 else 'auto'))
+
+ # Prepare options
+ cmake_opts = ['--trace-expand', '.']
+ if len(i) > 0:
+ cmake_opts = ['-G', i] + cmake_opts
+
+ # Run CMake
+ ret1, out1, err1 = self._call_cmake(cmake_opts, 'CMakePathInfo.txt')
+
+ # Current generator was successful
+ if ret1 == 0:
+ CMakeDependency.class_working_generator = i
+ break
+
+ mlog.debug('CMake failed to gather system information for generator {} with error code {}'.format(i, ret1))
+ mlog.debug('OUT:\n{}\n\n\nERR:\n{}\n\n'.format(out1, err1))
+
+ # Check if any generator succeeded
+ if ret1 != 0:
+ return None
+
+ try:
+ # First parse the trace
+ lexer1 = self._lex_trace(err1)
+
+ # Primary pass -- parse all invocations of set
+ for l in lexer1:
+ if l.func == 'set':
+ self._cmake_set(l)
+ except:
+ return None
+
+ # Extract the variables and sanity check them
+ module_paths = sorted(set(self.get_cmake_var('MESON_PATHS_LIST')))
+ module_paths = list(filter(lambda x: os.path.isdir(x), module_paths))
+ archs = self.get_cmake_var('MESON_ARCH_LIST')
+
+ common_paths = ['lib', 'lib32', 'lib64', 'libx32', 'share']
+ for i in archs:
+ common_paths += [os.path.join('lib', i)]
+
+ res = {
+ 'module_paths': module_paths,
+ 'cmake_root': self.get_cmake_var('MESON_CMAKE_ROOT')[0],
+ 'archs': archs,
+ 'common_paths': common_paths
+ }
+
+ mlog.debug(' -- Module search paths: {}'.format(res['module_paths']))
+ mlog.debug(' -- CMake root: {}'.format(res['cmake_root']))
+ mlog.debug(' -- CMake architectures: {}'.format(res['archs']))
+ mlog.debug(' -- CMake lib search paths: {}'.format(res['common_paths']))
+
+ # Reset variables
+ self.vars = {}
+ return res
+
+ @staticmethod
+ @functools.lru_cache(maxsize=None)
+ def _cached_listdir(path: str) -> Tuple[Tuple[str, str]]:
+ try:
+ return tuple((x, str(x).lower()) for x in os.listdir(path))
+ except OSError:
+ return ()
+
+ @staticmethod
+ @functools.lru_cache(maxsize=None)
+ def _cached_isdir(path: str) -> bool:
+ try:
+ return os.path.isdir(path)
+ except OSError:
+ return False
+
+ def _preliminary_find_check(self, name: str, module_path: List[str], machine: MachineInfo) -> bool:
+ lname = str(name).lower()
+
+ # Checks <path>, <path>/cmake, <path>/CMake
+ def find_module(path: str) -> bool:
+ for i in [path, os.path.join(path, 'cmake'), os.path.join(path, 'CMake')]:
+ if not self._cached_isdir(i):
+ continue
+
+ for j in ['Find{}.cmake', '{}Config.cmake', '{}-config.cmake']:
+ if os.path.isfile(os.path.join(i, j.format(name))):
+ return True
+ return False
+
+ # Search in <path>/(lib/<arch>|lib*|share) for cmake files
+ def search_lib_dirs(path: str) -> bool:
+ for i in [os.path.join(path, x) for x in self.cmakeinfo['common_paths']]:
+ if not self._cached_isdir(i):
+ continue
+
+ # Check <path>/(lib/<arch>|lib*|share)/cmake/<name>*/
+ cm_dir = os.path.join(i, 'cmake')
+ if self._cached_isdir(cm_dir):
+ content = self._cached_listdir(cm_dir)
+ content = list(filter(lambda x: x[1].startswith(lname), content))
+ for k in content:
+ if find_module(os.path.join(cm_dir, k[0])):
+ return True
+
+ # <path>/(lib/<arch>|lib*|share)/<name>*/
+ # <path>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/
+ content = self._cached_listdir(i)
+ content = list(filter(lambda x: x[1].startswith(lname), content))
+ for k in content:
+ if find_module(os.path.join(i, k[0])):
+ return True
+
+ return False
+
+ # Check the user provided and system module paths
+ for i in module_path + [os.path.join(self.cmakeinfo['cmake_root'], 'Modules')]:
+ if find_module(i):
+ return True
+
+ # Check the system paths
+ for i in self.cmakeinfo['module_paths']:
+ if find_module(i):
+ return True
+
+ if search_lib_dirs(i):
+ return True
+
+ content = self._cached_listdir(i)
+ content = list(filter(lambda x: x[1].startswith(lname), content))
+ for k in content:
+ if search_lib_dirs(os.path.join(i, k[0])):
+ return True
+
+ # Mac framework support
+ if machine.is_darwin():
+ for j in ['{}.framework', '{}.app']:
+ j = j.format(lname)
+ if j in content:
+ if find_module(os.path.join(i, j[0], 'Resources')) or find_module(os.path.join(i, j[0], 'Version')):
+ return True
+
+ # Check the environment path
+ env_path = os.environ.get('{}_DIR'.format(name))
+ if env_path and find_module(env_path):
+ return True
+
+ return False
+
def _detect_dep(self, name: str, modules: List[str], args: List[str]):
# Detect a dependency with CMake using the '--find-package' mode
# and the trace output (stderr)
@@ -1040,19 +1211,26 @@ class CMakeDependency(ExternalDependency):
# Try different CMake generators since specifying no generator may fail
# in cygwin for some reason
- for i in CMakeDependency.class_cmake_generators:
+ gen_list = []
+ # First try the last working generator
+ if CMakeDependency.class_working_generator is not None:
+ gen_list += [CMakeDependency.class_working_generator]
+ gen_list += CMakeDependency.class_cmake_generators
+
+ for i in gen_list:
mlog.debug('Try CMake generator: {}'.format(i if len(i) > 0 else 'auto'))
# Prepare options
- cmake_opts = ['--trace-expand', '-DNAME={}'.format(name)] + args + ['.']
+ cmake_opts = ['--trace-expand', '-DNAME={}'.format(name), '-DARCHS={}'.format(';'.join(self.cmakeinfo['archs']))] + args + ['.']
if len(i) > 0:
cmake_opts = ['-G', i] + cmake_opts
# Run CMake
- ret1, out1, err1 = self._call_cmake(cmake_opts)
+ ret1, out1, err1 = self._call_cmake(cmake_opts, 'CMakeLists.txt')
# Current generator was successful
if ret1 == 0:
+ CMakeDependency.class_working_generator = i
break
mlog.debug('CMake failed for generator {} and package {} with error code {}'.format(i, name, ret1))
@@ -1221,7 +1399,7 @@ class CMakeDependency(ExternalDependency):
def get_cmake_var(self, var):
# Return the value of the CMake variable var or an empty list if var does not exist
- for var in self.vars:
+ if var in self.vars:
return self.vars[var]
return []
@@ -1449,24 +1627,25 @@ set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_SIZEOF_VOID_P "{}")
'''.format(os.path.realpath(__file__), ctypes.sizeof(ctypes.c_voidp)))
- def _setup_cmake_dir(self):
+ def _setup_cmake_dir(self, cmake_file: str) -> str:
# Setup the CMake build environment and return the "build" directory
build_dir = '{}/cmake_{}'.format(self.cmake_root_dir, self.name)
os.makedirs(build_dir, exist_ok=True)
# Copy the CMakeLists.txt
cmake_lists = '{}/CMakeLists.txt'.format(build_dir)
- if not os.path.exists(cmake_lists):
- dir_path = os.path.dirname(os.path.realpath(__file__))
- src_cmake = '{}/data/CMakeLists.txt'.format(dir_path)
- shutil.copyfile(src_cmake, cmake_lists)
+ dir_path = os.path.dirname(os.path.realpath(__file__))
+ src_cmake = '{}/data/{}'.format(dir_path, cmake_file)
+ if os.path.exists(cmake_lists):
+ os.remove(cmake_lists)
+ shutil.copyfile(src_cmake, cmake_lists)
self._setup_compiler(build_dir)
self._reset_cmake_cache(build_dir)
return build_dir
- def _call_cmake_real(self, args, env):
- build_dir = self._setup_cmake_dir()
+ def _call_cmake_real(self, args, cmake_file: str, env):
+ build_dir = self._setup_cmake_dir(cmake_file)
cmd = self.cmakebin.get_command() + args
p, out, err = Popen_safe(cmd, env=env, cwd=build_dir)
rc = p.returncode
@@ -1475,7 +1654,7 @@ set(CMAKE_SIZEOF_VOID_P "{}")
return rc, out, err
- def _call_cmake(self, args, env=None):
+ def _call_cmake(self, args, cmake_file: str, env=None):
if env is None:
fenv = env
env = os.environ
@@ -1485,9 +1664,9 @@ set(CMAKE_SIZEOF_VOID_P "{}")
# First check if cached, if not call the real cmake function
cache = CMakeDependency.cmake_cache
- if (self.cmakebin, targs, fenv) not in cache:
- cache[(self.cmakebin, targs, fenv)] = self._call_cmake_real(args, env)
- return cache[(self.cmakebin, targs, fenv)]
+ if (self.cmakebin, targs, cmake_file, fenv) not in cache:
+ cache[(self.cmakebin, targs, cmake_file, fenv)] = self._call_cmake_real(args, cmake_file, env)
+ return cache[(self.cmakebin, targs, cmake_file, fenv)]
@staticmethod
def get_methods():
diff --git a/mesonbuild/dependencies/data/CMakeLists.txt b/mesonbuild/dependencies/data/CMakeLists.txt
index 6f51681..64f5b23 100644
--- a/mesonbuild/dependencies/data/CMakeLists.txt
+++ b/mesonbuild/dependencies/data/CMakeLists.txt
@@ -1,16 +1,5 @@
cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} )
-# Inspired by CMakeDetermineCompilerABI.cmake to set CMAKE_LIBRARY_ARCHITECTURE
-set(LIB_ARCH_LIST)
-if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
- file(GLOB implicit_dirs RELATIVE /lib /lib/*-linux-gnu* )
- foreach(dir ${implicit_dirs})
- if("${dir}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
- list(APPEND LIB_ARCH_LIST "${dir}")
- endif()
- endforeach()
-endif()
-
set(PACKAGE_FOUND FALSE)
set(_packageName "${NAME}")
string(TOUPPER "${_packageName}" PACKAGE_NAME)
@@ -18,12 +7,13 @@ string(TOUPPER "${_packageName}" PACKAGE_NAME)
while(TRUE)
find_package("${NAME}" QUIET)
- if(${_packageName}_FOUND OR ${PACKAGE_NAME}_FOUND OR "${LIB_ARCH_LIST}" STREQUAL "")
+ # ARCHS has to be set via the CMD interface
+ if(${_packageName}_FOUND OR ${PACKAGE_NAME}_FOUND OR "${ARCHS}" STREQUAL "")
break()
endif()
- list(GET LIB_ARCH_LIST 0 CMAKE_LIBRARY_ARCHITECTURE)
- list(REMOVE_AT LIB_ARCH_LIST 0)
+ list(GET ARCHS 0 CMAKE_LIBRARY_ARCHITECTURE)
+ list(REMOVE_AT ARCHS 0)
endwhile()
if(${_packageName}_FOUND OR ${PACKAGE_NAME}_FOUND)
diff --git a/mesonbuild/dependencies/data/CMakePathInfo.txt b/mesonbuild/dependencies/data/CMakePathInfo.txt
new file mode 100644
index 0000000..713c2da
--- /dev/null
+++ b/mesonbuild/dependencies/data/CMakePathInfo.txt
@@ -0,0 +1,29 @@
+cmake_minimum_required(VERSION ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION})
+
+set(TMP_PATHS_LIST)
+list(APPEND TMP_PATHS_LIST ${CMAKE_PREFIX_PATH})
+list(APPEND TMP_PATHS_LIST ${CMAKE_FRAMEWORK_PATH})
+list(APPEND TMP_PATHS_LIST ${CMAKE_APPBUNDLE_PATH})
+list(APPEND TMP_PATHS_LIST $ENV{CMAKE_PREFIX_PATH})
+list(APPEND TMP_PATHS_LIST $ENV{CMAKE_FRAMEWORK_PATH})
+list(APPEND TMP_PATHS_LIST $ENV{CMAKE_APPBUNDLE_PATH})
+list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_PREFIX_PATH})
+list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_FRAMEWORK_PATH})
+list(APPEND TMP_PATHS_LIST ${CMAKE_SYSTEM_APPBUNDLE_PATH})
+
+set(LIB_ARCH_LIST)
+if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
+ file(GLOB implicit_dirs RELATIVE /lib /lib/*-linux-gnu* )
+ foreach(dir ${implicit_dirs})
+ if("${dir}" MATCHES "${CMAKE_LIBRARY_ARCHITECTURE_REGEX}")
+ list(APPEND LIB_ARCH_LIST "${dir}")
+ endif()
+ endforeach()
+endif()
+
+# "Export" these variables:
+set(MESON_ARCH_LIST ${LIB_ARCH_LIST})
+set(MESON_PATHS_LIST ${TMP_PATHS_LIST})
+set(MESON_CMAKE_ROOT ${CMAKE_ROOT})
+
+message(STATUS ${TMP_PATHS_LIST})
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index b2cc657..bbe82ec 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -101,17 +101,6 @@ known_cpu_families = (
'x86_64'
)
-# Environment variables that each lang uses.
-cflags_mapping = {'c': 'CFLAGS',
- 'cpp': 'CXXFLAGS',
- 'cu': 'CUFLAGS',
- 'objc': 'OBJCFLAGS',
- 'objcpp': 'OBJCXXFLAGS',
- 'fortran': 'FFLAGS',
- 'd': 'DFLAGS',
- 'vala': 'VALAFLAGS'}
-
-
def detect_gcovr(version='3.1', log=False):
gcovr_exe = 'gcovr'
try:
diff --git a/run_unittests.py b/run_unittests.py
index e6df87a..cf6c910 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -3747,6 +3747,7 @@ class FailureTests(BasePlatformTests):
"""Subproject "subprojects/not-found-subproject" disabled can't get_variable on it.""")
+@unittest.skipUnless(is_windows() or is_cygwin(), "requires Windows (or Windows via Cygwin)")
class WindowsTests(BasePlatformTests):
'''
Tests that should run on Cygwin, MinGW, and MSVC
@@ -3857,6 +3858,7 @@ class WindowsTests(BasePlatformTests):
return
self.build()
+@unittest.skipUnless(is_osx(), "requires Darwin")
class DarwinTests(BasePlatformTests):
'''
Tests that should run on macOS
@@ -3953,6 +3955,7 @@ class DarwinTests(BasePlatformTests):
del os.environ["LDFLAGS"]
+@unittest.skipUnless(not is_windows(), "requires something Unix-like")
class LinuxlikeTests(BasePlatformTests):
'''
Tests that should run on Linux, macOS, and *BSD
@@ -4931,6 +4934,10 @@ endian = 'little'
self.assertEqual(max_count, 1, 'Export dynamic incorrectly deduplicated.')
+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(BasePlatformTests):
'''
Tests that cross-compilation to Linux/ARM works
@@ -4979,6 +4986,10 @@ class LinuxCrossArmTests(BasePlatformTests):
self.assertTrue(False, 'Option libdir not in introspect data.')
+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(BasePlatformTests):
'''
Tests that cross-compilation to Windows/MinGW works
@@ -5697,26 +5708,12 @@ def unset_envs():
if v in os.environ:
del os.environ[v]
-def should_run_cross_arm_tests():
- return shutil.which('arm-linux-gnueabihf-gcc') and not platform.machine().lower().startswith('arm')
-
-def should_run_cross_mingw_tests():
- return shutil.which('x86_64-w64-mingw32-gcc') and not (is_windows() or is_cygwin())
-
def main():
unset_envs()
cases = ['InternalTests', 'DataTests', 'AllPlatformTests', 'FailureTests',
- 'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests']
- if not is_windows():
- cases += ['LinuxlikeTests']
- if should_run_cross_arm_tests():
- cases += ['LinuxCrossArmTests']
- if should_run_cross_mingw_tests():
- cases += ['LinuxCrossMingwTests']
- if is_windows() or is_cygwin():
- cases += ['WindowsTests']
- if is_osx():
- cases += ['DarwinTests']
+ 'PythonTests', 'NativeFileTests', 'RewriterTests', 'CrossFileTests',
+ 'LinuxlikeTests', 'LinuxCrossArmTests', 'LinuxCrossMingwTests',
+ 'WindowsTests', 'DarwinTests']
return unittest.main(defaultTest=cases, buffer=True)
diff --git a/setup.py b/setup.py
index f352960..07bd3dd 100644
--- a/setup.py
+++ b/setup.py
@@ -35,7 +35,7 @@ packages = ['mesonbuild',
'mesonbuild.modules',
'mesonbuild.scripts',
'mesonbuild.wrap']
-package_data = {'mesonbuild.dependencies': ['data/CMakeLists.txt']}
+package_data = {'mesonbuild.dependencies': ['data/CMakeLists.txt', 'data/CMakePathInfo.txt']}
data_files = []
if sys.platform != 'win32':
# Only useful on UNIX-like systems
diff --git a/test cases/fortran/4 self dependency/meson.build b/test cases/fortran/4 self dependency/meson.build
index bc5dab4..8eef4eb 100644
--- a/test cases/fortran/4 self dependency/meson.build
+++ b/test cases/fortran/4 self dependency/meson.build
@@ -2,3 +2,5 @@ project('selfdep', 'fortran')
e = executable('selfdep', 'selfdep.f90')
test('selfdep', e)
+
+library('selfmod', 'src/selfdep_mod.f90')
diff --git a/test cases/fortran/4 self dependency/src/selfdep_mod.f90 b/test cases/fortran/4 self dependency/src/selfdep_mod.f90
new file mode 100644
index 0000000..4aa0057
--- /dev/null
+++ b/test cases/fortran/4 self dependency/src/selfdep_mod.f90
@@ -0,0 +1,6 @@
+module a
+end module a
+
+module b
+use a
+end module b
diff --git a/test cases/fortran/7 generated/prog.f90 b/test cases/fortran/7 generated/prog.f90
index c476e9c..8a102c0 100644
--- a/test cases/fortran/7 generated/prog.f90
+++ b/test cases/fortran/7 generated/prog.f90
@@ -1,9 +1,7 @@
program prog
- use mod2
- implicit none
+use mod2
+implicit none
- if (modval1 + modval2 /= 3) then
- stop 1
- end if
+if (modval1 + modval2 /= 3) stop 1
end program prog
diff --git a/test cases/unit/53 introspect buildoptions/main.c b/test cases/unit/53 introspect buildoptions/main.c
new file mode 100644
index 0000000..ef99ae6
--- /dev/null
+++ b/test cases/unit/53 introspect buildoptions/main.c
@@ -0,0 +1,6 @@
+#include <stdio.h>
+
+int main() {
+ printf("Hello World");
+ return 0;
+}
diff --git a/test cases/unit/53 introspect buildoptions/meson.build b/test cases/unit/53 introspect buildoptions/meson.build
index e94ef61..8052b5f 100644
--- a/test cases/unit/53 introspect buildoptions/meson.build
+++ b/test cases/unit/53 introspect buildoptions/meson.build
@@ -2,6 +2,11 @@ project('introspect buildargs', ['c'], default_options: ['c_std=c11', 'cpp_std=c
subA = subproject('projectA')
+target_name = 'MAIN'
+target_src = ['main.c']
+
+executable(target_name, target_src)
+
r = run_command(find_program('c_compiler.py'))
if r.returncode() != 0
error('FAILED')