aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.appveyor.yml43
-rw-r--r--.travis.yml8
-rw-r--r--mesonbuild/backend/backends.py70
-rw-r--r--mesonbuild/backend/ninjabackend.py17
-rw-r--r--mesonbuild/backend/vs2010backend.py160
-rw-r--r--mesonbuild/build.py10
-rw-r--r--mesonbuild/compilers.py93
-rw-r--r--mesonbuild/mesonmain.py8
-rw-r--r--mesonbuild/mlog.py6
-rw-r--r--mesonbuild/modules/gnome.py71
-rw-r--r--mesonbuild/modules/pkgconfig.py4
-rw-r--r--mesonbuild/modules/qt4.py6
-rw-r--r--mesonbuild/modules/qt5.py6
-rw-r--r--mesonbuild/modules/rpm.py15
-rwxr-xr-xmesonbuild/scripts/regen_checker.py2
-rw-r--r--mesonbuild/scripts/scanbuild.py13
-rw-r--r--mesonbuild/scripts/yelphelper.py2
-rwxr-xr-xrun_project_tests.py57
-rwxr-xr-xtest cases/common/103 manygen/subdir/manygen.py3
-rw-r--r--test cases/common/103 manygen/subdir/meson.build13
-rw-r--r--test cases/common/111 has header symbol/meson.build32
-rw-r--r--test cases/common/113 generatorcustom/meson.build26
-rw-r--r--test cases/common/121 skip/meson.build4
-rw-r--r--test cases/common/16 configure file/config.h1
-rw-r--r--test cases/common/16 configure file/prog.c5
-rw-r--r--test cases/common/16 configure file/prog2.c2
-rw-r--r--test cases/common/33 try compile/meson.build29
-rw-r--r--test cases/common/35 sizeof/meson.build24
-rw-r--r--test cases/common/35 sizeof/prog.c.in (renamed from test cases/common/35 sizeof/prog.c)6
-rw-r--r--test cases/common/37 has header/meson.build18
-rw-r--r--test cases/common/39 tryrun/meson.build80
-rw-r--r--test cases/common/43 has function/meson.build72
-rw-r--r--test cases/common/44 has member/meson.build30
-rw-r--r--test cases/common/45 alignment/meson.build48
-rw-r--r--test cases/common/51 pkgconfig-gen/meson.build2
-rw-r--r--test cases/common/56 custom target/meson.build2
-rwxr-xr-xtest cases/common/56 custom target/my_compiler.py9
-rw-r--r--test cases/common/62 exe static shared/stat.c4
-rw-r--r--test cases/common/83 has type/meson.build18
-rw-r--r--test cases/frameworks/10 gtk-doc/meson.build4
-rw-r--r--test cases/python3/3 cython/meson.build2
41 files changed, 653 insertions, 372 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 38ebe56..adc13b8 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -2,23 +2,56 @@ version: 1.0.{build}
os: Visual Studio 2015
+environment:
+ matrix:
+ - arch: x86
+ compiler: msvc2010
+ backend: ninja
+
+ - arch: x86
+ compiler: msvc2010
+ backend: vs2010
+
+ - arch: x86
+ compiler: msvc2015
+ backend: ninja
+
+ - arch: x86
+ compiler: msvc2015
+ backend: vs2015
+
+ - arch: x64
+ compiler: msvc2015
+ backend: ninja
+
+ - arch: x64
+ compiler: msvc2015
+ backend: vs2015
+
platform:
- - x86
+ - x64
branches:
only:
- master
install:
- - ps: (new-object net.webclient).DownloadFile('https://dl.dropboxusercontent.com/u/37517477/ninja.exe', 'c:\python34\ninja.exe')
- - cmd: copy c:\python34\python.exe c:\python34\python3.exe
- - '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86'
+ # Use the x86 python only when building for x86 for the cpython tests.
+ # For all other archs (including, say, arm), use the x64 python.
+ - ps: (new-object net.webclient).DownloadFile('https://dl.dropboxusercontent.com/u/37517477/ninja.exe', 'C:\projects\meson\ninja.exe')
+ - cmd: if %arch%==x86 (set MESON_PYTHON_PATH=C:\python34) else (set MESON_PYTHON_PATH=C:\python34-x64)
+ - cmd: echo Using Python at %MESON_PYTHON_PATH%
+ - cmd: copy %MESON_PYTHON_PATH%\python.exe %MESON_PYTHON_PATH%\python3.exe
+ - cmd: if %compiler%==msvc2010 ( call "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" %arch% )
+ - cmd: if %compiler%==msvc2015 ( call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %arch% )
build_script:
- cmd: echo No build step.
+ - cmd: if %backend%==ninja ( ninja.exe --version ) else ( MSBuild /version & echo. )
test_script:
- - cmd: PATH c:\python34;%PATH%; && python3 run_tests.py --backend=ninja
+ - cmd: echo Running tests for %arch% and %compiler% with the %backend% backend
+ - cmd: PATH=%cd%;%MESON_PYTHON_PATH%;%PATH%; && python3 run_tests.py --backend=%backend%
on_finish:
- appveyor PushArtifact meson-test-run.txt -DeploymentName "Text test logs"
diff --git a/.travis.yml b/.travis.yml
index bc52ffa..8648572 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -18,6 +18,12 @@ language:
services:
- docker
+matrix:
+ exclude:
+ # On OS X gcc is just a wrapper around clang, so don't waste time testing that
+ - os: osx
+ compiler: gcc
+
before_install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja python3; fi
@@ -30,5 +36,5 @@ script:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:yakkety > Dockerfile; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi
- - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true ./run_tests.py -- $MESON_ARGS"; fi
+ - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true CC=$CC CXX=$CXX ./run_tests.py -- $MESON_ARGS"; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) ./run_tests.py --backend=ninja -- $MESON_ARGS ; fi
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py
index a4f2b51..2861bb6 100644
--- a/mesonbuild/backend/backends.py
+++ b/mesonbuild/backend/backends.py
@@ -81,8 +81,8 @@ class Backend():
def get_target_filename(self, t):
if isinstance(t, build.CustomTarget):
if len(t.get_outputs()) != 1:
- mlog.log(mlog.red('WARNING'), 'custom_target {!r} has more ' \
- 'than one output! Using the first one.'.format(t.name))
+ mlog.warning('custom_target {!r} has more than one output! ' \
+ 'Using the first one.'.format(t.name))
filename = t.get_outputs()[0]
else:
assert(isinstance(t, build.BuildTarget))
@@ -572,32 +572,46 @@ class Backend():
i = i.replace('@INPUT%d@' % j, src)
for (j, res) in enumerate(ofilenames):
i = i.replace('@OUTPUT%d@' % j, res)
- if i == '@INPUT@':
- cmd += srcs
- elif i == '@OUTPUT@':
- cmd += ofilenames
- else:
- if '@OUTDIR@' in i:
- i = i.replace('@OUTDIR@', outdir)
- elif '@DEPFILE@' in i:
- if target.depfile is None:
- raise MesonException('Custom target %s has @DEPFILE@ but no depfile keyword argument.' % target.name)
- if absolute_paths:
- dfilename = os.path.join(self.get_target_private_dir_abs(target), target.depfile)
- else:
- dfilename = os.path.join(self.get_target_private_dir(target), target.depfile)
- i = i.replace('@DEPFILE@', dfilename)
- elif '@PRIVATE_OUTDIR_' in i:
- match = re.search('@PRIVATE_OUTDIR_(ABS_)?([-a-zA-Z0-9.@:]*)@', i)
- source = match.group(0)
- if match.group(1) is None and not absolute_paths:
- lead_dir = ''
- else:
- lead_dir = self.environment.get_build_dir()
- i = i.replace(source,
- os.path.join(lead_dir,
- outdir))
- cmd.append(i)
+ if '@INPUT@' in i:
+ msg = 'Custom target {} has @INPUT@ in the command, but'.format(target.name)
+ if len(srcs) == 0:
+ raise MesonException(msg + ' no input files')
+ if i == '@INPUT@':
+ cmd += srcs
+ continue
+ else:
+ if len(srcs) > 1:
+ raise MesonException(msg + ' more than one input file')
+ i = i.replace('@INPUT@', srcs[0])
+ elif '@OUTPUT@' in i:
+ msg = 'Custom target {} has @OUTPUT@ in the command, but'.format(target.name)
+ if len(ofilenames) == 0:
+ raise MesonException(msg + ' no output files')
+ if i == '@OUTPUT@':
+ cmd += ofilenames
+ continue
+ else:
+ if len(ofilenames) > 1:
+ raise MesonException(msg + ' more than one output file')
+ i = i.replace('@OUTPUT@', ofilenames[0])
+ elif '@OUTDIR@' in i:
+ i = i.replace('@OUTDIR@', outdir)
+ elif '@DEPFILE@' in i:
+ if target.depfile is None:
+ raise MesonException('Custom target %s has @DEPFILE@ but no depfile keyword argument.' % target.name)
+ dfilename = os.path.join(outdir, target.depfile)
+ i = i.replace('@DEPFILE@', dfilename)
+ elif '@PRIVATE_OUTDIR_' in i:
+ match = re.search('@PRIVATE_OUTDIR_(ABS_)?([-a-zA-Z0-9.@:]*)@', i)
+ source = match.group(0)
+ if match.group(1) is None and not absolute_paths:
+ lead_dir = ''
+ else:
+ lead_dir = self.environment.get_build_dir()
+ i = i.replace(source,
+ os.path.join(lead_dir,
+ outdir))
+ cmd.append(i)
# This should not be necessary but removing it breaks
# building GStreamer on Windows. The underlying issue
# is problems with quoting backslashes on Windows
diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py
index 5fa7d79..76f47ab 100644
--- a/mesonbuild/backend/ninjabackend.py
+++ b/mesonbuild/backend/ninjabackend.py
@@ -215,7 +215,7 @@ int dummy;
with open(os.path.join(builddir, 'compile_commands.json'), 'wb') as f:
f.write(jsondb)
except Exception:
- mlog.log(mlog.red('Warning:', 'Could not create compilation database.'))
+ mlog.warning('Could not create compilation database.')
# Get all generated headers. Any source file might need them so
# we need to add an order dependency to them.
@@ -494,8 +494,8 @@ int dummy;
cmd_type = 'custom'
if target.depfile is not None:
- rel_dfile = os.path.join(self.get_target_private_dir(target), target.depfile)
- abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_private_dir(target))
+ rel_dfile = os.path.join(self.get_target_dir(target), target.depfile)
+ abs_pdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
os.makedirs(abs_pdir, exist_ok=True)
elem.add_item('DEPFILE', rel_dfile)
elem.add_item('COMMAND', cmd)
@@ -581,7 +581,7 @@ int dummy;
elem.add_item('DESC', 'Generating HTML coverage report.')
elem.write(outfile)
if not added_rule:
- mlog.log(mlog.red('Warning:'), 'coverage requested but neither gcovr nor lcov/genhtml found.')
+ mlog.warning('coverage requested but neither gcovr nor lcov/genhtml found.')
def generate_install(self, outfile):
install_data_file = os.path.join(self.environment.get_scratch_dir(), 'install.dat')
@@ -1694,9 +1694,9 @@ rule FORTRAN_DEP_HACK
if target.has_pch():
tfilename = self.get_target_filename_abs(target)
- return compiler.get_compile_debugfile_args(tfilename)
+ return compiler.get_compile_debugfile_args(tfilename, pch=True)
else:
- return compiler.get_compile_debugfile_args(objfile)
+ return compiler.get_compile_debugfile_args(objfile, pch=False)
def get_link_debugfile_args(self, linker, target, outname):
return linker.get_link_debugfile_args(outname)
@@ -1720,10 +1720,11 @@ rule FORTRAN_DEP_HACK
# Add the root source and build directories as include dirs
curdir = target.get_subdir()
tmppath = os.path.normpath(os.path.join(self.build_to_src, curdir))
- commands += compiler.get_include_args(tmppath, False)
+ src_inc = compiler.get_include_args(tmppath, False)
if curdir == '':
curdir = '.'
- commands += compiler.get_include_args(curdir, False)
+ build_inc = compiler.get_include_args(curdir, False)
+ commands += build_inc + src_inc
# -I args work differently than other ones. In them the first found
# directory is used whereas for other flags (such as -ffoo -fno-foo) the
# latest one is used. Therefore put the internal include directories
diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py
index f1d949a..c66233e 100644
--- a/mesonbuild/backend/vs2010backend.py
+++ b/mesonbuild/backend/vs2010backend.py
@@ -284,20 +284,13 @@ class Vs2010Backend(backends.Backend):
def generate_projects(self):
projlist = []
- comp = None
- for l, c in self.environment.coredata.compilers.items():
- if l == 'c' or l == 'cpp':
- comp = c
- break
- if comp is None:
- raise RuntimeError('C and C++ compilers missing.')
for name, target in self.build.targets.items():
outdir = os.path.join(self.environment.get_build_dir(), self.get_target_dir(target))
fname = name + '.vcxproj'
relname = os.path.join(target.subdir, fname)
projfile = os.path.join(outdir, fname)
uuid = self.environment.coredata.target_guids[name]
- self.gen_vcxproj(target, projfile, uuid, comp)
+ self.gen_vcxproj(target, projfile, uuid)
projlist.append((name, relname, uuid))
return projlist
@@ -430,12 +423,26 @@ class Vs2010Backend(backends.Backend):
pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
pch_out.text = '$(IntDir)$(TargetName)-%s.pch' % lang
- def add_additional_options(self, source_file, parent_node, extra_args, has_additional_options_set):
- if has_additional_options_set:
+ def add_additional_options(self, lang, parent_node, file_args):
+ if len(file_args[lang]) == 0:
# We only need per file options if they were not set per project.
return
- lang = Vs2010Backend.lang_from_source_file(source_file)
- ET.SubElement(parent_node, "AdditionalOptions").text = ' '.join(extra_args[lang]) + ' %(AdditionalOptions)'
+ args = file_args[lang] + ['%(AdditionalOptions)']
+ ET.SubElement(parent_node, "AdditionalOptions").text = ' '.join(args)
+
+ def add_preprocessor_defines(self, lang, parent_node, file_defines):
+ if len(file_defines[lang]) == 0:
+ # We only need per file options if they were not set per project.
+ return
+ defines = file_defines[lang] + ['%(PreprocessorDefinitions)']
+ ET.SubElement(parent_node, "PreprocessorDefinitions").text = ';'.join(defines)
+
+ def add_include_dirs(self, lang, parent_node, file_inc_dirs):
+ if len(file_inc_dirs[lang]) == 0:
+ # We only need per file options if they were not set per project.
+ return
+ dirs = file_inc_dirs[lang] + ['%(AdditionalIncludeDirectories)']
+ ET.SubElement(parent_node, "AdditionalIncludeDirectories").text = ';'.join(dirs)
@staticmethod
def has_objects(objects, additional_objects, generated_objects):
@@ -505,7 +512,19 @@ class Vs2010Backend(backends.Backend):
other.append(arg)
return (lpaths, libs, other)
- def gen_vcxproj(self, target, ofname, guid, compiler):
+ def _get_cl_compiler(self, target):
+ for lang, c in target.compilers.items():
+ if lang in ('c', 'cpp'):
+ return c
+ # No source files, only objects, but we still need a compiler, so
+ # return a found compiler
+ if len(target.objects) > 0:
+ for lang, c in self.environment.coredata.compilers.items():
+ if lang in ('c', 'cpp'):
+ return c
+ raise MesonException('Could not find a C or C++ compiler. MSVC can only build C/C++ projects.')
+
+ def gen_vcxproj(self, target, ofname, guid):
mlog.debug('Generating vcxproj %s.' % target.name)
entrypoint = 'WinMainCRTStartup'
subsystem = 'Windows'
@@ -532,6 +551,7 @@ class Vs2010Backend(backends.Backend):
# Prefix to use to access the source tree's subdir from the vcxproj dir
proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir)
(sources, headers, objects, languages) = self.split_sources(target.sources)
+ compiler = self._get_cl_compiler(target)
buildtype_args = compiler.get_buildtype_args(self.buildtype)
buildtype_link_args = compiler.get_buildtype_linker_args(self.buildtype)
project_name = target.name
@@ -643,83 +663,86 @@ class Vs2010Backend(backends.Backend):
# Build information
compiles = ET.SubElement(root, 'ItemDefinitionGroup')
clconf = ET.SubElement(compiles, 'ClCompile')
- inc_dirs = ['.', self.relpath(self.get_target_private_dir(target), self.get_target_dir(target)),
- proj_to_src_dir] + generated_files_include_dirs
-
- extra_args = {'c': [], 'cpp': []}
+ # Arguments, include dirs, defines for all files in the current target
+ target_args = []
+ target_defines = []
+ target_inc_dirs = ['.', self.relpath(self.get_target_private_dir(target),
+ self.get_target_dir(target)),
+ proj_to_src_dir] + generated_files_include_dirs
+ # Arguments, include dirs, defines passed to individual files in
+ # a target; perhaps because the args are language-specific
+ file_args = dict((lang, []) for lang in target.compilers)
+ file_defines = dict((lang, []) for lang in target.compilers)
+ file_inc_dirs = dict((lang, []) for lang in target.compilers)
for l, args in self.environment.coredata.external_args.items():
- if l in extra_args:
- extra_args[l] += args
+ if l in file_args:
+ file_args[l] += args
for l, args in self.build.global_args.items():
- if l in extra_args:
- extra_args[l] += args
+ if l in file_args:
+ file_args[l] += args
for l, args in target.extra_args.items():
- if l in extra_args:
- extra_args[l] += compiler.unix_compile_flags_to_native(args)
- # FIXME all the internal flags of VS (optimization etc) are represented
- # by their own XML elements. In theory we should split all flags to those
- # that have an XML element and those that don't and serialise them
- # properly. This is a crapton of work for no real gain, so just dump them
- # here.
- general_args = compiler.get_option_compile_args(self.environment.coredata.compiler_options)
+ if l in file_args:
+ file_args[l] += compiler.unix_compile_flags_to_native(args)
+ for l, comp in target.compilers.items():
+ if l in file_args:
+ file_args[l] += comp.get_option_compile_args(self.environment.coredata.compiler_options)
for d in target.get_external_deps():
# Cflags required by external deps might have UNIX-specific flags,
# so filter them out if needed
d_compile_args = compiler.unix_compile_flags_to_native(d.get_compile_args())
for arg in d_compile_args:
- if arg.startswith('-I') or arg.startswith('/I'):
+ if arg.startswith(('-D', '/D')):
+ define = arg[2:]
+ # De-dup
+ if define not in target_defines:
+ target_defines.append(define)
+ elif arg.startswith(('-I', '/I')):
inc_dir = arg[2:]
# De-dup
- if inc_dir not in inc_dirs:
- inc_dirs.append(inc_dir)
+ if inc_dir not in target_inc_dirs:
+ target_inc_dirs.append(inc_dir)
else:
- general_args.append(arg)
+ # De-dup
+ if arg not in target_args:
+ target_args.append(arg)
- defines = []
# Split preprocessor defines and include directories out of the list of
# all extra arguments. The rest go into %(AdditionalOptions).
- for l, args in extra_args.items():
- extra_args[l] = []
+ for l, args in file_args.items():
+ file_args[l] = []
for arg in args:
- if arg.startswith('-D') or arg.startswith('/D'):
+ if arg.startswith(('-D', '/D')):
define = self.escape_preprocessor_define(arg[2:])
# De-dup
- if define not in defines:
- defines.append(define)
- elif arg.startswith('-I') or arg.startswith('/I'):
+ if define not in file_defines[l]:
+ file_defines[l].append(define)
+ elif arg.startswith(('-I', '/I')):
inc_dir = arg[2:]
# De-dup
- if inc_dir not in inc_dirs:
- inc_dirs.append(inc_dir)
+ if inc_dir not in file_inc_dirs[l]:
+ file_inc_dirs[l].append(inc_dir)
else:
- extra_args[l].append(self.escape_additional_option(arg))
+ file_args[l].append(self.escape_additional_option(arg))
languages += gen_langs
- has_language_specific_args = any(l != extra_args['c'] for l in extra_args.values())
- additional_options_set = False
- if not has_language_specific_args or len(languages) == 1:
- if len(languages) == 0:
- extra_args = []
- else:
- extra_args = extra_args[languages[0]]
- extra_args = general_args + extra_args
- if len(extra_args) > 0:
- extra_args.append('%(AdditionalOptions)')
- ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(extra_args)
- additional_options_set = True
+ if len(target_args) > 0:
+ target_args.append('%(AdditionalOptions)')
+ ET.SubElement(clconf, "AdditionalOptions").text = ' '.join(target_args)
+ additional_options_set = True
for d in target.include_dirs:
for i in d.incdirs:
curdir = os.path.join(d.curdir, i)
- inc_dirs.append(self.relpath(curdir, target.subdir)) # build dir
- inc_dirs.append(os.path.join(proj_to_src_root, curdir)) # src dir
+ target_inc_dirs.append(self.relpath(curdir, target.subdir)) # build dir
+ target_inc_dirs.append(os.path.join(proj_to_src_root, curdir)) # src dir
for i in d.get_extra_build_dirs():
curdir = os.path.join(d.curdir, i)
- inc_dirs.append(self.relpath(curdir, target.subdir)) # build dir
+ target_inc_dirs.append(self.relpath(curdir, target.subdir)) # build dir
- inc_dirs.append('%(AdditionalIncludeDirectories)')
- ET.SubElement(clconf, 'AdditionalIncludeDirectories').text = ';'.join(inc_dirs)
- ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(defines)
+ target_inc_dirs.append('%(AdditionalIncludeDirectories)')
+ ET.SubElement(clconf, 'AdditionalIncludeDirectories').text = ';'.join(target_inc_dirs)
+ target_defines.append('%(PreprocessorDefinitions)')
+ ET.SubElement(clconf, 'PreprocessorDefinitions').text = ';'.join(target_defines)
rebuild = ET.SubElement(clconf, 'MinimalRebuild')
rebuild.text = 'true'
funclink = ET.SubElement(clconf, 'FunctionLevelLinking')
@@ -834,19 +857,26 @@ class Vs2010Backend(backends.Backend):
for s in sources:
relpath = os.path.join(down, s.rel_to_builddir(self.build_to_src))
inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
+ lang = Vs2010Backend.lang_from_source_file(s)
self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s)
- self.add_additional_options(s, inc_cl, extra_args, additional_options_set)
+ self.add_additional_options(lang, inc_cl, file_args)
+ self.add_preprocessor_defines(lang, inc_cl, file_defines)
+ self.add_include_dirs(lang, inc_cl, file_inc_dirs)
basename = os.path.basename(s.fname)
if basename in self.sources_conflicts[target.get_id()]:
ET.SubElement(inc_cl, 'ObjectFileName').text = "$(IntDir)" + self.object_filename_from_source(target, s)
for s in gen_src:
inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=s)
+ lang = Vs2010Backend.lang_from_source_file(s)
self.add_pch(inc_cl, proj_to_src_dir, pch_sources, s)
- self.add_additional_options(s, inc_cl, extra_args, additional_options_set)
+ self.add_additional_options(lang, inc_cl, file_args)
+ self.add_preprocessor_defines(lang, inc_cl, file_defines)
+ self.add_include_dirs(lang, inc_cl, file_inc_dirs)
for lang in pch_sources:
header, impl, suffix = pch_sources[lang]
relpath = os.path.join(proj_to_src_dir, impl)
inc_cl = ET.SubElement(inc_src, 'CLCompile', Include=relpath)
+ lang = Vs2010Backend.lang_from_source_file(s)
pch = ET.SubElement(inc_cl, 'PrecompiledHeader')
pch.text = 'Create'
pch_out = ET.SubElement(inc_cl, 'PrecompiledHeaderOutputFile')
@@ -855,7 +885,9 @@ class Vs2010Backend(backends.Backend):
# MSBuild searches for the header relative from the implementation, so we have to use
# just the file name instead of the relative path to the file.
pch_file.text = os.path.split(header)[1]
- self.add_additional_options(impl, inc_cl, extra_args, additional_options_set)
+ self.add_additional_options(lang, inc_cl, file_args)
+ self.add_preprocessor_defines(lang, inc_cl, file_defines)
+ self.add_include_dirs(lang, inc_cl, file_inc_dirs)
if self.has_objects(objects, additional_objects, gen_objs):
inc_objs = ET.SubElement(root, 'ItemGroup')
diff --git a/mesonbuild/build.py b/mesonbuild/build.py
index c3867e0..d87d9a0 100644
--- a/mesonbuild/build.py
+++ b/mesonbuild/build.py
@@ -309,8 +309,8 @@ class BuildTarget():
if not k in known_kwargs:
unknowns.append(k)
if len(unknowns) > 0:
- mlog.log(mlog.bold('Warning:'), 'Unknown keyword argument(s) in target %s: %s.' %
- (self.name, ', '.join(unknowns)))
+ mlog.warning('Unknown keyword argument(s) in target %s: %s.' %
+ (self.name, ', '.join(unknowns)))
def process_objectlist(self, objects):
assert(isinstance(objects, list))
@@ -583,7 +583,7 @@ class BuildTarget():
if for_darwin(self.is_cross, self.environment) or for_windows(self.is_cross, self.environment):
self.pic = True
elif '-fPIC' in clist + cpplist:
- mlog.log(mlog.red('WARNING:'), "Use the 'pic' kwarg instead of passing -fPIC manually to static library {!r}".format(self.name))
+ mlog.warning("Use the 'pic' kwarg instead of passing -fPIC manually to static library {!r}".format(self.name))
self.pic = True
else:
self.pic = kwargs.get('pic', False)
@@ -1139,8 +1139,8 @@ class CustomTarget:
if k not in CustomTarget.known_kwargs:
unknowns.append(k)
if len(unknowns) > 0:
- mlog.log(mlog.bold('Warning:'), 'Unknown keyword arguments in target %s: %s' %
- (self.name, ', '.join(unknowns)))
+ mlog.warning('Unknown keyword arguments in target %s: %s' %
+ (self.name, ', '.join(unknowns)))
def __repr__(self):
repr_str = "<{0} {1}: {2}>"
diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py
index 94e8a54..bbe6a72 100644
--- a/mesonbuild/compilers.py
+++ b/mesonbuild/compilers.py
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import shutil
import contextlib
import subprocess, os.path
import tempfile
@@ -434,7 +435,7 @@ class Compiler():
# Some compilers (msvc) write debug info to a separate file.
# These args specify where it should be written.
- def get_compile_debugfile_args(self, rel_obj):
+ def get_compile_debugfile_args(self, rel_obj, **kwargs):
return []
def get_link_debugfile_args(self, rel_obj):
@@ -512,6 +513,13 @@ class CCompiler(Compiler):
def get_no_optimization_args(self):
return ['-O0']
+ def get_compiler_check_args(self):
+ '''
+ Get arguments useful for compiler checks such as being permissive in
+ the code quality and not doing any optimization.
+ '''
+ return self.get_no_optimization_args()
+
def get_output_args(self, target):
return ['-o', target]
@@ -643,9 +651,14 @@ int someSymbolHereJustForFun;
extra_args = []
templ = '''{2}
#include <{0}>
-int main () {{ {1}; }}'''
- # Pass -O0 to ensure that the symbol isn't optimized away
- args = extra_args + self.get_no_optimization_args()
+int main () {{
+ /* If it's not defined as a macro, try to use as a symbol */
+ #ifndef {1}
+ {1};
+ #endif
+ return 0;
+}}'''
+ args = extra_args + self.get_compiler_check_args()
return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
@contextlib.contextmanager
@@ -784,7 +797,7 @@ int main(int argc, char **argv) {{
%s
int temparray[%d-sizeof(%s)];
'''
- args = extra_args + self.get_no_optimization_args()
+ args = extra_args + self.get_compiler_check_args()
if not self.compiles(element_exists_templ.format(prefix, element), env, args, dependencies):
return -1
for i in range(1, 1024):
@@ -833,7 +846,7 @@ struct tmp {
int testarray[%d-offsetof(struct tmp, target)];
'''
- args = extra_args + self.get_no_optimization_args()
+ args = extra_args + self.get_compiler_check_args()
if not self.compiles(type_exists_templ.format(typename), env, args, dependencies):
return -1
for i in range(1, 1024):
@@ -918,7 +931,7 @@ int main(int argc, char **argv) {
head = '#include <limits.h>\n{0}\n'
# We don't know what the function takes or returns, so try to use it as
# a function pointer
- main = '\nint main() {{ int a = (int) &{1}; }}'
+ main = '\nint main() {{ void *a = (void*) &{1}; }}'
return head, main
def has_function(self, funcname, prefix, env, extra_args=None, dependencies=None):
@@ -967,9 +980,8 @@ int main(int argc, char **argv) {
head, main = self._no_prototype_templ()
templ = head + stubs_fail + main
- # Add -O0 to ensure that the symbol isn't optimized away by the compiler
- args = extra_args + self.get_no_optimization_args()
- if self.links(templ.format(prefix, funcname), env, extra_args, dependencies):
+ args = extra_args + self.get_compiler_check_args()
+ if self.links(templ.format(prefix, funcname), env, args, dependencies):
return True
# Some functions like alloca() are defined as compiler built-ins which
# are inlined by the compiler, so test for that instead. Built-ins are
@@ -1048,6 +1060,20 @@ class CPPCompiler(CCompiler):
code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n'
return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code)
+ def has_header_symbol(self, hname, symbol, prefix, env, extra_args=None, dependencies=None):
+ # Check if it's a C-like symbol
+ if super().has_header_symbol(hname, symbol, prefix, env, extra_args, dependencies):
+ return True
+ # Check if it's a class or a template
+ if extra_args is None:
+ extra_args = []
+ templ = '''{2}
+#include <{0}>
+using {1};
+int main () {{ return 0; }}'''
+ args = extra_args + self.get_compiler_check_args()
+ return self.compiles(templ.format(hname, symbol, prefix), env, args, dependencies)
+
class ObjCCompiler(CCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'objc'
@@ -1274,11 +1300,20 @@ class JavaCompiler(Compiler):
pc.wait()
if pc.returncode != 0:
raise EnvironmentException('Java compiler %s can not compile programs.' % self.name_string())
- cmdlist = [self.javarunner, obj]
- pe = subprocess.Popen(cmdlist, cwd=work_dir)
- pe.wait()
- if pe.returncode != 0:
- raise EnvironmentException('Executables created by Java compiler %s are not runnable.' % self.name_string())
+ runner = shutil.which(self.javarunner)
+ if runner:
+ cmdlist = [runner, obj]
+ pe = subprocess.Popen(cmdlist, cwd=work_dir)
+ pe.wait()
+ if pe.returncode != 0:
+ raise EnvironmentException('Executables created by Java compiler %s are not runnable.' % self.name_string())
+ else:
+ m = "Java Virtual Machine wasn't found, but it's needed by Meson. " \
+ "Please install a JRE.\nIf you have specific needs where this " \
+ "requirement doesn't make sense, please open a bug at " \
+ "https://github.com/mesonbuild/meson/issues/new and tell us " \
+ "all about it."
+ raise EnvironmentException(m)
def needs_static_linker(self):
return False
@@ -1848,19 +1883,29 @@ class VisualStudioCCompiler(CCompiler):
raise MesonException('Compiling test app failed.')
return not(warning_text in stde or warning_text in stdo)
- def get_compile_debugfile_args(self, rel_obj):
+ def get_compile_debugfile_args(self, rel_obj, pch=False):
pdbarr = rel_obj.split('.')[:-1]
pdbarr += ['pdb']
- return ['/Fd' + '.'.join(pdbarr)]
+ args = ['/Fd' + '.'.join(pdbarr)]
+ # When generating a PDB file with PCH, all compile commands write
+ # to the same PDB file. Hence, we need to serialize the PDB
+ # writes using /FS since we do parallel builds. This slows down the
+ # build obviously, which is why we only do this when PCH is on.
+ # This was added in Visual Studio 2013 (MSVC 18.0). Before that it was
+ # always on: https://msdn.microsoft.com/en-us/library/dn502518.aspx
+ if pch and mesonlib.version_compare(self.version, '>=18.0'):
+ args = ['/FS'] + args
+ return args
def get_link_debugfile_args(self, targetfile):
pdbarr = targetfile.split('.')[:-1]
pdbarr += ['pdb']
return ['/DEBUG', '/PDB:' + '.'.join(pdbarr)]
-class VisualStudioCPPCompiler(VisualStudioCCompiler):
+class VisualStudioCPPCompiler(VisualStudioCCompiler, CPPCompiler):
def __init__(self, exelist, version, is_cross, exe_wrap):
self.language = 'cpp'
+ CPPCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
VisualStudioCCompiler.__init__(self, exelist, version, is_cross, exe_wrap)
self.base_options = ['b_pch'] # FIXME add lto, pgo and the like
@@ -2035,6 +2080,12 @@ class GnuCPPCompiler(GnuCompiler, CPPCompiler):
return options['cpp_winlibs'].value
return []
+ def get_compiler_check_args(self):
+ # -fpermissive allows non-conforming code to compile which is necessary
+ # for many C++ checks. Particularly, the has_header_symbol check is
+ # too strict without this and always fails.
+ return self.get_no_optimization_args() + ['-fpermissive']
+
class GnuObjCCompiler(GnuCompiler,ObjCCompiler):
def __init__(self, exelist, version, is_cross, exe_wrapper=None, defines=None):
@@ -2057,6 +2108,12 @@ class GnuObjCPPCompiler(GnuCompiler, ObjCPPCompiler):
'2': ['-Wall', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor'],
'3' : ['-Wall', '-Wpedantic', '-Wextra', '-Winvalid-pch', '-Wnon-virtual-dtor']}
+ def get_compiler_check_args(self):
+ # -fpermissive allows non-conforming code to compile which is necessary
+ # for many ObjC++ checks. Particularly, the has_header_symbol check is
+ # too strict without this and always fails.
+ return self.get_no_optimization_args() + ['-fpermissive']
+
class ClangCompiler():
def __init__(self, clang_type):
self.id = 'clang'
diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py
index 943c087..88826f8 100644
--- a/mesonbuild/mesonmain.py
+++ b/mesonbuild/mesonmain.py
@@ -89,6 +89,10 @@ class MesonApp():
def validate_core_dirs(self, dir1, dir2):
ndir1 = os.path.abspath(dir1)
ndir2 = os.path.abspath(dir2)
+ if not os.path.exists(ndir1):
+ os.makedirs(ndir1)
+ if not os.path.exists(ndir2):
+ os.makedirs(ndir2)
if not stat.S_ISDIR(os.stat(ndir1).st_mode):
raise RuntimeError('%s is not a directory' % dir1)
if not stat.S_ISDIR(os.stat(ndir2).st_mode):
@@ -121,8 +125,8 @@ itself as required.'''
def check_pkgconfig_envvar(self, env):
curvar = os.environ.get('PKG_CONFIG_PATH', '')
if curvar != env.coredata.pkgconf_envvar:
- mlog.log(mlog.red("WARNING:"), 'PKG_CONFIG_PATH has changed between invocations from "%s" to "%s".' %
- (env.coredata.pkgconf_envvar, curvar))
+ mlog.warning('PKG_CONFIG_PATH has changed between invocations from "%s" to "%s".' %
+ (env.coredata.pkgconf_envvar, curvar))
env.coredata.pkgconf_envvar = curvar
def generate(self):
diff --git a/mesonbuild/mlog.py b/mesonbuild/mlog.py
index dab51bd..cded2b0 100644
--- a/mesonbuild/mlog.py
+++ b/mesonbuild/mlog.py
@@ -53,6 +53,9 @@ def red(text):
def green(text):
return AnsiDecorator(text, "\033[1;32m")
+def yellow(text):
+ return AnsiDecorator(text, "\033[1;33m")
+
def cyan(text):
return AnsiDecorator(text, "\033[1;36m")
@@ -81,3 +84,6 @@ def log(*args, **kwargs):
if colorize_console:
arr = process_markup(args, True)
print(*arr, **kwargs)
+
+def warning(*args, **kwargs):
+ log(yellow('WARNING:'), *args, **kwargs)
diff --git a/mesonbuild/modules/gnome.py b/mesonbuild/modules/gnome.py
index 27200ae..f3f22bc 100644
--- a/mesonbuild/modules/gnome.py
+++ b/mesonbuild/modules/gnome.py
@@ -18,6 +18,7 @@ functionality such as gobject-introspection and gresources.'''
from .. import build
import os
import sys
+import copy
import subprocess
from ..mesonlib import MesonException
from .. import dependencies
@@ -43,11 +44,11 @@ class GnomeModule:
def __print_gresources_warning(self, state):
global gresource_warning_printed
if not gresource_warning_printed:
- if mesonlib.version_compare(self._get_native_glib_version(state), '< 2.50.0'):
- mlog.log('Warning, GLib compiled dependencies do not work fully '
- 'with versions of GLib older than 2.50.0.\n'
- 'See the following upstream issue:',
- mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=745754'))
+ if mesonlib.version_compare(self._get_native_glib_version(state), '< 2.50.2'):
+ mlog.warning('GLib compiled dependencies do not work fully '
+ 'with versions of GLib older than 2.50.2.\n'
+ 'See the following upstream issue:',
+ mlog.bold('https://bugzilla.gnome.org/show_bug.cgi?id=745754'))
gresource_warning_printed = True
return []
@@ -60,9 +61,6 @@ class GnomeModule:
if not isinstance(source_dirs, list):
source_dirs = [source_dirs]
- # Always include current directory, but after paths set by user
- source_dirs.append(os.path.join(state.environment.get_source_dir(), state.subdir))
-
if len(args) < 2:
raise MesonException('Not enough arguments; The name of the resource and the path to the XML file are required')
@@ -70,8 +68,8 @@ class GnomeModule:
if not isinstance(dependencies, list):
dependencies = [dependencies]
- if mesonlib.version_compare(self._get_native_glib_version(state),
- '< 2.48.2'):
+ glib_version = self._get_native_glib_version(state)
+ if mesonlib.version_compare(glib_version, '< 2.48.2'):
if len(dependencies) > 0:
raise MesonException(
'The "dependencies" argument of gnome.compile_resources() '
@@ -87,18 +85,18 @@ class GnomeModule:
else:
raise RuntimeError('Unreachable code.')
- kwargs['depend_files'] = self._get_gresource_dependencies(
+ depend_files, depends, subdirs = self._get_gresource_dependencies(
state, ifile, source_dirs, dependencies)
- for source_dir in source_dirs:
- sourcedir = os.path.join(state.build_to_src, state.subdir, source_dir)
- cmd += ['--sourcedir', sourcedir]
+ # Make source dirs relative to build dir now
+ source_dirs = [os.path.join(state.build_to_src, state.subdir, d) for d in source_dirs]
+ # Always include current directory, but after paths set by user
+ source_dirs.append(os.path.join(state.build_to_src, state.subdir))
+ # Ensure build directories of generated deps are included
+ source_dirs += subdirs
- if len(dependencies) > 0:
- # Add the build variant of each sourcedir if we have any
- # generated dependencies.
- sourcedir = os.path.join(state.subdir, source_dir)
- cmd += ['--sourcedir', sourcedir]
+ for source_dir in set(source_dirs):
+ cmd += ['--sourcedir', source_dir]
if 'c_name' in kwargs:
cmd += ['--c-name', kwargs.pop('c_name')]
@@ -106,17 +104,30 @@ class GnomeModule:
cmd += mesonlib.stringlistify(kwargs.pop('extra_args', []))
- kwargs['command'] = cmd
kwargs['input'] = args[1]
kwargs['output'] = args[0] + '.c'
+ kwargs['depends'] = depends
+ if mesonlib.version_compare(glib_version, '< 2.50.2'):
+ # This will eventually go out of sync if dependencies are added
+ kwargs['depend_files'] = depend_files
+ kwargs['command'] = cmd
+ else:
+ depfile = kwargs['output'] + '.d'
+ kwargs['depfile'] = depfile
+ kwargs['command'] = copy.copy(cmd) + ['--dependency-file', '@DEPFILE@']
target_c = build.CustomTarget(args[0] + '_c', state.subdir, kwargs)
- kwargs['output'] = args[0] + '.h'
- target_h = build.CustomTarget(args[0] + '_h', state.subdir, kwargs)
+
+ h_kwargs = {
+ 'command': cmd,
+ 'input': args[1],
+ 'output': args[0] + '.h',
+ # The header doesn't actually care about the files yet it errors if missing
+ 'depends': depends
+ }
+ target_h = build.CustomTarget(args[0] + '_h', state.subdir, h_kwargs)
return [target_c, target_h]
def _get_gresource_dependencies(self, state, input_file, source_dirs, dependencies):
- self.__print_gresources_warning(state)
-
for dep in dependencies:
if not isinstance(dep, interpreter.CustomTargetHolder) and not \
isinstance(dep, mesonlib.File):
@@ -131,12 +142,13 @@ class GnomeModule:
for source_dir in source_dirs:
cmd += ['--sourcedir', os.path.join(state.subdir, source_dir)]
+ cmd += ['--sourcedir', state.subdir] # Current dir
pc = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True,
cwd=state.environment.get_source_dir())
(stdout, _) = pc.communicate()
if pc.returncode != 0:
- mlog.log(mlog.bold('Warning:'), 'glib-compile-resources has failed to get the dependencies for {}'.format(cmd[1]))
+ mlog.warning('glib-compile-resources has failed to get the dependencies for {}'.format(cmd[1]))
raise subprocess.CalledProcessError(pc.returncode, cmd)
dep_files = stdout.split('\n')[:-1]
@@ -154,6 +166,8 @@ class GnomeModule:
return os.path.exists(os.path.join(state.environment.get_source_dir(), f))
missing_dep_files = [f for f in dep_files if not exists_in_srcdir(f)]
+ depends = []
+ subdirs = []
for missing in missing_dep_files:
found = False
missing_basename = os.path.basename(missing)
@@ -164,6 +178,7 @@ class GnomeModule:
found = True
dep_files.remove(missing)
dep_files.append(dep)
+ subdirs.append(dep.subdir)
break
elif isinstance(dep, interpreter.CustomTargetHolder):
if dep.held_object.get_basename() == missing_basename:
@@ -174,6 +189,8 @@ class GnomeModule:
is_built=True,
subdir=dep.held_object.get_subdir(),
fname=dep.held_object.get_basename()))
+ depends.append(dep.held_object)
+ subdirs.append(dep.held_object.get_subdir())
break
if not found:
@@ -183,7 +200,7 @@ class GnomeModule:
'gnome.compile_resources() using the "dependencies" '
'keyword argument.' % (missing, input_file))
- return dep_files
+ return dep_files, depends, subdirs
@staticmethod
def _get_link_args(state, lib, depends=None):
@@ -297,7 +314,7 @@ class GnomeModule:
except Exception:
global girwarning_printed
if not girwarning_printed:
- mlog.log(mlog.bold('Warning:'), 'gobject-introspection dependency was not found, disabling gir generation.')
+ mlog.warning('gobject-introspection dependency was not found, disabling gir generation.')
girwarning_printed = True
return []
pkgargs = pkgstr.decode().strip().split()
diff --git a/mesonbuild/modules/pkgconfig.py b/mesonbuild/modules/pkgconfig.py
index 7556375..3ecb40d 100644
--- a/mesonbuild/modules/pkgconfig.py
+++ b/mesonbuild/modules/pkgconfig.py
@@ -34,7 +34,7 @@ class PkgConfigModule:
return l.name
# In other cases, we can't guarantee that the compiler will be able to
# find the library via '-lfoo', so tell the user that.
- mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_prefix', l.name, pcfile))
+ mlog.warning(msg.format(l.name, 'name_prefix', l.name, pcfile))
return l.name
def generate_pkgconfig_file(self, state, libraries, subdirs, name, description,
@@ -79,7 +79,7 @@ class PkgConfigModule:
# If using a custom suffix, the compiler may not be able to
# find the library
if l.name_suffix_set:
- mlog.log(mlog.red('WARNING:'), msg.format(l.name, 'name_suffix', lname, pcfile))
+ mlog.warning(msg.format(l.name, 'name_suffix', lname, pcfile))
yield '-l%s' % lname
if len(libraries) > 0:
ofile.write('Libs: {}\n'.format(' '.join(generate_libs_flags(libraries))))
diff --git a/mesonbuild/modules/qt4.py b/mesonbuild/modules/qt4.py
index 81a70fc..b1d951b 100644
--- a/mesonbuild/modules/qt4.py
+++ b/mesonbuild/modules/qt4.py
@@ -90,7 +90,7 @@ class Qt4Module():
result = []
for child in root[0]:
if child.tag != 'file':
- mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname))
+ mlog.warning("malformed rcc file: ", os.path.join(state.subdir, fname))
break
else:
result.append(os.path.join(state.subdir, relative_part, child.text))
@@ -150,6 +150,6 @@ class Qt4Module():
return sources
def initialize():
- mlog.log('Warning, rcc dependencies will not work properly until this upstream issue is fixed:',
- mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
+ mlog.warning('rcc dependencies will not work properly until this upstream issue is fixed:',
+ mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
return Qt4Module()
diff --git a/mesonbuild/modules/qt5.py b/mesonbuild/modules/qt5.py
index 4f19b78..9fffcff 100644
--- a/mesonbuild/modules/qt5.py
+++ b/mesonbuild/modules/qt5.py
@@ -97,7 +97,7 @@ class Qt5Module():
result = []
for child in root[0]:
if child.tag != 'file':
- mlog.log("Warning, malformed rcc file: ", os.path.join(state.subdir, fname))
+ mlog.warning("malformed rcc file: ", os.path.join(state.subdir, fname))
break
else:
result.append(os.path.join(state.subdir, relative_part, child.text))
@@ -160,6 +160,6 @@ class Qt5Module():
return sources
def initialize():
- mlog.log('Warning, rcc dependencies will not work reliably until this upstream issue is fixed:',
- mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
+ mlog.warning('rcc dependencies will not work reliably until this upstream issue is fixed:',
+ mlog.bold('https://bugreports.qt.io/browse/QTBUG-45460'))
return Qt5Module()
diff --git a/mesonbuild/modules/rpm.py b/mesonbuild/modules/rpm.py
index 13aa20b..2c9ed57 100644
--- a/mesonbuild/modules/rpm.py
+++ b/mesonbuild/modules/rpm.py
@@ -63,8 +63,8 @@ class RPMModule:
so_installed = True
elif isinstance(target, build.StaticLibrary) and target.need_install:
to_delete.add('%%{buildroot}%%{_libdir}/%s' % target.get_filename())
- mlog.log('Warning, removing', mlog.bold(target.get_filename()),
- 'from package because packaging static libs not recommended')
+ mlog.warning('removing', mlog.bold(target.get_filename()),
+ 'from package because packaging static libs not recommended')
elif isinstance(target, gnome.GirTarget) and target.should_install():
files_devel.add('%%{_datadir}/gir-1.0/%s' % target.get_filename()[0])
elif isinstance(target, gnome.TypelibTarget) and target.should_install():
@@ -94,14 +94,13 @@ class RPMModule:
for compiler in compiler_deps:
fn.write('BuildRequires: %s\n' % compiler)
for dep in state.environment.coredata.deps:
- fn.write('BuildRequires: pkgconfig(%s)\n' % dep)
+ fn.write('BuildRequires: pkgconfig(%s)\n' % dep[0])
for lib in state.environment.coredata.ext_libs.values():
fn.write('BuildRequires: %s # FIXME\n' % lib.fullpath)
- mlog.log('Warning, replace', mlog.bold(lib.fullpath),
- 'with real package.',
- 'You can use following command to find package which '
- 'contains this lib:',
- mlog.bold('dnf provides %s' % lib.fullpath))
+ mlog.warning('replace', mlog.bold(lib.fullpath), 'with real package.',
+ 'You can use following command to find package which '
+ 'contains this lib:',
+ mlog.bold('dnf provides %s' % lib.fullpath))
for prog in state.environment.coredata.ext_progs.values():
if not prog.found():
fn.write('BuildRequires: %{_bindir}/%s # FIXME\n' %
diff --git a/mesonbuild/scripts/regen_checker.py b/mesonbuild/scripts/regen_checker.py
index ddf4943..e8e1077 100755
--- a/mesonbuild/scripts/regen_checker.py
+++ b/mesonbuild/scripts/regen_checker.py
@@ -52,7 +52,7 @@ def run(args):
regeninfo = pickle.load(f)
with open(coredata, 'rb') as f:
coredata = pickle.load(f)
- mesonscript = coredata.meson_script_file
+ mesonscript = coredata.meson_script_launcher
backend = coredata.get_builtin_option('backend')
regen_timestamp = os.stat(dumpfile).st_mtime
if need_regen(regeninfo, regen_timestamp):
diff --git a/mesonbuild/scripts/scanbuild.py b/mesonbuild/scripts/scanbuild.py
index f13a1a4..dd74ce8 100644
--- a/mesonbuild/scripts/scanbuild.py
+++ b/mesonbuild/scripts/scanbuild.py
@@ -16,10 +16,10 @@ import subprocess
import shutil
import tempfile
-def scanbuild(srcdir, blddir, privdir, logdir, args):
+def scanbuild(exename, srcdir, blddir, privdir, logdir, args):
with tempfile.TemporaryDirectory(dir=privdir) as scandir:
- meson_cmd = ['scan-build'] + args
- build_cmd = ['scan-build', '-o', logdir, 'ninja']
+ meson_cmd = [exename] + args
+ build_cmd = [exename, '-o', logdir, 'ninja']
rc = subprocess.call(meson_cmd + [srcdir, scandir])
if rc != 0:
return rc
@@ -32,7 +32,8 @@ def run(args):
privdir = os.path.join(blddir, 'meson-private')
logdir = os.path.join(blddir, 'meson-logs/scanbuild')
shutil.rmtree(logdir, ignore_errors=True)
- if not shutil.which('scan-build'):
- print('Scan-build not installed')
+ exename = os.environ.get('SCANBUILD', 'scan-build')
+ if not shutil.which(exename):
+ print('Scan-build not installed.')
return 1
- return scanbuild(srcdir, blddir, privdir, logdir, meson_cmd)
+ return scanbuild(exename, srcdir, blddir, privdir, logdir, meson_cmd)
diff --git a/mesonbuild/scripts/yelphelper.py b/mesonbuild/scripts/yelphelper.py
index 00d713a..f33454d 100644
--- a/mesonbuild/scripts/yelphelper.py
+++ b/mesonbuild/scripts/yelphelper.py
@@ -75,7 +75,7 @@ def install_help(srcdir, blddir, sources, media, langs, install_dir, destdir, pr
outfile = os.path.join(indir, m)
if not os.path.exists(infile):
if lang == 'C':
- mlog.log(mlog.bold('Warning:'), 'Media file "%s" did not exist in C directory' %m)
+ mlog.warning('Media file "%s" did not exist in C directory' %m)
elif symlinks:
srcfile = os.path.join(c_install_dir, m)
mlog.log('Symlinking %s to %s.' %(outfile, srcfile))
diff --git a/run_project_tests.py b/run_project_tests.py
index 22e92b8..15d656b 100755
--- a/run_project_tests.py
+++ b/run_project_tests.py
@@ -326,6 +326,28 @@ def have_d_compiler():
return True
return False
+def have_java():
+ if shutil.which('javac') and shutil.which('java'):
+ return True
+ return False
+
+def using_backend(backends):
+ if isinstance(backends, str):
+ backends = (backends,)
+ for backend in backends:
+ if backend == 'ninja':
+ if not backend_flags:
+ return True
+ elif backend == 'xcode':
+ if backend_flags == '--backend=xcode':
+ return True
+ elif backend == 'vs':
+ if backend_flags.startswith('--backend=vs'):
+ return True
+ else:
+ raise AssertionError('Unknown backend type: ' + backend)
+ return False
+
def detect_tests_to_run():
all_tests = []
all_tests.append(('common', gather_tests('test cases/common'), False))
@@ -338,15 +360,15 @@ def detect_tests_to_run():
all_tests.append(('platform-windows', gather_tests('test cases/windows'), False if mesonlib.is_windows() 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(('java', gather_tests('test cases/java'), False if not mesonlib.is_osx() and shutil.which('javac') else True))
- all_tests.append(('C#', gather_tests('test cases/csharp'), False if shutil.which('mcs') else True))
- all_tests.append(('vala', gather_tests('test cases/vala'), False if shutil.which('valac') else True))
- all_tests.append(('rust', gather_tests('test cases/rust'), False if shutil.which('rustc') else True))
- all_tests.append(('d', gather_tests('test cases/d'), False if have_d_compiler() else True))
- all_tests.append(('objective c', gather_tests('test cases/objc'), False if not mesonlib.is_windows() else True))
- all_tests.append(('fortran', gather_tests('test cases/fortran'), False if shutil.which('gfortran') else True))
- all_tests.append(('swift', gather_tests('test cases/swift'), False if shutil.which('swiftc') else True))
- all_tests.append(('python3', gather_tests('test cases/python3'), False if shutil.which('python3') 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))
+ all_tests.append(('rust', gather_tests('test cases/rust'), False if using_backend('ninja') and shutil.which('rustc') else True))
+ all_tests.append(('d', gather_tests('test cases/d'), False if using_backend('ninja') and have_d_compiler() else True))
+ all_tests.append(('objective c', gather_tests('test cases/objc'), False if using_backend(('ninja', 'xcode')) and not mesonlib.is_windows() else True))
+ all_tests.append(('fortran', gather_tests('test cases/fortran'), False if using_backend('ninja') and shutil.which('gfortran') else True))
+ all_tests.append(('swift', gather_tests('test cases/swift'), False if using_backend(('ninja', 'xcode')) and shutil.which('swiftc') else True))
+ all_tests.append(('python3', gather_tests('test cases/python3'), False if using_backend('ninja') and shutil.which('python3') else True))
return all_tests
def run_tests(extra_args):
@@ -379,7 +401,7 @@ def run_tests(extra_args):
futures.append((testname, t, result))
for (testname, t, result) in futures:
result = result.result()
- if result is None:
+ if result is None or 'MESON_SKIP_TEST' in result.stdo:
print('Skipping:', t)
current_test = ET.SubElement(current_suite, 'testcase', {'name' : testname,
'classname' : name})
@@ -490,6 +512,21 @@ if __name__ == '__main__':
options = parser.parse_args()
setup_commands(options.backend)
+ # Appveyor sets the `platform` environment variable which completely messes
+ # up building with the vs2010 and vs2015 backends.
+ #
+ # Specifically, MSBuild reads the `platform` environment variable to set
+ # the configured value for the platform (Win32/x64/arm), which breaks x86
+ # builds.
+ #
+ # Appveyor setting this also breaks our 'native build arch' detection for
+ # Windows in environment.py:detect_windows_arch() by overwriting the value
+ # of `platform` set by vcvarsall.bat.
+ #
+ # While building for x86, `platform` should be unset.
+ if 'APPVEYOR' in os.environ and os.environ['arch'] == 'x86':
+ os.environ.pop('platform')
+
script_dir = os.path.split(__file__)[0]
if script_dir != '':
os.chdir(script_dir)
diff --git a/test cases/common/103 manygen/subdir/manygen.py b/test cases/common/103 manygen/subdir/manygen.py
index 4fd2f25..8449dc3 100755
--- a/test cases/common/103 manygen/subdir/manygen.py
+++ b/test cases/common/103 manygen/subdir/manygen.py
@@ -9,6 +9,7 @@ import shutil, subprocess
with open(sys.argv[1]) as f:
funcname = f.readline().strip()
outdir = sys.argv[2]
+buildtype_args = sys.argv[3]
if not os.path.isdir(outdir):
print('Outdir does not exist.')
@@ -67,7 +68,7 @@ with open(tmpc, 'w') as f:
''' % funcname)
if is_vs:
- subprocess.check_call([compiler, '/nologo', '/c', '/Fo' + outo, tmpc])
+ subprocess.check_call([compiler, '/nologo', '/c', buildtype_args, '/Fo' + outo, tmpc])
else:
subprocess.check_call([compiler, '-c', '-o', outo, tmpc])
diff --git a/test cases/common/103 manygen/subdir/meson.build b/test cases/common/103 manygen/subdir/meson.build
index 5c5d763..3036899 100644
--- a/test cases/common/103 manygen/subdir/meson.build
+++ b/test cases/common/103 manygen/subdir/meson.build
@@ -1,6 +1,17 @@
gen = find_program('manygen.py')
+buildtype = get_option('buildtype')
+buildtype_args = '-Dfooxxx' # a useless compiler argument
if meson.get_compiler('c').get_id() == 'msvc'
+ # We need our manually generated code to use the same CRT as the executable.
+ # Taken from compilers.py since build files do not have access to this.
+ if buildtype == 'debug'
+ buildtype_args = '/MDd'
+ elif buildtype == 'debugoptimized'
+ buildtype_args = '/MDd'
+ elif buildtype == 'release'
+ buildtype_args = '/MD'
+ endif
outfiles = ['gen_func.lib', 'gen_func.c', 'gen_func.h', 'gen_func.o']
else
outfiles = ['gen_func.a', 'gen_func.c', 'gen_func.h', 'gen_func.o']
@@ -9,5 +20,5 @@ endif
generated = custom_target('manygen',
output : outfiles,
input : ['funcinfo.def'],
- command : [gen, '@INPUT@', '@OUTDIR@'],
+ command : [gen, '@INPUT@', '@OUTDIR@', buildtype_args],
)
diff --git a/test cases/common/111 has header symbol/meson.build b/test cases/common/111 has header symbol/meson.build
index e0afb42..b5c865f 100644
--- a/test cases/common/111 has header symbol/meson.build
+++ b/test cases/common/111 has header symbol/meson.build
@@ -1,18 +1,32 @@
-project('has header symbol', 'c')
+project('has header symbol', 'c', 'cpp')
cc = meson.get_compiler('c')
+cpp = meson.get_compiler('cpp')
-assert (cc.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
-assert (cc.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
-assert (cc.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
-assert (cc.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
-assert (not cc.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
-assert (not cc.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
-assert (not cc.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
-assert (not cc.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+foreach comp : [cc, cpp]
+ assert (comp.has_header_symbol('stdio.h', 'int'), 'base types should always be available')
+ assert (comp.has_header_symbol('stdio.h', 'printf'), 'printf function not found')
+ assert (comp.has_header_symbol('stdio.h', 'FILE'), 'FILE structure not found')
+ assert (comp.has_header_symbol('limits.h', 'INT_MAX'), 'INT_MAX define not found')
+ assert (not comp.has_header_symbol('limits.h', 'guint64'), 'guint64 is not defined in limits.h')
+ assert (not comp.has_header_symbol('stdlib.h', 'FILE'), 'FILE structure is defined in stdio.h, not stdlib.h')
+ assert (not comp.has_header_symbol('stdlol.h', 'printf'), 'stdlol.h shouldn\'t exist')
+ assert (not comp.has_header_symbol('stdlol.h', 'int'), 'shouldn\'t be able to find "int" with invalid header')
+endforeach
# This is likely only available on Glibc, so just test for it
if cc.has_function('ppoll')
assert (not cc.has_header_symbol('poll.h', 'ppoll'), 'ppoll should not be accessible without _GNU_SOURCE')
assert (cc.has_header_symbol('poll.h', 'ppoll', prefix : '#define _GNU_SOURCE'), 'ppoll should be accessible with _GNU_SOURCE')
endif
+
+assert (cpp.has_header_symbol('iostream', 'std::iostream'), 'iostream not found in iostream.h')
+assert (cpp.has_header_symbol('vector', 'std::vector'), 'vector not found in vector.h')
+assert (not cpp.has_header_symbol('limits.h', 'std::iostream'), 'iostream should not be defined in limits.h')
+
+boost = dependency('boost', required : false)
+if boost.found()
+ assert (cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion not found')
+else
+ assert (not cpp.has_header_symbol('boost/math/quaternion.hpp', 'boost::math::quaternion', dependencies : boost), 'quaternion found?!')
+endif
diff --git a/test cases/common/113 generatorcustom/meson.build b/test cases/common/113 generatorcustom/meson.build
index 1f4cc88..472d565 100644
--- a/test cases/common/113 generatorcustom/meson.build
+++ b/test cases/common/113 generatorcustom/meson.build
@@ -1,17 +1,21 @@
project('generatorcustom', 'c')
-creator = find_program('gen.py')
-catter = find_program('catter.py')
+if meson.get_compiler('c').get_id() != 'msvc'
+ creator = find_program('gen.py')
+ catter = find_program('catter.py')
-gen = generator(creator,
- output: '@BASENAME@.h',
- arguments : ['@INPUT@', '@OUTPUT@'])
+ gen = generator(creator,
+ output: '@BASENAME@.h',
+ arguments : ['@INPUT@', '@OUTPUT@'])
-hs = gen.process('res1.txt', 'res2.txt')
+ hs = gen.process('res1.txt', 'res2.txt')
-allinone = custom_target('alltogether',
- input : hs,
- output : 'alltogether.h',
- command : [catter, '@INPUT@', '@OUTPUT@'])
+ allinone = custom_target('alltogether',
+ input : hs,
+ output : 'alltogether.h',
+ command : [catter, '@INPUT@', '@OUTPUT@'])
-executable('proggie', 'main.c', allinone)
+ executable('proggie', 'main.c', allinone)
+else
+ error('MESON_SKIP_TEST: Skipping test on VS backend; see: https://github.com/mesonbuild/meson/issues/1004')
+endif
diff --git a/test cases/common/121 skip/meson.build b/test cases/common/121 skip/meson.build
new file mode 100644
index 0000000..1adedb6
--- /dev/null
+++ b/test cases/common/121 skip/meson.build
@@ -0,0 +1,4 @@
+project('skip', 'c')
+
+error('MESON_SKIP_TEST this test is always skipped.')
+
diff --git a/test cases/common/16 configure file/config.h b/test cases/common/16 configure file/config.h
new file mode 100644
index 0000000..e85b634
--- /dev/null
+++ b/test cases/common/16 configure file/config.h
@@ -0,0 +1 @@
+#error "This file should not be included. Build dir must become before source dir in search order"
diff --git a/test cases/common/16 configure file/prog.c b/test cases/common/16 configure file/prog.c
index 718a402..89a718e 100644
--- a/test cases/common/16 configure file/prog.c
+++ b/test cases/common/16 configure file/prog.c
@@ -1,5 +1,8 @@
#include <string.h>
-#include "config.h"
+/* config.h must not be in quotes:
+ * https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
+ */
+#include <config.h>
#ifdef SHOULD_BE_UNDEF
#error "FAIL!"
diff --git a/test cases/common/16 configure file/prog2.c b/test cases/common/16 configure file/prog2.c
index be85033..a88c70f 100644
--- a/test cases/common/16 configure file/prog2.c
+++ b/test cases/common/16 configure file/prog2.c
@@ -1,4 +1,4 @@
-#include"config2.h"
+#include<config2.h>
int main(int argc, char **argv) {
return ZERO_RESULT;
diff --git a/test cases/common/33 try compile/meson.build b/test cases/common/33 try compile/meson.build
index bca82ce..09ca395 100644
--- a/test cases/common/33 try compile/meson.build
+++ b/test cases/common/33 try compile/meson.build
@@ -1,4 +1,4 @@
-project('try compile', 'c')
+project('try compile', 'c', 'cpp')
code = '''#include<stdio.h>
void func() { printf("Something.\n"); }
@@ -8,19 +8,20 @@ breakcode = '''#include<nonexisting.h>
void func() { printf("This won't work.\n"); }
'''
-compiler = meson.get_compiler('c')
-if compiler.compiles(code, name : 'should succeed') == false
- error('Compiler is fail.')
-endif
+foreach compiler : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+ if compiler.compiles(code, name : 'should succeed') == false
+ error('Compiler ' + compiler.get_id() + ' is fail.')
+ endif
-if compiler.compiles(files('valid.c'), name : 'should succeed') == false
- error('Compiler is fail.')
-endif
+ if compiler.compiles(files('valid.c'), name : 'should succeed') == false
+ error('Compiler ' + compiler.get_id() + ' is fail.')
+ endif
-if compiler.compiles(breakcode, name : 'should fail')
- error('Compiler returned true on broken code.')
-endif
+ if compiler.compiles(breakcode, name : 'should fail')
+ error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+ endif
-if compiler.compiles(files('invalid.c'), name : 'should fail')
- error('Compiler returned true on broken code.')
-endif
+ if compiler.compiles(files('invalid.c'), name : 'should fail')
+ error('Compiler ' + compiler.get_id() + ' returned true on broken code.')
+ endif
+endforeach
diff --git a/test cases/common/35 sizeof/meson.build b/test cases/common/35 sizeof/meson.build
index 4a0398b..9de5b78 100644
--- a/test cases/common/35 sizeof/meson.build
+++ b/test cases/common/35 sizeof/meson.build
@@ -1,13 +1,33 @@
-project('sizeof', 'c')
+project('sizeof', 'c', 'cpp')
+# Test with C
cc = meson.get_compiler('c')
+
intsize = cc.sizeof('int')
wcharsize = cc.sizeof('wchar_t', prefix : '#include<wchar.h>')
cd = configuration_data()
cd.set('INTSIZE', intsize)
cd.set('WCHARSIZE', wcharsize)
+cd.set('CONFIG', 'config.h')
configure_file(input : 'config.h.in', output : 'config.h', configuration : cd)
+s = configure_file(input : 'prog.c.in', output : 'prog.c', configuration : cd)
-e = executable('prog', 'prog.c')
+e = executable('prog', s)
test('sizeof test', e)
+
+# Test with C++
+cpp = meson.get_compiler('cpp')
+
+intsize = cpp.sizeof('int')
+wcharsize = cpp.sizeof('wchar_t', prefix : '#include<wchar.h>')
+
+cdpp = configuration_data()
+cdpp.set('INTSIZE', intsize)
+cdpp.set('WCHARSIZE', wcharsize)
+cdpp.set('CONFIG', 'config.hpp')
+configure_file(input : 'config.h.in', output : 'config.hpp', configuration : cdpp)
+spp = configure_file(input : 'prog.c.in', output : 'prog.cc', configuration : cdpp)
+
+epp = executable('progpp', spp)
+test('sizeof test c++', epp)
diff --git a/test cases/common/35 sizeof/prog.c b/test cases/common/35 sizeof/prog.c.in
index 9164c18..85b1229 100644
--- a/test cases/common/35 sizeof/prog.c
+++ b/test cases/common/35 sizeof/prog.c.in
@@ -1,6 +1,6 @@
-#include"config.h"
-#include<stdio.h>
-#include<wchar.h>
+#include "@CONFIG@"
+#include <stdio.h>
+#include <wchar.h>
int main(int argc, char **argv) {
if(INTSIZE != sizeof(int)) {
diff --git a/test cases/common/37 has header/meson.build b/test cases/common/37 has header/meson.build
index bbfce6d..ce6e71a 100644
--- a/test cases/common/37 has header/meson.build
+++ b/test cases/common/37 has header/meson.build
@@ -1,11 +1,11 @@
-project('has header', 'c')
+project('has header', 'c', 'cpp')
-cc = meson.get_compiler('c')
+foreach comp : [meson.get_compiler('c'), meson.get_compiler('cpp')]
+ if comp.has_header('stdio.h') == false
+ error('Stdio missing.')
+ endif
-if cc.has_header('stdio.h') == false
- error('Stdio missing.')
-endif
-
-if cc.has_header('ouagadougou.h')
- error('Found non-existant header.')
-endif
+ if comp.has_header('ouagadougou.h')
+ error('Found non-existant header.')
+ endif
+endforeach
diff --git a/test cases/common/39 tryrun/meson.build b/test cases/common/39 tryrun/meson.build
index f5d07ab..c64446f 100644
--- a/test cases/common/39 tryrun/meson.build
+++ b/test cases/common/39 tryrun/meson.build
@@ -1,14 +1,14 @@
-project('tryrun', 'c')
+project('tryrun', 'c', 'cpp')
# Complex to exercise all code paths.
if meson.is_cross_build()
if meson.has_exe_wrapper()
- cc = meson.get_compiler('c', native : false)
+ compilers = [meson.get_compiler('c', native : false), meson.get_compiler('cpp', native : false)]
else
- cc = meson.get_compiler('c', native : true)
+ compilers = [meson.get_compiler('c', native : true), meson.get_compiler('cpp', native : true)]
endif
else
- cc = meson.get_compiler('c')
+ compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
endif
ok_code = '''#include<stdio.h>
@@ -32,45 +32,47 @@ INPUTS = [
['File', files('ok.c'), files('error.c'), files('no_compile.c')],
]
-foreach input : INPUTS
- type = input[0]
- ok = cc.run(input[1], name : type + ' should succeed')
- err = cc.run(input[2], name : type + ' should fail')
- noc = cc.run(input[3], name : type + ' does not compile')
+foreach cc : compilers
+ foreach input : INPUTS
+ type = input[0]
+ ok = cc.run(input[1], name : type + ' should succeed')
+ err = cc.run(input[2], name : type + ' should fail')
+ noc = cc.run(input[3], name : type + ' does not compile')
- if noc.compiled()
- error(type + ' compilation fail test failed.')
- else
- message(type + ' fail detected properly.')
- endif
+ if noc.compiled()
+ error(type + ' compilation fail test failed.')
+ else
+ message(type + ' fail detected properly.')
+ endif
- if ok.compiled()
- message(type + ' compilation worked.')
- else
- error(type + ' compilation did not work.')
- endif
+ if ok.compiled()
+ message(type + ' compilation worked.')
+ else
+ error(type + ' compilation did not work.')
+ endif
- if ok.returncode() == 0
- message(type + ' return code ok.')
- else
- error(type + ' return code fail')
- endif
+ if ok.returncode() == 0
+ message(type + ' return code ok.')
+ else
+ error(type + ' return code fail')
+ endif
- if err.returncode() == 1
- message(type + ' bad return code ok.')
- else
- error(type + ' bad return code fail.')
- endif
+ if err.returncode() == 1
+ message(type + ' bad return code ok.')
+ else
+ error(type + ' bad return code fail.')
+ endif
- if ok.stdout().strip() == 'stdout'
- message(type + ' stdout ok.')
- else
- message(type + ' bad stdout.')
- endif
+ if ok.stdout().strip() == 'stdout'
+ message(type + ' stdout ok.')
+ else
+ message(type + ' bad stdout.')
+ endif
- if ok.stderr().strip() == 'stderr'
- message(type + ' stderr ok.')
- else
- message(type + ' bad stderr.')
- endif
+ if ok.stderr().strip() == 'stderr'
+ message(type + ' stderr ok.')
+ else
+ message(type + ' bad stderr.')
+ endif
+ endforeach
endforeach
diff --git a/test cases/common/43 has function/meson.build b/test cases/common/43 has function/meson.build
index 00ca640..61f96e1 100644
--- a/test cases/common/43 has function/meson.build
+++ b/test cases/common/43 has function/meson.build
@@ -1,41 +1,43 @@
-project('has function', 'c')
+project('has function', 'c', 'cpp')
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
-if not cc.has_function('printf', prefix : '#include<stdio.h>')
- error('"printf" function not found (should always exist).')
-endif
+foreach cc : compilers
+ if not cc.has_function('printf', prefix : '#include<stdio.h>')
+ error('"printf" function not found (should always exist).')
+ endif
-# Should also be able to detect it without specifying the header
-# We check for a different function here to make sure the result is
-# not taken from a cache (ie. the check above)
-# On MSVC fprintf is defined as an inline function in the header, so it cannot
-# be found without the include.
-if cc.get_id() != 'msvc'
- assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).')
-else
- assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).')
-endif
+ # Should also be able to detect it without specifying the header
+ # We check for a different function here to make sure the result is
+ # not taken from a cache (ie. the check above)
+ # On MSVC fprintf is defined as an inline function in the header, so it cannot
+ # be found without the include.
+ if cc.get_id() != 'msvc'
+ assert(cc.has_function('fprintf'), '"fprintf" function not found without include (on !msvc).')
+ else
+ assert(cc.has_function('fprintf', prefix : '#include <stdio.h>'), '"fprintf" function not found with include (on msvc).')
+ endif
-if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
- error('Found non-existent function "hfkerhisadf".')
-endif
+ if cc.has_function('hfkerhisadf', prefix : '#include<stdio.h>')
+ error('Found non-existent function "hfkerhisadf".')
+ endif
-# With glibc on Linux lchmod is a stub that will always return an error,
-# we want to detect that and declare that the function is not available.
-# We can't check for the C library used here of course, but if it's not
-# implemented in glibc it's probably not implemented in any other 'slimmer'
-# C library variants either, so the check should be safe either way hopefully.
-if host_machine.system() == 'linux' and cc.get_id() == 'gcc'
- assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect "poll" when defined by a header')
- assert (not cc.has_function('lchmod', prefix : '''#include <sys/stat.h>
- #include <unistd.h>'''), '"lchmod" check should have failed')
-endif
+ # With glibc on Linux lchmod is a stub that will always return an error,
+ # we want to detect that and declare that the function is not available.
+ # We can't check for the C library used here of course, but if it's not
+ # implemented in glibc it's probably not implemented in any other 'slimmer'
+ # C library variants either, so the check should be safe either way hopefully.
+ if host_machine.system() == 'linux' and cc.get_id() == 'gcc'
+ assert (cc.has_function('poll', prefix : '#include <poll.h>'), 'couldn\'t detect "poll" when defined by a header')
+ assert (not cc.has_function('lchmod', prefix : '''#include <sys/stat.h>
+ #include <unistd.h>'''), '"lchmod" check should have failed')
+ endif
-# For some functions one needs to define _GNU_SOURCE before including the
-# right headers to get them picked up. Make sure we can detect these functions
-# as well without any prefix
-if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
- # We assume that if recvmmsg exists sendmmsg does too
- assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
-endif
+ # For some functions one needs to define _GNU_SOURCE before including the
+ # right headers to get them picked up. Make sure we can detect these functions
+ # as well without any prefix
+ if cc.has_header_symbol('sys/socket.h', 'recvmmsg', prefix : '#define _GNU_SOURCE')
+ # We assume that if recvmmsg exists sendmmsg does too
+ assert (cc.has_function('sendmmsg'), 'Failed to detect function "sendmmsg" (should always exist).')
+ endif
+endforeach
diff --git a/test cases/common/44 has member/meson.build b/test cases/common/44 has member/meson.build
index e60aeb3..4e61956 100644
--- a/test cases/common/44 has member/meson.build
+++ b/test cases/common/44 has member/meson.build
@@ -1,19 +1,21 @@
-project('has member', 'c')
+project('has member', 'c', 'cpp')
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
-if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
- error('Did not detect member of "struct tm" that exists: "tm_sec"')
-endif
+foreach cc : compilers
+ if not cc.has_member('struct tm', 'tm_sec', prefix : '#include<time.h>')
+ error('Did not detect member of "struct tm" that exists: "tm_sec"')
+ endif
-if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
- error('Not existing member "tm_nonexistent" found.')
-endif
+ if cc.has_member('struct tm', 'tm_nonexistent', prefix : '#include<time.h>')
+ error('Not existing member "tm_nonexistent" found.')
+ endif
-if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
- error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
-endif
+ if not cc.has_members('struct tm', 'tm_sec', 'tm_min', prefix : '#include<time.h>')
+ error('Did not detect members of "struct tm" that exist: "tm_sec" "tm_min"')
+ endif
-if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
- error('Not existing member "tm_nonexistent2" found.')
-endif
+ if cc.has_members('struct tm', 'tm_sec', 'tm_nonexistent2', prefix : '#include<time.h>')
+ error('Not existing member "tm_nonexistent2" found.')
+ endif
+endforeach
diff --git a/test cases/common/45 alignment/meson.build b/test cases/common/45 alignment/meson.build
index 2ec3f89..a9bd65b 100644
--- a/test cases/common/45 alignment/meson.build
+++ b/test cases/common/45 alignment/meson.build
@@ -1,29 +1,31 @@
-project('alignment', 'c')
+project('alignment', 'c', 'cpp')
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
-# These tests should return the same value on all
-# platforms. If (and when) they don't, fix 'em up.
-if cc.alignment('char') != 1
- error('Alignment of char misdetected.')
-endif
+foreach cc : compilers
+ # These tests should return the same value on all
+ # platforms. If (and when) they don't, fix 'em up.
+ if cc.alignment('char') != 1
+ error('Alignment of char misdetected.')
+ endif
-ptr_size = cc.sizeof('void*')
-dbl_alignment = cc.alignment('double')
+ ptr_size = cc.sizeof('void*')
+ dbl_alignment = cc.alignment('double')
-# These tests are not thorough. Doing this properly
-# would take a lot of work because it is strongly
-# platform and compiler dependent. So just check
-# that they produce something fairly sane.
+ # These tests are not thorough. Doing this properly
+ # would take a lot of work because it is strongly
+ # platform and compiler dependent. So just check
+ # that they produce something fairly sane.
-if ptr_size == 8 or ptr_size == 4
- message('Size of ptr ok.')
-else
- error('Size of ptr misdetected.')
-endif
+ if ptr_size == 8 or ptr_size == 4
+ message('Size of ptr ok.')
+ else
+ error('Size of ptr misdetected.')
+ endif
-if dbl_alignment == 8 or dbl_alignment == 4
- message('Alignment of double ok.')
-else
- error('Alignment of double misdetected.')
-endif
+ if dbl_alignment == 8 or dbl_alignment == 4
+ message('Alignment of double ok.')
+ else
+ error('Alignment of double misdetected.')
+ endif
+endforeach
diff --git a/test cases/common/51 pkgconfig-gen/meson.build b/test cases/common/51 pkgconfig-gen/meson.build
index fa9439c..0933238 100644
--- a/test cases/common/51 pkgconfig-gen/meson.build
+++ b/test cases/common/51 pkgconfig-gen/meson.build
@@ -19,7 +19,7 @@ pkgg.generate(
)
pkgconfig = find_program('pkg-config', required: false)
-if pkgconfig.found()
+if pkgconfig.found() and build_machine.system() != 'windows'
test('pkgconfig-validation', pkgconfig,
args: ['--validate', 'simple'],
env: ['PKG_CONFIG_PATH=' + meson.current_build_dir() + '/meson-private' ],
diff --git a/test cases/common/56 custom target/meson.build b/test cases/common/56 custom target/meson.build
index e216bae..feaa762 100644
--- a/test cases/common/56 custom target/meson.build
+++ b/test cases/common/56 custom target/meson.build
@@ -9,7 +9,7 @@ comp = '@0@/@1@'.format(meson.current_source_dir(), 'my_compiler.py')
mytarget = custom_target('bindat',
output : 'data.dat',
input : 'data_source.txt',
-command : [python, comp, '@INPUT@', '@OUTPUT@'],
+command : [python, comp, '--input=@INPUT@', '--output=@OUTPUT@'],
install : true,
install_dir : 'subdir'
)
diff --git a/test cases/common/56 custom target/my_compiler.py b/test cases/common/56 custom target/my_compiler.py
index d99029b..4ba2da6 100755
--- a/test cases/common/56 custom target/my_compiler.py
+++ b/test cases/common/56 custom target/my_compiler.py
@@ -3,13 +3,14 @@
import sys
if __name__ == '__main__':
- if len(sys.argv) != 3:
- print(sys.argv[0], 'input_file output_file')
+ if len(sys.argv) != 3 or not sys.argv[1].startswith('--input') or \
+ not sys.argv[2].startswith('--output'):
+ print(sys.argv[0], '--input=input_file --output=output_file')
sys.exit(1)
- with open(sys.argv[1]) as f:
+ with open(sys.argv[1].split('=')[1]) as f:
ifile = f.read()
if ifile != 'This is a text only input file.\n':
print('Malformed input')
sys.exit(1)
- with open(sys.argv[2], 'w') as ofile:
+ with open(sys.argv[2].split('=')[1], 'w') as ofile:
ofile.write('This is a binary output file.\n')
diff --git a/test cases/common/62 exe static shared/stat.c b/test cases/common/62 exe static shared/stat.c
index 4eceb30..680ed92 100644
--- a/test cases/common/62 exe static shared/stat.c
+++ b/test cases/common/62 exe static shared/stat.c
@@ -1,5 +1,7 @@
+#include "subdir/exports.h"
+
int shlibfunc();
-int statlibfunc() {
+int DLL_PUBLIC statlibfunc() {
return shlibfunc();
}
diff --git a/test cases/common/83 has type/meson.build b/test cases/common/83 has type/meson.build
index 002f150..de8dbc8 100644
--- a/test cases/common/83 has type/meson.build
+++ b/test cases/common/83 has type/meson.build
@@ -1,11 +1,13 @@
-project('has type', 'c')
+project('has type', 'c', 'cpp')
-cc = meson.get_compiler('c')
+compilers = [meson.get_compiler('c'), meson.get_compiler('cpp')]
-if not cc.has_type('time_t', prefix : '#include<time.h>')
- error('Did not detect type that exists.')
-endif
+foreach cc : compilers
+ if not cc.has_type('time_t', prefix : '#include<time.h>')
+ error('Did not detect type that exists.')
+ endif
-if cc.has_type('no_time_t', prefix : '#include<time.h>')
- error('Not existing type found.')
-endif
+ if cc.has_type('no_time_t', prefix : '#include<time.h>')
+ error('Not existing type found.')
+ endif
+endforeach
diff --git a/test cases/frameworks/10 gtk-doc/meson.build b/test cases/frameworks/10 gtk-doc/meson.build
index c6881ab..95eeefa 100644
--- a/test cases/frameworks/10 gtk-doc/meson.build
+++ b/test cases/frameworks/10 gtk-doc/meson.build
@@ -8,4 +8,6 @@ inc = include_directories('include')
# We have to disable this test until this bug fix has landed to
# distros https://bugzilla.gnome.org/show_bug.cgi?id=753145
-# subdir('doc')
+error('MESON_SKIP_TEST can not enable gtk-doc test until upstream fixes have landed.')
+
+subdir('doc')
diff --git a/test cases/python3/3 cython/meson.build b/test cases/python3/3 cython/meson.build
index cd245c7..8729640 100644
--- a/test cases/python3/3 cython/meson.build
+++ b/test cases/python3/3 cython/meson.build
@@ -13,5 +13,5 @@ if cython.found()
env : ['PYTHONPATH=' + pydir]
)
else
- message('Cython not found, skipping test.')
+ error('MESON_SKIP_TEST: Cython not found, skipping test.')
endif