aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml15
-rw-r--r--authors.txt6
-rw-r--r--ci/appveyor-install.bat11
-rwxr-xr-xci/appveyor-test.sh6
-rw-r--r--mesonbuild/backend/backends.py12
-rw-r--r--mesonbuild/backend/ninjabackend.py19
-rw-r--r--mesonbuild/backend/vs2010backend.py13
-rw-r--r--mesonbuild/build.py17
-rw-r--r--mesonbuild/compilers.py101
-rw-r--r--mesonbuild/coredata.py7
-rw-r--r--mesonbuild/dependencies.py25
-rw-r--r--mesonbuild/environment.py48
-rw-r--r--mesonbuild/interpreter.py166
-rw-r--r--mesonbuild/mesonlib.py25
-rw-r--r--mesonbuild/modules/gnome.py2
-rw-r--r--mesonbuild/modules/windows.py14
-rw-r--r--mesonbuild/mparser.py1
-rw-r--r--mesonbuild/optinterpreter.py7
-rw-r--r--mesonbuild/scripts/commandrunner.py11
-rw-r--r--mesonbuild/scripts/meson_exe.py6
-rw-r--r--mesonbuild/scripts/meson_install.py15
-rwxr-xr-xmesontest.py8
-rwxr-xr-xrun_project_tests.py28
-rwxr-xr-xrun_unittests.py21
-rw-r--r--test cases/common/123 subproject project arguments/exe.c4
-rw-r--r--test cases/common/123 subproject project arguments/exe.cpp4
-rw-r--r--test cases/common/123 subproject project arguments/meson.build5
-rw-r--r--test cases/common/123 subproject project arguments/subprojects/subexe/subexe.c4
-rw-r--r--test cases/common/125 shared module/meson.build3
-rw-r--r--test cases/common/125 shared module/module.c17
-rw-r--r--test cases/common/126 llvm ir and assembly/square-x86_64.S4
-rw-r--r--test cases/common/135 generated assembly/main.c3
-rw-r--r--test cases/common/135 generated assembly/square-x86_64.S.in4
-rw-r--r--test cases/common/140 get define/meson.build31
-rw-r--r--test cases/common/140 get define/meson_options.txt1
-rw-r--r--test cases/common/141 mesonintrospect from scripts/check_env.py20
-rw-r--r--test cases/common/141 mesonintrospect from scripts/meson.build14
-rw-r--r--test cases/common/142 compute int/config.h.in (renamed from test cases/common/139 compute int/config.h.in)0
-rw-r--r--test cases/common/142 compute int/foobar.h (renamed from test cases/common/139 compute int/foobar.h)0
-rw-r--r--test cases/common/142 compute int/meson.build (renamed from test cases/common/139 compute int/meson.build)0
-rw-r--r--test cases/common/142 compute int/prog.c.in (renamed from test cases/common/139 compute int/prog.c.in)0
-rw-r--r--test cases/common/143 custom target object output/meson.build (renamed from test cases/common/139 custom target object output/meson.build)0
-rw-r--r--test cases/common/143 custom target object output/obj_generator.py (renamed from test cases/common/139 custom target object output/obj_generator.py)0
-rw-r--r--test cases/common/143 custom target object output/objdir/meson.build (renamed from test cases/common/139 custom target object output/objdir/meson.build)0
-rw-r--r--test cases/common/143 custom target object output/objdir/source.c (renamed from test cases/common/139 custom target object output/objdir/source.c)0
-rw-r--r--test cases/common/143 custom target object output/progdir/meson.build (renamed from test cases/common/139 custom target object output/progdir/meson.build)0
-rw-r--r--test cases/common/143 custom target object output/progdir/prog.c (renamed from test cases/common/139 custom target object output/progdir/prog.c)0
-rw-r--r--test cases/common/144 empty build file/meson.build2
-rw-r--r--test cases/common/144 empty build file/subdir/meson.build0
-rw-r--r--test cases/common/16 configure file/meson.build5
-rw-r--r--test cases/common/23 global arg/meson.build2
-rw-r--r--test cases/common/23 global arg/prog.c4
-rw-r--r--test cases/common/23 global arg/prog.cc4
-rw-r--r--test cases/common/37 has header/meson.build18
-rw-r--r--test cases/failing/14 invalid option name/meson_options.txt2
-rw-r--r--test cases/failing/19 target clash/meson.build2
-rw-r--r--test cases/failing/43 project name colon/meson.build1
-rw-r--r--test cases/linuxlike/10 large file support/meson.build4
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c3
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build2
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build3
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c11
-rw-r--r--test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build14
-rw-r--r--test cases/linuxlike/7 library versions/meson.build4
-rw-r--r--test cases/linuxlike/8 subproject library install/meson.build4
-rw-r--r--test cases/objc/2 nsstring/meson.build2
-rw-r--r--test cases/windows/5 resources/meson.build2
-rw-r--r--test cases/windows/7 mingw dll versioning/installed_files.txt8
68 files changed, 562 insertions, 233 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 9264f49..c79e250 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -38,6 +38,10 @@ environment:
compiler: msys2-mingw
backend: ninja
+ - arch: x64
+ compiler: cygwin
+ backend: ninja
+
platform:
- x64
@@ -55,15 +59,22 @@ install:
- cmd: if %compiler%==msvc2015 ( call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %arch% )
- cmd: if %compiler%==msvc2017 ( call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\Tools\VsDevCmd.bat" -arch=%arch% )
- cmd: if %compiler%==msys2-mingw (if %arch%==x86 (set "PATH=C:\msys64\mingw32\bin;%PATH%") else (set "PATH=C:\msys64\mingw64\bin;%PATH%"))
+ - cmd: if %compiler%==cygwin ( call ci\appveyor-install.bat )
build_script:
- cmd: echo No build step.
- - cmd: if %backend%==ninja ( ninja.exe --version ) else ( MSBuild /version & echo. )
+ - cmd: if not %compiler%==cygwin if %backend%==ninja ( ninja.exe --version ) else ( MSBuild /version & echo. )
test_script:
- cmd: echo Running tests for %arch% and %compiler% with the %backend% backend
- - cmd: PATH=%cd%;%MESON_PYTHON_PATH%;%PATH%; && python run_tests.py --backend=%backend%
+ - cmd: set "ORIG_PATH=%PATH%"
+ - cmd: if %compiler%==cygwin ( set "PATH=%CYGWIN_ROOT%\bin;%SYSTEMROOT%\system32" && bash -lc "cd $APPVEYOR_BUILD_FOLDER && ci/appveyor-test.sh" )
+ - cmd: if not %compiler%==cygwin ( set "PATH=%cd%;%MESON_PYTHON_PATH%;%PATH%;" && python run_tests.py --backend=%backend% )
on_finish:
+ - set "PATH=%ORIG_PATH%"
- appveyor PushArtifact meson-test-run.txt -DeploymentName "Text test logs"
- appveyor PushArtifact meson-test-run.xml -DeploymentName "XML test logs"
+
+cache:
+ - C:\cache
diff --git a/authors.txt b/authors.txt
index 0c575e7..467ab75 100644
--- a/authors.txt
+++ b/authors.txt
@@ -73,3 +73,9 @@ Joe Baldino
Peter Harris
Roger Boerdijk
melak47
+Philipp Ittershagen
+Dylan Baker
+Aaron Plattner
+Jon Turney
+Wade Berrier
+Richard Hughes
diff --git a/ci/appveyor-install.bat b/ci/appveyor-install.bat
new file mode 100644
index 0000000..0c1ce44
--- /dev/null
+++ b/ci/appveyor-install.bat
@@ -0,0 +1,11 @@
+set CACHE=C:\cache
+set CYGWIN_MIRROR="http://cygwin.mirror.constant.com"
+
+if _%arch%_ == _x64_ set SETUP=setup-x86_64.exe && set CYGWIN_ROOT=C:\cygwin64
+if _%arch%_ == _x86_ set SETUP=setup-x86.exe && set CYGWIN_ROOT=C:\cygwin
+
+if not exist %CACHE% mkdir %CACHE%
+
+echo Updating Cygwin and installing ninja and test prerequisites
+%CYGWIN_ROOT%\%SETUP% -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -l "%CACHE%" -g -P "ninja,gcc-objc,gcc-objc++,libglib2.0-devel,zlib-devel"
+echo Install done
diff --git a/ci/appveyor-test.sh b/ci/appveyor-test.sh
new file mode 100755
index 0000000..2f29630
--- /dev/null
+++ b/ci/appveyor-test.sh
@@ -0,0 +1,6 @@
+#!/bin/sh
+
+echo ninja $(ninja --version)
+python3 --version -V
+
+python3 run_tests.py --backend=${backend}
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index 9b541e9..2e630bd 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -20,7 +20,8 @@ from .. import mlog
from .. import compilers
import json
import subprocess
-from ..mesonlib import MesonException, get_compiler_for_source, classify_unity_sources
+from ..mesonlib import MesonException, get_meson_script
+from ..mesonlib import get_compiler_for_source, classify_unity_sources
from ..compilers import CompilerArgs
class CleanTrees:
@@ -33,7 +34,7 @@ class CleanTrees:
self.trees = trees
class InstallData:
- def __init__(self, source_dir, build_dir, prefix, strip_bin):
+ def __init__(self, source_dir, build_dir, prefix, strip_bin, mesonintrospect):
self.source_dir = source_dir
self.build_dir = build_dir
self.prefix = prefix
@@ -46,6 +47,7 @@ class InstallData:
self.po = []
self.install_scripts = []
self.install_subdirs = []
+ self.mesonintrospect = mesonintrospect
class ExecutableSerialisation:
def __init__(self, name, fname, cmd_args, env, is_cross, exe_wrapper,
@@ -252,7 +254,7 @@ class Backend:
exe_wrapper = self.environment.cross_info.config['binaries'].get('exe_wrapper', None)
else:
exe_wrapper = None
- if mesonlib.is_windows():
+ if mesonlib.is_windows() or mesonlib.is_cygwin():
extra_paths = self.determine_windows_extra_paths(exe)
else:
extra_paths = []
@@ -481,7 +483,7 @@ class Backend:
exe_wrapper = self.environment.cross_info.config['binaries'].get('exe_wrapper', None)
else:
exe_wrapper = None
- if mesonlib.is_windows():
+ if mesonlib.is_windows() or mesonlib.is_cygwin():
extra_paths = self.determine_windows_extra_paths(exe)
else:
extra_paths = []
@@ -714,7 +716,7 @@ class Backend:
def run_postconf_scripts(self):
env = {'MESON_SOURCE_ROOT': self.environment.get_source_dir(),
'MESON_BUILD_ROOT': self.environment.get_build_dir(),
- }
+ 'MESONINTROSPECT': get_meson_script(self.environment, 'mesonintrospect')}
child_env = os.environ.copy()
child_env.update(env)
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 9378a56..4c87951 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -20,7 +20,8 @@ from .. import mlog
from .. import dependencies
from .. import compilers
from ..compilers import CompilerArgs
-from ..mesonlib import File, MesonException, get_compiler_for_source, Popen_safe
+from ..mesonlib import File, MesonException
+from ..mesonlib import get_meson_script, get_compiler_for_source, Popen_safe
from .backends import CleanTrees, InstallData
from ..build import InvalidArguments
import os, sys, pickle, re
@@ -492,7 +493,7 @@ int dummy;
# the project, we need to set PATH so the DLLs are found. We use
# a serialized executable wrapper for that and check if the
# CustomTarget command needs extra paths first.
- if target.capture or (mesonlib.is_windows() and
+ if target.capture or ((mesonlib.is_windows() or mesonlib.is_cygwin()) and
self.determine_windows_extra_paths(target.command[0])):
exe_data = self.serialise_executable(target.command[0], cmd[1:],
# All targets are built from the build dir
@@ -515,7 +516,7 @@ int dummy;
self.processed_targets[target.name + target.type_suffix()] = True
def generate_run_target(self, target, outfile):
- runnerscript = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner']
+ cmd = [sys.executable, self.environment.get_build_command(), '--internal', 'commandrunner']
deps = self.unwrap_dep_list(target)
arg_strings = []
for i in target.args:
@@ -531,7 +532,10 @@ int dummy;
else:
raise AssertionError('Unreachable code in generate_run_target: ' + str(i))
elem = NinjaBuildElement(self.all_outputs, target.name, 'CUSTOM_COMMAND', [])
- cmd = runnerscript + [self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir]
+ cmd += [self.environment.get_source_dir(),
+ self.environment.get_build_dir(),
+ target.subdir,
+ get_meson_script(self.environment, 'mesonintrospect')]
texe = target.command
try:
texe = texe.held_object
@@ -608,7 +612,8 @@ int dummy;
d = InstallData(self.environment.get_source_dir(),
self.environment.get_build_dir(),
self.environment.get_prefix(),
- strip_bin)
+ strip_bin,
+ get_meson_script(self.environment, 'mesonintrospect'))
elem = NinjaBuildElement(self.all_outputs, 'install', 'CUSTOM_COMMAND', 'PHONY')
elem.add_dep('all')
elem.add_item('DESC', 'Installing files.')
@@ -775,9 +780,7 @@ int dummy;
def generate_tests(self, outfile):
self.serialise_tests()
- meson_exe = self.environment.get_build_command()
- (base, ext) = os.path.splitext(meson_exe)
- test_exe = base + 'test' + ext
+ test_exe = get_meson_script(self.environment, 'mesontest')
cmd = [sys.executable, test_exe, '--no-rebuild']
if not self.environment.coredata.get_builtin_option('stdsplit'):
cmd += ['--no-stdsplit']
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index 7afbc0d..139360c 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -24,7 +24,7 @@ from .. import mlog
from .. import compilers
from ..build import BuildTarget
from ..compilers import CompilerArgs
-from ..mesonlib import MesonException, File
+from ..mesonlib import MesonException, File, get_meson_script
from ..environment import Environment
def autodetect_vs_version(build):
@@ -409,8 +409,10 @@ class Vs2010Backend(backends.Backend):
customstep = ET.SubElement(action, 'PostBuildEvent')
cmd_raw = [target.command] + target.args
cmd = [sys.executable, os.path.join(self.environment.get_script_dir(), 'commandrunner.py'),
- self.environment.get_build_dir(), self.environment.get_source_dir(),
- self.get_target_dir(target)]
+ self.environment.get_build_dir(),
+ self.environment.get_source_dir(),
+ self.get_target_dir(target),
+ get_meson_script(self.environment, 'mesonintrospect')]
for i in cmd_raw:
if isinstance(i, build.BuildTarget):
cmd.append(os.path.join(self.environment.get_build_dir(), self.get_target_filename(i)))
@@ -1164,11 +1166,8 @@ if %%errorlevel%% neq 0 goto :VCEnd'''
postbuild = ET.SubElement(action, 'PostBuildEvent')
ET.SubElement(postbuild, 'Message')
# FIXME: No benchmarks?
- meson_py = self.environment.get_build_command()
- (base, ext) = os.path.splitext(meson_py)
- mesontest_py = base + 'test' + ext
test_command = [sys.executable,
- mesontest_py,
+ get_meson_script(self.environment, 'mesontest'),
'--no-rebuild']
if not self.environment.coredata.get_builtin_option('stdsplit'):
test_command += ['--no-stdsplit']
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index 973d8e9..df3f37b 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -21,7 +21,7 @@ from . import mlog
from .mesonlib import File, MesonException
from .mesonlib import flatten, typeslistify, stringlistify, classify_unity_sources
from .mesonlib import get_filenames_templates_dict, substitute_values
-from .environment import for_windows, for_darwin
+from .environment import for_windows, for_darwin, for_cygwin
from .compilers import is_object, clike_langs, sort_clike, lang_suffixes
known_basic_kwargs = {'install': True,
@@ -1000,7 +1000,8 @@ class Executable(BuildTarget):
self.prefix = ''
if not hasattr(self, 'suffix'):
# Executable for Windows or C#/Mono
- if for_windows(is_cross, environment) or 'cs' in self.compilers:
+ if (for_windows(is_cross, environment) or
+ for_cygwin(is_cross, environment) or 'cs' in self.compilers):
self.suffix = 'exe'
else:
self.suffix = ''
@@ -1125,6 +1126,18 @@ class SharedLibrary(BuildTarget):
self.filename_tpl = '{0.prefix}{0.name}-{0.soversion}.{0.suffix}'
else:
self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
+ elif for_cygwin(is_cross, env):
+ suffix = 'dll'
+ self.gcc_import_filename = 'lib{0}.dll.a'.format(self.name)
+ # Shared library is of the form cygfoo.dll
+ # (ld --dll-search-prefix=cyg is the default)
+ prefix = 'cyg'
+ # Import library is called libfoo.dll.a
+ self.import_filename = self.gcc_import_filename
+ if self.soversion:
+ self.filename_tpl = '{0.prefix}{0.name}-{0.soversion}.{0.suffix}'
+ else:
+ self.filename_tpl = '{0.prefix}{0.name}.{0.suffix}'
elif for_darwin(is_cross, env):
prefix = 'lib'
suffix = 'dylib'
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 5e7db24..e6be8b1 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -550,11 +550,11 @@ class Compiler:
def get_exelist(self):
return self.exelist[:]
- def get_define(self, *args, **kwargs):
- raise EnvironmentException('%s does not support get_define.' % self.id)
+ def get_builtin_define(self, *args, **kwargs):
+ raise EnvironmentException('%s does not support get_builtin_define.' % self.id)
- def has_define(self, *args, **kwargs):
- raise EnvironmentException('%s does not support has_define.' % self.id)
+ def has_builtin_define(self, *args, **kwargs):
+ raise EnvironmentException('%s does not support has_builtin_define.' % self.id)
def get_always_args(self):
return []
@@ -906,8 +906,6 @@ class CCompiler(Compiler):
return self.sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code)
def has_header(self, hname, prefix, env, extra_args=None, dependencies=None):
- if extra_args is None:
- extra_args = []
fargs = {'prefix': prefix, 'header': hname}
code = '''{prefix}
#ifdef __has_include
@@ -921,8 +919,6 @@ class CCompiler(Compiler):
dependencies, 'preprocess')
def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
- if extra_args is None:
- extra_args = []
fargs = {'prefix': prefix, 'header': hname, 'symbol': symbol}
t = '''{prefix}
#include <{header}>
@@ -934,7 +930,7 @@ class CCompiler(Compiler):
}}'''
return self.compiles(t.format(**fargs), env, extra_args, dependencies)
- def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'):
+ def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'):
if extra_args is None:
extra_args = []
elif isinstance(extra_args, str):
@@ -943,49 +939,43 @@ class CCompiler(Compiler):
dependencies = []
elif not isinstance(dependencies, list):
dependencies = [dependencies]
- # Add compile flags needed by dependencies
+ # Collect compiler arguments
args = CompilerArgs(self)
for d in dependencies:
+ # Add compile flags needed by dependencies
args += d.get_compile_args()
+ if mode == 'link':
+ # Add link flags needed to find dependencies
+ args += d.get_link_args()
+ # Select a CRT if needed since we're linking
+ if mode == 'link':
+ args += self.get_linker_debug_crt_args()
# Read c_args/cpp_args/etc from the cross-info file (if needed)
- args += self.get_cross_extra_flags(env, compile=True, link=False)
- # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env
- # We assume that the user has ensured these are compiler-specific
- args += env.coredata.external_args[self.language]
+ args += self.get_cross_extra_flags(env, compile=(mode != 'preprocess'),
+ link=(mode == 'link'))
+ if mode == 'preprocess':
+ # Add CPPFLAGS from the env.
+ args += env.coredata.external_preprocess_args[self.language]
+ elif mode == 'compile':
+ # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS from the env
+ args += env.coredata.external_args[self.language]
+ elif mode == 'link':
+ # Add LDFLAGS from the env
+ args += env.coredata.external_link_args[self.language]
args += self.get_compiler_check_args()
# extra_args must override all other arguments, so we add them last
args += extra_args
+ return args
+
+ def compiles(self, code, env, extra_args=None, dependencies=None, mode='compile'):
+ args = self._get_compiler_check_args(env, extra_args, dependencies, mode)
# We only want to compile; not link
with self.compile(code, args.to_native(), mode) as p:
return p.returncode == 0
def _links_wrapper(self, code, env, extra_args, dependencies):
"Shares common code between self.links and self.run"
- if extra_args is None:
- extra_args = []
- elif isinstance(extra_args, str):
- extra_args = [extra_args]
- if dependencies is None:
- dependencies = []
- elif not isinstance(dependencies, list):
- dependencies = [dependencies]
- # Add compile and link flags needed by dependencies
- args = CompilerArgs(self)
- for d in dependencies:
- args += d.get_compile_args()
- args += d.get_link_args()
- # Select a CRT if needed since we're linking
- args += self.get_linker_debug_crt_args()
- # Read c_args/c_link_args/cpp_args/cpp_link_args/etc from the
- # cross-info file (if needed)
- args += self.get_cross_extra_flags(env, compile=True, link=True)
- # Add LDFLAGS from the env. We assume that the user has ensured these
- # are compiler-specific
- args += env.coredata.external_link_args[self.language]
- # Add compiler check args such that they override
- args += self.get_compiler_check_args()
- # extra_args must override all other arguments, so we add them last
- args += extra_args
+ args = self._get_compiler_check_args(env, extra_args, dependencies, mode='link')
return self.compile(code, args.to_native())
def links(self, code, env, extra_args=None, dependencies=None):
@@ -1141,6 +1131,24 @@ class CCompiler(Compiler):
raise EnvironmentException('Could not determine alignment of %s. Sorry. You might want to file a bug.' % typename)
return align
+ def get_define(self, dname, prefix, env, extra_args, dependencies):
+ delim = '"MESON_GET_DEFINE_DELIMITER"'
+ fargs = {'prefix': prefix, 'define': dname, 'delim': delim}
+ code = '''
+ #ifndef {define}
+ # define {define}
+ #endif
+ {prefix}
+ {delim}\n{define}'''
+ args = self._get_compiler_check_args(env, extra_args, dependencies,
+ mode='preprocess').to_native()
+ with self.compile(code.format(**fargs), args, 'preprocess') as p:
+ if p.returncode != 0:
+ raise EnvironmentException('Could not get define {!r}'.format(dname))
+ # Get the preprocessed value after the delimiter,
+ # minus the extra newline at the end
+ return p.stdo.split(delim + '\n')[-1][:-1]
+
@staticmethod
def _no_prototype_templ():
"""
@@ -2301,6 +2309,7 @@ class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
GCC_STANDARD = 0
GCC_OSX = 1
GCC_MINGW = 2
+GCC_CYGWIN = 3
CLANG_STANDARD = 0
CLANG_OSX = 1
@@ -2316,7 +2325,7 @@ def get_gcc_soname_args(gcc_type, prefix, shlib_name, suffix, path, soversion, i
sostr = ''
else:
sostr = '.' + soversion
- if gcc_type == GCC_STANDARD or gcc_type == GCC_MINGW:
+ if gcc_type in (GCC_STANDARD, GCC_MINGW, GCC_CYGWIN):
# Might not be correct for mingw but seems to work.
return ['-Wl,-soname,%s%s.%s%s' % (prefix, shlib_name, suffix, sostr)]
elif gcc_type == GCC_OSX:
@@ -2382,15 +2391,15 @@ class GnuCompiler:
args[args.index('-Wpedantic')] = '-pedantic'
return args
- def has_define(self, define):
+ def has_builtin_define(self, define):
return define in self.defines
- def get_define(self, define):
+ def get_builtin_define(self, define):
if define in self.defines:
return self.defines[define]
def get_pic_args(self):
- if self.gcc_type in (GCC_MINGW, GCC_OSX):
+ if self.gcc_type in (GCC_CYGWIN, GCC_MINGW, GCC_OSX):
return [] # On Window and OS X, pic is always on.
return ['-fPIC']
@@ -2788,7 +2797,7 @@ class FortranCompiler(Compiler):
return ' '.join(self.exelist)
def get_pic_args(self):
- if self.gcc_type in (GCC_MINGW, GCC_OSX):
+ if self.gcc_type in (GCC_CYGWIN, GCC_MINGW, GCC_OSX):
return [] # On Window and OS X, pic is always on.
return ['-fPIC']
@@ -2896,10 +2905,10 @@ class GnuFortranCompiler(FortranCompiler):
self.defines = defines or {}
self.id = 'gcc'
- def has_define(self, define):
+ def has_builtin_define(self, define):
return define in self.defines
- def get_define(self, define):
+ def get_builtin_define(self, define):
if define in self.defines:
return self.defines[define]
diff --git a/mesonbuild/coredata.py b/mesonbuild/coredata.py
index 67516e7..27f1dd7 100644
--- a/mesonbuild/coredata.py
+++ b/mesonbuild/coredata.py
@@ -148,10 +148,11 @@ class CoreData:
self.user_options = {}
self.compiler_options = {}
self.base_options = {}
- # These two, external_*args, are set via env vars CFLAGS, LDFLAGS, etc
+ # These external_*args, are set via env vars CFLAGS, LDFLAGS, etc
# but only when not cross-compiling.
- self.external_args = {}
- self.external_link_args = {}
+ self.external_preprocess_args = {} # CPPFLAGS only
+ self.external_args = {} # CPPFLAGS + CFLAGS
+ self.external_link_args = {} # CFLAGS + LDFLAGS (with MSVC: only LDFLAGS)
if options.cross_file is not None:
self.cross_file = os.path.join(os.getcwd(), options.cross_file)
else:
diff --git a/mesonbuild/dependencies.py b/mesonbuild/dependencies.py
index eacb15b..2b110bb 100644
--- a/mesonbuild/dependencies.py
+++ b/mesonbuild/dependencies.py
@@ -598,12 +598,18 @@ class BoostDependency(Dependency):
self.boost_root = None
if self.boost_root is None:
if self.want_cross:
- raise DependencyException('BOOST_ROOT is needed while cross-compiling')
+ if 'BOOST_INCLUDEDIR' in os.environ:
+ self.incdir = os.environ['BOOST_INCLUDEDIR']
+ else:
+ raise DependencyException('BOOST_ROOT or BOOST_INCLUDEDIR is needed while cross-compiling')
if mesonlib.is_windows():
self.boost_root = self.detect_win_root()
self.incdir = self.boost_root
else:
- self.incdir = '/usr/include'
+ if 'BOOST_INCLUDEDIR' in os.environ:
+ self.incdir = os.environ['BOOST_INCLUDEDIR']
+ else:
+ self.incdir = '/usr/include'
else:
self.incdir = os.path.join(self.boost_root, 'include')
self.boost_inc_subdir = os.path.join(self.incdir, 'boost')
@@ -727,7 +733,9 @@ class BoostDependency(Dependency):
libsuffix = 'so'
globber = 'libboost_*.{}'.format(libsuffix)
- if self.boost_root is None:
+ if 'BOOST_LIBRARYDIR' in os.environ:
+ libdirs = [os.environ['BOOST_LIBRARYDIR']]
+ elif self.boost_root is None:
libdirs = mesonlib.get_library_dirs()
else:
libdirs = [os.path.join(self.boost_root, 'lib')]
@@ -758,6 +766,8 @@ class BoostDependency(Dependency):
args = []
if self.boost_root:
args.append('-L' + os.path.join(self.boost_root, 'lib'))
+ elif 'BOOST_LIBRARYDIR' in os.environ:
+ args.append('-L' + os.environ['BOOST_LIBRARYDIR'])
for module in self.requested_modules:
module = BoostDependency.name2lib.get(module, module)
libname = 'boost_' + module
@@ -1483,6 +1493,14 @@ class Python3Dependency(Dependency):
def get_version(self):
return self.version
+class ValgrindDependency(PkgConfigDependency):
+
+ def __init__(self, environment, kwargs):
+ PkgConfigDependency.__init__(self, 'valgrind', environment, kwargs)
+
+ def get_link_args(self):
+ return []
+
def get_dep_identifier(name, kwargs):
elements = [name]
modlist = kwargs.get('modules', [])
@@ -1544,4 +1562,5 @@ packages = {'boost': BoostDependency,
'gl': GLDependency,
'threads': ThreadDependency,
'python3': Python3Dependency,
+ 'valgrind': ValgrindDependency,
}
diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py
index 92040c4..7861612 100644
--- a/mesonbuild/environment.py
+++ b/mesonbuild/environment.py
@@ -102,7 +102,7 @@ def detect_windows_arch(compilers):
platform = os.environ.get('Platform', 'x86').lower()
if platform == 'x86':
return platform
- if compiler.id == 'gcc' and compiler.has_define('__i386__'):
+ if compiler.id == 'gcc' and compiler.has_builtin_define('__i386__'):
return 'x86'
return os_arch
@@ -129,10 +129,10 @@ def detect_cpu_family(compilers):
# to know is to check the compiler defines.
for c in compilers.values():
try:
- if c.has_define('__i386__'):
+ if c.has_builtin_define('__i386__'):
return 'x86'
except mesonlib.MesonException:
- # Ignore compilers that do not support has_define.
+ # Ignore compilers that do not support has_builtin_define.
pass
return 'x86_64'
# Add fixes here as bugs are reported.
@@ -149,7 +149,7 @@ def detect_cpu(compilers):
# Same check as above for cpu_family
for c in compilers.values():
try:
- if c.has_define('__i386__'):
+ if c.has_builtin_define('__i386__'):
return 'i686' # All 64 bit cpus have at least this level of x86 support.
except mesonlib.MesonException:
pass
@@ -158,7 +158,10 @@ def detect_cpu(compilers):
return trial
def detect_system():
- return platform.system().lower()
+ system = platform.system().lower()
+ if system.startswith('cygwin'):
+ return 'cygwin'
+ return system
def for_windows(is_cross, env):
@@ -173,6 +176,20 @@ def for_windows(is_cross, env):
return env.cross_info.config['host_machine']['system'] == 'windows'
return False
+
+def for_cygwin(is_cross, env):
+ """
+ Host machine is cygwin?
+
+ Note: 'host' is the machine on which compiled binaries will run
+ """
+ if not is_cross:
+ return mesonlib.is_cygwin()
+ elif env.cross_info.has_host():
+ return env.cross_info.config['host_machine']['system'] == 'cygwin'
+ return False
+
+
def for_darwin(is_cross, env):
"""
Host machine is Darwin (iOS/OS X)?
@@ -257,6 +274,11 @@ class Environment:
self.exe_suffix = 'exe'
self.object_suffix = 'obj'
self.win_libdir_layout = True
+ elif (not cross and mesonlib.is_cygwin()) \
+ or (cross and self.cross_info.has_host() and self.cross_info.config['host_machine']['system'] == 'cygwin'):
+ self.exe_suffix = 'exe'
+ self.object_suffix = 'o'
+ self.win_libdir_layout = True
else:
self.exe_suffix = ''
self.object_suffix = 'o'
@@ -368,7 +390,8 @@ class Environment:
return GCC_OSX
elif '__MINGW32__' in defines or '__MINGW64__' in defines:
return GCC_MINGW
- # We ignore Cygwin for now, and treat it as a standard GCC
+ elif '__CYGWIN__' in defines:
+ return GCC_CYGWIN
return GCC_STANDARD
def _get_compilers(self, lang, evar, want_cross):
@@ -770,7 +793,7 @@ def get_args_from_envvars(compiler):
compiler_is_linker = (compiler.get_exelist() == compiler.get_linker_exelist())
if lang not in ('c', 'cpp', 'objc', 'objcpp', 'fortran', 'd'):
- return [], []
+ return [], [], []
# Compile flags
cflags_mapping = {'c': 'CFLAGS',
@@ -781,12 +804,12 @@ def get_args_from_envvars(compiler):
'd': 'DFLAGS'}
compile_flags = os.environ.get(cflags_mapping[lang], '')
log_var(cflags_mapping[lang], compile_flags)
- compile_flags = compile_flags.split()
+ compile_flags = shlex.split(compile_flags)
# Link flags (same for all languages)
link_flags = os.environ.get('LDFLAGS', '')
log_var('LDFLAGS', link_flags)
- link_flags = link_flags.split()
+ link_flags = shlex.split(link_flags)
if compiler_is_linker:
# When the compiler is used as a wrapper around the linker (such as
# with GCC and Clang), the compile flags can be needed while linking
@@ -794,14 +817,15 @@ def get_args_from_envvars(compiler):
# this when the linker is stand-alone such as with MSVC C/C++, etc.
link_flags = compile_flags + link_flags
- # Pre-processof rlags (not for fortran)
+ # Pre-processor flags (not for fortran or D)
preproc_flags = ''
if lang in ('c', 'cpp', 'objc', 'objcpp'):
preproc_flags = os.environ.get('CPPFLAGS', '')
log_var('CPPFLAGS', preproc_flags)
- compile_flags += preproc_flags.split()
+ preproc_flags = shlex.split(preproc_flags)
+ compile_flags += preproc_flags
- return compile_flags, link_flags
+ return preproc_flags, compile_flags, link_flags
class CrossBuildInfo:
def __init__(self, filename):
diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py
index 945de6b..2f8e5f6 100644
--- a/mesonbuild/interpreter.py
+++ b/mesonbuild/interpreter.py
@@ -22,7 +22,7 @@ from . import optinterpreter
from . import compilers
from .wrap import wrap, WrapMode
from . import mesonlib
-from .mesonlib import FileMode, Popen_safe
+from .mesonlib import FileMode, Popen_safe, get_meson_script
from .dependencies import InternalDependency, Dependency
from .interpreterbase import InterpreterBase
from .interpreterbase import check_stringlist, noPosargs, noKwargs, stringArgs
@@ -72,20 +72,21 @@ class TryRunResultHolder(InterpreterObject):
class RunProcess(InterpreterObject):
- def __init__(self, command_array, source_dir, build_dir, subdir, in_builddir=False):
+ def __init__(self, command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir=False):
super().__init__()
- pc, self.stdout, self.stderr = self.run_command(command_array, source_dir, build_dir, subdir, in_builddir)
+ pc, self.stdout, self.stderr = self.run_command(command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir)
self.returncode = pc.returncode
self.methods.update({'returncode': self.returncode_method,
'stdout': self.stdout_method,
'stderr': self.stderr_method,
})
- def run_command(self, command_array, source_dir, build_dir, subdir, in_builddir):
+ def run_command(self, command_array, source_dir, build_dir, subdir, mesonintrospect, in_builddir):
cmd_name = command_array[0]
env = {'MESON_SOURCE_ROOT': source_dir,
'MESON_BUILD_ROOT': build_dir,
- 'MESON_SUBDIR': subdir}
+ 'MESON_SUBDIR': subdir,
+ 'MESONINTROSPECT': mesonintrospect}
if in_builddir:
cwd = os.path.join(build_dir, subdir)
else:
@@ -634,6 +635,7 @@ class CompilerHolder(InterpreterObject):
'get_id': self.get_id_method,
'compute_int': self.compute_int_method,
'sizeof': self.sizeof_method,
+ 'get_define': self.get_define_method,
'has_header': self.has_header_method,
'has_header_symbol': self.has_header_symbol_method,
'run': self.run_method,
@@ -865,6 +867,20 @@ class CompilerHolder(InterpreterObject):
mlog.log('Checking for size of "%s": %d' % (element, esize))
return esize
+ def get_define_method(self, args, kwargs):
+ if len(args) != 1:
+ raise InterpreterException('get_define() takes exactly one argument.')
+ check_stringlist(args)
+ element = args[0]
+ prefix = kwargs.get('prefix', '')
+ if not isinstance(prefix, str):
+ raise InterpreterException('Prefix argument of get_define() must be a string.')
+ extra_args = self.determine_args(kwargs)
+ deps = self.determine_dependencies(kwargs)
+ value = self.compiler.get_define(element, prefix, self.environment, extra_args, deps)
+ mlog.log('Checking for value of define "%s": %s' % (element, value))
+ return value
+
def compiles_method(self, args, kwargs):
if len(args) != 1:
raise InterpreterException('compiles method takes exactly one argument.')
@@ -1224,7 +1240,8 @@ class Interpreter(InterpreterBase):
self.builtin.update({'meson': MesonMain(build, self)})
self.generators = []
self.visited_subdirs = {}
- self.args_frozen = False
+ self.project_args_frozen = False
+ self.global_args_frozen = False # implies self.project_args_frozen
self.subprojects = {}
self.subproject_stack = []
self.default_project_options = default_project_options[:] # Passed from the outside, only used in subprojects.
@@ -1474,8 +1491,8 @@ class Interpreter(InterpreterBase):
in_builddir = kwargs.get('in_builddir', False)
if not isinstance(in_builddir, bool):
raise InterpreterException('in_builddir must be boolean.')
- return RunProcess(args, self.environment.source_dir, self.environment.build_dir,
- self.subdir, in_builddir)
+ return RunProcess(args, self.environment.source_dir, self.environment.build_dir, self.subdir,
+ get_meson_script(self.environment, 'mesonintrospect'), in_builddir)
@stringArgs
def func_gettext(self, nodes, args, kwargs):
@@ -1507,7 +1524,7 @@ class Interpreter(InterpreterBase):
raise InterpreterException(msg.format(os.path.join(self.subproject_dir, dirname), e))
subdir = os.path.join(self.subproject_dir, resolved)
os.makedirs(os.path.join(self.build.environment.get_build_dir(), subdir), exist_ok=True)
- self.args_frozen = True
+ self.global_args_frozen = True
mlog.log('\nExecuting subproject ', mlog.bold(dirname), '.\n', sep='')
subi = Interpreter(self.build, self.backend, dirname, subdir, self.subproject_dir,
mesonlib.stringlistify(kwargs.get('default_options', [])))
@@ -1615,25 +1632,29 @@ class Interpreter(InterpreterBase):
def func_project(self, node, args, kwargs):
if len(args) < 1:
raise InvalidArguments('Not enough arguments to project(). Needs at least the project name.')
+ proj_name = args[0]
+ proj_langs = args[1:]
+ if ':' in proj_name:
+ raise InvalidArguments("Project name {!r} must not contain ':'".format(proj_name))
default_options = kwargs.get('default_options', [])
if self.environment.first_invocation and (len(default_options) > 0 or
len(self.default_project_options) > 0):
self.parse_default_options(default_options)
if not self.is_subproject():
- self.build.project_name = args[0]
+ self.build.project_name = proj_name
if os.path.exists(self.option_file):
oi = optinterpreter.OptionInterpreter(self.subproject,
self.build.environment.cmd_line_options.projectoptions,
)
oi.process(self.option_file)
self.build.environment.merge_options(oi.options)
- self.active_projectname = args[0]
+ self.active_projectname = proj_name
self.project_version = kwargs.get('version', 'undefined')
if self.build.project_version is None:
self.build.project_version = self.project_version
proj_license = mesonlib.stringlistify(kwargs.get('license', 'unknown'))
- self.build.dep_manifest[args[0]] = {'version': self.project_version,
- 'license': proj_license}
+ self.build.dep_manifest[proj_name] = {'version': self.project_version,
+ 'license': proj_license}
if self.subproject in self.build.projects:
raise InvalidCode('Second call to project().')
if not self.is_subproject() and 'subproject_dir' in kwargs:
@@ -1644,9 +1665,9 @@ class Interpreter(InterpreterBase):
pv = kwargs['meson_version']
if not mesonlib.version_compare(cv, pv):
raise InterpreterException('Meson version is %s but project requires %s.' % (cv, pv))
- self.build.projects[self.subproject] = args[0]
- mlog.log('Project name: ', mlog.bold(args[0]), sep='')
- self.add_languages(args[1:], True)
+ self.build.projects[self.subproject] = proj_name
+ mlog.log('Project name: ', mlog.bold(proj_name), sep='')
+ self.add_languages(proj_langs, True)
langs = self.coredata.compilers.keys()
if 'vala' in langs:
if 'c' not in langs:
@@ -1772,9 +1793,10 @@ class Interpreter(InterpreterBase):
raise
mlog.log('Native %s compiler: ' % lang, mlog.bold(' '.join(comp.get_exelist())), ' (%s %s)' % (comp.id, comp.version), sep='')
if not comp.get_language() in self.coredata.external_args:
- (ext_compile_args, ext_link_args) = environment.get_args_from_envvars(comp)
- self.coredata.external_args[comp.get_language()] = ext_compile_args
- self.coredata.external_link_args[comp.get_language()] = ext_link_args
+ (preproc_args, compile_args, link_args) = environment.get_args_from_envvars(comp)
+ self.coredata.external_preprocess_args[comp.get_language()] = preproc_args
+ self.coredata.external_args[comp.get_language()] = compile_args
+ self.coredata.external_link_args[comp.get_language()] = link_args
self.build.add_compiler(comp)
if need_cross_compiler:
mlog.log('Cross %s compiler: ' % lang, mlog.bold(' '.join(cross_comp.get_exelist())), ' (%s %s)' % (cross_comp.id, cross_comp.version), sep='')
@@ -2290,7 +2312,11 @@ class Interpreter(InterpreterBase):
inputfile = inputfile[0]
if not isinstance(inputfile, (str, mesonlib.File)):
raise InterpreterException('Input must be a string or a file')
- ifile_abs = os.path.join(self.environment.source_dir, self.subdir, inputfile)
+ if isinstance(inputfile, str):
+ inputfile = os.path.join(self.subdir, inputfile)
+ else:
+ inputfile = inputfile.relative_name()
+ ifile_abs = os.path.join(self.environment.source_dir, inputfile)
elif 'command' in kwargs and '@INPUT@' in kwargs['command']:
raise InterpreterException('@INPUT@ used as command argument, but no input file specified.')
# Validate output
@@ -2309,7 +2335,7 @@ class Interpreter(InterpreterBase):
if inputfile is not None:
# Normalize the path of the conffile to avoid duplicates
# This is especially important to convert '/' to '\' on Windows
- conffile = os.path.normpath(os.path.join(self.subdir, inputfile))
+ conffile = os.path.normpath(inputfile)
if conffile not in self.build_def_files:
self.build_def_files.append(conffile)
os.makedirs(os.path.join(self.environment.build_dir, self.subdir), exist_ok=True)
@@ -2415,83 +2441,51 @@ different subdirectory.
@stringArgs
def func_add_global_arguments(self, node, args, kwargs):
- if self.subproject != '':
- msg = 'Global arguments can not be set in subprojects because ' \
- 'there is no way to make that reliable.\nPlease only call ' \
- 'this if is_subproject() returns false. Alternatively, ' \
- 'define a variable that\ncontains your language-specific ' \
- 'arguments and add it to the appropriate *_args kwarg ' \
- 'in each target.'
- raise InvalidCode(msg)
- if self.args_frozen:
- msg = 'Tried to set global arguments after a build target has ' \
- 'been declared.\nThis is not permitted. Please declare all ' \
- 'global arguments before your targets.'
- raise InvalidCode(msg)
- if 'language' not in kwargs:
- raise InvalidCode('Missing language definition in add_global_arguments')
- lang = kwargs['language'].lower()
- if lang in self.build.global_args:
- self.build.global_args[lang] += args
- else:
- self.build.global_args[lang] = args
+ self.add_global_arguments(node, self.build.global_args, args, kwargs)
@stringArgs
def func_add_global_link_arguments(self, node, args, kwargs):
+ self.add_global_arguments(node, self.build.global_link_args, args, kwargs)
+
+ @stringArgs
+ def func_add_project_arguments(self, node, args, kwargs):
+ self.add_project_arguments(node, self.build.projects_args, args, kwargs)
+
+ @stringArgs
+ def func_add_project_link_arguments(self, node, args, kwargs):
+ self.add_project_arguments(node, self.build.projects_link_args, args, kwargs)
+
+ def add_global_arguments(self, node, argsdict, args, kwargs):
if self.subproject != '':
- msg = 'Global link arguments can not be set in subprojects because ' \
+ msg = 'Function \'{}\' cannot be used in subprojects because ' \
'there is no way to make that reliable.\nPlease only call ' \
'this if is_subproject() returns false. Alternatively, ' \
'define a variable that\ncontains your language-specific ' \
'arguments and add it to the appropriate *_args kwarg ' \
- 'in each target.'
+ 'in each target.'.format(node.func_name)
raise InvalidCode(msg)
- if self.args_frozen:
- msg = 'Tried to set global link arguments after a build target has ' \
- 'been declared.\nThis is not permitted. Please declare all ' \
- 'global arguments before your targets.'
+ frozen = self.project_args_frozen or self.global_args_frozen
+ self.add_arguments(node, argsdict, frozen, args, kwargs)
+
+ def add_project_arguments(self, node, argsdict, args, kwargs):
+ if self.subproject not in argsdict:
+ argsdict[self.subproject] = {}
+ self.add_arguments(node, argsdict[self.subproject],
+ self.project_args_frozen, args, kwargs)
+
+ def add_arguments(self, node, argsdict, args_frozen, args, kwargs):
+ if args_frozen:
+ msg = 'Tried to use \'{}\' after a build target has been declared.\n' \
+ 'This is not permitted. Please declare all ' \
+ 'arguments before your targets.'.format(node.func_name)
raise InvalidCode(msg)
- if 'language' not in kwargs:
- raise InvalidCode('Missing language definition in add_global_link_arguments')
- lang = kwargs['language'].lower()
- if lang in self.build.global_link_args:
- self.build.global_link_args[lang] += args
- else:
- self.build.global_link_args[lang] = args
- @stringArgs
- def func_add_project_link_arguments(self, node, args, kwargs):
- if self.args_frozen:
- msg = 'Tried to set project link arguments after a build target has ' \
- 'been declared.\nThis is not permitted. Please declare all ' \
- 'project link arguments before your targets.'
- raise InvalidCode(msg)
if 'language' not in kwargs:
- raise InvalidCode('Missing language definition in add_project_link_arguments')
- lang = kwargs['language'].lower()
- if self.subproject not in self.build.projects_link_args:
- self.build.projects_link_args[self.subproject] = {}
+ raise InvalidCode('Missing language definition in {}'.format(node.func_name))
- args = self.build.projects_link_args[self.subproject].get(lang, []) + args
- self.build.projects_link_args[self.subproject][lang] = args
-
- @stringArgs
- def func_add_project_arguments(self, node, args, kwargs):
- if self.args_frozen:
- msg = 'Tried to set project arguments after a build target has ' \
- 'been declared.\nThis is not permitted. Please declare all ' \
- 'project arguments before your targets.'
- raise InvalidCode(msg)
-
- if 'language' not in kwargs:
- raise InvalidCode('Missing language definition in add_project_arguments')
-
- if self.subproject not in self.build.projects_args:
- self.build.projects_args[self.subproject] = {}
-
- lang = kwargs['language'].lower()
- args = self.build.projects_args[self.subproject].get(lang, []) + args
- self.build.projects_args[self.subproject][lang] = args
+ for lang in mesonlib.stringlistify(kwargs['language']):
+ lang = lang.lower()
+ argsdict[lang] = argsdict.get(lang, []) + args
def func_environment(self, node, args, kwargs):
return EnvironmentVariablesHolder()
@@ -2576,7 +2570,7 @@ different subdirectory.
self.add_cross_stdlib_info(target)
l = targetholder(target, self)
self.add_target(name, l.held_object)
- self.args_frozen = True
+ self.project_args_frozen = True
return l
def get_used_languages(self, target):
diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py
index ef169c1..5377d8e 100644
--- a/mesonbuild/mesonlib.py
+++ b/mesonbuild/mesonlib.py
@@ -125,14 +125,14 @@ class File:
assert(isinstance(self.fname, str))
def __str__(self):
- return os.path.join(self.subdir, self.fname)
+ return self.relative_name()
def __repr__(self):
ret = '<File: {0}'
if not self.is_built:
ret += ' (not built)'
ret += '>'
- return ret.format(os.path.join(self.subdir, self.fname))
+ return ret.format(self.relative_name())
@staticmethod
def from_source_file(source_root, subdir, fname):
@@ -150,15 +150,15 @@ class File:
def rel_to_builddir(self, build_to_src):
if self.is_built:
- return os.path.join(self.subdir, self.fname)
+ return self.relative_name()
else:
return os.path.join(build_to_src, self.subdir, self.fname)
def absolute_path(self, srcdir, builddir):
+ absdir = srcdir
if self.is_built:
- return os.path.join(builddir, self.subdir, self.fname)
- else:
- return os.path.join(srcdir, self.subdir, self.fname)
+ absdir = builddir
+ return os.path.join(absdir, self.relative_name())
def endswith(self, ending):
return self.fname.endswith(ending)
@@ -175,6 +175,15 @@ class File:
def relative_name(self):
return os.path.join(self.subdir, self.fname)
+def get_meson_script(env, script):
+ '''
+ Given the path of `meson.py`/`meson`, get the path of a meson script such
+ as `mesonintrospect` or `mesontest`.
+ '''
+ meson_py = env.get_build_command()
+ (base, ext) = os.path.splitext(meson_py)
+ return os.path.join(os.path.dirname(base), script + ext)
+
def get_compiler_for_source(compilers, src):
for comp in compilers:
if comp.can_compile(src):
@@ -212,6 +221,10 @@ def is_windows():
platname = platform.system().lower()
return platname == 'windows' or 'mingw' in platname
+def is_cygwin():
+ platname = platform.system().lower()
+ return platname.startswith('cygwin')
+
def is_debianlike():
return os.path.isfile('/etc/debian_version')
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 2f5bfb9..adb6fa8 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -766,6 +766,8 @@ class GnomeModule(ExtensionModule):
cmd += ['--interface-prefix', kwargs.pop('interface_prefix')]
if 'namespace' in kwargs:
cmd += ['--c-namespace', kwargs.pop('namespace')]
+ if kwargs.get('object_manager', False):
+ cmd += ['--c-generate-object-manager']
# https://git.gnome.org/browse/glib/commit/?id=ee09bb704fe9ccb24d92dd86696a0e6bb8f0dc1a
if mesonlib.version_compare(self._get_native_glib_version(state), '>= 2.51.3'):
diff --git a/mesonbuild/modules/windows.py b/mesonbuild/modules/windows.py
index c233d90..3fb0107 100644
--- a/mesonbuild/modules/windows.py
+++ b/mesonbuild/modules/windows.py
@@ -51,9 +51,17 @@ class WindowsModule(ExtensionModule):
for arg in extra_args:
if ' ' in arg:
mlog.warning(m.format(arg))
- # Pick-up env var WINDRES if set. This is often used for specifying
- # an arch-specific windres.
- rescomp_name = os.environ.get('WINDRES', 'windres')
+ rescomp_name = None
+ # FIXME: Does not handle `native: true` executables, see
+ # https://github.com/mesonbuild/meson/issues/1531
+ if state.environment.is_cross_build():
+ # If cross compiling see if windres has been specified in the
+ # cross file before trying to find it another way.
+ rescomp_name = state.environment.cross_info.config['binaries'].get('windres')
+ if rescomp_name is None:
+ # Pick-up env var WINDRES if set. This is often used for
+ # specifying an arch-specific windres.
+ rescomp_name = os.environ.get('WINDRES', 'windres')
rescomp = dependencies.ExternalProgram(rescomp_name, silent=True)
res_args = extra_args + ['@INPUT@', '@OUTPUT@']
suffix = 'o'
diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py
index 7a91539..a9f25b1 100644
--- a/mesonbuild/mparser.py
+++ b/mesonbuild/mparser.py
@@ -407,6 +407,7 @@ class Parser:
def __init__(self, code, subdir):
self.lexer = Lexer(code)
self.stream = self.lexer.lex(subdir)
+ self.current = Token('eof', '', 0, 0, 0, (0, 0), None)
self.getsym()
self.in_ternary = False
diff --git a/mesonbuild/optinterpreter.py b/mesonbuild/optinterpreter.py
index 10b8fab..f9e7f26 100644
--- a/mesonbuild/optinterpreter.py
+++ b/mesonbuild/optinterpreter.py
@@ -75,15 +75,16 @@ class OptionInterpreter:
self.cmd_line_options = {}
for o in command_line_options:
if self.subproject != '': # Strip the beginning.
+ # Ignore options that aren't for this subproject
if not o.startswith(self.sbprefix):
continue
- else:
- if ':' in o:
- continue
try:
(key, value) = o.split('=', 1)
except ValueError:
raise OptionException('Option {!r} must have a value separated by equals sign.'.format(o))
+ # Ignore subproject options if not fetching subproject options
+ if self.subproject == '' and ':' in key:
+ continue
self.cmd_line_options[key] = value
def process(self, option_file):
diff --git a/mesonbuild/scripts/commandrunner.py b/mesonbuild/scripts/commandrunner.py
index cf2770d..87e3b8b 100644
--- a/mesonbuild/scripts/commandrunner.py
+++ b/mesonbuild/scripts/commandrunner.py
@@ -17,11 +17,11 @@ what to run, sets up the environment and executes the command."""
import sys, os, subprocess, shutil
-def run_command(source_dir, build_dir, subdir, command, arguments):
+def run_command(source_dir, build_dir, subdir, mesonintrospect, command, arguments):
env = {'MESON_SOURCE_ROOT': source_dir,
'MESON_BUILD_ROOT': build_dir,
'MESON_SUBDIR': subdir,
- }
+ 'MESONINTROSPECT': mesonintrospect}
cwd = os.path.join(source_dir, subdir)
child_env = os.environ.copy()
child_env.update(env)
@@ -47,9 +47,10 @@ def run(args):
src_dir = args[0]
build_dir = args[1]
subdir = args[2]
- command = args[3]
- arguments = args[4:]
- pc = run_command(src_dir, build_dir, subdir, command, arguments)
+ mesonintrospect = args[3]
+ command = args[4]
+ arguments = args[5:]
+ pc = run_command(src_dir, build_dir, subdir, mesonintrospect, command, arguments)
pc.wait()
return pc.returncode
diff --git a/mesonbuild/scripts/meson_exe.py b/mesonbuild/scripts/meson_exe.py
index 5c5c317..643e1af 100644
--- a/mesonbuild/scripts/meson_exe.py
+++ b/mesonbuild/scripts/meson_exe.py
@@ -29,8 +29,12 @@ def is_windows():
platname = platform.system().lower()
return platname == 'windows' or 'mingw' in platname
+def is_cygwin():
+ platname = platform.system().lower()
+ return 'cygwin' in platname
+
def run_with_mono(fname):
- if fname.endswith('.exe') and not is_windows():
+ if fname.endswith('.exe') and not (is_windows() or is_cygwin()):
return True
return False
diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py
index 8fb9e04..2205f1a 100644
--- a/mesonbuild/scripts/meson_install.py
+++ b/mesonbuild/scripts/meson_install.py
@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import sys, pickle, os, shutil, subprocess, gzip, platform
+import sys, pickle, os, shutil, subprocess, gzip, platform, errno
from glob import glob
from . import depfixer
from . import destdir_join
@@ -34,6 +34,15 @@ def set_mode(path, mode):
except PermissionError as e:
msg = '{!r}: Unable to set owner {!r} and group {!r}: {}, ignoring...'
print(msg.format(path, mode.owner, mode.group, e.strerror))
+ except LookupError as e:
+ msg = '{!r}: Non-existent owner {!r} or group {!r}: ignoring...'
+ print(msg.format(path, mode.owner, mode.group))
+ except OSError as e:
+ if e.errno == errno.EINVAL:
+ msg = '{!r}: Non-existent numeric owner {!r} or group {!r}: ignoring...'
+ print(msg.format(path, mode.owner, mode.group))
+ else:
+ raise
# Must set permissions *after* setting owner/group otherwise the
# setuid/setgid bits will get wiped by chmod
# NOTE: On Windows you can set read/write perms; the rest are ignored
@@ -174,7 +183,7 @@ def run_install_script(d):
'MESON_BUILD_ROOT': d.build_dir,
'MESON_INSTALL_PREFIX': d.prefix,
'MESON_INSTALL_DESTDIR_PREFIX': d.fullprefix,
- }
+ 'MESONINTROSPECT': d.mesonintrospect}
child_env = os.environ.copy()
child_env.update(env)
@@ -193,7 +202,7 @@ def run_install_script(d):
def is_elf_platform():
platname = platform.system().lower()
- if platname == 'darwin' or platname == 'windows':
+ if platname == 'darwin' or platname == 'windows' or platname == 'cygwin':
return False
return True
diff --git a/mesontest.py b/mesontest.py
index a1708e3..c4d1178 100755
--- a/mesontest.py
+++ b/mesontest.py
@@ -36,6 +36,10 @@ def is_windows():
platname = platform.system().lower()
return platname == 'windows' or 'mingw' in platname
+def is_cygwin():
+ platname = platform.system().lower()
+ return 'cygwin' in platname
+
def determine_worker_count():
varname = 'MESON_TESTTHREADS'
if varname in os.environ:
@@ -150,7 +154,7 @@ def write_json_log(jsonlogfile, test_name, result):
jsonlogfile.write(json.dumps(jresult) + '\n')
def run_with_mono(fname):
- if fname.endswith('.exe') and not is_windows():
+ if fname.endswith('.exe') and not (is_windows() or is_cygwin()):
return True
return False
@@ -202,7 +206,7 @@ class TestHarness:
child_env.update(test.env)
if len(test.extra_paths) > 0:
- child_env['PATH'] += ';'.join([''] + test.extra_paths)
+ child_env['PATH'] += os.pathsep.join([''] + test.extra_paths)
# If MALLOC_PERTURB_ is not set, or if it is set to an empty value,
# (i.e., the test or the environment don't explicitly set it), set
diff --git a/run_project_tests.py b/run_project_tests.py
index 28de638..dc05524 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -31,6 +31,7 @@ import xml.etree.ElementTree as ET
import time
import multiprocessing
import concurrent.futures as conc
+import re
from mesonbuild.coredata import backendlist
@@ -208,12 +209,18 @@ def get_relative_files_list_from_dir(fromdir):
paths.append(path)
return paths
-def platform_fix_exe_name(fname):
- if not fname.endswith('?exe'):
- return fname
- fname = fname[:-4]
- if mesonlib.is_windows():
- return fname + '.exe'
+def platform_fix_name(fname):
+ if '?lib' in fname:
+ if mesonlib.is_cygwin():
+ fname = re.sub(r'\?lib(.*)\.dll$', r'cyg\1.dll', fname)
+ else:
+ fname = re.sub(r'\?lib', 'lib', fname)
+
+ if fname.endswith('?exe'):
+ fname = fname[:-4]
+ if mesonlib.is_windows() or mesonlib.is_cygwin():
+ return fname + '.exe'
+
return fname
def validate_install(srcdir, installdir):
@@ -230,13 +237,16 @@ def validate_install(srcdir, installdir):
elif os.path.exists(info_file):
with open(info_file) as f:
for line in f:
- expected[platform_fix_exe_name(line.strip())] = False
+ expected[platform_fix_name(line.strip())] = False
# Check if expected files were found
for fname in expected:
if os.path.exists(os.path.join(installdir, fname)):
expected[fname] = True
for (fname, found) in expected.items():
if not found:
+ # Ignore missing PDB files if we aren't using cl
+ if fname.endswith('.pdb') and compiler != 'cl':
+ continue
ret_msg += 'Expected file {0} missing.\n'.format(fname)
# Check if there are any unexpected files
found = get_relative_files_list_from_dir(installdir)
@@ -437,9 +447,9 @@ def detect_tests_to_run():
all_tests.append(('prebuilt', gather_tests('test cases/prebuilt'), False))
all_tests.append(('platform-osx', gather_tests('test cases/osx'), False if mesonlib.is_osx() else True))
- all_tests.append(('platform-windows', gather_tests('test cases/windows'), False if mesonlib.is_windows() else True))
+ all_tests.append(('platform-windows', gather_tests('test cases/windows'), False if mesonlib.is_windows() or mesonlib.is_cygwin() else True))
all_tests.append(('platform-linux', gather_tests('test cases/linuxlike'), False if not (mesonlib.is_osx() or mesonlib.is_windows()) else True))
- all_tests.append(('framework', gather_tests('test cases/frameworks'), False if not mesonlib.is_osx() and not mesonlib.is_windows() else True))
+ all_tests.append(('framework', gather_tests('test cases/frameworks'), False if not mesonlib.is_osx() and not mesonlib.is_windows() and not mesonlib.is_cygwin() else True))
all_tests.append(('java', gather_tests('test cases/java'), False if using_backend('ninja') and not mesonlib.is_osx() and have_java() else True))
all_tests.append(('C#', gather_tests('test cases/csharp'), False if using_backend('ninja') and shutil.which('mcs') else True))
all_tests.append(('vala', gather_tests('test cases/vala'), False if using_backend('ninja') and shutil.which('valac') else True))
diff --git a/run_unittests.py b/run_unittests.py
index 0656f88..1b24d08 100755
--- a/run_unittests.py
+++ b/run_unittests.py
@@ -24,11 +24,11 @@ from pathlib import PurePath
import mesonbuild.compilers
import mesonbuild.environment
import mesonbuild.mesonlib
-from mesonbuild.mesonlib import is_windows, is_osx
+from mesonbuild.mesonlib import is_windows, is_osx, is_cygwin
from mesonbuild.environment import detect_ninja, Environment
from mesonbuild.dependencies import PkgConfigDependency, ExternalProgram
-if is_windows():
+if is_windows() or is_cygwin():
exe_suffix = '.exe'
else:
exe_suffix = ''
@@ -833,6 +833,8 @@ class AllPlatformTests(BasePlatformTests):
self.assertEqual(cc.gcc_type, mesonbuild.compilers.GCC_OSX)
elif is_windows():
self.assertEqual(cc.gcc_type, mesonbuild.compilers.GCC_MINGW)
+ elif is_cygwin():
+ self.assertEqual(cc.gcc_type, mesonbuild.compilers.GCC_CYGWIN)
else:
self.assertEqual(cc.gcc_type, mesonbuild.compilers.GCC_STANDARD)
if isinstance(cc, clang):
@@ -947,6 +949,21 @@ class AllPlatformTests(BasePlatformTests):
m = re.search('build c-asm.*: c_LINKER', contents)
self.assertIsNotNone(m, msg=contents)
+ def test_preprocessor_checks_CPPFLAGS(self):
+ '''
+ Test that preprocessor compiler checks read CPPFLAGS but not CFLAGS
+ '''
+ testdir = os.path.join(self.common_test_dir, '140 get define')
+ define = 'MESON_TEST_DEFINE_VALUE'
+ # NOTE: this list can't have \n, ' or "
+ # \n is never substituted by the GNU pre-processor via a -D define
+ # ' and " confuse shlex.split() even when they are escaped
+ # % and # confuse the MSVC preprocessor
+ value = 'spaces and fun!@$^&*()-=_+{}[]:;<>?,./~`'
+ os.environ['CPPFLAGS'] = '-D{}="{}"'.format(define, value)
+ os.environ['CFLAGS'] = '-DMESON_FAIL_VALUE=cflags-read'.format(define)
+ self.init(testdir, ['-D{}={}'.format(define, value)])
+
class WindowsTests(BasePlatformTests):
'''
diff --git a/test cases/common/123 subproject project arguments/exe.c b/test cases/common/123 subproject project arguments/exe.c
index b04344a..d6440f0 100644
--- a/test cases/common/123 subproject project arguments/exe.c
+++ b/test cases/common/123 subproject project arguments/exe.c
@@ -18,6 +18,10 @@
#error
#endif
+#ifndef PROJECT_OPTION_C_CPP
+#error
+#endif
+
int main(int argc, char **argv) {
return 0;
}
diff --git a/test cases/common/123 subproject project arguments/exe.cpp b/test cases/common/123 subproject project arguments/exe.cpp
index 7ffe098..8471c6f 100644
--- a/test cases/common/123 subproject project arguments/exe.cpp
+++ b/test cases/common/123 subproject project arguments/exe.cpp
@@ -18,6 +18,10 @@
#error
#endif
+#ifndef PROJECT_OPTION_C_CPP
+#error
+#endif
+
int main(int argc, char **argv) {
return 0;
}
diff --git a/test cases/common/123 subproject project arguments/meson.build b/test cases/common/123 subproject project arguments/meson.build
index aee803c..90d4c05 100644
--- a/test cases/common/123 subproject project arguments/meson.build
+++ b/test cases/common/123 subproject project arguments/meson.build
@@ -4,10 +4,13 @@ project('project options tester', 'c', 'cpp',
add_global_arguments('-DGLOBAL_ARGUMENT', language: 'c')
add_project_arguments('-DPROJECT_OPTION', language: 'c')
-add_project_arguments('-DPROJECT_OPTION_1', language: 'c')
add_project_arguments('-DPROJECT_OPTION_CPP', language: 'cpp')
+add_project_arguments('-DPROJECT_OPTION_C_CPP', language: ['c', 'cpp'])
sub = subproject('subexe', version : '1.0.0')
+
+add_project_arguments('-DPROJECT_OPTION_1', language: 'c')
+
e = executable('exe', 'exe.c')
e = executable('execpp', 'exe.cpp')
test('exetest', e)
diff --git a/test cases/common/123 subproject project arguments/subprojects/subexe/subexe.c b/test cases/common/123 subproject project arguments/subprojects/subexe/subexe.c
index 6ebd752..f748afc 100644
--- a/test cases/common/123 subproject project arguments/subprojects/subexe/subexe.c
+++ b/test cases/common/123 subproject project arguments/subprojects/subexe/subexe.c
@@ -6,6 +6,10 @@
#error
#endif
+#ifdef PROJECT_OPTION_C_CPP
+#error
+#endif
+
#ifndef GLOBAL_ARGUMENT
#error
#endif
diff --git a/test cases/common/125 shared module/meson.build b/test cases/common/125 shared module/meson.build
index 7c15bcc..d96d8fc 100644
--- a/test cases/common/125 shared module/meson.build
+++ b/test cases/common/125 shared module/meson.build
@@ -5,7 +5,8 @@ l = shared_library('runtime', 'runtime.c')
# Do NOT link the module with the runtime library. This
# is a common approach for plugins that are only used
# with dlopen. Any symbols are resolved dynamically
-# at runtime
+# at runtime. This requires extra help on Windows, so
+# should be avoided unless really neccessary.
m = shared_module('mymodule', 'module.c')
e = executable('prog', 'prog.c', link_with : l, dependencies : dl)
test('import test', e, args : m)
diff --git a/test cases/common/125 shared module/module.c b/test cases/common/125 shared module/module.c
index 56078c5..181b760 100644
--- a/test cases/common/125 shared module/module.c
+++ b/test cases/common/125 shared module/module.c
@@ -9,14 +9,24 @@
#endif
#endif
-#ifdef _WIN32
+#if defined(_WIN32) || defined(__CYGWIN__)
#include <stdio.h>
-#include <windows.h>
-#include <tlhelp32.h>
typedef int (*fptr) (void);
+#ifdef __CYGWIN__
+
+#include <dlfcn.h>
+
+fptr find_any_f (const char *name) {
+ return (fptr) dlsym(RTLD_DEFAULT, name);
+}
+#else /* _WIN32 */
+
+#include <windows.h>
+#include <tlhelp32.h>
+
/* Unlike Linux and OS X, when a library is loaded, all the symbols aren't
* loaded into a single namespace. You must fetch the symbol by iterating over
* all loaded modules. Code for finding the function from any of the loaded
@@ -45,6 +55,7 @@ fptr find_any_f (const char *name) {
CloseHandle (snapshot);
return f;
}
+#endif
int DLL_PUBLIC func() {
fptr f;
diff --git a/test cases/common/126 llvm ir and assembly/square-x86_64.S b/test cases/common/126 llvm ir and assembly/square-x86_64.S
index 4adc31e..1452f47 100644
--- a/test cases/common/126 llvm ir and assembly/square-x86_64.S
+++ b/test cases/common/126 llvm ir and assembly/square-x86_64.S
@@ -19,12 +19,12 @@ END
.text
.globl SYMBOL_NAME(square_unsigned)
-# ifdef _WIN32 /* MinGW */
+# if defined(_WIN32) || defined(__CYGWIN__) /* msabi */
SYMBOL_NAME(square_unsigned):
imull %ecx, %ecx
movl %ecx, %eax
retq
-# else /* Linux and OS X */
+# else /* sysvabi */
SYMBOL_NAME(square_unsigned):
imull %edi, %edi
movl %edi, %eax
diff --git a/test cases/common/135 generated assembly/main.c b/test cases/common/135 generated assembly/main.c
index 97fe723..b669cba 100644
--- a/test cases/common/135 generated assembly/main.c
+++ b/test cases/common/135 generated assembly/main.c
@@ -1,5 +1,8 @@
#include <stdio.h>
+#if defined(_WIN32) || defined(__CYGWIN__)
+ __declspec(dllimport)
+#endif
unsigned square_unsigned (unsigned a);
int
diff --git a/test cases/common/135 generated assembly/square-x86_64.S.in b/test cases/common/135 generated assembly/square-x86_64.S.in
index b6d7fb0..0834f16 100644
--- a/test cases/common/135 generated assembly/square-x86_64.S.in
+++ b/test cases/common/135 generated assembly/square-x86_64.S.in
@@ -23,12 +23,12 @@ END
.type square_unsigned,@function
# endif
-# ifdef _WIN32 /* MinGW */
+# if defined(_WIN32) || defined(__CYGWIN__) /* msabi */
SYMBOL_NAME(square_unsigned):
imull %ecx, %ecx
movl %ecx, %eax
retq
-# else /* Linux and OS X */
+# else /* sysvabi */
SYMBOL_NAME(square_unsigned):
imull %edi, %edi
movl %edi, %eax
diff --git a/test cases/common/140 get define/meson.build b/test cases/common/140 get define/meson.build
new file mode 100644
index 0000000..5ce4b36
--- /dev/null
+++ b/test cases/common/140 get define/meson.build
@@ -0,0 +1,31 @@
+project('get define', 'c', 'cpp')
+
+host_system = host_machine.system()
+
+foreach lang : ['c', 'cpp']
+ cc = meson.get_compiler(lang)
+ if host_system == 'linux'
+ d = cc.get_define('__linux__')
+ assert(d == '1', '__linux__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'darwin'
+ d = cc.get_define('__APPLE__')
+ assert(d == '1', '__APPLE__ value is @0@ instead of 1'.format(d))
+ elif host_system == 'windows'
+ d = cc.get_define('_WIN32')
+ assert(d == '1', '_WIN32 value is @0@ instead of 1'.format(d))
+ elif host_system == 'cygwin'
+ d = cc.get_define('__CYGWIN__')
+ assert(d == '1', '__CYGWIN__ value is @0@ instead of 1'.format(d))
+ else
+ error('Please report a bug and help us improve support for this platform')
+ endif
+
+ # Check that an undefined value is empty.
+ have = cc.get_define('MESON_FAIL_VALUE')
+ assert(have == '', 'MESON_FAIL_VALUE value is "@0@" instead of ""'.format(have))
+
+ # This is used in the test_preprocessor_checks_CPPFLAGS() unit test.
+ have = cc.get_define('MESON_TEST_DEFINE_VALUE')
+ expect = get_option('MESON_TEST_DEFINE_VALUE')
+ assert(have == expect, 'MESON_TEST_DEFINE_VALUE value is "@0@" instead of "@1@"'.format(have, expect))
+endforeach
diff --git a/test cases/common/140 get define/meson_options.txt b/test cases/common/140 get define/meson_options.txt
new file mode 100644
index 0000000..a88cecd
--- /dev/null
+++ b/test cases/common/140 get define/meson_options.txt
@@ -0,0 +1 @@
+option('MESON_TEST_DEFINE_VALUE', type : 'string', default : '')
diff --git a/test cases/common/141 mesonintrospect from scripts/check_env.py b/test cases/common/141 mesonintrospect from scripts/check_env.py
new file mode 100644
index 0000000..dc8ad63
--- /dev/null
+++ b/test cases/common/141 mesonintrospect from scripts/check_env.py
@@ -0,0 +1,20 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+
+do_print = False
+
+if len(sys.argv) > 1:
+ do_print = bool(sys.argv[1])
+
+if 'MESONINTROSPECT' not in os.environ:
+ raise RuntimeError('MESONINTROSPECT not found')
+
+mesonintrospect = os.environ['MESONINTROSPECT']
+
+if not os.path.isfile(mesonintrospect):
+ raise RuntimeError('{!r} does not exist'.format(mesonintrospect))
+
+if do_print:
+ print(mesonintrospect, end='')
diff --git a/test cases/common/141 mesonintrospect from scripts/meson.build b/test cases/common/141 mesonintrospect from scripts/meson.build
new file mode 100644
index 0000000..f78710b
--- /dev/null
+++ b/test cases/common/141 mesonintrospect from scripts/meson.build
@@ -0,0 +1,14 @@
+project('mesonintrospect from scripts', 'c')
+
+python = import('python3').find_python()
+
+ret = run_command(python, ['check_env.py', '1'])
+if ret.returncode() == 0
+ find_program(ret.stdout())
+else
+ message(ret.stdout())
+ message(ret.stderr())
+endif
+
+meson.add_postconf_script('check_env.py')
+meson.add_install_script('check_env.py')
diff --git a/test cases/common/139 compute int/config.h.in b/test cases/common/142 compute int/config.h.in
index ad8d077..ad8d077 100644
--- a/test cases/common/139 compute int/config.h.in
+++ b/test cases/common/142 compute int/config.h.in
diff --git a/test cases/common/139 compute int/foobar.h b/test cases/common/142 compute int/foobar.h
index fd3cb5e..fd3cb5e 100644
--- a/test cases/common/139 compute int/foobar.h
+++ b/test cases/common/142 compute int/foobar.h
diff --git a/test cases/common/139 compute int/meson.build b/test cases/common/142 compute int/meson.build
index 43553fe..43553fe 100644
--- a/test cases/common/139 compute int/meson.build
+++ b/test cases/common/142 compute int/meson.build
diff --git a/test cases/common/139 compute int/prog.c.in b/test cases/common/142 compute int/prog.c.in
index 3ff1463..3ff1463 100644
--- a/test cases/common/139 compute int/prog.c.in
+++ b/test cases/common/142 compute int/prog.c.in
diff --git a/test cases/common/139 custom target object output/meson.build b/test cases/common/143 custom target object output/meson.build
index ede165b..ede165b 100644
--- a/test cases/common/139 custom target object output/meson.build
+++ b/test cases/common/143 custom target object output/meson.build
diff --git a/test cases/common/139 custom target object output/obj_generator.py b/test cases/common/143 custom target object output/obj_generator.py
index a33872a..a33872a 100644
--- a/test cases/common/139 custom target object output/obj_generator.py
+++ b/test cases/common/143 custom target object output/obj_generator.py
diff --git a/test cases/common/139 custom target object output/objdir/meson.build b/test cases/common/143 custom target object output/objdir/meson.build
index 0d7f6c2..0d7f6c2 100644
--- a/test cases/common/139 custom target object output/objdir/meson.build
+++ b/test cases/common/143 custom target object output/objdir/meson.build
diff --git a/test cases/common/139 custom target object output/objdir/source.c b/test cases/common/143 custom target object output/objdir/source.c
index 7779b33..7779b33 100644
--- a/test cases/common/139 custom target object output/objdir/source.c
+++ b/test cases/common/143 custom target object output/objdir/source.c
diff --git a/test cases/common/139 custom target object output/progdir/meson.build b/test cases/common/143 custom target object output/progdir/meson.build
index 4216c24..4216c24 100644
--- a/test cases/common/139 custom target object output/progdir/meson.build
+++ b/test cases/common/143 custom target object output/progdir/meson.build
diff --git a/test cases/common/139 custom target object output/progdir/prog.c b/test cases/common/143 custom target object output/progdir/prog.c
index c1ece33..c1ece33 100644
--- a/test cases/common/139 custom target object output/progdir/prog.c
+++ b/test cases/common/143 custom target object output/progdir/prog.c
diff --git a/test cases/common/144 empty build file/meson.build b/test cases/common/144 empty build file/meson.build
new file mode 100644
index 0000000..73d0397
--- /dev/null
+++ b/test cases/common/144 empty build file/meson.build
@@ -0,0 +1,2 @@
+project('subdir with empty meson.build test', 'c')
+subdir('subdir')
diff --git a/test cases/common/144 empty build file/subdir/meson.build b/test cases/common/144 empty build file/subdir/meson.build
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test cases/common/144 empty build file/subdir/meson.build
diff --git a/test cases/common/16 configure file/meson.build b/test cases/common/16 configure file/meson.build
index 8271ca3..8ffc28c 100644
--- a/test cases/common/16 configure file/meson.build
+++ b/test cases/common/16 configure file/meson.build
@@ -22,6 +22,11 @@ e = executable('inctest', 'prog.c',
cfile)
test('inctest', e)
+# Test if we can also pass files() as input
+configure_file(input : files('config.h.in'),
+ output : 'config2.h',
+ configuration : conf)
+
# Now generate a header file with an external script.
genprog = import('python3').find_python()
scriptfile = '@0@/generator.py'.format(meson.current_source_dir())
diff --git a/test cases/common/23 global arg/meson.build b/test cases/common/23 global arg/meson.build
index aec5c2d..d7fd428 100644
--- a/test cases/common/23 global arg/meson.build
+++ b/test cases/common/23 global arg/meson.build
@@ -3,6 +3,8 @@ project('global arg test', 'cpp', 'c')
add_global_arguments('-DMYTHING', language : 'c')
add_global_arguments('-DMYCPPTHING', language : 'cpp')
+add_global_arguments('-DMYCANDCPPTHING', language: ['c', 'cpp'])
+
exe1 = executable('prog', 'prog.c')
exe2 = executable('prog2', 'prog.cc')
diff --git a/test cases/common/23 global arg/prog.c b/test cases/common/23 global arg/prog.c
index df91777..ace5a0a 100644
--- a/test cases/common/23 global arg/prog.c
+++ b/test cases/common/23 global arg/prog.c
@@ -6,6 +6,10 @@
#error "Wrong global argument set"
#endif
+#ifndef MYCANDCPPTHING
+#error "Global argument not set"
+#endif
+
int main(int argc, char **argv) {
return 0;
}
diff --git a/test cases/common/23 global arg/prog.cc b/test cases/common/23 global arg/prog.cc
index 342fdd0..0ffd85e 100644
--- a/test cases/common/23 global arg/prog.cc
+++ b/test cases/common/23 global arg/prog.cc
@@ -6,6 +6,10 @@
#error "Global argument not set"
#endif
+#ifndef MYCANDCPPTHING
+#error "Global argument not set"
+#endif
+
int main(int argc, char **argv) {
return 0;
}
diff --git a/test cases/common/37 has header/meson.build b/test cases/common/37 has header/meson.build
index 4299ce5..b53849c 100644
--- a/test cases/common/37 has header/meson.build
+++ b/test cases/common/37 has header/meson.build
@@ -11,19 +11,19 @@ configure_file(input : non_existant_header,
# Test that the fallback to __has_include also works on all compilers
if host_system != 'darwin'
- args = [[], ['-U__has_include']]
+ fallbacks = ['', '\n#undef __has_include']
else
# On Darwin's clang you can't redefine builtin macros so the above doesn't work
- args = [[]]
+ fallbacks = ['']
endif
-foreach arg : args
+foreach fallback : fallbacks
foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
- assert(comp.has_header('stdio.h', args : arg), 'Stdio missing.')
+ assert(comp.has_header('stdio.h', prefix : fallback), 'Stdio missing.')
# stdio.h doesn't actually need stdlib.h, but just test that setting the
# prefix does not result in an error.
- assert(comp.has_header('stdio.h', prefix : '#include <stdlib.h>', args : arg),
+ assert(comp.has_header('stdio.h', prefix : '#include <stdlib.h>' + fallback),
'Stdio missing.')
# XInput.h should not require type definitions from windows.h, but it does
@@ -32,9 +32,9 @@ foreach arg : args
# We only do this check on MSVC because MinGW often defines its own wrappers
# that pre-include windows.h
if comp.get_id() == 'msvc'
- assert(comp.has_header('XInput.h', prefix : '#include <windows.h>', args : arg),
+ assert(comp.has_header('XInput.h', prefix : '#include <windows.h>' + fallback),
'XInput.h should not be missing on Windows')
- assert(comp.has_header('XInput.h', prefix : '#define _X86_', args : arg),
+ assert(comp.has_header('XInput.h', prefix : '#define _X86_' + fallback),
'XInput.h should not need windows.h')
endif
@@ -42,13 +42,13 @@ foreach arg : args
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80005
# https://github.com/mesonbuild/meson/issues/1458
if host_system == 'linux'
- assert(comp.has_header('linux/if.h', args : arg),
+ assert(comp.has_header('linux/if.h', prefix : fallback),
'Could not find <linux/if.h>')
endif
# This header exists in the source and the builddir, but we still must not
# find it since we are looking in the system directories.
- assert(not comp.has_header(non_existant_header, args : arg),
+ assert(not comp.has_header(non_existant_header, prefix : fallback),
'Found non-existant header.')
endforeach
endforeach
diff --git a/test cases/failing/14 invalid option name/meson_options.txt b/test cases/failing/14 invalid option name/meson_options.txt
index c656402..aab6ae8 100644
--- a/test cases/failing/14 invalid option name/meson_options.txt
+++ b/test cases/failing/14 invalid option name/meson_options.txt
@@ -1 +1 @@
-option('invalid/name', type : 'boolean', value : false) \ No newline at end of file
+option('invalid:name', type : 'boolean', value : false)
diff --git a/test cases/failing/19 target clash/meson.build b/test cases/failing/19 target clash/meson.build
index 070631b..fbc757c 100644
--- a/test cases/failing/19 target clash/meson.build
+++ b/test cases/failing/19 target clash/meson.build
@@ -7,7 +7,7 @@ project('clash', 'c')
# This test might fail to work on different backends or when
# output location is redirected.
-if host_machine.system() == 'windows'
+if host_machine.system() == 'windows' or host_machine.system() == 'cygwin'
error('This is expected.')
endif
diff --git a/test cases/failing/43 project name colon/meson.build b/test cases/failing/43 project name colon/meson.build
new file mode 100644
index 0000000..53e947e
--- /dev/null
+++ b/test cases/failing/43 project name colon/meson.build
@@ -0,0 +1 @@
+project('name with :')
diff --git a/test cases/linuxlike/10 large file support/meson.build b/test cases/linuxlike/10 large file support/meson.build
index aa4eccf..6683345 100644
--- a/test cases/linuxlike/10 large file support/meson.build
+++ b/test cases/linuxlike/10 large file support/meson.build
@@ -1,5 +1,9 @@
project('trivial test', 'c')
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST _FILE_OFFSET_BITS not yet supported on Cygwin.')
+endif
+
cc = meson.get_compiler('c')
size = cc.sizeof('off_t')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c
new file mode 100644
index 0000000..2784e01
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib.c
@@ -0,0 +1,3 @@
+int some_symbol (void) {
+ return RET_VALUE;
+}
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build
new file mode 100644
index 0000000..cbc75bd
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib1/meson.build
@@ -0,0 +1,2 @@
+lib1 = shared_library('testeh', libsrc,
+ c_args : '-DRET_VALUE=1')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build
new file mode 100644
index 0000000..f2c6dcc
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/lib2/meson.build
@@ -0,0 +1,3 @@
+lib2 = shared_library('esteh', libsrc,
+ name_prefix : 'libt',
+ c_args : '-DRET_VALUE=2')
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c b/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c
new file mode 100644
index 0000000..c9eff99
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/main.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+int some_symbol (void);
+
+int main (int argc, char *argv[]) {
+ int ret = some_symbol ();
+ if (ret == 1)
+ return 0;
+ fprintf (stderr, "ret was %i instead of 1\n", ret);
+ return -1;
+}
diff --git a/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build b/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build
new file mode 100644
index 0000000..b49da66
--- /dev/null
+++ b/test cases/linuxlike/11 runpath rpath ldlibrarypath/meson.build
@@ -0,0 +1,14 @@
+project('runpath rpath ldlibrarypath', 'c')
+
+libsrc = files('lib.c')
+
+subdir('lib1')
+subdir('lib2')
+
+lib2dir = meson.current_build_dir() + '/lib2'
+
+e = executable('testexe', 'main.c',
+ link_with : lib1)
+
+test('ld-library-path-test', e,
+ env : ['LD_LIBRARY_PATH=' + lib2dir])
diff --git a/test cases/linuxlike/7 library versions/meson.build b/test cases/linuxlike/7 library versions/meson.build
index f162210..d156eb0 100644
--- a/test cases/linuxlike/7 library versions/meson.build
+++ b/test cases/linuxlike/7 library versions/meson.build
@@ -1,5 +1,9 @@
project('library versions', 'c')
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST linuxlike soversions not supported on Cygwin.')
+endif
+
some = shared_library('some', 'lib.c',
version : '1.2.3',
soversion : '0',
diff --git a/test cases/linuxlike/8 subproject library install/meson.build b/test cases/linuxlike/8 subproject library install/meson.build
index 63e57cf..ff55799 100644
--- a/test cases/linuxlike/8 subproject library install/meson.build
+++ b/test cases/linuxlike/8 subproject library install/meson.build
@@ -2,5 +2,9 @@ project('subproj lib install', 'c',
version : '2.3.4',
license : 'mylicense')
+if host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST linuxlike soversions not supported on Cygwin.')
+endif
+
# Test that the subproject library gets installed
subproject('sublib', version : '1.0.0')
diff --git a/test cases/objc/2 nsstring/meson.build b/test cases/objc/2 nsstring/meson.build
index ec496a2..a877d74 100644
--- a/test cases/objc/2 nsstring/meson.build
+++ b/test cases/objc/2 nsstring/meson.build
@@ -2,6 +2,8 @@ project('nsstring', 'objc')
if host_machine.system() == 'darwin'
dep = dependency('appleframeworks', modules : 'foundation')
+elif host_machine.system() == 'cygwin'
+ error('MESON_SKIP_TEST GNUstep is not packaged for Cygwin.')
else
dep = dependency('gnustep')
if host_machine.system() == 'linux' and meson.get_compiler('objc').get_id() == 'clang'
diff --git a/test cases/windows/5 resources/meson.build b/test cases/windows/5 resources/meson.build
index e92a43c..ddb7d6e 100644
--- a/test cases/windows/5 resources/meson.build
+++ b/test cases/windows/5 resources/meson.build
@@ -3,7 +3,7 @@ project('winmain', 'c')
# MinGW windres has a bug due to which it doesn't parse args with space properly:
# https://github.com/mesonbuild/meson/pull/1346
# https://sourceware.org/bugzilla/show_bug.cgi?id=4933
-if meson.get_compiler('c').get_id() == 'gcc'
+if meson.get_compiler('c').get_id() == 'gcc' and host_machine.system() == 'windows'
# Construct build_to_src and skip this test if it has spaces
# because then the -I flag to windres will also have spaces
# and we know the test will fail
diff --git a/test cases/windows/7 mingw dll versioning/installed_files.txt b/test cases/windows/7 mingw dll versioning/installed_files.txt
index 56187a6..9acd7db 100644
--- a/test cases/windows/7 mingw dll versioning/installed_files.txt
+++ b/test cases/windows/7 mingw dll versioning/installed_files.txt
@@ -1,10 +1,10 @@
-usr/bin/libsome-0.dll
+usr/bin/?libsome-0.dll
usr/lib/libsome.dll.a
-usr/bin/libnoversion.dll
+usr/bin/?libnoversion.dll
usr/lib/libnoversion.dll.a
-usr/bin/libonlyversion-1.dll
+usr/bin/?libonlyversion-1.dll
usr/lib/libonlyversion.dll.a
-usr/bin/libonlysoversion-5.dll
+usr/bin/?libonlysoversion-5.dll
usr/lib/libonlysoversion.dll.a
usr/libexec/libcustomdir.dll
usr/libexec/libcustomdir.dll.a