diff options
-rw-r--r-- | .appveyor.yml | 8 | ||||
-rw-r--r-- | .travis.yml | 8 | ||||
-rw-r--r-- | ci/appveyor-install.bat | 4 | ||||
-rw-r--r-- | docs/markdown/Users.md | 9 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 11 | ||||
-rw-r--r-- | mesonbuild/environment.py | 10 | ||||
-rw-r--r-- | mesonbuild/scripts/depfixer.py | 5 | ||||
-rwxr-xr-x | mesontest.py | 106 | ||||
-rwxr-xr-x | run_project_tests.py | 9 | ||||
-rwxr-xr-x | run_tests.py | 6 |
10 files changed, 89 insertions, 87 deletions
diff --git a/.appveyor.yml b/.appveyor.yml index a78a328..6551445 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -49,15 +49,17 @@ branches: only: - master +skip_commits: + files: + - docs/**/* + install: - cmd: set "ORIG_PATH=%PATH%" # Boost 1.56.0: https://www.appveyor.com/docs/build-environment/#boost #- cmd: set "BOOST_ROOT=C:\Libraries\boost" - # Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219 - - cmd: set "MESON_FIXED_NINJA=1" - - ps: (new-object net.webclient).DownloadFile('http://nirbheek.in/files/binaries/ninja/win32/ninja.exe', 'C:\projects\meson\ninja.exe') # 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://www.dropbox.com/s/bbzvepq85hv47x1/ninja.exe?dl=1', 'C:\projects\meson\ninja.exe') - cmd: if %arch%==x86 (set MESON_PYTHON_PATH=C:\python34) else (set MESON_PYTHON_PATH=C:\python34-x64) # Set paths and config for each build type. diff --git a/.travis.yml b/.travis.yml index 662b769..724f9ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -30,9 +30,7 @@ matrix: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install python3; fi - # Use a Ninja with QuLogic's patch: https://github.com/ninja-build/ninja/issues/1219 - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir -p $HOME/tools; curl -L http://nirbheek.in/files/binaries/ninja/macos/ninja -o $HOME/tools/ninja; chmod +x $HOME/tools/ninja; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja python3; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull jpakkane/mesonci:zesty; fi - pip3 install codecov - mkdir .coverage @@ -49,9 +47,9 @@ script: ci_env=`bash <(curl -s https://codecov.io/env)` docker run $ci_env -v ${PWD}/.coverage:/root/.coverage \ withgit \ - /bin/sh -c "cd /root && mkdir -p tools; wget -c http://nirbheek.in/files/binaries/ninja/linux-amd64/ninja -O /root/tools/ninja; chmod +x /root/tools/ninja; CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX PATH=/root/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --cov -- $MESON_ARGS && chmod -R a+rwX .coverage" + /bin/sh -c "cd /root && CC=$CC CXX=$CXX OBJC=$CC OBJCXX=$CXX ./run_tests.py --cov -- $MESON_ARGS && chmod -R a+rwX .coverage" fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) OBJC=$CC OBJCXX=$CXX PATH=$HOME/tools:$PATH MESON_FIXED_NINJA=1 ./run_tests.py --cov --backend=ninja -- $MESON_ARGS ; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then SDKROOT=$(xcodebuild -version -sdk macosx Path) OBJC=$CC OBJCXX=$CXX ./run_tests.py --cov --backend=ninja -- $MESON_ARGS ; fi after_success: - coverage3 combine diff --git a/ci/appveyor-install.bat b/ci/appveyor-install.bat index 9eddeac..becc80a 100644 --- a/ci/appveyor-install.bat +++ b/ci/appveyor-install.bat @@ -1,7 +1,5 @@ set CACHE=C:\cache set CYGWIN_MIRROR="http://cygwin.mirror.constant.com" -set CYGWIN_ADDITIONAL_REPO="http://www.dronecode.org.uk/cygwin/" -set CYGWIN_ADDITIONAL_REPO_KEY="http://www.dronecode.org.uk/cygwin/dronecode.gpg" 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 @@ -9,5 +7,5 @@ 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%" -s "%CYGWIN_ADDITIONAL_REPO%" -K "%CYGWIN_ADDITIONAL_REPO_KEY%" -l "%CACHE%" -g -P "ninja,gcc-objc,gcc-objc++,libglib2.0-devel,zlib-devel,python3-pip" +%CYGWIN_ROOT%\%SETUP% -qnNdO -R "%CYGWIN_ROOT%" -s "%CYGWIN_MIRROR%" -l "%CACHE%" -g -P "ninja,gcc-objc,gcc-objc++,libglib2.0-devel,zlib-devel,python3-pip" echo Install done diff --git a/docs/markdown/Users.md b/docs/markdown/Users.md index 8cfaf94..6c6a368 100644 --- a/docs/markdown/Users.md +++ b/docs/markdown/Users.md @@ -8,9 +8,11 @@ If you have a project that uses Meson that you want to add to this list, let us - [AQEMU](https://github.com/tobimensch/aqemu), a Qt GUI for QEMU virtual machines, since version 0.9.3 - [Arduino sample project](https://github.com/jpakkane/mesonarduino) + - [Budgie Desktop](https://github.com/budgie-desktop/budgie-desktop), a desktop environment built on GNOME technologies + - [casync](https://github.com/systemd/casync), - [Emeus](https://github.com/ebassi/emeus), Constraint based layout manager for GTK+ - [Frida](https://www.frida.re/), a dynamic binary instrumentation toolkit - - [GLib](https://github.com/centricular/glib/), cross-platform C library used by GTK+ (not merged yet) + - [GLib](https://git.gnome.org/browse/glib/), cross-platform C library used by GTK+ and GStreamer (not the default yet) - [Gnome Builder](https://git.gnome.org/browse/gnome-builder/), an IDE for the Gnome platform - [Gnome MPV](https://github.com/gnome-mpv/gnome-mpv), Gnome frontend to the mpv video player - [Gnome Recipes](https://github.com/matthiasclasen/gr), application for cooking recipes @@ -19,8 +21,9 @@ If you have a project that uses Meson that you want to add to this list, let us - [Graphene](https://ebassi.github.io/graphene/), a thin type library for graphics - [Grilo](https://mail.gnome.org/archives/grilo-list/2017-February/msg00000.html) and [Grilo plugins](https://git.gnome.org/browse/grilo-plugins/commit/?id=ea047c4fb63e90268eb795ed91a09a2be5068a4c), the Grilo multimedia framework - [GStreamer](https://cgit.freedesktop.org/gstreamer/gstreamer/), multimedia framework (not the default yet) - - [GTK+](https://git.gnome.org/browse/gtk+/log/?h=wip/meson), the multi-platform toolkit used by GNOME (not merged yet) + - [GTK+](https://git.gnome.org/browse/gtk+/), the multi-platform toolkit used by GNOME (not the default yet) - [GtkDApp](https://gitlab.com/csoriano/GtkDApp), an application template for developing Flatpak apps with Gtk+ and D + - [HexChat](https://github.com/hexchat/hexchat), a cross-platform IRC client in C - [Json-glib](https://git.gnome.org/browse/json-glib), GLib-based JSON manipulation library - [Libepoxy](https://github.com/anholt/libepoxy/), a library for handling OpenGL function pointer management - [Libgit2-glib](https://git.gnome.org/browse/libgit2-glib/), a GLib wrapper for libgit2 @@ -28,6 +31,8 @@ If you have a project that uses Meson that you want to add to this list, let us - [Lightdm-Webkit2-Greeter](https://github.com/Antergos/lightdm-webkit2-greeter) - [Kiwix libraries](https://github.com/kiwix/kiwix-lib) - [Nautilus](https://git.gnome.org/browse/nautilus/commit/?id=ed5652c89ac0654df2e82b54b00b27d51c825465) the Gnome file manager + - [Orc](http://cgit.freedesktop.org/gstreamer/orc/), the Optimized Inner Loop Runtime Compiler (not the default yet) + - [Pango](https://git.gnome.org/browse/pango/), an Internationalized text layout and rendering library (not the default yet) - [Parzip](https://github.com/jpakkane/parzip), a multithreaded reimplementation of Zip - [Pitivi](http://pitivi.org/), a nonlinear video editor - [Polari](https://git.gnome.org/browse/polari), an IRC client diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index ece4e8b..7f974ee 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -177,9 +177,6 @@ int dummy; def generate(self, interp): self.interpreter = interp - self.ninja_command = environment.detect_ninja(log=True) - if self.ninja_command is None: - raise MesonException('Could not detect Ninja v1.5 or newer') outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename) tempfilename = outfilename + '~' with open(tempfilename, 'w') as outfile: @@ -213,9 +210,10 @@ int dummy; # http://clang.llvm.org/docs/JSONCompilationDatabase.html def generate_compdb(self): + ninja_exe = environment.detect_ninja() native_compilers = ['%s_COMPILER' % i for i in self.build.compilers] cross_compilers = ['%s_CROSS_COMPILER' % i for i in self.build.cross_compilers] - ninja_compdb = [self.ninja_command, '-t', 'compdb'] + native_compilers + cross_compilers + ninja_compdb = [ninja_exe, '-t', 'compdb'] + native_compilers + cross_compilers builddir = self.environment.get_build_dir() try: jsondb = subprocess.check_output(ninja_compdb, cwd=builddir) @@ -2511,8 +2509,11 @@ rule FORTRAN_DEP_HACK default = 'default all\n\n' outfile.write(default) + ninja_command = environment.detect_ninja() + if ninja_command is None: + raise MesonException('Could not detect Ninja v1.6 or newer') elem = NinjaBuildElement(self.all_outputs, 'clean', 'CUSTOM_COMMAND', 'PHONY') - elem.add_item('COMMAND', [self.ninja_command, '-t', 'clean']) + elem.add_item('COMMAND', [ninja_command, '-t', 'clean']) elem.add_item('description', 'Cleaning.') # If we have custom targets in this project, add all their outputs to diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index 29ff19e..dd9f56e 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -89,19 +89,16 @@ def find_coverage_tools(): genhtml_exe = None return gcovr_exe, lcov_exe, genhtml_exe -def detect_ninja(version='1.5', log=False): +def detect_ninja(version='1.5'): for n in ['ninja', 'ninja-build']: try: p, found = Popen_safe([n, '--version'])[0:2] except (FileNotFoundError, PermissionError): # Doesn't exist in PATH or isn't executable continue - found = found.strip() # Perhaps we should add a way for the caller to know the failure mode # (not found or too old) if p.returncode == 0 and mesonlib.version_compare(found, '>=' + version): - if log: - mlog.log('Found ninja-{} at {}'.format(found, shlex.quote(shutil.which(n)))) return n def detect_native_windows_arch(): @@ -916,9 +913,8 @@ class CrossBuildInfo: def parse_datafile(self, filename): config = configparser.ConfigParser() try: - f = open(filename, 'r') - config.read_file(f, filename) - f.close() + with open(filename, 'r') as f: + config.read_file(f, filename) except FileNotFoundError: raise EnvironmentException('File not found: %s.' % filename) # This is a bit hackish at the moment. diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py index 1528ddb..ee63147 100644 --- a/mesonbuild/scripts/depfixer.py +++ b/mesonbuild/scripts/depfixer.py @@ -127,8 +127,13 @@ class Elf(DataSizes): def __enter__(self): return self + def __del__(self): + if self.bf: + self.bf.close() + def __exit__(self, exc_type, exc_value, traceback): self.bf.close() + self.bf = None def detect_elf_type(self): data = self.bf.read(6) diff --git a/mesontest.py b/mesontest.py index 62ca4b2..1528ded 100755 --- a/mesontest.py +++ b/mesontest.py @@ -177,6 +177,8 @@ class TestHarness: self.is_run = False self.tests = None self.suites = None + self.logfile = None + self.jsonlogfile = None if self.options.benchmark: datafile = os.path.join(options.wd, 'meson-private', 'meson_benchmark_setup.dat') else: @@ -185,6 +187,12 @@ class TestHarness: raise TestException('Directory %s does not seem to be a Meson build directory.' % options.wd) self.load_datafile(datafile) + def __del__(self): + if self.logfile: + self.logfile.close() + if self.jsonlogfile: + self.jsonlogfile.close() + def run_single_test(self, wrap, test): if test.fname[0].endswith('.jar'): cmd = ['java', '-jar'] + test.fname @@ -285,7 +293,7 @@ class TestHarness: return result - def print_stats(self, numlen, tests, name, result, i, logfile, jsonlogfile): + def print_stats(self, numlen, tests, name, result, i): startpad = ' ' * (numlen - len('%d' % (i + 1))) num = '%s%d/%d' % (startpad, i + 1, len(tests)) padding1 = ' ' * (38 - len(name)) @@ -308,12 +316,12 @@ class TestHarness: and (result.returncode != 0) != result.should_fail: if self.options.print_errorlogs: self.collected_logs.append(result_str) - if logfile: - logfile.write(result_str) - if jsonlogfile: - write_json_log(jsonlogfile, name, result) + if self.logfile: + self.logfile.write(result_str) + if self.jsonlogfile: + write_json_log(self.jsonlogfile, name, result) - def print_summary(self, logfile): + def print_summary(self): msg = ''' OK: %4d FAIL: %4d @@ -321,8 +329,8 @@ SKIP: %4d TIMEOUT: %4d ''' % (self.success_count, self.fail_count, self.skip_count, self.timeout_count) print(msg) - if logfile: - logfile.write(msg) + if self.logfile: + self.logfile.write(msg) def print_collected_logs(self): if len(self.collected_logs) > 0: @@ -431,16 +439,14 @@ TIMEOUT: %4d if namebase: logfile_base += '-' + namebase.replace(' ', '_') - logfilename = logfile_base + '.txt' - jsonlogfilename = logfile_base + '.json' - - jsonlogfile = open(jsonlogfilename, 'w') - logfile = open(logfilename, 'w') + self.logfilename = logfile_base + '.txt' + self.jsonlogfilename = logfile_base + '.json' - logfile.write('Log of Meson test suite run on %s\n\n' - % datetime.datetime.now().isoformat()) + self.jsonlogfile = open(self.jsonlogfilename, 'w') + self.logfile = open(self.logfilename, 'w') - return logfile, logfilename, jsonlogfile, jsonlogfilename + self.logfile.write('Log of Meson test suite run on %s\n\n' + % datetime.datetime.now().isoformat()) def get_wrapper(self): wrap = [] @@ -467,56 +473,48 @@ TIMEOUT: %4d def run_tests(self, tests): executor = None - logfile = None - jsonlogfile = None futures = [] - try: - numlen = len('%d' % len(tests)) - (logfile, logfilename, jsonlogfile, jsonlogfilename) = self.open_log_files() - wrap = self.get_wrapper() - - for _ in range(self.options.repeat): - for i, test in enumerate(tests): - visible_name = self.get_pretty_suite(test) - - if self.options.gdb: - test.timeout = None - - if not test.is_parallel or self.options.gdb: - self.drain_futures(futures) - futures = [] - res = self.run_single_test(wrap, test) - self.print_stats(numlen, tests, visible_name, res, i, logfile, jsonlogfile) - else: - if not executor: - executor = conc.ThreadPoolExecutor(max_workers=self.options.num_processes) - f = executor.submit(self.run_single_test, wrap, test) - futures.append((f, numlen, tests, visible_name, i, logfile, jsonlogfile)) - if self.options.repeat > 1 and self.fail_count: - break + numlen = len('%d' % len(tests)) + self.open_log_files() + wrap = self.get_wrapper() + + for _ in range(self.options.repeat): + for i, test in enumerate(tests): + visible_name = self.get_pretty_suite(test) + + if self.options.gdb: + test.timeout = None + + if not test.is_parallel or self.options.gdb: + self.drain_futures(futures) + futures = [] + res = self.run_single_test(wrap, test) + self.print_stats(numlen, tests, visible_name, res, i) + else: + if not executor: + executor = conc.ThreadPoolExecutor(max_workers=self.options.num_processes) + f = executor.submit(self.run_single_test, wrap, test) + futures.append((f, numlen, tests, visible_name, i)) if self.options.repeat > 1 and self.fail_count: break + if self.options.repeat > 1 and self.fail_count: + break - self.drain_futures(futures) - self.print_summary(logfile) - self.print_collected_logs() + self.drain_futures(futures) + self.print_summary() + self.print_collected_logs() - if logfilename: - print('Full log written to %s' % logfilename) - finally: - if jsonlogfile: - jsonlogfile.close() - if logfile: - logfile.close() + if self.logfilename: + print('Full log written to %s' % self.logfilename) def drain_futures(self, futures): for i in futures: - (result, numlen, tests, name, i, logfile, jsonlogfile) = i + (result, numlen, tests, name, i) = i if self.options.repeat > 1 and self.fail_count: result.cancel() if self.options.verbose: result.result() - self.print_stats(numlen, tests, name, result.result(), i, logfile, jsonlogfile) + self.print_stats(numlen, tests, name, result.result(), i) def run_special(self): 'Tests run by the user, usually something like "under gdb 1000 times".' diff --git a/run_project_tests.py b/run_project_tests.py index 5994c5a..3420946 100755 --- a/run_project_tests.py +++ b/run_project_tests.py @@ -463,10 +463,15 @@ def detect_tests_to_run(): return gathered_tests def run_tests(all_tests, log_name_base, extra_args): - global stop, executor, futures + global logfile txtname = log_name_base + '.txt' + with open(txtname, 'w', encoding="utf_8") as lf: + logfile = lf + return _run_tests(all_tests, log_name_base, extra_args) + +def _run_tests(all_tests, log_name_base, extra_args): + global stop, executor, futures xmlname = log_name_base + '.xml' - logfile = open(txtname, 'w', encoding="utf_8") junit_root = ET.Element('testsuites') conf_time = 0 build_time = 0 diff --git a/run_tests.py b/run_tests.py index b17e0cb..040f958 100755 --- a/run_tests.py +++ b/run_tests.py @@ -104,12 +104,6 @@ def get_backend_commands(backend, debug=False): return cmd, clean_cmd, test_cmd, install_cmd, uninstall_cmd def ensure_backend_detects_changes(backend): - # We're using a ninja with QuLogic's patch for sub-1s resolution timestamps - # and not running on HFS+ which only stores dates in seconds: - # https://developer.apple.com/legacy/library/technotes/tn/tn1150.html#HFSPlusDates - # FIXME: Upgrade Travis image to Apple FS when that becomes available - if 'MESON_FIXED_NINJA' in os.environ and not mesonlib.is_osx(): - return # This is needed to increase the difference between build.ninja's # timestamp and the timestamp of whatever you changed due to a Ninja # bug: https://github.com/ninja-build/ninja/issues/371 |