This doesn't touch everything as it's just based on the python3 module
tests, ported to the python module. It's still better than the one very
basic test in the unit test module.
Deal with clang-cl doing the sane (but different to MSVC) thing, of
generating an empty import library, rather than silently ignoring
/IMPLIB when there are no exports.
Extend platform_fix_name() to handle this case
We avoid using library(version:), so we don't have to teach
platform_fix_name() all the platform details of versioned shared library
naming. Hopefully that's exercised by platform-specific tests...
Use the compiler detector in detect_system_compiler(), rather than trying to
guess based on what it is the PATH (which could utterly fail e.g when CC env
var is set)
Note that this detection is only used by platform_fix_name() to interpret
installed_files.txt
This has the adventage that "meson --help" shows a list of all commands,
making them discoverable. This also reduce the manual parsing of
arguments to the strict minimum needed for backward compatibility.
As per commit 2340fd3, unexpected installed files are not reported anymore when
using compilers other than 'cl', this regression was introduced in the attempt
of not reporting extra .pdb files, but actually caused any non extra .pdb file
in other compilers to be ignored.
Fix boolean test, by reporting any extra file a part '.pdb' ones under non 'cl'
compiler, while anyone under 'cl'.
This is a simple test case, checking for installed_files.txt, which just
makes sure the syntax is accepted.
Manual tests confirmed the permissions were set correctly.
A follow up commit adds a unit test based on this directory.
Instead of using fragile guessing to figure out how to invoke meson,
set the value when meson is run. Also rework how we pass of
meson_script_launcher to regenchecker.py -- it wasn't even being used
With this change, we only need to guess the meson path when running
the tests, and in that case:
1. If MESON_EXE is set in the env, we know how to run meson
for project tests.
2. MESON_EXE is not set, which means we run the configure in-process
for project tests and need to guess what meson to run, so either
- meson.py is found next to run_tests.py, or
- meson, meson.py, or meson.exe is in PATH
Otherwise, you can invoke meson in the following ways:
1. meson is installed, and mesonbuild is available in PYTHONPATH:
- meson, meson.py, meson.exe from PATH
- python3 -m mesonbuild.mesonmain
- python3 /path/to/meson.py
- meson is a shell wrapper to meson.real
2. meson is not installed, and is run from git:
- Absolute path to meson.py
- Relative path to meson.py
- Symlink to meson.py
All these are tested in test_meson_commands.py, except meson.exe since
that involves building the meson msi and installing it.
There are cases when it is useful to wrap the main meson executable with
a script that sets up environment variables, passes --cross-file, etc.
For example, in a Yocto SDK, we need to point to the right meson.cross
so that everything "just works", and we need to alter CC, CXX, etc. In
such cases, it can happen that the "meson" found in the path is actually
a wrapper script that invokes the real meson, which may be in another
location (e.g. "meson.real" or similar).
Currently, in such a situation, meson gets confused because it tries to
invoke itself using the "meson" executable (which points to the wrapper
script) instead of the actual meson (which may be called "meson.real" or
similar). In fact, the wrapper script is not necessarily even Python, so
the whole thing fails.
Fix this by using Python imports to directly find mesonmain.py instead
of trying to detect it heuristically. In addition to fixing the wrapper
issue, this should make the detection logic much more robust.
I sincerely hope sufficient amounts of goats have now been sacrificed
at the altar of Debian Locales so things will actually work and I
can get to sleep.
Enable 'test cases/frameworks/10 gtk-doc' if gtkdoc version is 1.26 or
later.
Old versions of gtkdoc-scan also output the version to stdout rather than
stderr, so be sure to handle that...
PR #2527 suggests "making failing tests more strict about failing
gracefully".
To achive this, make meson exit with distinct exit statuses for meson errors
and python exceptions, and check the exit status is as expected for failing
tests.
I can't see how to write a test for this, within the current framework.
You can test this change by reverting the fix (but not the test) from commit
1a159db8 and verifying that 'test cases/failing/66 string as link target'
fails.
Instead of looking for an objc compiler. Fixes objc++ tests on
DragonFlyBSD (which has an objc but not an objc++ compiler)
Really though, the objc and objc++ tests need to be untangled so that
the objc tests can run even if an objc++ compiler is unavilable.
g-ir-scanner --no-libtool needed some fixes similar to [1] for Cygwin, as
well. Now that is done, it's possible to make these tests run and pass on
Cygwin.
[1] https://bugzilla.gnome.org/show_bug.cgi?id=781525
Also, use '^' to escape newlines in appveyor-install.bat to avoid an
absurdly long line, remove some unnecessary quotation, and alphabetically
sort packages
Also, define the _XOPEN_SOURCE feature test macro in the boost test to avoid
'not declared in this scope' warnings for pthread_rwlock_init(), etc.
Add a boolean 'implib' kwarg to executable(). If true, it is permitted to
use the returned build target object in link_with:
On platforms where this makes sense (e.g. Windows), an implib is generated
for the executable and used when linking. Otherwise, it has no effect.
(Rather than checking if it is a StaticLibrary or SharedLibary, BuildTarget
subclasses gain the is_linkable_target method to test if they can appear in
link_with:)
Also install any executable implib in a similar way to a shared library
implib, i.e. placing the implib in the appropriate place
Add tests of:
- a shared_module containing a reference to a symbol which is known (at link
time) to be provided by the executable
- trying to link with non-implib executables (should fail)
- installing the implib
(This last one needs a little enhancement of the installed file checking as
this is the first install test we have which needs to work with either
MSVC-style or GCC-style implib filenames)
Boost tests are disabled on Windows for now because the detection
is actually completely broken. Once that's fixed (after the release)
we can enable it again.
It is not feasible to test all failure modes by creating projects in
`test cases/failing` that would be an explosion of files, and that
mechanism is too coarse anyway. We have no way to ensure that the
expected error is being raised.
See FailureTests.test_dependency for an example.
This actually caught a cached-dependency related bug for me that the
test-time regen did not. I also increased the ninja wait time to
1 second because that's actually how long you need to sleep to be
guaranteed that a change will be detected.
Must poke upstream about https://github.com/ninja-build/ninja/issues/371
Meson has a common pattern of using 'if len(foo) == 0:' or
'if len(foo) != 0:', however, this is a common anti-pattern in python.
Instead tests for emptiness/non-emptiness should be done with a simple
'if foo:' or 'if not foo:'
Consider the following:
>>> import timeit
>>> timeit.timeit('if len([]) == 0: pass')
0.10730923599840025
>>> timeit.timeit('if not []: pass')
0.030033907998586074
>>> timeit.timeit('if len(['a', 'b', 'c', 'd']) == 0: pass')
0.1154778649979562
>>> timeit.timeit("if not ['a', 'b', 'c', 'd']: pass")
0.08259823200205574
>>> timeit.timeit('if len("") == 0: pass')
0.089759664999292
>>> timeit.timeit('if not "": pass')
0.02340641999762738
>>> timeit.timeit('if len("foo") == 0: pass')
0.08848102600313723
>>> timeit.timeit('if not "foo": pass')
0.04032287199879647
And for the one additional case of 'if len(foo.strip()) == 0', which can
be replaced with 'if not foo.isspace()'
>>> timeit.timeit('if len(" ".strip()) == 0: pass')
0.15294511600222904
>>> timeit.timeit('if " ".isspace(): pass')
0.09413968399894657
>>> timeit.timeit('if len(" abc".strip()) == 0: pass')
0.2023209120015963
>>> timeit.timeit('if " abc".isspace(): pass')
0.09571301700270851
In other words, it's always a win to not use len(), when you don't
actually want to check the length.
Also sets more groundwork for running unit tests with backends other
that Ninja.
Transferring global state to executors is totally broken in Python 3.4
so just serialize all the commands.
And use generic build/clean/test/install commands in the unit tests,
just like project tests. This sets the groundwork for running the unit
tests with all backends.
Added and tested on MSYS2/MinGW which doesn't implement the required
semaphore locks in the multiprocessing module:
Traceback (most recent call last):
File "C:/msys64/mingw64/lib/python3.5\multiprocessing\synchronize.py", line 29, in <module>
from _multiprocessing import SemLock, sem_unlink
ImportError: cannot import name 'sem_unlink'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "run_project_tests.py", line 560, in <module>
(passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.extra_args)
File "run_project_tests.py", line 406, in run_tests
executor = conc.ProcessPoolExecutor(max_workers=num_workers)
File "F:/msys64/mingw64/lib/python3.5\concurrent\futures\process.py", line 390, in __init__
EXTRA_QUEUED_CALLS)
File "F:/msys64/mingw64/lib/python3.5\multiprocessing\context.py", line 101, in Queue
return Queue(maxsize, ctx=self.get_context())
File "F:/msys64/mingw64/lib/python3.5\multiprocessing\queues.py", line 42, in __init__
self._rlock = ctx.Lock()
File "F:/msys64/mingw64/lib/python3.5\multiprocessing\context.py", line 65, in Lock
from .synchronize import Lock
File "F:/msys64/mingw64/lib/python3.5\multiprocessing\synchronize.py", line 34, in <module>
" function, see issue 3770.")
ImportError: This platform lacks a functioning sem_open implementation, therefore, the required synchronization primitives needed will not function, see issue 3770.
See also:
https://bugs.python.org/issue3770https://github.com/mesonbuild/meson/issues/1323
According to 3770, the same problem also exists on OpenBSD, so this
will potentially also be useful there.
Back in November when this broke, we didn't notice because our tests
are run in-process, so we don't check that `msbuild RUN_TESTS.vcxproj`
and `ninja test` actually work.
Now we do.
This change helps us run on older distros such as Ubuntu LTS which is
very lazy in updating even non-core and stable packages such as Ninja.
Ninja 1.6.x is only needed for running the tests.
It seems on Windows, deleting in a loop can cause a race where the
following error is raised:
Traceback (most recent call last):
File "run_project_tests.py", line 550, in <module>
(passing_tests, failing_tests, skipped_tests) = run_tests(all_tests, 'meson-test-run', options.extra_args)
File "run_project_tests.py", line 416, in run_tests
result = result.result()
File "C:\python34-x64\lib\concurrent\futures\_base.py", line 402, in result
return self.__get_result()
File "C:\python34-x64\lib\concurrent\futures\_base.py", line 354, in __get_result
raise self._exception
ValueError: I/O operation on closed file.
https://ci.appveyor.com/project/jpakkane/meson/build/1.0.1559/job/vsek754eu000kg3e
There is never any reason to not do this since this script is supposed
to be run by developers and testers who are concerned with the details
of the problems.
It also helps with intermittent or hard-to-reproduce errors.
We have no test coverage for regeneration at all, which is why issues
like #1246 slide by without us noticing. With this, we will run a regen
on every test during `ninja test` after it has been compiled. This will
not affect test times too much since the regen will not rebuild anything
at all since there have been no source changes.
There is no way to do this in the .appveyor.yml file since it seems that
the appveyor environment is forcibly written after each cmd command that
is run.